From b306a170b593c38bd6456cf2d4376d8f5c4a2884 Mon Sep 17 00:00:00 2001 From: Benjamin Mack <benni@typo3.org> Date: Sun, 1 Mar 2015 14:47:15 +0100 Subject: [PATCH] [TASK] Introduce unified RequestHandling for all requests The TYPO3 Bootstrap gets a new function run() to unify existing entrypoints in FE, BE, CLI and Install Tool. This way the "visible" part of the bootstrap is reduced to solely using the new "run()" method, which resolves to a proper RequestHandler depending on the following constraints. * Install Tool * Frontend: eID * Frontend: TSFE * Backend: Regular request * Backend: AJAX * Command-Line (CLIkeys) The interface behaves exactly like TYPO3 Flow. Unlike Flow, the request handlers are currently hardcoded inside the bootstrap, but can be extended later. Each RequestHandler logic is currently put from the global scope into the main "handleRequest()" method. Further changes are the deprecation of init.php and the streamlining of Backend requests, as well as diagram of the bootstrap process. Resolves: #65437 Releases: master Change-Id: I3a2ffe60e59005955c5ef3d3c541b61de2b97526 Reviewed-on: http://review.typo3.org/37409 Reviewed-by: Christian Kuhn <lolli@schwarzbu.ch> Tested-by: Christian Kuhn <lolli@schwarzbu.ch> Reviewed-by: Helmut Hummel <helmut.hummel@typo3.org> Tested-by: Helmut Hummel <helmut.hummel@typo3.org> Reviewed-by: Anja Leichsenring <aleichsenring@ab-softlab.de> Tested-by: Anja Leichsenring <aleichsenring@ab-softlab.de> --- index.php | 9 +- typo3/ajax.php | 77 +-------- typo3/cli_dispatch.phpsh | 27 +-- typo3/init.php | 26 +-- .../backend/Classes/AjaxRequestHandler.php | 154 ++++++++++++++++++ .../backend/Classes/CliRequestHandler.php | 140 ++++++++++++++++ .../sysext/backend/Classes/RequestHandler.php | 84 ++++++++++ typo3/sysext/core/Classes/Core/Bootstrap.php | 122 +++++++++++++- .../sysext/core/Classes/Core/CliBootstrap.php | 35 ---- .../Classes/Core/RequestHandlerInterface.php | 50 ++++++ .../frontend/Classes/EidRequestHandler.php | 84 ++++++++++ ...dRequestHandler.php => RequestHandler.php} | 114 +++++++------ .../sysext/install/Classes/RequestHandler.php | 84 ++++++++++ .../install/Resources/Private/PHP/Boot.php | 39 ----- typo3/sysext/install/Start/Install.php | 9 +- 15 files changed, 793 insertions(+), 261 deletions(-) create mode 100644 typo3/sysext/backend/Classes/AjaxRequestHandler.php create mode 100644 typo3/sysext/backend/Classes/CliRequestHandler.php create mode 100644 typo3/sysext/backend/Classes/RequestHandler.php create mode 100644 typo3/sysext/core/Classes/Core/RequestHandlerInterface.php create mode 100644 typo3/sysext/frontend/Classes/EidRequestHandler.php rename typo3/sysext/frontend/Classes/{FrontendRequestHandler.php => RequestHandler.php} (79%) create mode 100644 typo3/sysext/install/Classes/RequestHandler.php delete mode 100644 typo3/sysext/install/Resources/Private/PHP/Boot.php diff --git a/index.php b/index.php index fcacf5da0d77..e24c525274fe 100644 --- a/index.php +++ b/index.php @@ -30,11 +30,4 @@ if (version_compare(PHP_VERSION, '5.5.0', '<')) { define('TYPO3_MODE', 'FE'); require __DIR__ . '/typo3/sysext/core/Classes/Core/Bootstrap.php'; -\TYPO3\CMS\Core\Core\Bootstrap::getInstance() - ->baseSetup('') - ->redirectToInstallerIfEssentialConfigurationDoesNotExist() - ->startOutputBuffering() - ->loadConfigurationAndInitialize(); - -$frontendRequestHandler = new \TYPO3\CMS\Frontend\FrontendRequestHandler(); -$frontendRequestHandler->handleRequest(); +\TYPO3\CMS\Core\Core\Bootstrap::getInstance()->run()->shutdown(); diff --git a/typo3/ajax.php b/typo3/ajax.php index 98503819b4eb..fbe1263e02bf 100644 --- a/typo3/ajax.php +++ b/typo3/ajax.php @@ -14,77 +14,12 @@ /** * AJAX dispatcher - * - * @author Benjamin Mack <mack@xnos.org> + * main entry point for AJAX calls in the TYPO3 Backend. Based on $TYPO3_AJAX the Bootstrap let's the request + * handled by TYPO3\CMS\Backend\AjaxRequestHandler and AjaxController. + * See $TYPO3_CONF_VARS['BE']['AJAX'] and the Core APIs on how to register an AJAX call in the TYPO3 Backend. */ - $TYPO3_AJAX = TRUE; +define('TYPO3_MODE', 'BE'); -// This is a list of requests that don't necessarily need a valid BE user -$noUserAjaxIDs = array( - 'BackendLogin::login', - 'BackendLogin::logout', - 'BackendLogin::refreshLogin', - 'BackendLogin::isTimedOut', - 'BackendLogin::getChallenge', - 'BackendLogin::getRsaPublicKey', -); - -// First get the ajaxID -$ajaxID = isset($_POST['ajaxID']) ? $_POST['ajaxID'] : $_GET['ajaxID']; -if (isset($ajaxID)) { - $ajaxID = (string)stripslashes($ajaxID); -} - -// If we're trying to do an ajax login, don't require a user. -if (in_array($ajaxID, $noUserAjaxIDs)) { - define('TYPO3_PROCEED_IF_NO_USER', 2); -} - -require __DIR__ . '/init.php'; - -// Finding the script path from the registry -$ajaxRegistryEntry = isset($GLOBALS['TYPO3_CONF_VARS']['BE']['AJAX'][$ajaxID]) ? $GLOBALS['TYPO3_CONF_VARS']['BE']['AJAX'][$ajaxID] : NULL; -$ajaxScript = NULL; -$csrfTokenCheck = FALSE; -if ($ajaxRegistryEntry !== NULL) { - if (is_array($ajaxRegistryEntry)) { - if (isset($ajaxRegistryEntry['callbackMethod'])) { - $ajaxScript = $ajaxRegistryEntry['callbackMethod']; - $csrfTokenCheck = $ajaxRegistryEntry['csrfTokenCheck']; - } - } else { - // @Deprecated since 6.2 will be removed two versions later - $ajaxScript = $ajaxRegistryEntry; - } -} - -// Instantiating the AJAX object -$ajaxObj = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance(\TYPO3\CMS\Core\Http\AjaxRequestHandler::class, $ajaxID); -$ajaxParams = array(); - -// Evaluating the arguments and calling the AJAX method/function -if (empty($ajaxID)) { - $ajaxObj->setError('No valid ajaxID parameter given.'); -} elseif (empty($ajaxScript)) { - $ajaxObj->setError('No backend function registered for ajaxID "' . $ajaxID . '".'); -} else { - $success = TRUE; - $tokenIsValid = TRUE; - if ($csrfTokenCheck) { - $tokenIsValid = \TYPO3\CMS\Core\FormProtection\FormProtectionFactory::get()->validateToken(\TYPO3\CMS\Core\Utility\GeneralUtility::_GP('ajaxToken'), 'ajaxCall', $ajaxID); - } - if ($tokenIsValid) { - // Cleanup global variable space - unset($csrfTokenCheck, $ajaxRegistryEntry, $tokenIsValid, $success); - $success = \TYPO3\CMS\Core\Utility\GeneralUtility::callUserFunction($ajaxScript, $ajaxParams, $ajaxObj, FALSE, TRUE); - } else { - $ajaxObj->setError('Invalid CSRF token detected for ajaxID "' . $ajaxID . '"!'); - } - if ($success === FALSE) { - $ajaxObj->setError('Registered backend function for ajaxID "' . $ajaxID . '" was not found.'); - } -} - -// Outputting the content (and setting the X-JSON-Header) -$ajaxObj->render(); +require __DIR__ . '/sysext/core/Classes/Core/Bootstrap.php'; +\TYPO3\CMS\Core\Core\Bootstrap::getInstance()->run('typo3/')->shutdown(); diff --git a/typo3/cli_dispatch.phpsh b/typo3/cli_dispatch.phpsh index 3eaf59e57f59..1bc8ed2ec924 100755 --- a/typo3/cli_dispatch.phpsh +++ b/typo3/cli_dispatch.phpsh @@ -30,29 +30,4 @@ require __DIR__ . '/sysext/core/Classes/Core/CliBootstrap.php'; \TYPO3\CMS\Core\Core\CliBootstrap::checkEnvironmentOrDie(); require __DIR__ . '/sysext/core/Classes/Core/Bootstrap.php'; -\TYPO3\CMS\Core\Core\Bootstrap::getInstance() - ->baseSetup('typo3/') - ->loadConfigurationAndInitialize() - ->loadTypo3LoadedExtAndExtLocalconf(TRUE) - ->applyAdditionalConfigurationSettings() - ->initializeTypo3DbGlobal(); - -\TYPO3\CMS\Core\Core\CliBootstrap::initializeCliKeyOrDie(); - -\TYPO3\CMS\Core\Core\Bootstrap::getInstance() - ->loadExtensionTables(TRUE) - ->initializeBackendUser() - ->initializeBackendAuthentication() - ->initializeLanguageObject(); - - // Make sure output is not buffered, so command-line output and interaction can take place -\TYPO3\CMS\Core\Utility\GeneralUtility::flushOutputBuffers(); - -try { - include(TYPO3_cliInclude); -} catch (\Exception $e) { - fwrite(STDERR, $e->getMessage() . LF); - exit(99); -} - -\TYPO3\CMS\Core\Core\Bootstrap::getInstance()->shutdown(); +\TYPO3\CMS\Core\Core\Bootstrap::getInstance()->run('typo3/')->shutdown(); diff --git a/typo3/init.php b/typo3/init.php index 49d6ced88cbb..235b9c8f92bd 100644 --- a/typo3/init.php +++ b/typo3/init.php @@ -35,30 +35,12 @@ * For a detailed description of this script, the scope of constants and variables in it, * please refer to the document "Inside TYPO3" * + * Please note that this file might be removed in the future in favor of adding these lines to all entry + * scripts as well. + * * @author Kasper Skårhøj <kasperYYYY@typo3.com> */ define('TYPO3_MODE', 'BE'); require __DIR__ . '/sysext/core/Classes/Core/Bootstrap.php'; - -\TYPO3\CMS\Core\Core\Bootstrap::getInstance() - ->baseSetup('typo3/') - ->redirectToInstallerIfEssentialConfigurationDoesNotExist('../') - ->startOutputBuffering() - ->loadConfigurationAndInitialize() - ->loadTypo3LoadedExtAndExtLocalconf(TRUE) - ->applyAdditionalConfigurationSettings() - ->initializeTypo3DbGlobal() - ->checkLockedBackendAndRedirectOrDie() - ->checkBackendIpOrDie() - ->checkSslBackendAndRedirectIfNeeded() - ->checkValidBrowserOrDie() - ->loadExtensionTables(TRUE) - ->initializeSpriteManager() - ->initializeBackendUser() - ->initializeBackendAuthentication() - ->initializeLanguageObject() - ->initializeBackendTemplate() - ->endOutputBufferingAndCleanPreviousOutput() - ->initializeOutputCompression() - ->sendHttpHeaders(); +\TYPO3\CMS\Core\Core\Bootstrap::getInstance()->run('typo3/'); diff --git a/typo3/sysext/backend/Classes/AjaxRequestHandler.php b/typo3/sysext/backend/Classes/AjaxRequestHandler.php new file mode 100644 index 000000000000..fb96fd3f65e3 --- /dev/null +++ b/typo3/sysext/backend/Classes/AjaxRequestHandler.php @@ -0,0 +1,154 @@ +<?php +namespace TYPO3\CMS\Backend; + +/* + * This file is part of the TYPO3 CMS project. + * + * It is free software; you can redistribute it and/or modify it under + * the terms of the GNU General Public License, either version 2 + * of the License, or any later version. + * + * For the full copyright and license information, please read the + * LICENSE.txt file that was distributed with this source code. + * + * The TYPO3 project - inspiring people to share! + */ + +use TYPO3\CMS\Core\Core\Bootstrap; +use TYPO3\CMS\Core\Core\RequestHandlerInterface; +use TYPO3\CMS\Core\Utility\GeneralUtility; + +/** + * Base class for all AJAX-related calls for the TYPO3 Backend run through typo3/ajax.php. + * Before doing the basic BE-related set up of this request (see the additional calls on $this->bootstrap inside + * handleRequest()), some AJAX-calls can be made without a valid user, which is determined here. + * + * Due to legacy reasons, the actual logic is in EXT:core/Http/AjaxRequestHandler which will eventually + * be moved into this class. + * In the future, the logic for "TYPO3_PROCEED_IF_NO_USER" will be moved in here as well. + */ +class AjaxRequestHandler implements RequestHandlerInterface { + + /** + * Instance of the current TYPO3 bootstrap + * @var Bootstrap + */ + protected $bootstrap; + + /** + * Constructor handing over the bootstrap + * + * @param Bootstrap $bootstrap + */ + public function __construct(Bootstrap $bootstrap) { + $this->bootstrap = $bootstrap; + } + + /** + * Handles any AJAX request in the TYPO3 Backend + * + * @return void + */ + public function handleRequest() { + + // This is a list of requests that don't necessarily need a valid BE user + $noUserAjaxIDs = array( + 'BackendLogin::login', + 'BackendLogin::logout', + 'BackendLogin::refreshLogin', + 'BackendLogin::isTimedOut', + 'BackendLogin::getChallenge', + 'BackendLogin::getRsaPublicKey', + ); + + // First get the ajaxID + $ajaxID = isset($_POST['ajaxID']) ? $_POST['ajaxID'] : $_GET['ajaxID']; + if (isset($ajaxID)) { + $ajaxID = (string)stripslashes($ajaxID); + } + + // If we're trying to do an ajax login, don't require a user. + if (in_array($ajaxID, $noUserAjaxIDs)) { + define('TYPO3_PROCEED_IF_NO_USER', 2); + } + + $this->bootstrap + ->checkLockedBackendAndRedirectOrDie() + ->checkBackendIpOrDie() + ->checkSslBackendAndRedirectIfNeeded() + ->checkValidBrowserOrDie() + ->loadExtensionTables(TRUE) + ->initializeSpriteManager() + ->initializeBackendUser() + ->initializeBackendAuthentication() + ->initializeLanguageObject() + ->initializeBackendTemplate() + ->endOutputBufferingAndCleanPreviousOutput() + ->initializeOutputCompression() + ->sendHttpHeaders(); + + // Finding the script path from the registry + $ajaxRegistryEntry = isset($GLOBALS['TYPO3_CONF_VARS']['BE']['AJAX'][$ajaxID]) ? $GLOBALS['TYPO3_CONF_VARS']['BE']['AJAX'][$ajaxID] : NULL; + $ajaxScript = NULL; + $csrfTokenCheck = FALSE; + if ($ajaxRegistryEntry !== NULL) { + if (is_array($ajaxRegistryEntry)) { + if (isset($ajaxRegistryEntry['callbackMethod'])) { + $ajaxScript = $ajaxRegistryEntry['callbackMethod']; + $csrfTokenCheck = $ajaxRegistryEntry['csrfTokenCheck']; + } + } else { + // @deprecated since 6.2 will be removed two versions later + $ajaxScript = $ajaxRegistryEntry; + } + } + + // Instantiating the AJAX object + $ajaxObj = GeneralUtility::makeInstance(\TYPO3\CMS\Core\Http\AjaxRequestHandler::class, $ajaxID); + $ajaxParams = array(); + + // Evaluating the arguments and calling the AJAX method/function + if (empty($ajaxID)) { + $ajaxObj->setError('No valid ajaxID parameter given.'); + } elseif (empty($ajaxScript)) { + $ajaxObj->setError('No backend function registered for ajaxID "' . $ajaxID . '".'); + } else { + $success = TRUE; + $tokenIsValid = TRUE; + if ($csrfTokenCheck) { + $tokenIsValid = \TYPO3\CMS\Core\FormProtection\FormProtectionFactory::get()->validateToken(GeneralUtility::_GP('ajaxToken'), 'ajaxCall', $ajaxID); + } + if ($tokenIsValid) { + // Cleanup global variable space + unset($csrfTokenCheck, $ajaxRegistryEntry, $tokenIsValid, $success); + $success = GeneralUtility::callUserFunction($ajaxScript, $ajaxParams, $ajaxObj, FALSE, TRUE); + } else { + $ajaxObj->setError('Invalid CSRF token detected for ajaxID "' . $ajaxID . '"!'); + } + if ($success === FALSE) { + $ajaxObj->setError('Registered backend function for ajaxID "' . $ajaxID . '" was not found.'); + } + } + + // Outputting the content (and setting the X-JSON-Header) + $ajaxObj->render(); + } + + /** + * This request handler can handle any backend request coming from ajax.php + * + * @return bool If the request is an AJAX backend request, TRUE otherwise FALSE + */ + public function canHandleRequest() { + return TYPO3_REQUESTTYPE & TYPO3_REQUESTTYPE_AJAX; + } + + /** + * Returns the priority - how eager the handler is to actually handle the request. + * + * @return int The priority of the request handler. + */ + public function getPriority() { + return 80; + } +} diff --git a/typo3/sysext/backend/Classes/CliRequestHandler.php b/typo3/sysext/backend/Classes/CliRequestHandler.php new file mode 100644 index 000000000000..fe6f88313ff5 --- /dev/null +++ b/typo3/sysext/backend/Classes/CliRequestHandler.php @@ -0,0 +1,140 @@ +<?php +namespace TYPO3\CMS\Backend; + +/* + * This file is part of the TYPO3 CMS project. + * + * It is free software; you can redistribute it and/or modify it under + * the terms of the GNU General Public License, either version 2 + * of the License, or any later version. + * + * For the full copyright and license information, please read the + * LICENSE.txt file that was distributed with this source code. + * + * The TYPO3 project - inspiring people to share! + */ + +use TYPO3\CMS\Core\Core\Bootstrap; +use TYPO3\CMS\Core\Core\RequestHandlerInterface; +use TYPO3\CMS\Core\Utility\GeneralUtility; + +/** + * Command Line Interface Request Handler dealing with "cliKey"-based Commands from the cli_dispatch.phpsh script. + * Picks up requests only when coming from the CLI mode. + * Resolves the "cliKey" which is registered inside $TYPO3_CONF_VARS[SC_OPTIONS][GLOBAL][cliKeys] + * and includes the CLI-based script or exits if no valid "cliKey" is found. + */ +class CliRequestHandler implements RequestHandlerInterface { + + /** + * Instance of the current TYPO3 bootstrap + * @var Bootstrap + */ + protected $bootstrap; + + /** + * Constructor handing over the bootstrap + * + * @param Bootstrap $bootstrap + */ + public function __construct(Bootstrap $bootstrap) { + $this->bootstrap = $bootstrap; + } + + /** + * Handles any commandline request + * + * @return void + */ + public function handleRequest() { + $commandLineKey = $this->getCommandLineKeyOrDie(); + $commandLineScript = $this->getIncludeScriptByCommandLineKey($commandLineKey); + + $this->bootstrap + ->loadExtensionTables(TRUE) + ->initializeBackendUser() + ->initializeBackendAuthentication() + ->initializeLanguageObject(); + + // Make sure output is not buffered, so command-line output and interaction can take place + GeneralUtility::flushOutputBuffers(); + + try { + include($commandLineScript); + } catch (\Exception $e) { + fwrite(STDERR, $e->getMessage() . LF); + exit(99); + } + } + + /** + * Check CLI parameters. + * First argument is a key that points to the script configuration. + * If it is not set or not valid, the script exits with an error message. + * + * @return string the CLI key in use + */ + protected function getCommandLineKeyOrDie() { + $cliKey = $_SERVER['argv'][1]; + $errorMessage = ''; + if (empty($cliKey)) { + $errorMessage = 'This script must have a \'cliKey\' as first argument.'; + } elseif (!is_array($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['GLOBAL']['cliKeys'][$cliKey])) { + $errorMessage = 'The supplied \'cliKey\' is not valid.'; + } + + // exit with an error message + if (!empty($errorMessage)) { + $errorMessage .= ' Valid keys are: + +'; + $cliKeys = array_keys($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['GLOBAL']['cliKeys']); + asort($cliKeys); + foreach ($cliKeys as $key => $value) { + $errorMessage .= ' ' . $value . LF; + } + fwrite(STDERR, $errorMessage . LF); + die(1); + } + + return $cliKey; + } + + /** + * Define cli-related parameters and return the include script. + * + * @param string $cliKey the CLI key + * @return string the absolute path to the include script + */ + protected function getIncludeScriptByCommandLineKey($cliKey) { + list($commandLineScript, $commandLineName) = $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['GLOBAL']['cliKeys'][$cliKey]; + $commandLineScript = GeneralUtility::getFileAbsFileName($commandLineScript); + // Note: These constants are not in use anymore + define('TYPO3_cliKey', $cliKey); + define('TYPO3_cliInclude', $commandLineScript); + $GLOBALS['MCONF']['name'] = $commandLineName; + // This is a compatibility layer: Some cli scripts rely on this, like ext:phpunit cli + $GLOBALS['temp_cliScriptPath'] = array_shift($_SERVER['argv']); + $GLOBALS['temp_cliKey'] = array_shift($_SERVER['argv']); + array_unshift($_SERVER['argv'], $GLOBALS['temp_cliScriptPath']); + return $commandLineScript; + } + + /** + * This request handler can handle any CLI request . + * + * @return bool If the request is a CLI request, TRUE otherwise FALSE + */ + public function canHandleRequest() { + return defined('TYPO3_cliMode') && (TYPO3_REQUESTTYPE & TYPO3_REQUESTTYPE_BE) && (TYPO3_REQUESTTYPE & TYPO3_REQUESTTYPE_CLI); + } + + /** + * Returns the priority - how eager the handler is to actually handle the request. + * + * @return int The priority of the request handler. + */ + public function getPriority() { + return 50; + } +} diff --git a/typo3/sysext/backend/Classes/RequestHandler.php b/typo3/sysext/backend/Classes/RequestHandler.php new file mode 100644 index 000000000000..23be5e2ca6a5 --- /dev/null +++ b/typo3/sysext/backend/Classes/RequestHandler.php @@ -0,0 +1,84 @@ +<?php +namespace TYPO3\CMS\Backend; + +/* + * This file is part of the TYPO3 CMS project. + * + * It is free software; you can redistribute it and/or modify it under + * the terms of the GNU General Public License, either version 2 + * of the License, or any later version. + * + * For the full copyright and license information, please read the + * LICENSE.txt file that was distributed with this source code. + * + * The TYPO3 project - inspiring people to share! + */ + +use TYPO3\CMS\Core\Core\Bootstrap; +use TYPO3\CMS\Core\Core\RequestHandlerInterface; + +/** + * General RequestHandler for the TYPO3 Backend. This is used for all Backend requests except for CLI + * or AJAX calls. Unlike all other RequestHandlers in the TYPO3 CMS Core, the actual logic for choosing + * the controller is still done inside places like mod.php and each single file. + * This RequestHandler here serves solely to check and set up all requirements needed for a TYPO3 Backend. + * This class might be changed in the future. + */ +class RequestHandler implements RequestHandlerInterface { + + /** + * Instance of the current TYPO3 bootstrap + * @var Bootstrap + */ + protected $bootstrap; + + /** + * Constructor handing over the bootstrap + * + * @param Bootstrap $bootstrap + */ + public function __construct(Bootstrap $bootstrap) { + $this->bootstrap = $bootstrap; + } + + /** + * Handles any backend request + * + * @return void + */ + public function handleRequest() { + $this->bootstrap + ->checkLockedBackendAndRedirectOrDie() + ->checkBackendIpOrDie() + ->checkSslBackendAndRedirectIfNeeded() + ->checkValidBrowserOrDie() + ->loadExtensionTables(TRUE) + ->initializeSpriteManager() + ->initializeBackendUser() + ->initializeBackendAuthentication() + ->initializeLanguageObject() + ->initializeBackendTemplate() + ->endOutputBufferingAndCleanPreviousOutput() + ->initializeOutputCompression() + ->sendHttpHeaders(); + } + + /** + * This request handler can handle any backend request (but not CLI). + * + * @return bool If the request is not a CLI script, TRUE otherwise FALSE + */ + public function canHandleRequest() { + return (TYPO3_REQUESTTYPE & TYPO3_REQUESTTYPE_BE && !(TYPO3_REQUESTTYPE & TYPO3_REQUESTTYPE_CLI)); + } + + /** + * Returns the priority - how eager the handler is to actually handle the + * request. + * + * @return int The priority of the request handler. + */ + public function getPriority() { + return 50; + } +} diff --git a/typo3/sysext/core/Classes/Core/Bootstrap.php b/typo3/sysext/core/Classes/Core/Bootstrap.php index b6f35f5155ea..2af75563701e 100644 --- a/typo3/sysext/core/Classes/Core/Bootstrap.php +++ b/typo3/sysext/core/Classes/Core/Bootstrap.php @@ -70,6 +70,12 @@ class Bootstrap { */ protected $activeErrorHandlerClassName; + /** + * registered request handlers + * @var RequestHandlerInterface[] + */ + protected $availableRequestHandlers = array(); + /** * @var bool */ @@ -151,6 +157,45 @@ class Bootstrap { return $this; } + /** + * Main entry point called at every request usually from Global scope. Checks if everthing is correct, + * and sets up the base request information for a regular request, then + * resolves the RequestHandler which handles the request. + * + * @param string $relativePathPart Relative path of entry script back to document root + * @return Bootstrap + */ + public function run($relativePathPart = '') { + $this->baseSetup($relativePathPart); + + // Failsafe minimal setup mode for the install tool + if (defined('TYPO3_enterInstallScript')) { + $this->startOutputBuffering() + ->loadConfigurationAndInitialize(FALSE, \TYPO3\CMS\Core\Package\FailsafePackageManager::class); + } elseif (!$this->checkIfEssentialConfigurationExists() && !defined('TYPO3_cliMode')) { + // Redirect to install tool if base configuration is not found + $backPathToSiteRoot = ''; + $pathParts = explode('/', $relativePathPart); + for ($i = 1; $i <= count($pathParts); $i++) { + $backPathToSiteRoot .= '../'; + } + $this->redirectToInstallTool($backPathToSiteRoot); + } else { + // Regular request (Frontend, AJAX, Backend, CLI) + $this->startOutputBuffering() + ->loadConfigurationAndInitialize() + ->loadTypo3LoadedExtAndExtLocalconf(TRUE) + ->applyAdditionalConfigurationSettings() + ->initializeTypo3DbGlobal(); + } + + // Resolve request handler that were registered based on TYPO3_MODE + $this->registerRequestHandlers(); + $requestHandler = $this->resolveRequestHandler(); + $requestHandler->handleRequest(); + return $this; + } + /** * Run the base setup that checks server environment, determines pathes, * populates base files and sets common configuration. @@ -208,25 +253,86 @@ class Bootstrap { } } + /** + * checks if LocalConfiguration.php or PackageStates.php is missing, + * used to see if a redirect to the install tool is needed + * + * @return bool TRUE when the essential configuration is available, otherwise FALSE + */ + protected function checkIfEssentialConfigurationExists() { + $configurationManager = new \TYPO3\CMS\Core\Configuration\ConfigurationManager; + $this->setEarlyInstance(\TYPO3\CMS\Core\Configuration\ConfigurationManager::class, $configurationManager); + return (!file_exists($configurationManager->getLocalConfigurationFileLocation()) || !file_exists(PATH_typo3conf . 'PackageStates.php')) ? FALSE : TRUE; + } + /** * Redirect to install tool if LocalConfiguration.php is missing. * * @param string $pathUpToDocumentRoot Can contain '../' if called from a sub directory + * @internal This is not a public API method, do not use in own extensions + */ + public function redirectToInstallTool($pathUpToDocumentRoot = '') { + define('TYPO3_enterInstallScript', '1'); + $this->defineTypo3RequestTypes(); + Utility\HttpUtility::redirect($pathUpToDocumentRoot . 'typo3/sysext/install/Start/Install.php'); + } + + /** + * Adds available request handlers, which currently hard-coded here based on the TYPO3_MODE. The extensability + * of adding own request handlers would be too complex for now, but can be added later. + * * @return Bootstrap * @internal This is not a public API method, do not use in own extensions */ - public function redirectToInstallerIfEssentialConfigurationDoesNotExist($pathUpToDocumentRoot = '') { - $configurationManager = new \TYPO3\CMS\Core\Configuration\ConfigurationManager; - $this->setEarlyInstance(\TYPO3\CMS\Core\Configuration\ConfigurationManager::class, $configurationManager); - if (!file_exists($configurationManager->getLocalConfigurationFileLocation()) || !file_exists(PATH_typo3conf . 'PackageStates.php')) { - define('TYPO3_enterInstallScript', '1'); - $this->defineTypo3RequestTypes(); - require_once __DIR__ . '/../Utility/HttpUtility.php'; - Utility\HttpUtility::redirect($pathUpToDocumentRoot . 'typo3/sysext/install/Start/Install.php'); + protected function registerRequestHandlers() { + // Use the install tool handler if in install tool mode + if (!$this->checkIfEssentialConfigurationExists() || (TYPO3_REQUESTTYPE & TYPO3_REQUESTTYPE_INSTALL)) { + $this->availableRequestHandlers = array( + \TYPO3\CMS\Install\RequestHandler::class + ); + } elseif (TYPO3_MODE == 'BE') { + $this->availableRequestHandlers = array( + \TYPO3\CMS\Backend\RequestHandler::class, + \TYPO3\CMS\Backend\AjaxRequestHandler::class, + \TYPO3\CMS\Backend\CliRequestHandler::class + ); + } elseif (TYPO3_MODE == 'FE') { + $this->availableRequestHandlers = array( + \TYPO3\CMS\Frontend\RequestHandler::class, + \TYPO3\CMS\Frontend\EidRequestHandler::class + ); } return $this; } + /** + * Fetches the request handler that suits the best based on the priority and the interface + * Be sure to always have the constants that are defined in $this->defineTypo3RequestTypes() are set, + * so most RequestHandlers can check if they can handle the request. + * + * @return RequestHandlerInterface + * @throws \TYPO3\CMS\Core\Exception + * @internal This is not a public API method, do not use in own extensions + */ + public function resolveRequestHandler() { + $suitableRequestHandlers = array(); + foreach ($this->availableRequestHandlers as $requestHandlerClassName) { + $requestHandler = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance($requestHandlerClassName, $this); + if ($requestHandler->canHandleRequest()) { + $priority = $requestHandler->getPriority(); + if (isset($suitableRequestHandlers[$priority])) { + throw new \TYPO3\CMS\Core\Exception('More than one request handler with the same priority can handle the request, but only one handler may be active at a time!', 1176471352); + } + $suitableRequestHandlers[$priority] = $requestHandler; + } + } + if (count($suitableRequestHandlers) === 0) { + throw new \TYPO3\CMS\Core\Exception('No suitable request handler found.', 1225418233); + } + ksort($suitableRequestHandlers); + return array_pop($suitableRequestHandlers); + } + /** * Registers the instance of the specified object for an early boot stage. * On finalizing the Object Manager initialization, all those instances will diff --git a/typo3/sysext/core/Classes/Core/CliBootstrap.php b/typo3/sysext/core/Classes/Core/CliBootstrap.php index 5f3ced9f1bad..daedab43b630 100644 --- a/typo3/sysext/core/Classes/Core/CliBootstrap.php +++ b/typo3/sysext/core/Classes/Core/CliBootstrap.php @@ -39,41 +39,6 @@ class CliBootstrap { } } - /** - * Check and define cli parameters. - * First argument is a key that points to the script configuration. - * If it is not set or not valid, the script exits with an error message. - * - * @return void - * @internal This is not a public API method, do not use in own extensions - */ - static public function initializeCliKeyOrDie() { - if (!isset($_SERVER['argv'][1]) || !is_array($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['GLOBAL']['cliKeys'][$_SERVER['argv'][1]])) { - if (!isset($_SERVER['argv'][1])) { - $message = 'This script must have a \'cliKey\' as first argument.'; - } else { - $message = 'The supplied \'cliKey\' is not valid.'; - } - $message .= ' Valid keys are: - -'; - $cliKeys = array_keys($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['GLOBAL']['cliKeys']); - asort($cliKeys); - foreach ($cliKeys as $key => $value) { - $message .= ' ' . $value . LF; - } - fwrite(STDERR, $message . LF); - die(1); - } - define('TYPO3_cliKey', $_SERVER['argv'][1]); - define('TYPO3_cliInclude', \TYPO3\CMS\Core\Utility\GeneralUtility::getFileAbsFileName($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['GLOBAL']['cliKeys'][TYPO3_cliKey][0])); - $GLOBALS['MCONF']['name'] = $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['GLOBAL']['cliKeys'][TYPO3_cliKey][1]; - // This is a compatibility layer: Some cli scripts rely on this, like ext:phpunit cli - $GLOBALS['temp_cliScriptPath'] = array_shift($_SERVER['argv']); - $GLOBALS['temp_cliKey'] = array_shift($_SERVER['argv']); - array_unshift($_SERVER['argv'], $GLOBALS['temp_cliScriptPath']); - } - /** * Set up cgi sapi as de facto cli, but check no HTTP * environment variables are set. diff --git a/typo3/sysext/core/Classes/Core/RequestHandlerInterface.php b/typo3/sysext/core/Classes/Core/RequestHandlerInterface.php new file mode 100644 index 000000000000..cdddae390b09 --- /dev/null +++ b/typo3/sysext/core/Classes/Core/RequestHandlerInterface.php @@ -0,0 +1,50 @@ +<?php +namespace TYPO3\CMS\Core\Core; + +/* + * This file is part of the TYPO3 CMS project. + * + * It is free software; you can redistribute it and/or modify it under + * the terms of the GNU General Public License, either version 2 + * of the License, or any later version. + * + * For the full copyright and license information, please read the + * LICENSE.txt file that was distributed with this source code. + * + * The TYPO3 project - inspiring people to share! + */ + +/** + * The interface for a request handler + * see FrontendRequestHandler + * + * @api + */ +interface RequestHandlerInterface { + + /** + * Handles a raw request + * + * @return void + * @api + */ + public function handleRequest(); + + /** + * Checks if the request handler can handle the current request. + * + * @return bool TRUE if it can handle the request, otherwise FALSE + * @api + */ + public function canHandleRequest(); + + /** + * Returns the priority - how eager the handler is to actually handle the + * request. An integer > 0 means "I want to handle this request" where + * "100" is default. "0" means "I am a fallback solution". + * + * @return int The priority of the request handler + * @api + */ + public function getPriority(); +} diff --git a/typo3/sysext/frontend/Classes/EidRequestHandler.php b/typo3/sysext/frontend/Classes/EidRequestHandler.php new file mode 100644 index 000000000000..804d768c0260 --- /dev/null +++ b/typo3/sysext/frontend/Classes/EidRequestHandler.php @@ -0,0 +1,84 @@ +<?php +namespace TYPO3\CMS\Frontend; + +/* + * This file is part of the TYPO3 CMS project. + * + * It is free software; you can redistribute it and/or modify it under + * the terms of the GNU General Public License, either version 2 + * of the License, or any later version. + * + * For the full copyright and license information, please read the + * LICENSE.txt file that was distributed with this source code. + * + * The TYPO3 project - inspiring people to share! + */ + +use TYPO3\CMS\Core\Core\Bootstrap; +use TYPO3\CMS\Frontend\Utility\EidUtility; +use TYPO3\CMS\Core\Utility\GeneralUtility; +use TYPO3\CMS\Core\Core\RequestHandlerInterface; + +/** + * Lightweight alternative to the regular RequestHandler used when $_GET[eID] is set. + * In the future, logic from the EidUtility will be moved to this class. + */ +class EidRequestHandler implements RequestHandlerInterface { + + /** + * Instance of the current TYPO3 bootstrap + * @var Bootstrap + */ + protected $bootstrap; + + /** + * Constructor handing over the bootstrap + * + * @param Bootstrap $bootstrap + */ + public function __construct(Bootstrap $bootstrap) { + $this->bootstrap = $bootstrap; + } + + /** + * Handles a frontend request based on the _GP "eID" variable. + * + * @return void + */ + public function handleRequest() { + // Hook to preprocess the current request + if (is_array($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['tslib/index_ts.php']['preprocessRequest'])) { + foreach ($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['tslib/index_ts.php']['preprocessRequest'] as $hookFunction) { + $hookParameters = array(); + GeneralUtility::callUserFunction($hookFunction, $hookParameters, $hookParameters); + } + unset($hookFunction); + unset($hookParameters); + } + + // Remove any output produced until now + $this->bootstrap->endOutputBufferingAndCleanPreviousOutput(); + require EidUtility::getEidScriptPath(); + $this->bootstrap->shutdown(); + exit; + } + + /** + * This request handler can handle any frontend request. + * + * @return bool If the request is not an eID request, TRUE otherwise FALSE + */ + public function canHandleRequest() { + return GeneralUtility::_GP('eID') ? TRUE : FALSE; + } + + /** + * Returns the priority - how eager the handler is to actually handle the + * request. + * + * @return int The priority of the request handler. + */ + public function getPriority() { + return 80; + } +} diff --git a/typo3/sysext/frontend/Classes/FrontendRequestHandler.php b/typo3/sysext/frontend/Classes/RequestHandler.php similarity index 79% rename from typo3/sysext/frontend/Classes/FrontendRequestHandler.php rename to typo3/sysext/frontend/Classes/RequestHandler.php index dd4bcf55632f..85d2ea109054 100644 --- a/typo3/sysext/frontend/Classes/FrontendRequestHandler.php +++ b/typo3/sysext/frontend/Classes/RequestHandler.php @@ -14,17 +14,35 @@ namespace TYPO3\CMS\Frontend; * The TYPO3 project - inspiring people to share! */ -use TYPO3\CMS\Frontend\Utility\EidUtility; +use TYPO3\CMS\Core\Core\Bootstrap; +use TYPO3\CMS\Core\Core\RequestHandlerInterface; +use TYPO3\CMS\Core\Utility\GeneralUtility; /** - * This is the MAIN DOCUMENT of the TypoScript driven standard front-end + * This is the main entry point of the TypoScript driven standard front-end * - * Basically put this is the script which all requests for TYPO3 - * delivered pages goes to in the frontend (the website). The script configures - * constants, includes libraries and does a little logic here and there in order - * to instantiate the right classes to create the webpage. + * Basically put, this is the script which all requests for TYPO3 delivered pages goes to in the + * frontend (the website). The script instantiates a $TSFE object, includes libraries and does a little logic here + * and there in order to instantiate the right classes to create the webpage. + * Previously, this was called index_ts.php and also included the logic for the lightweight "eID" concept, + * which is now handled in a separate request handler (EidRequestHandler). */ -class FrontendRequestHandler { +class RequestHandler implements RequestHandlerInterface { + + /** + * Instance of the current TYPO3 bootstrap + * @var Bootstrap + */ + protected $bootstrap; + + /** + * Constructor handing over the bootstrap + * + * @param Bootstrap $bootstrap + */ + public function __construct(Bootstrap $bootstrap) { + $this->bootstrap = $bootstrap; + } /** * Handles a frontend request @@ -32,9 +50,15 @@ class FrontendRequestHandler { * @return void */ public function handleRequest() { - \TYPO3\CMS\Core\Core\Bootstrap::getInstance() - ->loadTypo3LoadedExtAndExtLocalconf(TRUE) - ->applyAdditionalConfigurationSettings(); + // Hook to preprocess the current request: + if (is_array($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['tslib/index_ts.php']['preprocessRequest'])) { + foreach ($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['tslib/index_ts.php']['preprocessRequest'] as $hookFunction) { + $hookParameters = array(); + GeneralUtility::callUserFunction($hookFunction, $hookParameters, $hookParameters); + } + unset($hookFunction); + unset($hookParameters); + } // Timetracking started $configuredCookieName = trim($GLOBALS['TYPO3_CONF_VARS']['BE']['cookieName']); @@ -49,41 +73,22 @@ class FrontendRequestHandler { $GLOBALS['TT']->start(); - \TYPO3\CMS\Core\Core\Bootstrap::getInstance()->initializeTypo3DbGlobal(); - // Hook to preprocess the current request: - if (is_array($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['tslib/index_ts.php']['preprocessRequest'])) { - foreach ($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['tslib/index_ts.php']['preprocessRequest'] as $hookFunction) { - $hookParameters = array(); - \TYPO3\CMS\Core\Utility\GeneralUtility::callUserFunction($hookFunction, $hookParameters, $hookParameters); - } - unset($hookFunction); - unset($hookParameters); - } - // Look for extension ID which will launch alternative output engine - if (EidUtility::isEidRequest()) { - // Remove any output produced until now - ob_clean(); - require EidUtility::getEidScriptPath(); - \TYPO3\CMS\Core\Core\Bootstrap::getInstance()->shutdown(); - exit; - } - /** @var $GLOBALS['TSFE'] \TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController */ - $GLOBALS['TSFE'] = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance( + $GLOBALS['TSFE'] = GeneralUtility::makeInstance( \TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController::class, $GLOBALS['TYPO3_CONF_VARS'], - \TYPO3\CMS\Core\Utility\GeneralUtility::_GP('id'), - \TYPO3\CMS\Core\Utility\GeneralUtility::_GP('type'), - \TYPO3\CMS\Core\Utility\GeneralUtility::_GP('no_cache'), - \TYPO3\CMS\Core\Utility\GeneralUtility::_GP('cHash'), - \TYPO3\CMS\Core\Utility\GeneralUtility::_GP('jumpurl'), - \TYPO3\CMS\Core\Utility\GeneralUtility::_GP('MP'), - \TYPO3\CMS\Core\Utility\GeneralUtility::_GP('RDCT') + GeneralUtility::_GP('id'), + GeneralUtility::_GP('type'), + GeneralUtility::_GP('no_cache'), + GeneralUtility::_GP('cHash'), + GeneralUtility::_GP('jumpurl'), + GeneralUtility::_GP('MP'), + GeneralUtility::_GP('RDCT') ); if ($GLOBALS['TYPO3_CONF_VARS']['FE']['pageUnavailable_force'] - && !\TYPO3\CMS\Core\Utility\GeneralUtility::cmpIP( - \TYPO3\CMS\Core\Utility\GeneralUtility::getIndpEnv('REMOTE_ADDR'), + && !GeneralUtility::cmpIP( + GeneralUtility::getIndpEnv('REMOTE_ADDR'), $GLOBALS['TYPO3_CONF_VARS']['SYS']['devIPmask']) ) { $GLOBALS['TSFE']->pageUnavailableAndExit('This page is temporarily unavailable.'); @@ -100,7 +105,7 @@ class FrontendRequestHandler { // Prevent errors if ini_set() is unavailable (safe mode) @ini_set('zlib.output_compression_level', $GLOBALS['TYPO3_CONF_VARS']['FE']['compressionLevel']); } - ob_start(array(\TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance(\TYPO3\CMS\Frontend\Utility\CompressionUtility::class), 'compressionOutputHandler')); + ob_start(array(GeneralUtility::makeInstance(\TYPO3\CMS\Frontend\Utility\CompressionUtility::class), 'compressionOutputHandler')); } // FE_USER @@ -120,9 +125,9 @@ class FrontendRequestHandler { // Initialize admin panel since simulation settings are required here: if ($GLOBALS['TSFE']->isBackendUserLoggedIn()) { $GLOBALS['BE_USER']->initializeAdminPanel(); - \TYPO3\CMS\Core\Core\Bootstrap::getInstance()->loadExtensionTables(TRUE); + $this->bootstrap->loadExtensionTables(TRUE); } else { - \TYPO3\CMS\Core\Core\Bootstrap::getInstance()->loadCachedTca(); + $this->bootstrap->loadCachedTca(); } $GLOBALS['TSFE']->checkAlternativeIdMethods(); $GLOBALS['TSFE']->clear_preview(); @@ -133,7 +138,7 @@ class FrontendRequestHandler { // \TYPO3\CMS\Version\Hook\PreviewHook might need to know if a backend user is logged in. if ( $GLOBALS['TSFE']->isBackendUserLoggedIn() - && (!$GLOBALS['BE_USER']->extPageReadAccess($GLOBALS['TSFE']->page) || \TYPO3\CMS\Core\Utility\GeneralUtility::_GP('ADMCMD_noBeUser')) + && (!$GLOBALS['BE_USER']->extPageReadAccess($GLOBALS['TSFE']->page) || GeneralUtility::_GP('ADMCMD_noBeUser')) ) { // Remove user unset($GLOBALS['BE_USER']); @@ -151,7 +156,7 @@ class FrontendRequestHandler { if ($GLOBALS['TSFE']->isBackendUserLoggedIn()) { $GLOBALS['BE_USER']->initializeFrontendEdit(); if ($GLOBALS['BE_USER']->adminPanel instanceof \TYPO3\CMS\Frontend\View\AdminPanelView) { - \TYPO3\CMS\Core\Core\Bootstrap::getInstance() + $this->bootstrap ->initializeLanguageObject() ->initializeSpriteManager(); } @@ -284,9 +289,26 @@ class FrontendRequestHandler { $GLOBALS['error']->debugOutput(); } if (TYPO3_DLOG) { - \TYPO3\CMS\Core\Utility\GeneralUtility::devLog('END of FRONTEND session', 'cms', 0, array('_FLUSH' => TRUE)); + GeneralUtility::devLog('END of FRONTEND session', 'cms', 0, array('_FLUSH' => TRUE)); } - \TYPO3\CMS\Core\Core\Bootstrap::getInstance()->shutdown(); } + /** + * This request handler can handle any frontend request. + * + * @return bool If the request is not an eID request, TRUE otherwise FALSE + */ + public function canHandleRequest() { + return GeneralUtility::_GP('eID') ? FALSE : TRUE; + } + + /** + * Returns the priority - how eager the handler is to actually handle the + * request. + * + * @return int The priority of the request handler. + */ + public function getPriority() { + return 50; + } } diff --git a/typo3/sysext/install/Classes/RequestHandler.php b/typo3/sysext/install/Classes/RequestHandler.php new file mode 100644 index 000000000000..007d51170d5f --- /dev/null +++ b/typo3/sysext/install/Classes/RequestHandler.php @@ -0,0 +1,84 @@ +<?php +namespace TYPO3\CMS\Install; + +/* + * This file is part of the TYPO3 CMS project. + * + * It is free software; you can redistribute it and/or modify it under + * the terms of the GNU General Public License, either version 2 + * of the License, or any later version. + * + * For the full copyright and license information, please read the + * LICENSE.txt file that was distributed with this source code. + * + * The TYPO3 project - inspiring people to share! + */ + +use TYPO3\CMS\Core\Core\Bootstrap; +use TYPO3\CMS\Core\Core\RequestHandlerInterface; +use TYPO3\CMS\Core\Utility\GeneralUtility; + +/** + * Default request handler for all requests inside the TYPO3 Install Tool, which does a simple hardcoded + * dispatching to a controller based on the get/post variable. + * + * @package TYPO3\CMS\Install + */ +class RequestHandler implements RequestHandlerInterface { + + /** + * Instance of the current TYPO3 bootstrap + * @var Bootstrap + */ + protected $bootstrap; + + /** + * Constructor handing over the bootstrap + * + * @param Bootstrap $bootstrap + */ + public function __construct(Bootstrap $bootstrap) { + $this->bootstrap = $bootstrap; + } + + /** + * Handles an install tool request + * Execute 'tool' or 'step' controller depending on install[controller] GET/POST parameter + * + * @return void + */ + public function handleRequest() { + $getPost = GeneralUtility::_GP('install'); + switch ($getPost['controller']) { + case 'tool': + $controllerClassName = Controller\ToolController::class; + break; + case 'ajax': + $controllerClassName = Controller\AjaxController::class; + break; + default: + $controllerClassName = Controller\StepController::class; + } + GeneralUtility::makeInstance($controllerClassName)->execute(); + } + + /** + * This request handler can handle any request when not in CLI mode and the install tool flag is set + * please note that both checks are needed, as when in "failsafe" mode, the TYPO3_REQUESTTYPE is not + * necessarily set at this point. + * + * @return bool Returns TRUE if the request is in Install Tool mode, otherwise FALSE + */ + public function canHandleRequest() { + return defined('TYPO3_enterInstallScript') || (TYPO3_REQUESTTYPE & TYPO3_REQUESTTYPE_INSTALL); + } + + /** + * Returns the priority - how eager the handler is to actually handle the request. + * + * @return int The priority of the request handler. + */ + public function getPriority() { + return 20; + } +} diff --git a/typo3/sysext/install/Resources/Private/PHP/Boot.php b/typo3/sysext/install/Resources/Private/PHP/Boot.php deleted file mode 100644 index 4029796da2ca..000000000000 --- a/typo3/sysext/install/Resources/Private/PHP/Boot.php +++ /dev/null @@ -1,39 +0,0 @@ -<?php -namespace TYPO3\CMS\Install; - -/* - * This file is part of the TYPO3 CMS project. - * - * It is free software; you can redistribute it and/or modify it under - * the terms of the GNU General Public License, either version 2 - * of the License, or any later version. - * - * For the full copyright and license information, please read the - * LICENSE.txt file that was distributed with this source code. - * - * The TYPO3 project - inspiring people to share! - */ - -defined('TYPO3_MODE') or die(); - -// Bootstrap bare minimum: class loader, LocalConfiguration, but no extensions and such -require __DIR__ . '/../../../../core/Classes/Core/Bootstrap.php'; -\TYPO3\CMS\Core\Core\Bootstrap::getInstance() - ->baseSetup('typo3/sysext/install/Start/') - ->startOutputBuffering() - ->loadConfigurationAndInitialize(FALSE, \TYPO3\CMS\Core\Package\FailsafePackageManager::class); - -// Execute 'tool' or 'step' controller depending on install[controller] GET/POST parameter -$getPost = \TYPO3\CMS\Core\Utility\GeneralUtility::_GP('install'); -$controllerClassName = \TYPO3\CMS\Install\Controller\StepController::class; -if (isset($getPost['controller'])) { - switch ($getPost['controller']) { - case 'tool': - $controllerClassName = \TYPO3\CMS\Install\Controller\ToolController::class; - break; - case 'ajax': - $controllerClassName = \TYPO3\CMS\Install\Controller\AjaxController::class; - break; - } -} -\TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance($controllerClassName)->execute(); \ No newline at end of file diff --git a/typo3/sysext/install/Start/Install.php b/typo3/sysext/install/Start/Install.php index a014cfe201f1..32eb05dfcf5e 100644 --- a/typo3/sysext/install/Start/Install.php +++ b/typo3/sysext/install/Start/Install.php @@ -105,9 +105,6 @@ if (version_compare(PHP_VERSION, '5.5.0', '<')) { define('TYPO3_MODE', 'BE'); define('TYPO3_enterInstallScript', '1'); -/* - * The following functionality must be required from another file, otherwise a parse error - * "unexpected 'class'" will be shown on PHP 5.4 instead of the die() from version_compare above. - */ -require __DIR__ . '/../Resources/Private/PHP/Boot.php'; - +// Bootstrap bare minimum: class loader, LocalConfiguration, but no extensions and such +require __DIR__ . '/../../core/Classes/Core/Bootstrap.php'; +\TYPO3\CMS\Core\Core\Bootstrap::getInstance()->run('typo3/sysext/install/Start/')->shutdown(); -- GitLab