Changeset 4578 for trunk/core/router.core.php
- Timestamp:
- 08/15/10 18:45:12 (22 months ago)
- File:
-
- 1 edited
-
trunk/core/router.core.php (modified) (41 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/core/router.core.php
r4568 r4578 24 24 * 25 25 * @license GNU/GPL v2 or (at your option) any later version, see "/doc/LICENSE". 26 *27 26 * @author Jens-André Koch <vain@clansuite.com> 28 27 * @copyright Jens-André Koch (2005 - onwards) 28 * @link http://www.clansuite.com 29 29 * 30 * @link http://www.clansuite.com 31 * @link http://gna.org/projects/clansuite 32 * 33 * @version SVN: $Id$response.class.php 2580 2008-11-20 20:38:03Z vain $ 30 * @version SVN: $Id$ 34 31 */ 35 32 … … 51 48 * Normally all requests made map to a specific physical resource rather than a logical name. 52 49 * With Routing you are able to map a logical name to a specific physical name. 53 * Example : map a logical URL (a mod_rewritten one) to a Controller/Method/Parameter54 * Map a FileRequest via logical URL (a mod_rewritten one) to a DownloadController/Method/Parameter50 * Examples: map a logical URL (a mod_rewritten one) to a Controller/Method/Parameter 51 * or map a FileRequest via logical URL (a mod_rewritten one) to a DownloadController/Method/Parameters 55 52 * 56 53 * There are two different URL Formatings allowed: … … 58 55 * 2. Fake HTML File Request or SMF-Style, like so: /mod.sub.action.id.html 59 56 * 60 * SPL Iterator and ArrayAccess are used for fast iteration and easier access to the stored routes.61 *62 57 * @category Clansuite 63 58 * @package Core 64 59 * @subpackage Router 65 60 */ 66 class Clansuite_Router implements Iterator,ArrayAccess, Clansuite_Router_Interface61 class Clansuite_Router implements ArrayAccess, Clansuite_Router_Interface 67 62 { 68 63 private static $use_cache = false; … … 70 65 private $uri = ''; 71 66 private $uri_segments = array(); 72 private $extension = '';67 private static $extension = ''; 73 68 74 69 /** … … 83 78 */ 84 79 private $routes = array(); 85 80 86 81 /** 87 82 * Constructor. 88 * 89 * @param string $request_url The Request URL incomming via Clansuite_HttpRequest::getRequestURI()90 */91 public function __construct($request_uri)92 { 83 */ 84 public function __construct(Clansuite_HttpRequest $request) 85 { 86 $request_uri = $request::getRequestURI(); 87 93 88 # clean the incomming uri 94 89 $this->uri = self::prepareRequestURI($request_uri); 95 96 # check if routes caching is activated in config, maybe we can load routes from cache97 if(isset($config['routing']['cache_routes']) and true === $config['routing']['cache_routes'])98 {99 self::$use_cache = true;100 }101 else102 {103 self::$use_cache = false;104 }105 90 } 106 91 … … 111 96 * @param array $route_options 112 97 */ 113 public function addRoute($url_pattern, array $route_options) 114 { 115 $this->connect($url_pattern, $route_options); 98 public function addRoute($url_pattern, array $route_options = null) 99 { 100 /** 101 * 1) Preprocess the route 102 */ 103 # split the pattern describing the URL target into uri segments 104 $url_pattern = ltrim($url_pattern, '/'); 105 $segments = explode('/', $url_pattern); 106 107 # because the incomming route might have placeholders lile (:num) or (:id) 108 $url_pattern = self::placeholdersToRegexp($url_pattern); 109 110 $regexp = ''; 111 $regexp = $this->processSegmentsRegExp($segments, $route_options); 112 $number_of_segments = count($segments); 113 $options = array('regexp' => $regexp, 114 'number_of_segments' => $number_of_segments); 115 116 117 /** 118 * 2) Finally add the *now preprocessed* Route. 119 */ 120 $this->routes[$url_pattern] = $options; 121 } 122 123 public function processSegmentsRegExp(array $segments, array $requirements = null) 124 { 125 # start regular expression 126 $regexp = '/^'; 127 128 # process all segments 129 foreach($segments as $segment) 130 { 131 /** 132 * process static named parameter => ":contoller" 133 */ 134 if (preg_match('/^:([a-zA-Z_]+)$/', $segment, $match)) 135 { 136 $name = $match[1]; #controller 137 138 # is there a requirement for this param? 139 if(isset($requirements[$name])) 140 { 141 # add it to the regex 142 $regexp .= '\/(?P<' . $name . '>' . $requirements[$name] . ')'; 143 # and remove the requirement 144 unset($requirement[$name]); 145 } 146 else # no requirement 147 { 148 $regexp .= '(?P<' . $name . '>[a-z0-9_-]+)'; 149 } 150 } 151 else # process static parameter = string => "/index" or "/news" 152 { 153 $regexp .= '\\/' . $segment; 154 } 155 156 # regexp between segments 157 $regexp .= '\/?'; 158 } 159 160 # finish regular expression 161 $regexp .= '$/'; 162 163 return $regexp; 116 164 } 117 165 … … 138 186 return $this->routes; 139 187 } 140 188 141 189 /** 142 190 * Delete a route by its url pattern … … 161 209 public function generateURL($url_pattern, array $params = null, $fragment = null, $absolute = false) 162 210 { 163 211 164 212 } 165 213 … … 194 242 if(empty($this->uri) or $this->uri === '/') 195 243 { 196 $route = new Clansuite_TargetRoute();197 $route->setController('news');198 $route->setAction('show'); 199 return $route;244 Clansuite_TargetRoute::setController('news'); 245 Clansuite_TargetRoute::setAction('show'); 246 247 return Clansuite_TargetRoute::getInstance(); 200 248 } 201 249 202 250 # attach more routes to this object via the event "onInitializeRoutes" 203 Clansuite_CMS::triggerEvent('onInitializeRoutes', $this);251 #Clansuite_CMS::triggerEvent('onInitializeRoutes', $this); 204 252 205 253 # initalize Routes 206 #$this->loadDefaultRoutes();254 $this->loadDefaultRoutes(); 207 255 208 256 # first filter: drop all routes with more segments then uri_segments 209 #self::removeRoutesBySegmentCount();257 self::removeRoutesBySegmentCount(); 210 258 211 259 # map match uri 212 260 return $this->mapMatchURI(); 261 } 262 263 /** 264 * Matches the URI against the Routes Table 265 * takes static, dynamic and regexp routings into account 266 * 267 * @return object Clansuite_TargetRoute 268 */ 269 public function mapMatchURI() 270 { 271 Clansuite_Debug::firebug($this->uri); 272 273 /** 274 * Do we have a direct match ? 275 * URI = '/index/show' => Routes['/index/show'] 276 */ 277 if(isset($this->routes[$this->uri])) # does this check work? 278 { 279 $found_route = $this->routes[$this->uri]; 280 } 281 else # no, there wasn't a 1:1 match. now we have to check the uri segments 282 { 283 # loop over the remaining routes and try to map match the uri_segments 284 foreach($this->routes as $route_pattern => $route_values) 285 { 286 # @todo $this->uri might be enough here 287 $uri = implode('/', $this->uri_segments); 288 289 Clansuite_Debug::firebug($route_values); 290 291 /** 292 * process static named parameter 293 * like ":controller" or ":subcontroller" or ":action" or ":id" 294 * $route_pattern 295 */ 296 if (1 === preg_match('/^:([a-zA-Z_]+)$/', $uri, $match)) 297 { 298 Clansuite_Debug::firebug($match); 299 $name = $match[1]; #setController($match[1]); 300 $found_route = $name; 301 } 302 303 # dynamic regexp segment? 304 elseif(1 === preg_match( $route_values['regexp'], $uri, $matches)) 305 { 306 Clansuite_Debug::firebug($matches); 307 308 # parameters found by regular expression have priority 309 if(isset($matches['controller'])) 310 { 311 Clansuite_TargetRoute::setController($matches['controller']); 312 } 313 314 if(isset($matches['action'])) 315 { 316 Clansuite_TargetRoute::setAction($matches['action']); 317 } 318 319 if(isset($matches['id'])) 320 { 321 Clansuite_TargetRoute::setId($matches['id']); 322 } 323 } 324 325 # route found 326 break; 327 } 328 } 329 330 #Clansuite_TargetRoute::setController($found_route); 331 #Clansuite_TargetRoute::setAction('show'); 332 333 return Clansuite_TargetRoute::getInstance(); 334 # Clansuite_CMS::triggerEvent('onAfterInitializeRoutes', $this); 213 335 } 214 336 … … 221 343 * @return bool True, if "RewriteEngine On". False otherwise. 222 344 */ 223 public staticfunction isRewriteEngineOn()345 public function isRewriteEngineOn() 224 346 { 225 347 # maybe, we have a modrewrite config setting, this avoids overhead … … 232 354 if(function_exists('apache_get_modules') and in_array('mod_rewrite', apache_get_modules())) 233 355 { 234 # load htacces and check if RewriteEngine is enabled 235 $htaccess_content = @file_get_contents(ROOT . '.htaccess'); 236 self::$rewriteEngineOn = preg_match('/.*[^#][\t ]+RewriteEngine[\t ]+On/i', $htaccess_content); 356 # load htaccess and check if RewriteEngine is enabled 357 if(true === is_file(ROOT . '.htaccess')) 358 { 359 $htaccess_content = file_get_contents(ROOT . '.htaccess'); 360 self::$rewriteEngineOn = preg_match('/.*[^#][\t ]+RewriteEngine[\t ]+On/i', $htaccess_content); 361 } 237 362 238 363 if(self::$rewriteEngineOn == 1) … … 288 413 $route = new Clansuite_TargetRoute(); 289 414 415 # Controller 290 416 if(isset($this->uri_segments['mod'])) 291 417 { … … 294 420 } 295 421 422 # SubController 296 423 if(isset($this->uri_segments['sub'])) 297 424 { … … 300 427 } 301 428 429 # Action 302 430 if(isset($this->uri_segments['action'])) 303 431 { … … 306 434 } 307 435 308 # the rest of the uri_segments are just params for the method 309 436 # Parameters 310 437 if(count($this->uri_segments) > 0) 311 438 { … … 321 448 * 322 449 * This URLParser has to extract mod, sub, action, id/parameters from the URI. 450 * This is the Standard_Request_Resolver. 323 451 * 324 452 * @param string $url The Request URL 325 453 */ 326 private function UrlParser_NoRewrite($uri) # Standard_Request_Resolver 327 { 328 454 private function UrlParser_NoRewrite($uri) 455 { 329 456 # use some parse_url magic to get the url_query part from the uri 330 457 $uri_query_string = parse_url($uri, PHP_URL_QUERY); … … 346 473 foreach($uri_query_array as $query_pair) 347 474 { 348 list($key, $value) = explode('=', $query_pair); 349 $parameters[$key] = $value; 475 if( false !== strpos($query_pair, '=')) 476 { 477 list($key, $value) = explode('=', $query_pair); 478 $parameters[$key] = $value; 479 } 350 480 } 351 481 } 352 353 482 unset($uri_query_string, $uri_query_array, $query_pair, $key, $value); 354 483 … … 384 513 $uri = mb_substr($uri, 0, $pos); 385 514 } 386 unset($pos);387 515 388 516 /** … … 401 529 $uri_dot_array = explode('.', $uri); 402 530 # chop off the last piece as the extension 403 $this->extension = array_pop($uri_dot_array);531 self::$extension = array_pop($uri_dot_array); 404 532 # there might be multiple dots in the url 405 533 # thats why implode is used to reassemble the segmentized array to a string again … … 407 535 # = ini_get('arg_separator.output') 408 536 $uri = implode('/', $uri_dot_array); 409 }410 unset($uri_dot_array);537 unset($uri_dot_array); 538 } 411 539 unset($pos); 412 540 … … 422 550 #Clansuite_Debug::firebug($uri_split); 423 551 $this->uri_segments = $url_split; 552 unset($url_split); 424 553 } 425 554 … … 461 590 } 462 591 592 public static function checkRouteCachingActive() 593 { 594 # check if routes caching is activated in config, maybe we can load routes from cache 595 if(isset($config['routing']['cache_routes']) and true === $config['routing']['cache_routes']) 596 { 597 self::$use_cache = true; 598 } 599 else 600 { 601 self::$use_cache = false; 602 } 603 } 604 463 605 /** 464 606 * Register the default routes. … … 466 608 public function loadDefaultRoutes() 467 609 { 468 # check cache for routes 610 self::checkRouteCachingActive(); 611 612 # Load Routes from Cache 469 613 if(true === self::$use_cache and empty($this->routes) and Clansuite_Cache::contains('clansuite.routes')) 470 614 { … … 472 616 } 473 617 474 if(empty($this->routes)) # load routes table from routes.config.php 618 # Load Routes from routes.config.php 619 if(empty($this->routes)) 475 620 { 476 621 $this->addRoutes( Clansuite_Routes_Manager::loadRoutesFromConfig()); … … 490 635 if(empty($this->routes)) 491 636 { 492 $this->connect('/:controller'); 493 $this->connect('/:controller/:action'); 494 $this->connect('/:controller/:action/:id'); 495 $this->connect('/:controller/:action/:id/:format'); 637 $this->addRoute('/:controller'); 638 $this->addRoute('/:controller/:action'); 639 $this->addRoute('/:controller/:action/:id'); 640 $this->addRoute('/:controller/:action/:id/:format'); 641 /* 642 $this->addRoute('/:controller/:subcontroller'); 643 $this->addRoute('/:controller/:subcontroller/:action'); 644 $this->addRoute('/:controller/:subcontroller/:action/:id'); 645 $this->addRoute('/:controller/:subcontroller/:action/:id/:format'); 646 */ 496 647 } 497 648 } … … 535 686 /** 536 687 * Clansuite_Mapper 688 * 689 * Provides helper methods to transform (map) 690 * (a) the controller name into the specific application classname and filename 691 * (b) the action name into the specific application actioname. 537 692 * 538 693 * @category Clansuite … … 600 755 601 756 # attach subcontroller to classname 602 if( $subcontroller !== null)757 if(isset($subcontroller)) 603 758 { 604 759 $classname .= '_' . ucfirst($subcontroller); … … 609 764 610 765 /** 611 * Maps the action to anmethod name.612 * The p seudo-namesspace prefix 'action_'is used for all actions.613 * Example: action_show()766 * Maps the action to it's method name. 767 * The prefix 'action_' (pseudo-namesspace) is used for all actions. 768 * Example: A action named "show" will be mapped to "action_show()" 614 769 * This is also a way to ensure some kind of whitelisting via namespacing. 615 770 * … … 617 772 * In this case the actionname is action_admin_show(). 618 773 * 619 * @param string the action620 * @param string the submodule621 * @return string the mapped method name774 * @param string $action the action 775 * @param string $submodule the submodule 776 * @return string the mapped method name 622 777 */ 623 778 public static function mapActionToActioname($action, $submodule = null) 624 779 { 625 # action not set by URL, so we set action from config/this class780 # set default value for action, when not set by URL 626 781 if(false === isset($action)) 627 782 { 628 # set the method name629 783 $action = self::$defaultAction; 630 784 } 631 785 632 # if $submodule is set, use it as a prefixon $action633 if(isset($submodule) and ($submodule !== null))786 # if a $submodule is set, use it as a PREFIX on $action 787 if(isset($submodule)) 634 788 { 635 789 $action = $submodule . '_' . $action; 636 790 } 637 791 792 #Clansuite_Debug::firebug($action); 793 638 794 # all clansuite actions are prefixed with 'action_' 639 return 'action_' . $action;795 return self::METHOD_PREFIX . '_' . $action; 640 796 } 641 797 } 642 798 799 /** 800 * Clansuite_TargetRoute (processed RequestObject) 801 */ 643 802 class Clansuite_TargetRoute extends Clansuite_Mapper 644 803 { 645 private static $parameters = array( 804 public static $parameters = array( 805 # File 646 806 'filename' => null, 647 807 'classname' => null, 808 # Call 648 809 'controller' => 'index', 649 810 'subcontroller' => null, … … 651 812 'method' => null, 652 813 'params' => null, 814 # Output 653 815 'format' => 'html', 654 816 'language' => 'en', … … 660 822 ); 661 823 824 /** 825 * Clansuite_TargetRoute is a Singleton 826 * 827 * @return instance of Clansuite_TargetRoute class 828 */ 829 public static function getInstance() 830 { 831 static $instance; 832 if(isset($instance) == null) 833 { 834 $instance = new Clansuite_TargetRoute(); 835 } 836 return $instance; 837 } 838 662 839 public static function setFilename($filename) 663 840 { … … 695 872 } 696 873 874 /** 875 * Returns Name of the Controller 876 * 877 * @return string Controller/Modulename 878 */ 697 879 public static function getController() 698 880 { … … 700 882 } 701 883 884 /** 885 * Convenience/shorthand Method for getController() 886 * 887 * @return string Controller/Modulename 888 */ 889 public static function getModuleName() 890 { 891 return self::$parameters['controller']; 892 } 893 702 894 public static function setSubController($subcontroller) 703 895 { … … 710 902 } 711 903 904 /** 905 * Method to get the SubModuleName 906 * 907 * @return $string 908 */ 909 public static function getSubModuleName() 910 { 911 return self::$parameters['subcontroller']; 912 } 913 712 914 public static function setAction($action) 713 915 { … … 718 920 { 719 921 return self::$parameters['action']; 922 } 923 924 public static function setId($id) 925 { 926 self::$parameters['params']['id'] = $id; 927 } 928 929 public static function getId() 930 { 931 return self::$parameters['params']['id']; 932 } 933 934 /** 935 * Method to get the Action with Prefix 936 * 937 * @return $string 938 */ 939 public static function getActionName() 940 { 941 return self::$parameters['method']; 720 942 } 721 943 … … 732 954 return self::$parameters['method']; 733 955 } 734 else # add method prefix 735 { 736 $method = 'action_' . self::$parameters['action'];737 738 # action + prefix = method, set it739 self::setMethod($method);956 else # add method prefix (action_) and subcontroller prefix (admin_) 957 { 958 #if(empty(self::$parameters['method'])) 959 #{ 960 self::setMethod(self::mapActionToActioname(self::getAction(), self::getSubController())); 961 #} 740 962 } 741 963 … … 791 1013 { 792 1014 return ROOT_MOD . self::getController() . DS; 1015 } 1016 1017 public static function debug() 1018 { 1019 $string = (string) implode(",", self::$parameters); 1020 Clansuite_Debug::firebug($string); 1021 } 1022 1023 public static function getRoute() 1024 { 1025 return self::$parameters; 793 1026 } 794 1027 } … … 802 1035 class Clansuite_Routes_Manager 803 1036 { 804 public staticfunction addRoutesOfModule($modulename)1037 public function addRoutesOfModule($modulename) 805 1038 { 806 1039 self:updateApplicationRoutes($modulename); 807 1040 } 808 1041 809 public staticfunction delRoutesOfModule($modulename)1042 public function delRoutesOfModule($modulename) 810 1043 { 811 1044 $module_routes_file = ROOT_MOD . '/' . $modulename . '/' . $modulename . '.routes.php'; … … 825 1058 { 826 1059 $routes_count = count($this->routes); 1060 1061 # loop over all routes 827 1062 for($i == 0; $i < $routes_count; $i++) 828 1063 { 1064 # check if there is a route with the given name 829 1065 if($this->routes[$i]['name'] == $route_name) 830 1066 { 1067 # got one? then remove it from the routes array and stop 831 1068 array_splice($this->routes, $i, 1); 832 1069 break; 833 1070 } 834 1071 } 1072 835 1073 return $this->routes;; 836 1074 } … … 841 1079 * @param string $modulename Name of module 842 1080 */ 843 public staticfunction updateApplicationRoutes($modulename = null)1081 public function updateApplicationRoutes($modulename = null) 844 1082 { 845 1083 $activated_modules = array(); … … 884 1122 { 885 1123 # load common routes configuration 886 $routes = include ROOT . 'configuration/routes.config.php'; 1124 # includes array $routes 1125 include ROOT . 'configuration/routes.config.php'; 887 1126 } 888 1127 else 889 1128 { 890 1129 # load specific routes config file 891 $routes =include ROOT . $routes_config_file;1130 include ROOT . $routes_config_file; 892 1131 } 893 1132
Note: See TracChangeset
for help on using the changeset viewer.
