Tina MVC Dispatcher Method Tutorial

The dispatch() method was added to the Tina MVC base in version 0.1.10. It automatically executes a method in your page controller using a simple naming convention.

This should save you time and make your code more readable.

Why use the dispatcher?

Short answer:

You don’t have to. In fact for simple applications (that do not require authentication) there is no real advantage to using the dispatcher.

Longer answer:

The Tina MVC front end controller loads your class file and automatically creates an instance of your page controller. Up to now, the constructor also decides which class method to call based on the value of the Tina MVC request (the $request variable passed to your page controller). It also means that your class method is executed before authentication has been completed, which is inefficient and can cause unexpected results.

The dispatcher method is part of the base page class and does away with this. It also saves you having to write your own dispatcher logic into your own classes.

How the dispatcher works

For example, a call to http://www.example.com/my-front-end-controller/my-page-controller will automatically load the file my_page_controller.php and create an instance of the class my_page_controller. The my_page_controller class extends the tina_mvc_base_page_controller_class.

The dispatch() method is invoked by setting $this->use_dispatcher = TRUE in my_page_controller->__construct(). It will be called after authentication checks in the front end controller have been completed successfully.

An example

(You will find this example in the tina-mvc/sample_apps folder. Copy it into your apps folder as is.)

<?php
/**
* A test for the dispatcher
*
* Shows you how to use the disatcher
*
* @package    Tina-MVC
* @subpackage Tina-Sample-Apps
* @author     Francis Crossen <francis@crossen.org>
*/
 
/**
 * Illustrates the use of the dispatcher
 *
 * @package    Tina-MVC
 * @subpackage  Tina-Sample-Apps
 */
class dispatcher_example_page extends tina_mvc_base_page_class {
 
    /**
    * Check the request and call the appropriate class method
    *
    * @param   array $request extracted from $_GET - /controller/action/some/data
    */
    function __construct( $request ) {
 
        // permission override - this controller should be accessible to all...
        $this->role_to_view = FALSE;
        parent::__construct(  $request );
 
        /**
         * This is what enables the dispatcher function. Your method will be called AFTER
         * permissions checks have been completed.
         */
        $this->use_dispatcher = TRUE;
 
    }
 
    /**
    * Default controller
    */
    function index() {        
        $this->set_post_title('Hello from the \''.__FUNCTION__.'\' method!');
        $this->set_post_content( $this->_some_blurb() );
    }
 
    /**
    * Another controller
    */
    function another_controller() {
        $this->set_post_title('Hello from the \''.__FUNCTION__.'\' method!');
        $this->set_post_content( $this->_some_blurb() );
    }
 
    /**
    * Yet another controller
    */
    function yet_another_controller() {
        $this->set_post_title('Hello from the \''.__FUNCTION__.'\' method!');
        $this->set_post_content( $this->_some_blurb() );
    }
 
    /**
    * Some blurb
    *
    * You will note it is private to prevent it from being called in response to a
    * request. Name it with a leading underscore to prevent the dispatcher from executing
    * it. Follow this example
    */
    private function _some_blurb() {
        return
        'It Worked! (at '.tina_mvc_db_datetime().')'.
        '<hr>Valid Controllers:<br />'.
        tina_mvc_make_controller_link( 'dispatcher-example' ).' - <br />'.
        tina_mvc_make_controller_link( 'dispatcher-example/index' ).' - The index (default) controller. Same as above. <br />'.
        tina_mvc_make_controller_link( 'dispatcher-example/another-controller' ) . ' - The another-controller controller.<br />'.
        tina_mvc_make_controller_link( 'dispatcher-example/yet-another-controller' ) . ' - The yet-another-controller controller.<br />'.
        tina_mvc_make_controller_link( 'dispatcher-example/_some-blurb' ) . ' - This should be inaccessible - it is defined private and named with a leading underscore to prevent the dispatcher from executing it.<br />'.
        tina_mvc_make_controller_link( 'dispatcher-example/private_function' ) . ' - Inaccessible - it is defined private. Clicking this will display a PHP error (if your server displays them) or a blank page.<br />'.
        tina_mvc_make_controller_link( 'dispatcher-example/doesnt-exist' ) . ' - A non existant controller.<br />'
        ;
    }
 
    /**
    * Private
    *
    * Cannot be loaded by the dispatcher. Will trigger a PHP error
    */
    private function private_function() {
        return true;
        'It Worked! It shouldn\'t have - call Zend!'
        ;
    }
 
}
 
?>

Main points

1. Your page controller methods are called according to the Tina MVC request. For example:

URL path called (File) Class and method called Notes
/my-front-end-controller/my-page-controller (my_page_controller.php) my_page_controller->index()
/my-front-end-controller/my-page-controller/index (my_page_controller.php) my_page_controller->index() This is the same as the default action above
/my-front-end-controller/my-page-controller/an-action (my_page_controller.php) my_page_controller->an_action()
/my-front-end-controller/my-page-controller/_an-invalid-action Will not work! Methods named with a leading underscore are ignored by the dispatch() method
/my-front-end-controller/my-page-controller/a-private-class-method Will not work! Private methods can not be accessed by derived (descendant) classes.

2. Any public class method can be accessed using this convention (see point 3 below)

http://www.example.com/my-front-end-controller/my-page-controller/a-public-method is mapped onto my_page_controller->an_action().

3. Prevent methods from being loaded by the dispatcher by naming them with a leading underscore (‘_’) and by defining them as private.

http://www.example.com/my-front-end-controller/_this-will-not-work will not call the _this_will_not_work() method. In the example above the _some_blurb() method cannot be loaded by a descendant class because it is private. If you do not name it with a leading underscore, and the dispatcher attempts to load it, a fatal PHP error will result.

4. Read point 3 again – it is important for security!

Enjoy,
Fran.

Leave a Reply