[ Index ]

PHP Cross Reference of Limb3

title

Body

[close]

/web_app/src/request/ -> lmbRoutes.class.php (source)

   1  <?php
   2  /*
   3   * Limb PHP Framework
   4   *
   5   * @link http://limb-project.com 
   6   * @copyright  Copyright &copy; 2004-2007 BIT(http://bit-creative.com)
   7   * @license    LGPL http://www.gnu.org/copyleft/lesser.html 
   8   */
   9  
  10  /**

  11   * class lmbRoutes.

  12   *

  13   * @package web_app

  14   * @version $Id: lmbRoutes.class.php 5945 2007-06-06 08:31:43Z pachanga $

  15   */
  16  class lmbRoutes
  17  {
  18    protected $config = array();
  19    const NAMED_PARAM_REGEXP = '(?:\/([^\/]+))?';
  20    const EXTRA_PARAM_REGEXP = '(?:\/(.*))?';
  21  
  22    function __construct($config)
  23    {
  24      $this->config = $config;
  25    }
  26  
  27    function dispatch($url)
  28    {
  29      foreach($this->config as $route)
  30      {
  31        if(($result = $this->_getResultMatchedParams($route, $url)) === null)
  32          continue;
  33  
  34        if(!$this->_routeParamsMeetRequirements($route, $result))
  35          continue;
  36  
  37        return $this->_applyDispatchFilter($route, $result);
  38      }
  39  
  40      return array();
  41    }
  42  
  43    function toUrl($params, $route_name = '')
  44    {
  45      if($route_name && isset($this->config[$route_name]))
  46      {
  47        if($path = $this->_makeUrlByRoute($params, $this->config[$route_name]))
  48          return $path;
  49      }
  50      elseif(!$route_name)
  51      {
  52        foreach($this->config as $name => $route)
  53        {
  54          if($path = $this->_makeUrlByRoute($params, $route))
  55            return $path;
  56        }
  57      }
  58      throw new lmbException($message = "Route '$route_name' not found for params '" . lmb_var_dump($params) . "'");
  59    }
  60  
  61    protected function _applyDispatchFilter($route, $dispatched)
  62    {
  63      if(!isset($route['dispatch_filter']) && !isset($route['rewriter']))
  64        return $dispatched;
  65  
  66      //'rewriter' is going to be obsolete

  67      $filter = isset($route['dispatch_filter']) ? $route['dispatch_filter'] : $route['rewriter'];
  68  
  69      if(!is_callable($filter))
  70        throw new lmbException('Dispatch filter is not callable!', array('filter' => $filter));
  71  
  72      call_user_func_array($filter, array(&$dispatched, $route));
  73      return $dispatched;
  74    }
  75  
  76    protected function _applyUrlFilter($route, $path)
  77    {
  78      if(!isset($route['url_filter']))
  79        return $path;
  80  
  81      $filter = $route['url_filter'];
  82  
  83      if(!is_callable($filter))
  84        throw new lmbException('Url filter is not callable!', array('filter' => $filter));
  85  
  86      call_user_func_array($filter, array(&$path, $route));
  87      return $path;
  88    }
  89  
  90    protected function _getResultMatchedParams($route, $url)
  91    {
  92      if(($matched_params = $this->_getMatchedParams($route, $url)) === null)
  93        return null;
  94  
  95      if(isset($route['defaults']))
  96        return array_merge($route['defaults'], $matched_params);
  97      else
  98        return $matched_params;
  99    }
 100  
 101    function _getMatchedParams($route, $url)
 102    {
 103      $named_params = array();
 104  
 105      $regexp = $this->_getRouteRegexp($route['path'], $named_params);
 106  
 107      if(!preg_match($regexp, $url, $matched_params))
 108        return null;
 109  
 110      array_shift($matched_params);
 111  
 112      $result = array();
 113  
 114      $index = 0;
 115      foreach($matched_params as $matched_item)
 116        if($param_name = $named_params[$index++])
 117          $result[$param_name] = $matched_item;
 118  
 119      return $result;
 120    }
 121  
 122    function _getRouteRegexp($route_path, &$named_params)
 123    {
 124      $elements = array();
 125      foreach (explode('/', $route_path) as $element)
 126        if (trim($element))
 127          $elements[] = $element;
 128  
 129      $final_regexp_parts = array();
 130  
 131      foreach ($elements as $element)
 132      {
 133        if($name = $this->_getNamedUrlParam($element))
 134        {
 135          $final_regexp_parts[] = self :: NAMED_PARAM_REGEXP;
 136          $named_params[] = $name;
 137        }
 138        elseif ($name = $this->_getExtraNamedParam($element))
 139        {
 140          $final_regexp_parts[] = self :: EXTRA_PARAM_REGEXP;
 141          $named_params[] = $name;
 142        }
 143        else
 144          $final_regexp_parts[] = '/' . $element;
 145      }
 146  
 147      return '#^' . implode('', $final_regexp_parts) . '[\/]*$#';
 148    }
 149  
 150    protected function _getNamedUrlParam($element)
 151    {
 152      if(preg_match('/^:(.+)$/', $element, $matches))
 153        return $matches[1];
 154      else
 155        return null;
 156    }
 157  
 158    protected function _getExtraNamedParam($element)
 159    {
 160      if(preg_match('/^\*(.+)?$/', $element, $matches))
 161      {
 162        if(isset($matches[1]))
 163          return $matches[1];
 164        else
 165          return 'extra';
 166      }
 167      else
 168        return null;
 169    }
 170  
 171    protected function _routeParamsMeetRequirements($route, $params)
 172    {
 173      foreach($params as $param_name => $param_value)
 174      {
 175        if(!$this->_singleParamMeetsRequirements($route, $param_name, $param_value))
 176          return false;
 177      }
 178      return true;
 179    }
 180  
 181    protected function _singleParamMeetsRequirements($route, $param_name, $param_value)
 182    {
 183       return (!isset($route['requirements'][$param_name]) ||
 184              preg_match($route['requirements'][$param_name], $param_value, $req_res));
 185    }
 186  
 187    function _makeUrlByRoute($params, $route)
 188    {
 189      $path = $route['path'];
 190  
 191      foreach($params as $param_name => $param_value)
 192      {
 193        if(strpos($path, ':'.$param_name) === false)
 194          continue;
 195  
 196        $path = str_replace(':'. $param_name, $param_value, $path);
 197        unset($params[$param_name]);
 198      }
 199  
 200      if(count($params))
 201        return '';
 202  
 203      if(isset($route['defaults']))
 204      {
 205        foreach($route['defaults'] as $param_name => $param_value)
 206          $path = str_replace(':'. $param_name, $param_value, $path);
 207      }
 208  
 209      if(strpos($path, "/:") !== false)
 210        return '';
 211  
 212      return $this->_applyUrlFilter($route, $path);
 213    }
 214  }
 215  
 216  ?>


Generated: Tue Oct 7 05:02:03 2008 Cross-referenced by PHPXref 0.7