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_path) > 0) {
  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 Thu, 04 May 2006 19:47:52 -0600 by phpDocumentor 1.3.0RC4