wiki:ShortIntroductionToDevelopmentBasedOnPlatformPT

Short introduction to Bewelcome development

Key for understanding how the code works is to watch the action. Therefore we start looking at what happens, when a browser sends a request to the webserver of Bewelcome. Certain areas of development are particularly challenging; this is true for the way browser POST requests are dealt with. An explanation of POST request handling is given afterwards.

Request handling

1. Entry point /htdocs/index.php

We suppose your URL looks like this:

http://[your host]/[your app]

A typical URL in Bewelcome is http://www.bewelcome.org/donate. www.bewelcome.org is the host, donate is the application. An "application" or "app" in this sense of the word is a special area of the website, e.g. a place where you can donate, a forum or a place where you can send messages to other members.

Whatever URL is called, /htdocs/index.php is the entry point. The reason is the Rewrite rules in the Apache configuration of the virtual host of BeWelcome. (The virtual host config is probably called bewelcome or bewelcome.conf on your box - on Ubuntu it's usually in /etc/apache2/sites-available/.). index.php reads basic initialization files and sets several important constants. Lots of files and PHP classes are loaded, but most are not yet instantiated.

2. Your application is called

At one point in index.php the RoxLauncher? is instantiated. This moment is key:

  • Right after the launcher is instantiated, its launch method is called.
  • The launch method calls chooseAndRunApplication.
  • /routes.php is executed.

And routes.php has many of the mappings between URL and controller method. (Two remarks: Only a subset of the URLs are configured in routes.php; the rest is covered by a default mapping mechanism. And order matters: the first match in routes.php is followed.) Controllers are the files with the format extension ctrl.php. If you don't know what a controller is, you might want to read http://en.wikipedia.org/wiki/Model-view-controller.

Whenever you add a new app to Bewelcome, amend routes.php.

3. Model - View - Controller

Three types of files make an application in an MVC environment - and they're all in directories under /build/:

  1. [your app].model.php (model)
  2. [your app].view.php (view)
  3. [your app].ctrl.php (controller)

Depending on what you configured in routes.php, your application could have a completely different name from what is used in the URL. But better don't make use of it!

Because the controller is called from the framework, we start with the controller.

Controller

A method in the controller is the first method called in your application. The controller instantiates the model - at best in the constructor of the controller, but if you need a model depending on the request, you can also instantiate it in the entry method itself. [Is there a general recommendation or even a rule? I don't know.]

The controller method will use the model object for database access, call methods of the viewer (often initialized after the model - with the model as its object) and then PPHP::PExit();. It's also possible to return a page object.

Model

The model is, where you build query strings for the database and execute them. If you start to write a new application, create the model file with an empty constructor. At best just copy and adapt an existing model.php file.

A model class is always a child class of RoxModelBase?. RoxModelBase? gives you useful functionality out-of-the-box, e.g. tells you, if a user is logged in.

Keep in mind: The model class is for database access. Don't write HTML into a model class! Avoid to put logic into this class too. All methods should return the desired value (often an array) or update the database - that's it. But as the check of input of form fields is often involving database requests, you may place check methods in the model class.

View

There are two standard ways to write the actual content to the HTTP response in Bewelcome, views and pages.

The traditional way: View & Template

The view class is a list of methods that display things. As displaying things via HTML is verbose, the methods usually look like this:

  function displayPage() {
    // do some initialization of variables
    require '[directory of you app]/templates/[a particular page or page part of your app].php';
  }

As you can see: the HTML is somewhere else. At least most of it is in template files. The view class may be responsible for displaying different large pages. But it wouldn't make sense to put all the HTML in a single file.

Methods in the view class rarely return values. Instead they print the stuff to be displayed to the user.

If you're sure that no input is to be added after execution of the method in the viewer, terminate it with PPHP::PExit(); - the Bewelcome way of saying "all done in dealing with this request".

The modern way: Page & Template

There is another possibility to write HTML into the HTTP response. Instead of creating output in the wake of calling a viewer method, the controller method can return an object that extends PageWithHTML (see html.page.php). As part of such a page other controller classes can be called that contribute to the resulting HTML. More importantly such a page facilitates the use of existing layout widgets. For a good example see /build/activities/activities.ctrl.php and the use it makes of child classes of ActivitiesBasePage?.

4. Autoloader

autoload.ini is another file belonging to an app and is a simple text file that maps file names to classes in a x = y style. (You could have several classes in a single file. But don't! Create one file per class. That way it's possible for others to locate your classes without having to read the autoload.ini.) autoload.ini is important and should be amended as you're adding new MVC files to your app. [Would a class be loaded when not listed in this file? I don't know.]

5. Standard templates

May be you noticed something is missing. The content your application produced is only the main part of the page. Header, footer and other stuff are very similiar across many pages. Their elements are defined in /templates/shared/roxpage/[standard page element].php. But you will rarely need to change something here.

POST request handling

The POST handling follows the Post-Redirect-Get design pattern (e.g. see the Wikipedia article http://en.wikipedia.org/wiki/Post/Redirect/Get). The form submit is throughout replied to by a HTTP redirect (302). The standard way of implementing a POST form in platformPT requires three steps that are looked at in more detail below.

Step 1

Three special hidden fields need to be inserted in an HTML form in order to make platfromPT track form variables: posthandler_callback_id, posthandler_callback_classname and posthandler_callback_methodname. The details are of no importance, because there is a simple way to include them:

	<form action="myPrimaryFormAction" method="post">
	[...]
	<?=
        $this->layoutkit->formkit->setPostCallback('MyController', 'myCallBackMethod');
	?>
	[...]
	</form>

The setPostCallback method creates the string containing the three elements for you. Have a look at the generated code.

Step 2

The form action ("myPrimaryFormAction") must be declared in routes.php and is executed before myCalBackMethod (see Step 3). If the form action is not specified (at least add action="" to your form tag - otherwise you breach the HTML4 standard), the browser request will trigger the same method that was used to render the page - make sure it's suitable and doesn't execute any lengthy SQL queries that are unused in the resulting page!

If the method is new, it must be added to routes.php and the controller. It is executed before the callback method (see below). If the callback doesn't return a string (url - again, see below), the generated page must be returned by this method.

Step 3

Implement myCallBackMethod in your controller. This method is guaranteed to be called in the context of processing your form response. myCallBackMethod should have four arguments:

StdClass? $args: $args->post provides access to the form variables

ReadOnlyObject? $action: ?

ReadWriteObject? $mem_redirect: always (?!) empty when passed into the method, this variable can afterwards be accessed in the template as a container of the POST or error variables by $this->getRedirectedMem('vars') resp. $this->getRedirectedMem('errors');

ReadWriteObject? $mem_resend: always (?!) empty when passed into the method; [not sure what its purpose is]

The implementation of the method should be along these lines:

  1. Check form variables, typically done by a call to a validating method in the model that returns an error array.
  1. If the array of errors in not empty, this code could be used:
	$mem_redirect->errors = $errors;
	$mem_redirect->vars = $args->post;

Your method can either return a boolean (true or false) to indicate the success or failure of the method. (The generated page will however be the same - the boolean value is not seen by the user.) Or it can return a string that is used for the redirect, e.g.

return $this->router->url('admin_rights_member', array("username" => $vars['username']), false);

(an example in the adminrights.ctrl.php). The url method returns a string - for a documentation see the method comment.

Your Hello World Application

This application might help you to get started: HelloWorld.



[[Category:Platform PT]]

Last modified 3 years ago Last modified on Jul 4, 2014 11:40:58 AM