Adventure,PHP,framework,page controller,front controller,pattern,object orientated design,software,development,reusability,uml,tutorial,benchmark,brilliant performance,

Search:    
Downloads  |  SVN!  |  Roadmap  |  Forum!  |  Bugtracking  |  Guestbook  |  Backlinks!  |  References!  |  Sitemap  |  Impress  
 
Deutsch | English Adventure PHP Framework  Bookmark @ Technorati Bookmark @ del.icio.us Bookmark @ Mr. Wong Bookmark @ Simpy Bookmark @ Google Bookmark @ Digg.com Adventure PHP Framework Print page 012-Frontcontroller

Frontcontroller

1. Introduction

Rank article:
This article has not yet been ranked. Vote this article first of all!
The front controller is as mentioned before another central integral part of the adventure php framework. Basic to this implementation ar the definition of the fron controller pattern of Martin Fowler and the java sources of the java application framework struts. To go further into this topic please visit the PHP patterns website (german).

The front controller component used in this application framework is a singleton instance of the FrontController class, takes the command given in the users' requests and executes the actions existing for the effective application. There are several kinds of actions that are executed according to the timing model described later on. In common, action types containing the "pre" keyword are execuded before a specific task, action types that contain the "post" keyword are execued after a defined step. The "prepagecreate" actions often are taken to create the application's model, "posttransform" actions merely are used to to things like logging. To implement front controller actions the framework contains two abstract implementations that serve as basis for concrete implementations for actions (AbstractFrontcontrollerAction) and their information (FrontcontrollerInput). The frontcontrollerRequestFilter and frontcontrollerRewriteRequestFilter are designed to extract the action commands out of the url so that the front controller can execute them. These two components the developers does not get in contact with in common, becaus the front controller executes them itself. In order to have actions, that are executed at each request, the developer can register these actions to the front controller in the central index.php file. These act like normal actions concering the timing model. The following UML diagramm shows the front controller components altogether:

Frontcontroller


2. Implementation

Software written in front controller style merely contain two areas. For a start action and input classes must be written that inherit from AbstractFrontcontrollerAction and FrontcontrollerInput, further, a configuration that describes the action must be built.


2.1. Action and input classes

Classes that are descended from the abstract action and input classes encapsulate the functionality of an action. As it is described in the API documentation an action class must implement the run() method, because this function is execuded for each action during dispatching. An input class is a data class that contains the model information of the action. In a simple application, the input object of an front controller action can form the model concurrently. The code example printed after this passage shows two simple action an input classes:
   class DemoAction extends AbstractFrontcontrollerAction
   
{

      function 
DemoAction(){
      }

      function 
run(){
         echo 
'I am front controller action class! My name is '.$this->__Input->getAttribute('Name').'!';
       
// end function
      
}

    
// end class
   
}

   class 
DemoInput extends FrontcontrollerInput
   
