Improved handling of aliased/mistyped controllers
authorAlexander Ebert <ebert@woltlab.com>
Fri, 20 Feb 2015 16:57:10 +0000 (17:57 +0100)
committerAlexander Ebert <ebert@woltlab.com>
Fri, 20 Feb 2015 16:57:10 +0000 (17:57 +0100)
wcfsetup/install/files/lib/system/request/FlexibleRoute.class.php
wcfsetup/install/files/lib/system/request/RequestHandler.class.php

index 81f433239f33238412d966d48d06af6fa753a539..3a6209d3f0b6af5bd5848e1437cca13a002af079 100644 (file)
@@ -67,7 +67,11 @@ class FlexibleRoute implements IRoute {
                                (?P<controller>[A-Za-z0-9\-]+)
                                (?:
                                        /
-                                       (?P<id>\d+)     
+                                       (?P<id>\d+)
+                                       (?:
+                                               -
+                                               (?P<title>[^/]+)
+                                       )?
                                )?
                        )?
                ~x';
@@ -282,7 +286,7 @@ class FlexibleRoute implements IRoute {
                                $controllerName .= strtolower($parts[$i]);
                        }
                        
-                       $alias = RequestHandler::getInstance()->getAliasByController($controllerName);
+                       $alias = (!$this->isACP) ? RequestHandler::getInstance()->getAliasByController($controllerName) : null;
                        
                        self::$controllerNames[$controller] = ($alias) ?: $controllerName;
                }
index b0d223d4ee76f5f43e241862b9ff725c07dba4e3..81d3da3b928591907a5d1132e313a32081cc7dcc 100644 (file)
@@ -179,9 +179,10 @@ class RequestHandler extends SingletonFactory {
                                
                                // handle controller aliasing
                                if (!URL_LEGACY_MODE && isset($routeData['controller'])) {
-                                       // aliased controller, pretend it does not exist
-                                       if ($this->getAliasByController($routeData['controller']) !== null) {
-                                               throw new IllegalLinkException();
+                                       // aliased controller, redirect to new URL
+                                       $alias = $this->getAliasByController($routeData['controller']);
+                                       if ($alias !== null) {
+                                               $this->redirect($routeData, $application);
                                        }
                                        
                                        $controller = $this->getControllerByAlias($routeData['controller']);
@@ -222,6 +223,19 @@ class RequestHandler extends SingletonFactory {
                                throw new SystemException("unable to find class '".$classData['className']."'");
                        }
                        
+                       // check if controller was provided exactly as it should
+                       if (!URL_LEGACY_MODE && !$this->isACPRequest()) {
+                               if (preg_match('~([A-Za-z0-9]+)(?:Action|Form|Page)$~', $classData['className'], $matches)) {
+                                       $parts = preg_split('~([A-Z][a-z0-9]+)~', $matches[1], null, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY);
+                                       $parts = array_map('strtolower', $parts);
+                                       $realController = implode('-', $parts);
+                                       
+                                       if ($controller != $realController) {
+                                               $this->redirect($routeData, $application, $matches[1]);
+                                       }
+                               }
+                       }
+                       
                        $this->activeRequest = new Request($classData['className'], $classData['controller'], $classData['pageType']);
                }
                catch (SystemException $e) {
@@ -229,6 +243,29 @@ class RequestHandler extends SingletonFactory {
                }
        }
        
+       /**
+        * Redirects to the actual URL, e.g. controller has been aliased or mistyped (boardlist instead of board-list).
+        * 
+        * @param       array<string>           $routeData
+        * @param       string                  $application
+        * @param       string                  $controller
+        */
+       protected function redirect(array $routeData, $application, $controller = null) {
+               $routeData['application'] = $application;
+               if ($controller !== null) $routeData['controller'] = $controller;
+               
+               // append the remaining query parameters
+               foreach ($_GET as $key => $value) {
+                       if (!empty($value)) {
+                               $linkData[$key] = $value;
+                       }
+               }
+               
+               $redirectURL = LinkHandler::getInstance()->getLink($routeData['controller'], $linkData);
+               HeaderUtil::redirect($redirectURL, true);
+               exit;
+       }
+       
        /**
         * Checks page access for possible mandatory redirects.
         *