PHPonTrax
[ class tree: PHPonTrax ] [ index: PHPonTrax ] [ all elements ]

Source for file router.php

Documentation is available at router.php

  1. <?php
  2. /**
  3.  *  File containing the Router class
  4.  *
  5.  *  (PHP 5)
  6.  *
  7.  *  @package PHPonTrax
  8.  *  @version $Id: router.php 174 2006-03-14 04:10:15Z haas $
  9.  *  @copyright (c) 2005 John Peterson
  10.  *  
  11.  *   Permission is hereby granted, free of charge, to any person obtaining
  12.  *   a copy of this software and associated documentation files (the
  13.  *   "Software"), to deal in the Software without restriction, including
  14.  *   without limitation the rights to use, copy, modify, merge, publish,
  15.  *   distribute, sublicense, and/or sell copies of the Software, and to
  16.  *   permit persons to whom the Software is furnished to do so, subject to
  17.  *   the following conditions:
  18.  *
  19.  *   The above copyright notice and this permission notice shall be
  20.  *   included in all copies or substantial portions of the Software.
  21.  *
  22.  *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  23.  *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  24.  *   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  25.  *   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
  26.  *   LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
  27.  *   OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
  28.  *   WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  29.  */
  30.  
  31. /**
  32.  *  Convert a URL to an action
  33.  *  @tutorial PHPonTrax/Router.cls
  34.  */
  35. class Router {
  36.  
  37.     /**
  38.      *  Route table
  39.      *
  40.      *  For a description of the structure, see
  41.      *  {@tutorial PHPonTrax/Router.cls#table the Router tutorial}.
  42.      *  Routes are added by calling {@link connect()} and looked up
  43.      *  by calling {@link find_route()}.
  44.      *  <b>FIXME:</b> Should we have a Route class to describe an
  45.      *  entry in the route table?
  46.      *  @var string[][] 
  47.      */
  48.     private $routes = array();
  49.  
  50.     /**
  51.      *  Last route found by a call to find_route()
  52.      *  @var string[] 
  53.      */
  54.     private $selected_route = null;
  55.  
  56.     /**
  57.      *  Default route path
  58.      *
  59.      *  This route path is added to the route table if the table is
  60.      *  empty when find_route() is called.
  61.      *  @var string constant
  62.      */
  63.     private $default_route_path = ":controller/:action/:id";
  64.  
  65.     /**
  66.      *  Count of the number of elements in $routes
  67.      *  @var integer 
  68.      */
  69.     public $routes_count = 0;
  70.  
  71.     /**
  72.      *  Accessor method to return contents of $selected_route
  73.      *  @return string[] Contents of $selected_route
  74.      *  @uses $selected_route
  75.      */
  76.     function get_selected_route({
  77.         return $this->selected_route;
  78.     }
  79.  
  80.     /**
  81.      *  Accessor method to add a route to the route table
  82.      *
  83.      *  The route is added to the end of
  84.      *  {@link $routes the route table}. If $params is not an array,
  85.      *  NULL is stored in the route parameter area.
  86.      *  @param string $path 
  87.      *  @param mixed[] $params 
  88.      *  @uses $routes
  89.      *  @uses $routes_count
  90.      */
  91.     function connect($path$params null{
  92.         if(!is_array($params)) $params null;
  93.         $this->routes[$this->routes_count]['path'$path;
  94.         $this->routes[$this->routes_count]['params'$params;
  95.         $this->routes_count = count($this->routes);
  96.     }
  97.  
  98.     /**
  99.      *  Find first route in route table with path that matches argument
  100.      *
  101.      *  First, assure that the route table {@link $routes} has at
  102.      *  least one route by adding
  103.      *  {@link $default_route_path the default route} if the table is
  104.      *  empty.  Then search the table to find the first route in the
  105.      *  table whose path matches the argument $url. If $url is an
  106.      *  empty string, it matches a path that is an empty string.
  107.      *  Otherwise, try to match $url to the path part of the table
  108.      *  entry according to
  109.      *  {@link http://www.php.net/manual/en/ref.pcre.php Perl regular expression}
  110.      *  rules.  If a matching route is found, return it any to the caller, and
  111.      *  also save a copy in {@link $selected_route}; if no matching
  112.      *  route is found return null.
  113.      *  @param string $url 
  114.      *  @uses build_route_regexp()
  115.      *  @uses $default_route_path
  116.      *  @uses $routes
  117.      *  @uses $routes_count
  118.      *  @uses $selected_route
  119.      *  @return mixed Matching route or null.  Path is in return['path'],
  120.      *                    params in return['params'],
  121.      */
  122.     function find_route($url{
  123.         //error_log('url='.$url);
  124.         // ensure at least one route (the default route) exists
  125.         if($this->routes_count == 0{
  126.             $this->connect($this->default_route_path);
  127.         }
  128.  
  129.         $this->selected_route = null;
  130.  
  131.         foreach($this->routes as $route{
  132.             unset($route_regexp);
  133.             unset($reg_exp);
  134.             $route_regexp $this->build_route_regexp($route['path']);
  135.             //error_log("route regexp=/$route_regexp/");
  136.             if($url == "" && $route_regexp == ""{
  137.                 //error_log('selected');
  138.                 $this->selected_route = $route;
  139.                 break;
  140.             elseif(preg_match("/$route_regexp/",$url&& $route_regexp != ""{
  141.                 //error_log('selected');
  142.                 $this->selected_route = $route;
  143.                 break;
  144.             elseif($route['path'== $this->default_route_path{
  145.                 //error_log('defaulted');
  146.                 $this->selected_route = $route;
  147.                 break;
  148.             }
  149.         }
  150.         //error_log('selected route='.var_export($this->selected_route,true));
  151.         return $this->selected_route;
  152.     }                                 // function find_route($url)
  153.  
  154.     /**
  155.      *  Build a regular expression that matches a route
  156.      *
  157.      *  @todo <b>FIXME:</b> Should this method be private?
  158.      *  @todo <b>FIXME:</b> Shouldn't the regexp match be the same as
  159.      *   for a PHP variable name? '[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*'
  160.      *  @param string $route_path  A route path.
  161.      *  @return string Regular expression that matches the route in
  162.      *                 $route_path
  163.      */
  164.     function build_route_regexp($route_path{
  165.         //        echo "entering build_route_regexp(), \$route_path is '$route_path'\n";
  166.  
  167.         $route_regexp null;
  168.  
  169.         if(!is_array($route_path)) {
  170.             $route_path explode("/",$route_path);
  171.         }
  172.         //error_log("route path:\n".var_export($route_path,true));
  173.         if(count($route_path0{
  174.             foreach($route_path as $path_element{
  175.                 if(preg_match('/:[a-z0-9_\-]+/',$path_element)) {
  176.                     $reg_exp['[a-z0-9_\-]+';
  177.                 else {
  178.                     $reg_exp[$path_element;
  179.                 }
  180.             }
  181.             if(is_array($reg_exp)) {
  182.                 $route_regexp "^".implode("\/",$reg_exp)."$";
  183.             }
  184.         }
  185.         return $route_regexp;
  186.     }
  187.  
  188. }
  189.  
  190. // -- set Emacs parameters --
  191. // Local variables:
  192. // tab-width: 4
  193. // c-basic-offset: 4
  194. // c-hanging-comment-ender-p: nil
  195. // indent-tabs-mode: nil
  196. // End:
  197. ?>

Documentation generated on Mon, 21 May 2007 22:28:45 -0600 by phpDocumentor 1.3.2