{

      function 
DemoInput(){
         
$this->__Attributes['Name'] = 'James Blunt';
       
// end function
      
}

    
// end class
   
If this action is executed, the output shows the sentence
  I am front controller action class! My name is James Blunt!
Due to the fact that actions know the context of the entire application, actions can be used to encapsulate various parts of an application if reasonable. A popular example is user authentication. This can be achieved by checking the user's credentials in a "prepagecreate" action and set the parameters of the application to the desired valued.


2.2. Configuration

Each action must be defined within a configuration file. This file must contain the namespace to the action and input classes, the file name of the classes and the class names itself. Configuration files must be stored under the directory that can be defined by the expression
{ActionNamespace}::actions::{Context}
The name of the configuration file can be described by
{ENVIRONMENT}_actionconfig.ini
{ENVIRONMENT} must be replaced by the current value of the environment variable stored in the registry. By default, this valus must be replaced with DEFAULT. Each file can contain one or more action definitions for actions, that belong to the same namespace.
[{ActionName}]
FC.ActionNamespace = ""
FC.ActionFile = ""
FC.ActionClass = ""
FC.InputFile = ""
FC.InputClass = ""
FC.InputParams = ""
Besides, the performed parameters have the following meanings:
  • ActionName:
    Name of the action. This name must be present in the URL if the defined action should be called (Example: setModel).
  • FC.ActionNamespace:
    Namespace of the action's configuration file (Example: sites::demosite::biz::actions).
  • FC.ActionFile:
    Name of the file that contains the action class implementation (Example: LoadModelAction).
  • FC.ActionClass:
    Name of the action class (Example: LoadModelAction).
  • FC.InputFile:
    Name of the file, the input class resides (Example: DemositeModel).
  • FC.InputClass:
    Name of the input class (Example: DemositeModel).
  • FC.InputParams:
    Configuration directive that defines the start parameters of an input object. This is often used to configure a specific action for the use in a specific application without changing the source code. (Example: login:true|headview:menu. Key and value are separated by ":", different pairs by "|").
Due to the fact, that front controller actions are part of the business layer the code files should be placed under the biz folder of an module or application. In common the developer creates a subfolder named actions to store these files and to generate more clarity. Since namespace and name of the class files can be choosen freely the developer faces no restictions.


2.3. Changes to the index.php

To operate an application in front controller style the index.php file must contain the following lines of code:
   // create an instance of the front controller
   
$fC = &Singleton::getInstance('Frontcontroller');

   
// set the context of the application
   
$fC->set('Context','sites::demosite');

   
// set the desired standard language
   
$fC->set('Language','de');

   
// generate the specified site
   
$fC->start('sites::demosite::pres::templates','website'); 
If desired the developer can register "permanent" actions by
   // register action "Login"
   
$fC->registerAction('sites::demosite::biz','Login'); 
before the execution of the start() methode. Now it is possible to execute any actions in applications or modules.


2.4. Link generation

In order to generate links as easy as within page controller applications the component frontcontrollerLinkHandler was introduced. This class can be used to manipulate existing URLs or create new URLs. If an action's private attribute $__KeepInURL is set to true, the action along with its input attributes is added to the URL that is generated by the frontcontrollerLinkHandler. This adds the possibility to have more than one action definition in one URL and so create complex programms. The following example shows how the frontcontrollerLinkHandler can be used. To keep things simple the links will be descussed in rewrite mode only. Manipulating "normal" URLs is similar.


2.4.1. Simple manipulation of parameters
In many applications it is necessary to generate dynamic links. Within front controller based applications where no dynamic URLs are necessary the linkHandler can be used instead of the frontcontrollerLinkHandler component. But it is recommended to use the the latter to be secure. To change the link
  http://www.adventure-php-framework.org/Page/Home/benchmarkreport/true/param1/value1/param2/value2
to the link
  http://www.adventure-php-framework.org/Page/Guestbook/benchmarkreport/true
in an easy way, the following code fragment can be used:
   // define URL
   
$URL 'http://www.adventure-php-framework.org/Page/ChangeLog/benchmarkreport/true/param1/value1/param2/value2';

   
// define changes
   
$ChangeParams = array(
                         
'Page' => 'Guestbook',
                         
'param1' => '',
                         
'param2' => ''
                         
);

   echo 
frontcontrollerLinkHandler::generateLink($URL,$ChangeParams); 

2.4.2. Manipulation of parameters and actions
Action definitions are treated as "normal" URL parameters as well. Thus is low-end to change the URL
  http://www.adventure-php-framework.org/Page/ChangeLog/benchmarkreport/true/param1/value1/param2/value2
to
  http://www.adventure-php-framework.org/Page/Guestbook/benchmarkreport/true/param1/value1/param2/value2/~/
  modules_guestbook_biz-action/LoadEntryList/pagesize/20/pager/false/adminview/true
In this case the following parameter array was given to the generateLink methode:
   // define URL
   
$URL 'http://www.adventure-php-framework.org/Page/ChangeLog/benchmarkreport/true/param1/value1/param2/value2';

   
// define changes to the URL
   
$ChangeParams = array(
                         
'modules_guestbook_biz-action:LoadEntryList' => 'pagesize:20|pager:false|adminview:true',
                         
'Page' => 'Guestbook'
                         
);

   
// generate link
   
echo frontcontrollerLinkHandler::generateLink($URL,$ChangeParams); 
If the desired action was added as a "permanent" action it is only necessary to call the frontcontrollerLinkHandler without a second parameter. In doing so all actions that have configured $__KeepInURL to true will be contained in the URL definition.


2.4.3. Manipulation of parameters and actions with help of generateURLParams()
The example in chapter 1.4.2 has the disadvantage, that the developer must be aware of the syntax of a frontcontroller URL. To make generation of front controller URLs more comfortable, the frontcontrollerLinkHandler features the method generateURLParams. This function can generate an action parameter array for use with the generateLink() method. Generation goes as follows:
   // define URL
   
$URL 'http://www.adventure-php-framework.org/Page/ChangeLog/benchmarkreport/true/param1/value1/param2/value2';

   
// define URL changes
   
$ChangeParams = array(
                         
'Page' => 'Guestbook'
                        
);

   
// Parameter der FrontController-Action erzeugen
   
$ChangeParams array_merge(
                               
$ChangeParams,
                               
frontcontrollerLinkHandler::generateURLParams(
                                                                             
'modules::guestbook::biz',
                                                                             
'LoadEntryList',
                                                                             array(
                                                                                   
'pagesize' => '20',
                                                                                   
'pager' => 'false',
                                                                                   
'adminview'  => 'true'
                                                                                  
)
                                                                             )
                              );

   
// generate link
   
echo frontcontrollerLinkHandler::generateLink($URL,$ChangeParams); 
Owing to performance issues this method should not be used excessively. One generation commonly consumes about 0.004 sec to generate the parameter array. If the operation mode concerning the url style is clear, the URLs should be generated as described in chapter 1.4.2.


2.5. Timing model

The FrontController has it's own timing model that enables the developer to influence at which point of time the action is executed. The time can be defined the class attribute $__Type of the AbstractFrontcontrollerAction class. This value is prepagecreate by default. There are four modes defined:
  • prepagecreate: Action is executed before the page object is created an the DOM tree is created.
  • postpagecreate: Action is executed after the creation of the page controller page.
  • pretransform: Action is executed before transforming the page controller page.
  • posttransform: Action is executed after transforming the page controller page.
To define the right mode of your action, please define your action class as follows:
   class MyAction extends AbstractFrontcontrollerAction
   
{

      
// set timing
      
var $__Type 'pretransform';


      function 
MyAction(){
      }

      function 
run(){
      }

    
// end class
   
Details for the function run() can be seen in the API documentation of the class Frontcontroller.


2.6. Model based view concept

In contrast to page controller applications, the front controller allows to instanciate the business layer before the presentation tier. This holds the advantage to use the business layer to control the presentation tier, in particular, the views or the content of the views of an application.

To rip this advantage off in GUI design the XML taglib fcon_taglib_importdesign was introduced. This component includes views, that are defined within an application model, that is filled by front controller actions. In common the developer can create a independent business class like this:
   class DemoSiteModel extends coreObject
   
{

      function 
DemoSiteModel(){
         
$this->__Attributes['view.content.template'] = 'login';
         
$this->__Attributes['view.topmenu.template'] = 'empty';
       
// end function
      
}

    
// end class
   
Filling the attributes can be achieved by getting reference on this class by
   $Model = &$this->__getServiceObject('sites::demosite::biz','DemoSiteModel'); 
By adding the XML tag
  <fcon:importdesign
      templatenamespace="sites::apfdocupage::pres::templates"
      modelnamespace="sites::demosite::biz"
      modelfile="DemoSiteModel"
      modelclass="DemoSiteModel"
      modelparam="view.content.template"
  />
to a template file a view depending on the model's parameters can be included. To use the tag it must be announced using the
  <core:addtaglib namespace="tools::html::taglib" prefix="fcon" class="importdesign" />
directive.

With this concept views can easily be included by model information and the GUI can be controlled by the business layer completely. Moreover this is more flexible compared with the page controller as a single responsible entity.


Comments

Do you want to add a comment to the article above, or do you want to post additional hints? So please click here. Comments already posted can be found below.


There are no comments belonging to this article.


Powered by WebRing.