Changeset 161
- Timestamp:
- 03/02/06 17:20:34 (6 years ago)
- Location:
- trunk/trax
- Files:
-
- 5 modified
-
config/routes.php (modified) (1 diff)
-
test/RouterTest.php (modified) (1 diff)
-
tutorials/PHPonTrax/Router.cls (modified) (2 diffs)
-
vendor/trax/action_controller.php (modified) (10 diffs)
-
vendor/trax/router.php (modified) (7 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/trax/config/routes.php
r138 r161 1 1 <?php 2 2 /** 3 * Configuration file to define URL to action mapping 4 * 5 * This file contains one or more PHP statements that call 6 * {@link Router::connect() $router->connect()} to add routes to the 7 * route table stored in the {@link Router} object pointed to by 8 * $router. 9 * 3 10 * Add your own custom routes here. 4 11 * The priority is based upon order of creation: first created -> -
trunk/trax/test/RouterTest.php
r159 r161 65 65 66 66 /** 67 * @todo Implement testGet_selected_route().67 * Test build_route_regexp(). 68 68 */ 69 public function testGet_selected_route() { 70 // Remove the following line when you implement this test. 71 throw new PHPUnit2_Framework_IncompleteTestError; 69 public function testBuild_route_regexp() { 70 $r = new Router; 71 // Two abstract route components 72 $regexp = $r->build_route_regexp(':foo/:bar'); 73 $this->assertEquals($regexp, 74 '^[a-z0-9_\-]+\/[a-z0-9_\-]+$'); 75 // Three abstract route components 76 $regexp = $r->build_route_regexp(':foo/:bar/:mumble'); 77 $this->assertEquals($regexp, 78 '^[a-z0-9_\-]+\/[a-z0-9_\-]+\/[a-z0-9_\-]+$'); 79 // Abstract, concrete, abstract route components 80 $regexp = $r->build_route_regexp(':foo/bar/:mumble'); 81 $this->assertEquals($regexp, 82 '^[a-z0-9_\-]+\/bar\/[a-z0-9_\-]+$'); 83 // Two concrete route components 84 $regexp = $r->build_route_regexp('foo/bar'); 85 $this->assertEquals($regexp, 86 '^foo\/bar$'); 72 87 } 73 88 74 89 /** 75 * @todo Implement testConnect().90 * Test default route table 76 91 */ 77 public function testConnect() { 78 // Remove the following line when you implement this test. 79 throw new PHPUnit2_Framework_IncompleteTestError; 92 public function testDefault_route() { 93 $r = new Router; 94 // Should find default route 95 $route = $r->find_route('a/b/mumble'); 96 $this->assertEquals(':controller/:action/:id', $route['path']); 97 $this->assertNull($route['params']); 80 98 } 81 99 82 100 /** 83 * @todo Implement testFind_route().101 * Test route table with one simple entry besides default 84 102 */ 85 public function testFind_route() { 86 // Remove the following line when you implement this test. 87 throw new PHPUnit2_Framework_IncompleteTestError; 103 public function testSimple_route() { 104 $r = new Router; 105 // Build route table 106 $r->connect(':foo/:bar/mumble', array('mumble route')); 107 // Params not an array ignored, null is stored 108 $r->connect(':controller/:action/:id', 'not-an-array'); 109 110 // Match first route 111 $route = $r->find_route('a/b/mumble'); 112 $this->assertEquals(':foo/:bar/mumble', $route['path']); 113 $this->assertEquals(array('mumble route'), $route['params']); 114 $selected = $r->get_selected_route(); 115 $this->assertEquals(':foo/:bar/mumble', $selected['path']); 116 $this->assertEquals(array('mumble route'), $selected['params']); 117 118 // Match second route 119 $route = $r->find_route('a/b/c'); 120 $this->assertEquals(':controller/:action/:id', $route['path']); 121 $this->assertNull($route['params']); 122 $selected = $r->get_selected_route(); 123 $this->assertEquals(':controller/:action/:id', $selected['path']); 124 $this->assertNull($selected['params']); 88 125 } 89 126 90 127 /** 91 * @todo Implement testBuild_route_regexp().128 * Test route table with one regexp entry besides default 92 129 */ 93 public function testBuild_route_regexp() { 94 // Remove the following line when you implement this test. 95 throw new PHPUnit2_Framework_IncompleteTestError; 130 public function testRegexp_route() { 131 $r = new Router; 132 // Build route table 133 $r->connect(':foo/:bar/\?(catalog|part)number=.*', 134 array('number route')); 135 $r->connect(':controller/:action/:id', array('default route')); 136 137 // Match first route 138 $route = $r->find_route('a/b/?catalognumber=17'); 139 $this->assertEquals(':foo/:bar/\?(catalog|part)number=.*', 140 $route['path']); 141 $this->assertEquals(array('number route'), $route['params']); 142 $route = $r->find_route('a/b/?partnumber=123-456'); 143 $this->assertEquals(':foo/:bar/\?(catalog|part)number=.*', 144 $route['path']); 145 $this->assertEquals(array('number route'), $route['params']); 146 $route = $r->find_route('a/b/?personnumber=156'); 147 $this->assertEquals(':controller/:action/:id', $route['path']); 148 $this->assertEquals(array('default route'), $route['params']); 149 } 150 151 /** 152 * Test route table with route with empty path 153 */ 154 public function testEmpty_route() { 155 $r = new Router; 156 // Build route table with only an empty path 157 $r->connect('', array('empty route')); 158 $route = $r->find_route(''); 159 $this->assertEquals('', $route['path']); 160 $this->assertEquals(array('empty route'), $route['params']); 161 // This route shouldn't match anything 162 $route = $r->find_route('mumble/foo'); 163 $this->assertNull($route); 96 164 } 97 165 } -
trunk/trax/tutorials/PHPonTrax/Router.cls
r155 r161 2 2 <refnamediv> 3 3 <refname>Router</refname> 4 <refpurpose> @todo Router tutorial</refpurpose>4 <refpurpose>Convert a URL to an action</refpurpose> 5 5 </refnamediv> 6 6 <refsynopsisdiv> … … 15 15 <refsect1 id="{@id intro}"> 16 16 <title>Introduction</title> 17 18 <para>The {@link Router Router class} owns the information and 19 algorithms that convert URLs to actions. An object of this class 20 holds a {@link Router::$routes route table} containing routes to be 21 matched to URLs.</para> 22 23 <para>In normal operation, a Router object is created by 24 {@link ActionController::load_router()} which reads routes from the 25 configuration file {@link routes.php config/routes.php}.</para> 26 17 27 </refsect1> 28 <refsect1 id="{@id table}"> 29 <title>Structure of the Route Table</title> 30 31 <para>The route table is an ordered list of routes. A route consists 32 of a path and a (possibly null) parameter array. The structure of 33 the table is:</para> 34 35 <example> 36 $routes[0]['path'] First route path 37 ['params'] First route parameters 38 [1]['path'] Second route path 39 ['params'] Second route parameters 40 ... 41 </example> 42 43 <para>A route path consists of character strings separated by 44 forward slash ('/') characters. The route path must not begin 45 or end with '/', and the character strings in the path must 46 not contain '/'. There are two kinds of character strings in 47 route paths:</para> 48 49 <unorderedlist> 50 <listitem>Placeholder strings start with a colon (':') followed by 51 one or more alphameric characters chosen from "a..z0..9_-". A 52 placeholder string matches any alphameric string in the same 53 position of a URL. The actual contents of the placeholder string 54 following ':' are irrelevant.</listitem> 55 <listitem>Pattern strings start with any character except ':' or 56 '/' followed by any character except '/'. The contents of 57 the pattern string are a 58 {@link http://www.php.net/manual/en/ref.pcre.php Perl regular expression}. 59 </listitem> 60 </unorderedlist> 61 62 <para>The order of routes in the table is significant. When a URL 63 is to be matched, the route table is searched in order from first 64 entry to last. The first route entry that matches is 65 returned.</para> 66 67 <para>{@link Router::find_route()} guarantees that there will always be 68 at least one route in the table by inserting 69 {@link Router::$default_route_path} if the table is empty when 70 find_route() is called.</para> 71 </refsect1> 72 73 <refsect1 id="{@id build}"> 74 <title>Constructing the Route Table</title> 75 76 <para>To construct a route table, first create a new Router object, 77 then make multiple calls to {@link Router::connect()} to add route 78 entries to the object's table. The second argument to connect(), if 79 specified, must be an array, but the array can hold anything (or 80 nothing).</para> 81 82 <para>There is no way to change or delete an existing route table 83 entry.</para> 84 <para>Either assure that any path you search for will return some 85 route, or prepare to deal with a null return from 86 {@link Router::find_route()} </para> 87 88 <para><important>CAUTION:</important> Do not call 89 {@link Router::find_route()} before calling 90 {@link Router::connect()}, unless you want the default route to be 91 the first entry in the route table.</para> 92 93 </refsect1> 94 <refsect1 id="{@id search}"> 95 <title>Searching the Route Table</title> 96 97 <para>To look up a URL in the route table, call 98 {@link Router::find_route()} with the URL as argument. A copy of 99 the first matching route table entry, if any, will be returned. If 100 none matches, null will be returned.</para> 101 102 <para>A URL consisting of a null string '' matches a route 103 whose path is a null string.</para> 104 105 <para>A copy of the last route table entry returned by find_route() 106 is saved in {@link Router::$selected_route}. It can be fetched by 107 a call to {@link Router::get_selected_route()}. The next call to 108 find_route() overwrites the previous value in 109 $selected_route.</para> 110 111 </refsect1> 112 <!-- 113 Local variables: 114 mode: xml 115 c-basic-offset: 1 116 indent-tabs-mode: nil 117 End: 118 --> 18 119 </refentry> -
trunk/trax/vendor/trax/action_controller.php
r155 r161 182 182 * } 183 183 * </pre> 184 *185 * @package PHPonTrax186 184 */ 187 185 class ActionController { 188 186 189 private 190 $controller, 191 $action, 192 $id, 193 $controllers_path, 194 $helpers_path, 195 $helpers_base_path, 196 $layouts_path, 197 $url_path, 198 $default_layout_file, 199 $helper_file, 200 $application_controller_file, 201 $application_helper_file, 202 $loaded = false, 203 $router_loaded = false, 204 $helpers = array(), 205 $before_filters = array(), 206 $after_filters = array(); 207 protected 208 $before_filter = null, 209 $after_filter = null; 210 public 211 $controller_file, 212 $view_file, 213 $views_path, 214 $controller_class, 215 $controller_object, 216 $asset_host = null, 217 $views_file_extention = TRAX_VIEWS_EXTENTION; 218 187 /** 188 * @todo Document this attribute 189 */ 190 private $controller; 191 192 /** 193 * @todo Document this attribute 194 */ 195 private $action; 196 197 /** 198 * @todo Document this attribute 199 */ 200 private $id; 201 202 /** 203 * @todo Document this attribute 204 */ 205 private $controllers_path; 206 207 /** 208 * @todo Document this attribute 209 */ 210 private $helpers_path; 211 212 /** 213 * @todo Document this attribute 214 */ 215 private $helpers_base_path; 216 217 /** 218 * @todo Document this attribute 219 */ 220 private $layouts_path; 221 222 /** 223 * @todo Document this attribute 224 */ 225 private $url_path; 226 227 /** 228 * @todo Document this attribute 229 */ 230 private $default_layout_file; 231 232 /** 233 * @todo Document this attribute 234 */ 235 private $helper_file; 236 237 /** 238 * @todo Document this attribute 239 */ 240 private $application_controller_file; 241 242 /** 243 * @todo Document this attribute 244 */ 245 private $application_helper_file; 246 247 /** 248 * @todo Document this attribute 249 */ 250 private $loaded = false; 251 252 /** 253 * Whether a Router object was loaded 254 * 255 * @var boolean 256 * <ul> 257 * <li>true => $router points to the Router object</li> 258 * <li>false => no Router object exists</li> 259 * </ul> 260 */ 261 private $router_loaded = false; 262 263 /** 264 * @todo Document this attribute 265 */ 266 private $helpers = array(); 267 268 /** 269 * @todo Document this attribute 270 */ 271 private $before_filters = array(); 272 273 /** 274 * @todo Document this attribute 275 */ 276 private $after_filters = array(); 277 278 /** 279 * @todo Document this attribute 280 */ 281 protected $before_filter = null; 282 283 /** 284 * @todo Document this attribute 285 */ 286 protected $after_filter = null; 287 288 /** 289 * @todo Document this attribute 290 */ 291 public $controller_file; 292 293 /** 294 * @todo Document this attribute 295 */ 296 public $view_file; 297 298 /** 299 * @todo Document this attribute 300 */ 301 public $views_path; 302 303 /** 304 * @todo Document this attribute 305 */ 306 public $controller_class; 307 308 /** 309 * @todo Document this attribute 310 */ 311 public $controller_object; 312 313 /** 314 * @todo Document this attribute 315 */ 316 public $asset_host = null; 317 318 /** 319 * @todo Document this attribute 320 */ 321 public $views_file_extention = TRAX_VIEWS_EXTENTION; 322 323 /** 324 * @todo Document this method 325 */ 219 326 function __construct() { 220 327 if(!isset($this->router) || !is_object($this->router)) { … … 223 330 } 224 331 332 /** 333 * @todo Document this method 334 */ 225 335 function __set($key, $value) { 226 336 #echo "setting: $key = $value<br>"; … … 236 346 } 237 347 348 /** 349 * @todo Document this method 350 */ 238 351 function __call($method_name, $parameters) { 239 352 if(method_exists($this, $method_name)) { … … 252 365 } 253 366 367 /** 368 * Load routes from configuration file routes.php 369 * 370 * Routes are loaded by requiring {@link routes.php} from the 371 * configuration directory. 372 * @uses Router 373 * @uses $router 374 * @uses $router_loaded 375 */ 254 376 function load_router() { 255 377 $this->router_loaded = false; … … 263 385 } 264 386 387 /** 388 * @todo Document this method 389 * @uses load_router() 390 * @uses $router 391 * @uses $router_loaded 392 * @uses set_paths() 393 * @uses $url_path 394 */ 265 395 function recognize_route() { 266 396 … … 341 471 } 342 472 473 /** 474 * @todo Document this method 475 */ 343 476 function process_route() { 344 477 … … 346 479 if(!$this->loaded) { 347 480 if(!$this->recognize_route()) { 348 $this->raise("Failed to load any defined routes", "Controller ".$this->controller." not found", "404"); 481 $this->raise("Failed to load any defined routes", 482 "Controller ".$this->controller." not found", 483 "404"); 349 484 } 350 485 } … … 496 631 497 632 return true; 498 } 499 633 } // function process_route() 634 635 /** 636 * @todo Document this method 637 */ 500 638 function set_paths() { 501 639 if(is_array($this->url_path)) { … … 681 819 } 682 820 821 /** 822 * @todo Document this method 823 */ 683 824 function determine_layout() { 684 825 # I guess you don't want any layout … … 788 929 } 789 930 931 // -- set Emacs parameters -- 932 // Local variables: 933 // tab-width: 4 934 // c-basic-offset: 4 935 // c-hanging-comment-ender-p: nil 936 // indent-tabs-mode: nil 937 // End: 790 938 ?> -
trunk/trax/vendor/trax/router.php
r138 r161 30 30 31 31 /** 32 * 33 * @todo Document this class 34 * @package PHPonTrax 32 * Convert a URL to an action 33 * @tutorial PHPonTrax/Router.cls 35 34 */ 36 35 class Router { 37 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 */ 38 48 private $routes = array(); 49 50 /** 51 * Last route found by a call to find_route() 52 * @var string[] 53 */ 39 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 */ 40 63 private $default_route_path = ":controller/:action/:id"; 64 65 /** 66 * Count of the number of elements in $routes 67 * @var integer 68 */ 41 69 public $routes_count = 0; 42 70 43 71 /** 44 * 45 * @todo Document this method 72 * Accessor method to return contents of $selected_route 73 * @return string[] Contents of $selected_route 74 * @uses $selected_route 46 75 */ 47 76 function get_selected_route() { … … 50 79 51 80 /** 81 * Accessor method to add a route to the route table 52 82 * 53 * @todo Document this method 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 54 90 */ 55 91 function connect($path, $params = null) { … … 61 97 62 98 /** 99 * Find first route in route table with path that matches argument 63 100 * 64 * @todo Document this method 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 {@link http://www.php.net/manual/en/ref.pcre.php Perl regular expression} 109 * rules. Return the first matching route to the caller, and 110 * also save a copy in {@link $selected_route}. 111 * @param string $url 112 * @uses build_route_regexp() 113 * @uses $default_route_path 114 * @uses $routes 115 * @uses $routes_count 116 * @uses $selected_route 117 * @return string[] Selected route. Path is in return['path'], 118 * params in return['params'], 65 119 */ 66 120 function find_route($url) { 67 68 121 // ensure at least one route (the default route) exists 69 122 if($this->routes_count == 0) { 70 $this->routes['path'] = $this->default_route_path; 71 $this->routes['params'] = null; 123 $this->connect($this->default_route_path); 72 124 } 73 125 … … 78 130 unset($reg_exp); 79 131 $route_regexp = $this->build_route_regexp($route['path']); 80 81 132 if($url == "" && $route_regexp == "") { 82 133 $this->selected_route = $route; … … 92 143 93 144 return $this->selected_route; 94 } 145 } // function find_route($url) 95 146 96 147 /** 148 * Build a regular expression that matches a route 97 149 * 98 * @todo Document this method 150 * <b>FIXME:</b> Should this method be private? 151 * @param string $route_path A route path. 152 * @return string Regular expression that matches the route in 153 * $route_path 99 154 */ 100 155 function build_route_regexp($route_path) { 156 // echo "entering build_route_regexp(), \$route_path is '$route_path'\n"; 101 157 102 158 $route_regexp = null; … … 105 161 $route_path = explode("/",$route_path); 106 162 } 107 163 // echo "route path:\n"; 164 // var_dump($route_path); 108 165 if(count($route_path) > 0) { 109 166 foreach($route_path as $path_element) { … … 124 181 } 125 182 183 // -- set Emacs parameters -- 184 // Local variables: 185 // tab-width: 4 186 // c-basic-offset: 4 187 // c-hanging-comment-ender-p: nil 188 // indent-tabs-mode: nil 189 // End: 126 190 ?>
