[TASK] Re-work/simplify copyright header in PHP files - Part 2
[Packages/TYPO3.CMS.git] / typo3 / sysext / install / Classes / Controller / ToolController.php
1 <?php
2 namespace TYPO3\CMS\Install\Controller;
3
4 /**
5 * This file is part of the TYPO3 CMS project.
6 *
7 * It is free software; you can redistribute it and/or modify it under
8 * the terms of the GNU General Public License, either version 2
9 * of the License, or any later version.
10 *
11 * For the full copyright and license information, please read the
12 * LICENSE.txt file that was distributed with this source code.
13 *
14 * The TYPO3 project - inspiring people to share!
15 */
16
17 use TYPO3\CMS\Install\Service\EnableFileService;
18
19 /**
20 * Install tool controller, dispatcher class of the install tool.
21 *
22 * Handles install tool session, login and login form rendering,
23 * calls actions that need authentication and handles form tokens.
24 */
25 class ToolController extends AbstractController {
26
27 /**
28 * @var array List of valid action names that need authentication
29 */
30 protected $authenticationActions = array(
31 'welcome',
32 'importantActions',
33 'systemEnvironment',
34 'configuration',
35 'folderStructure',
36 'testSetup',
37 'upgradeWizard',
38 'allConfiguration',
39 'cleanUp',
40 'loadExtensions',
41 );
42
43 /**
44 * Main dispatch method
45 *
46 * @return void
47 */
48 public function execute() {
49 $this->loadBaseExtensions();
50 $this->initializeObjectManager();
51
52 // Warning: Order of these methods is security relevant and interferes with different access
53 // conditions (new/existing installation). See the single method comments for details.
54 $this->outputInstallToolNotEnabledMessageIfNeeded();
55 $this->outputInstallToolPasswordNotSetMessageIfNeeded();
56 $this->initializeSession();
57 $this->checkSessionToken();
58 $this->checkSessionLifetime();
59 $this->logoutIfRequested();
60 $this->loginIfRequested();
61 $this->outputLoginFormIfNotAuthorized();
62 $this->registerExtensionConfigurationErrorHandler();
63 $this->dispatchAuthenticationActions();
64 }
65
66 /**
67 * Logout user if requested
68 *
69 * @return void
70 */
71 protected function logoutIfRequested() {
72 $action = $this->getAction();
73 if ($action === 'logout') {
74 if (!EnableFileService::isInstallToolEnableFilePermanent()) {
75 EnableFileService::removeInstallToolEnableFile();
76 }
77
78 /** @var $formProtection \TYPO3\CMS\Core\FormProtection\InstallToolFormProtection */
79 $formProtection = \TYPO3\CMS\Core\FormProtection\FormProtectionFactory::get(
80 'TYPO3\\CMS\\Core\\FormProtection\\InstallToolFormProtection'
81 );
82 $formProtection->clean();
83 $this->session->destroySession();
84 $this->redirect();
85 }
86 }
87
88 /**
89 * This function registers a shutdown function, which is called even if a fatal error occurs.
90 * The request either gets redirected to an action where all extension configurations are checked for compatibility or
91 * an information with a link to that action.
92 *
93 * @return void
94 */
95 protected function registerExtensionConfigurationErrorHandler() {
96 register_shutdown_function(function() {
97 $error = error_get_last();
98 if ($error !== NULL) {
99 $errorType = $error["type"];
100
101 if ($errorType & (E_ERROR | E_PARSE | E_CORE_ERROR | E_COMPILE_ERROR | E_USER_ERROR | E_RECOVERABLE_ERROR)) {
102 $getPostValues = \TYPO3\CMS\Core\Utility\GeneralUtility::_GP('install');
103
104 $parameters = array();
105
106 // Add context parameter in case this script was called within backend scope
107 $context = 'install[context]=standalone';
108 if (isset($getPostValues['context']) && $getPostValues['context'] === 'backend') {
109 $context = 'install[context]=backend';
110 }
111 $parameters[] = $context;
112
113 // Add controller parameter
114 $parameters[] = 'install[controller]=tool';
115
116 // Add action if specified
117 $parameters[] = 'install[action]=loadExtensions';
118
119 // Add error to display a message what triggered the check
120 $errorEncoded = json_encode($error);
121 $parameters[] = 'install[lastError]=' . rawurlencode($errorEncoded);
122 // We do not use GeneralUtility here to be sure that hash generation works even if that class might not exist any more.
123 $parameters[] = 'install[lastErrorHash]=' . hash_hmac('sha1', $errorEncoded, $GLOBALS['TYPO3_CONF_VARS']['SYS']['encryptionKey'] . 'InstallToolError');
124
125 $redirectLocation = 'Install.php?' . implode('&', $parameters);
126
127 if (!headers_sent()) {
128 \TYPO3\CMS\Core\Utility\HttpUtility::redirect(
129 $redirectLocation,
130 \TYPO3\CMS\Core\Utility\HttpUtility::HTTP_STATUS_303
131 );
132 } else {
133 echo '
134 <p><strong>
135 The system detected a fatal error during script execution.
136 Please use the <a href="' . $redirectLocation . '">extension check tool</a> to find incompatible extensions.
137 </strong></p>';
138 }
139 }
140 }
141 });
142 }
143
144 /**
145 * Get last error values of install tool.
146 *
147 * @return array
148 */
149 protected function getLastError() {
150 $getVars = \TYPO3\CMS\Core\Utility\GeneralUtility::_GET('install');
151 $lastError = array();
152 if (isset($getVars['lastError']) && isset($getVars['lastErrorHash']) && !empty($GLOBALS['TYPO3_CONF_VARS']['SYS']['encryptionKey'])) {
153 $calculatedHash = hash_hmac('sha1', $getVars['lastError'], $GLOBALS['TYPO3_CONF_VARS']['SYS']['encryptionKey'] . 'InstallToolError');
154 if ($calculatedHash === $getVars['lastErrorHash']) {
155 $lastError = json_decode($getVars['lastError'], TRUE);
156 }
157 }
158 return $lastError;
159 }
160
161 /**
162 * Call an action that needs authentication
163 *
164 * @throws Exception
165 * @return string Rendered content
166 */
167 protected function dispatchAuthenticationActions() {
168 $action = $this->getAction();
169 if ($action === '') {
170 $action = 'welcome';
171 }
172 $this->validateAuthenticationAction($action);
173 $actionClass = ucfirst($action);
174 /** @var \TYPO3\CMS\Install\Controller\Action\ActionInterface $toolAction */
175 $toolAction = $this->objectManager->get('TYPO3\\CMS\\Install\\Controller\\Action\\Tool\\' . $actionClass);
176 if (!($toolAction instanceof Action\ActionInterface)) {
177 throw new Exception(
178 $action . ' does not implement ActionInterface',
179 1369474309
180 );
181 }
182 $toolAction->setController('tool');
183 $toolAction->setAction($action);
184 $toolAction->setToken($this->generateTokenForAction($action));
185 $toolAction->setPostValues($this->getPostValues());
186 $toolAction->setLastError($this->getLastError());
187 $this->output($toolAction->handle());
188 }
189 }