Improved route handling
authorAlexander Ebert <ebert@woltlab.com>
Sun, 23 Nov 2014 12:36:55 +0000 (13:36 +0100)
committerAlexander Ebert <ebert@woltlab.com>
Sun, 23 Nov 2014 12:36:55 +0000 (13:36 +0100)
wcfsetup/install/files/lib/system/request/RequestHandler.class.php
wcfsetup/install/files/lib/system/request/Route.class.php

index 8f106267c85d6178d3423e984b5fc8dd461336b5..b46623fb92669e2c69db685df743ab9dc0674426 100644 (file)
@@ -135,57 +135,7 @@ class RequestHandler extends SingletonFactory {
                        
                        // handle landing page for frontend requests
                        if (!$this->isACPRequest()) {
-                               $landingPage = PageMenu::getInstance()->getLandingPage();
-                               if ($landingPage !== null && RouteHandler::getInstance()->isDefaultController()) {
-                                       // check if redirect URL matches current URL
-                                       $redirectURL = $landingPage->getLink();
-                                       $relativeRoute = str_replace(RouteHandler::getHost(), '', $redirectURL);
-                                       
-                                       // strip query string for comparison
-                                       $pos = mb_strpos($relativeRoute, '?');
-                                       if ($pos !== false) $relativeRoute = mb_substr($relativeRoute, 0, $pos);
-                                       $requestUri = $_SERVER['REQUEST_URI'];
-                                       $pos = mb_strpos($requestUri, '?');
-                                       if ($pos !== false) $requestUri = mb_substr($requestUri, 0, $pos);
-                                       
-                                       if ($relativeRoute == $requestUri) {
-                                               $routeData['controller'] = $landingPage->getController();
-                                       }
-                                       else {
-                                               // check if request URI resolves to an application different from relative route
-                                               // important: request URI may not contain anything else except for the path
-                                               $currentRequestURI = RouteHandler::getHost() . $requestUri;
-                                               $redirectToLandingPage = false;
-                                               if ($currentRequestURI == ApplicationHandler::getInstance()->getPrimaryApplication()->getPageURL()) {
-                                                       HeaderUtil::redirect($landingPage->getLink(), true);
-                                                       exit;
-                                               }
-                                               
-                                               // check if current URL matches an application but controller was omitted
-                                               foreach (ApplicationHandler::getInstance()->getApplications() as $applicationObject) {
-                                                       if ($currentRequestURI == $applicationObject->getPageURL()) {
-                                                               if ($controller = WCF::getApplicationObject($applicationObject)->getPrimaryController()) {
-                                                                       $controller = explode('\\', $controller);
-                                                                       
-                                                                       if (URL_LEGACY_MODE) {
-                                                                               HeaderUtil::redirect(LinkHandler::getInstance()->getLink(preg_replace('~(Action|Form|Page)$~', '', array_pop($controller)), array('application' => $controller[0])));
-                                                                               exit;
-                                                                       }
-                                                                       else {
-                                                                               $routeData['controller'] = preg_replace('~(Action|Form|Page)$~', '', array_pop($controller));
-                                                                               $redirectURL = '';
-                                                                       }
-                                                               }
-                                                       }
-                                               }
-                                               
-                                               // redirect to landing page
-                                               if (!empty($redirectURL)) {
-                                                       HeaderUtil::redirect($redirectURL, true);
-                                                       exit;
-                                               }
-                                       }
-                               }
+                               $this->handleDefaultController($application, $routeData);
                                
                                // check if accessing from the wrong domain (e.g. "www." omitted but domain was configured with)
                                if (!defined('WCF_RUN_MODE') || WCF_RUN_MODE != 'embedded') {
@@ -239,6 +189,54 @@ class RequestHandler extends SingletonFactory {
                }
        }
        
+       /**
+        * Checks page access for possible mandatory redirects.
+        * 
+        * @param       string          $application
+        * @param       array           $routeData
+        */
+       protected function handleDefaultController($application, array &$routeData) {
+               if (!RouteHandler::getInstance()->isDefaultController()) {
+                       return;
+               }
+               
+               $landingPage = PageMenu::getInstance()->getLandingPage();
+               if ($landingPage === null) {
+                       return;
+               }
+               
+               // resolve implicit application abbreviation for landing page controller
+               $landingPageApplication = $landingPage->getApplication();
+               if ($landingPageApplication == 'wcf') {
+                       $primaryApplication = ApplicationHandler::getInstance()->getPrimaryApplication();
+                       $landingPageApplication = ApplicationHandler::getInstance()->getAbbreviation($primaryApplication->packageID);
+               }
+               
+               // check if currently invoked application matches the landing page
+               if ($landingPageApplication == $application) {
+                       $routeData['controller'] = $landingPage->getController();
+                       return;
+               }
+               
+               // assign the default controller
+               $currentApplication = ApplicationHandler::getInstance()->getApplication($application);
+               if ($controller = WCF::getApplicationObject($currentApplication)->getPrimaryController()) {
+                       $controller = explode('\\', $controller);
+                       
+                       if (URL_LEGACY_MODE) {
+                               HeaderUtil::redirect(LinkHandler::getInstance()->getLink(preg_replace('~(Action|Form|Page)$~', '', array_pop($controller)), array('application' => $controller[0])));
+                               exit;
+                       }
+                       else {
+                               $routeData['controller'] = preg_replace('~(Action|Form|Page)$~', '', array_pop($controller));
+                               return;
+                       }
+               }
+               
+               HeaderUtil::redirect($landingPage->getLink());
+               exit;
+       }
+       
        /**
         * Returns the class data for the active request or null if for the given
         * configuration no proper class exist.
index 2f73c8321667dd3660751999117ff5024b5d926e..645e676d47833380500b72d7bf87007199d31cc5 100644 (file)
@@ -262,7 +262,7 @@ class Route {
         * @return      string
         */
        public function buildLink(array $components) {
-               $application = $components['application'];
+               $application = (isset($components['application'])) ? $components['application'] : null;
                self::loadDefaultControllers();
                
                // drop application component to avoid being appended as query string
@@ -283,12 +283,17 @@ class Route {
                                if ($landingPage !== null && strcasecmp($landingPage->getController(), $components['controller']) == 0) {
                                        $ignoreController = true;
                                }
-                       }
-                       
-                       // check if this is the default controller of the requested application
-                       if (!URL_LEGACY_MODE && !$ignoreController) {
-                               if (isset(self::$defaultControllers[$application]) && self::$defaultControllers[$application] == $components['controller']) {
-                                       $ignoreController = true;
+                               
+                               // check if this is the default controller of the requested application
+                               if (!URL_LEGACY_MODE && !$ignoreController && $application !== null) {
+                                       if (isset(self::$defaultControllers[$application]) && self::$defaultControllers[$application] == $components['controller']) {
+                                               // check if this is the primary application and the landing page originates to the same application
+                                               $primaryApplication = ApplicationHandler::getInstance()->getPrimaryApplication();
+                                               $abbreviation = ApplicationHandler::getInstance()->getAbbreviation($primaryApplication->packageID);
+                                               if ($abbreviation != $application || $landingPage === null || $landingPage->getApplication() != 'wcf') {
+                                                       $ignoreController = true;
+                                               }
+                                       }
                                }
                        }