Tuesday, May 18, 2010

Routing of a controller action


In this example, we create routes and we compare URLs against those routes.

Components used in this example
Using the router

class MyRouter
{
    const BASE_URL 'http://domain/';

Description of the routes

    public static $routes = array(
        => array('default'),
        array(
            'author/USER-NAME [controller="profile", action="userinfo"]',
            'Zend_Controller_Router_Route',
            'author/:username',
            array(
                'controller' => 'profile',
                'action' => 'userinfo',
            )
        ),
        array(
            'archive/YYYY [controller="archive", action="show", YEAR=2006]',
            'Zend_Controller_Router_Route',
            'archive/:year',
            array(
                'year' => 2006,
                'controller' => 'archive',
                'action' => 'show',
            ),
            array('year' => '\d+')
        ),
        array(
            'case/NNN-DESCRIPTION.html [controller="case", action="view"]',
            'Zend_Controller_Router_Route_Regex',
            'case/(\d+)-(.+)\.html',
            array(
                'controller' => 'case',
                'action'     => 'view'
            ),
            array(
                => 'id',
                => 'description'
            )
        ),
    );

Definition of the URLs

    public static $uri = array(
        'default route' => array(
            '',
            'news',
            'blog/archive',
            'blog/archive/list',
            'blog/archive/list/sort/alpha/date/desc',
            'foo',
        ),
        'author route' => array(
            'author/martel',
            'author/john/param/unexpected',
        ),
        'archive route' => array(
            'archive',
            'archive/2008',
            'archive/bad',
        ),
        'case route' => array(
            'case/123-the-good-case.html',
            'case/xyz-the-bad-case.html',
        ),
    );

Processing the routing request
  • We get the route, the option to disable of the default routes, the option to ignore modules, the URL.
  • We create the front controller.
  • We ignore the modules if requested.
  • We instantiate the router.
  • We remove the default routes if requested.
  • We add the route.
  • We extract from the URL, the module, the controller, the action and the parameters.
  • If we catch an exception, we return the error message.

    public function process()
    {
        // We get the route, the option to disable of the default routes,
        // the option to ignore modules, the URL.
        list($route$disableDefault$disableModule$uri) = $this->_getParameters();

        try {
            // We create the front controller.
            $front Zend_Controller_Front::getInstance();

            if (!$disableModule) {
                // We ignore the modules if requested.
                $front->addControllerDirectory('dummy''blog');
                $front->addControllerDirectory('dummy''news');
            }

            // We instantiate the router.
            $router $front->getRouter();
            // We remove the default routes if requested.
            $disableDefault and $route and $router->removeDefaultRoutes();

            // We add the route.
            @list(, $class$pattern$defaults$reqs) = self::$routes[$route];
            $class and $router->addRoute('route',
                new $class($pattern$defaults$reqs));

            // We extract from the URL,  the module, the controller, the action and the parameters.
            $request = new Zend_Controller_Request_Http(self::BASE_URL $uri);
            $params $router->route($request)->getParams();
            $result array_diff_key($params$_GET);

            } catch (Exception $e) {
            // If we catch an exception, we return the error message.
            $result $e->getMessage();
        }

        return array($route$disableDefault$disableModule$uri$result);
    }

Extraction of the parameters from the GET request

    private function _getParameters()
    {
        $route = (isset($_GET['route']) and isset(self::$routes[$_GET['route']]))?
            $_GET['route'] : 0;

        $disableDefault = empty($_GET)? : !empty($_GET['disable-default']);
        $disableModule = empty($_GET)? : !empty($_GET['disable-module']);

        $uri = isset($_GET['uri'])? $_GET['uri'] : '';

        return array($route$disableDefault$disableModule$uri);
    }


}

No comments:

Post a Comment