/** * Run the controller * * @return Response * * @throws AccessDeniedException */ public function run() { global $objPage; $pageId = $this->getPageIdFromUrl(); $objRootPage = null; // Load a website root page object if there is no page ID if ($pageId === null) { $objRootPage = $this->getRootPageFromUrl(); /** @var PageRoot $objHandler */ $objHandler = new $GLOBALS['TL_PTY']['root'](); $pageId = $objHandler->generate($objRootPage->id, true, true); } elseif ($pageId === false) { $this->User->authenticate(); throw new PageNotFoundException('Page not found'); } // Get the current page object(s) $objPage = \PageModel::findPublishedByIdOrAlias($pageId); // Check the URL and language of each page if there are multiple results if ($objPage !== null && $objPage->count() > 1) { $objNewPage = null; $arrPages = array(); // Order by domain and language while ($objPage->next()) { /** @var PageModel $objModel */ $objModel = $objPage->current(); $objCurrentPage = $objModel->loadDetails(); $domain = $objCurrentPage->domain ?: '*'; $arrPages[$domain][$objCurrentPage->rootLanguage] = $objCurrentPage; // Also store the fallback language if ($objCurrentPage->rootIsFallback) { $arrPages[$domain]['*'] = $objCurrentPage; } } $strHost = \Environment::get('host'); // Look for a root page whose domain name matches the host name if (isset($arrPages[$strHost])) { $arrLangs = $arrPages[$strHost]; } else { $arrLangs = $arrPages['*'] ?: array(); // empty domain } // Use the first result (see #4872) if (!\Config::get('addLanguageToUrl')) { $objNewPage = current($arrLangs); } elseif (($lang = \Input::get('language')) != '' && isset($arrLangs[$lang])) { $objNewPage = $arrLangs[$lang]; } // Store the page object if (is_object($objNewPage)) { $objPage = $objNewPage; } } // Throw a 404 error if the page could not be found if ($objPage === null) { $this->User->authenticate(); $this->log('No active page for page ID "' . $pageId . '" (' . \Environment::get('base') . \Environment::get('request') . ')', __METHOD__, TL_ERROR); throw new PageNotFoundException('Page not found'); } // Throw a 500 error if the result is still ambiguous if ($objPage instanceof Model\Collection && $objPage->count() != 1) { $this->log('More than one page matches page ID "' . $pageId . '" (' . \Environment::get('base') . \Environment::get('request') . ')', __METHOD__, TL_ERROR); throw new \LogicException('More than one page found'); } // Make sure $objPage is a Model if ($objPage instanceof Model\Collection) { $objPage = $objPage->current(); } // If the page has an alias, it can no longer be called via ID (see #7661) if ($objPage->alias != '' && preg_match('#^' . $objPage->id . '[$/.]#', \Environment::get('relativeRequest'))) { $this->User->authenticate(); throw new PageNotFoundException('Page not found'); } // Load a website root page object (will redirect to the first active regular page) if ($objPage->type == 'root') { /** @var PageRoot $objHandler */ $objHandler = new $GLOBALS['TL_PTY']['root'](); $objHandler->generate($objPage->id); } // Inherit the settings from the parent pages if it has not been done yet if (!is_bool($objPage->protected)) { $objPage->loadDetails(); } // Set the admin e-mail address if ($objPage->adminEmail != '') { list($GLOBALS['TL_ADMIN_NAME'], $GLOBALS['TL_ADMIN_EMAIL']) = \StringUtil::splitFriendlyEmail($objPage->adminEmail); } else { list($GLOBALS['TL_ADMIN_NAME'], $GLOBALS['TL_ADMIN_EMAIL']) = \StringUtil::splitFriendlyEmail(\Config::get('adminEmail')); } // Exit if the root page has not been published (see #2425) // Do not try to load the 404 page, it can cause an infinite loop! if (!BE_USER_LOGGED_IN && !$objPage->rootIsPublic) { throw new PageNotFoundException('Page not found'); } // Check wether the language matches the root page language if (\Config::get('addLanguageToUrl') && \Input::get('language') != $objPage->rootLanguage) { $this->User->authenticate(); $this->log('No active page for page ID "' . $pageId . '" and language "' . \Input::get('language') . '" (' . \Environment::get('base') . \Environment::get('request') . ')', __METHOD__, TL_ERROR); throw new PageNotFoundException('Page not found'); } // Check whether there are domain name restrictions if ($objPage->domain != '') { // Load an error 404 page object if ($objPage->domain != \Environment::get('host')) { $this->User->authenticate(); $this->log('Page ID "' . $pageId . '" was requested via "' . \Environment::get('host') . '" but can only be accessed via "' . $objPage->domain . '" (' . \Environment::get('base') . \Environment::get('request') . ')', __METHOD__, TL_ERROR); throw new PageNotFoundException('Page not found'); } } // Authenticate the user if (!$this->User->authenticate() && $objPage->protected && !BE_USER_LOGGED_IN) { $this->log('Access to page ID "' . $pageId . '" denied (' . \Environment::get('base') . \Environment::get('request') . ')', __METHOD__, TL_ERROR); throw new AccessDeniedException('Access denied'); } // Check the user groups if the page is protected if ($objPage->protected && !BE_USER_LOGGED_IN) { $arrGroups = $objPage->groups; // required for empty() if (!is_array($arrGroups) || empty($arrGroups) || !count(array_intersect($arrGroups, $this->User->groups))) { $this->log('Page ID "' . $pageId . '" can only be accessed by groups "' . implode(', ', (array) $objPage->groups) . '" (current user groups: ' . implode(', ', $this->User->groups) . ')', __METHOD__, TL_ERROR); throw new AccessDeniedException('Access denied'); } } // Backup some globals (see #7659) $arrHead = $GLOBALS['TL_HEAD']; $arrBody = $GLOBALS['TL_BODY']; $arrMootools = $GLOBALS['TL_MOOTOOLS']; $arrJquery = $GLOBALS['TL_JQUERY']; try { // Generate the page switch ($objPage->type) { case 'error_404': /** @var PageError404 $objHandler */ $objHandler = new $GLOBALS['TL_PTY']['error_404'](); return $objHandler->getResponse(); break; case 'error_403': /** @var PageError403 $objHandler */ $objHandler = new $GLOBALS['TL_PTY']['error_403'](); return $objHandler->getResponse($objRootPage); break; default: /** @var PageRegular $objHandler */ $objHandler = new $GLOBALS['TL_PTY'][$objPage->type](); // Backwards compatibility if (!method_exists($objHandler, 'getResponse')) { ob_start(); $objHandler->generate($objPage, true); return new Response(ob_get_clean(), http_response_code()); } return $objHandler->getResponse($objPage, true); break; } } catch (\UnusedArgumentsException $e) { // Restore the globals (see #7659) $GLOBALS['TL_HEAD'] = $arrHead; $GLOBALS['TL_BODY'] = $arrBody; $GLOBALS['TL_MOOTOOLS'] = $arrMootools; $GLOBALS['TL_JQUERY'] = $arrJquery; /** @var PageError404 $objHandler */ $objHandler = new $GLOBALS['TL_PTY']['error_404'](); $this->log('The request for page ID "' . $pageId . '" contained unused GET parameters: "' . implode('", "', \Input::getUnusedGet()) . '" (' . \Environment::get('base') . \Environment::get('request') . ')', __METHOD__, TL_ERROR); return $objHandler->getResponse(); } }