From 9bfbe27477744dddd97879ae790e2ca7554f883e Mon Sep 17 00:00:00 2001 From: Alexander Ebert Date: Sun, 23 Nov 2014 13:36:55 +0100 Subject: [PATCH] Improved route handling --- .../system/request/RequestHandler.class.php | 100 +++++++++--------- .../files/lib/system/request/Route.class.php | 19 ++-- 2 files changed, 61 insertions(+), 58 deletions(-) diff --git a/wcfsetup/install/files/lib/system/request/RequestHandler.class.php b/wcfsetup/install/files/lib/system/request/RequestHandler.class.php index 8f106267c8..b46623fb92 100644 --- a/wcfsetup/install/files/lib/system/request/RequestHandler.class.php +++ b/wcfsetup/install/files/lib/system/request/RequestHandler.class.php @@ -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. diff --git a/wcfsetup/install/files/lib/system/request/Route.class.php b/wcfsetup/install/files/lib/system/request/Route.class.php index 2f73c83216..645e676d47 100644 --- a/wcfsetup/install/files/lib/system/request/Route.class.php +++ b/wcfsetup/install/files/lib/system/request/Route.class.php @@ -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; + } + } } } -- 2.20.1