2 // Router v2 (a Canvas component)
4 // @email <mtodd@clayton.edu>
5 // @created_on 23 Apr 2006
8 // internal static variables
9 private static $routes = array(); // the routes provided to route against
10 private static $route = null; // the route for the request
12 // regular expressions for validations
13 private static $validations = array(
15 'controller'=>'([\w_]+)',
17 'id'=>'([\d]*)?', // makes the :id optional
20 'word'=>'([\w\d_+-\.\?]+)',
26 'multiple'=>'((%s\/?)+)',
29 'date'=>'(\d\d\d\d-(0[1-9]|1[1-2])-([0-2][0-9]|3[0-2]))',
31 'month'=>'(0?[1-9]|1[1-2])',
32 'day'=>'(0?[1-9]|[1-2][0-9]|3[0-2])'
36 public static function route($request) {
37 // compare the request against the available routes
38 foreach(self
::$routes as $route=>$options) {
39 if(preg_match("/^{$route}$/", $request, $matches) == 1) break;
42 // map values into $map
43 foreach($options['values'] as $name=>$value) {
46 array_shift($matches);
47 foreach($matches as $key=>$match) {
48 if($options['names'][$key][strlen($options['names'][$key]) - 1] != '*') {
49 // not a multiple name... (it's not sucking up the rest of the values)
50 $map[$options['names'][$key]] = $match;
52 $map[substr($options['names'][$key], 0, -1)] = explode('/', $match);
57 // create new Route object and give it to self::$route, then return it
58 self
::$route = new Route($route, $map);
63 public static function map($route, $values = array(), $validates = array()) {
64 // @description Takes a route, like ':controller/:action/:id', and values to include in the route when not specified
65 // bythe actual route itself. This is handy for complex requests with simplified routes.
69 // parse $route into regex
70 if($route[0] == '/') $route = substr($route, 1); // strip out initial slash
71 $route = explode('/', $route); // pull route into its parts
72 foreach($route as $key=>$part) {
73 // pull out names (start with a ':')
75 $name = substr($part, 1);
82 // put in regular expression pieces (opting for whatever is in $validates, using 'word' as default unless it's a literal)
83 if(self
::$validations[$name]) $test = self
::$validations[$name]; // default values
84 if($validates[$name]) $test = self
::$validations[$validates[$name]]; // use specific validations as often as possible
85 if($part[0] != ':') $test = $part; // just keep literals
86 if(empty($test)) $test = self
::$validations['word']; // last resort
87 if($name[strlen($name) - 1] == '*') $test = sprintf(self
::$validations['multiple'], $test);
89 $test = ''; // reset $test;
92 // assemble new regular expression route for testing
93 $route = implode('\/', $route);
95 // assign $routes with appropriate data
96 self
::$routes[$route] = array('route'=>$request, 'names'=>$names, 'values'=>$values, 'validates'=>$validates);
101 // generate a route, given a Route object
102 public static function url_for($request = array()) {
103 // loop through routes, matching them
104 foreach(self
::$routes as $route=>$options) {
105 // default to none found
108 // find an appropriate route
109 if(is_array($request)) {
111 foreach(array_keys($request) as $key) {
112 if((is_array($options['names']) && array_search($key, $options['names']) !== false) ||
($options['values'][$key] == $request[$key])) {
119 if($found == true) break;
121 // if it's a string, return the routing data
122 if(preg_match("/^{$route}$/", $request) > 0) {
123 return array($route=>$options);
131 // get the route (to form the URL)
132 $url = $options['route']; // the route
134 // loop through the names, inserting the values into the route/URL
135 foreach($options['names'] as $name) {
136 $url = str_replace(":{$name}", $request[$name], $url);
139 // that's it! the Request or Response objects will handle the domain data (because that's their domain!)
148 // the tangible, active part of the routing system, representing an actual route
151 private $map = array(); // the route mapping
152 private $route = ''; // the route requested
155 public function __get($name) {
156 return $this->map
[$name];
158 public function __set($name, $value) {
159 return $this->map
[$name] = $value;
162 // give the route's mapping
163 public function mapping() {
164 return array_keys($this->map
);
168 public function __construct($route, $map) {
169 $this->route
= $route;