TYPO3  7.6
BackendModuleRequestHandler.php
Go to the documentation of this file.
1 <?php
2 namespace TYPO3\CMS\Backend\Http;
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 
29 
35 {
39  protected $bootstrap;
40 
44  protected $moduleRegistry = array();
45 
50 
55  protected $request;
56 
62  public function __construct(Bootstrap $bootstrap)
63  {
64  $this->bootstrap = $bootstrap;
65  }
66 
75  {
76  $this->request = $request;
77  $this->boot();
78 
79  $this->moduleRegistry = $GLOBALS['TBE_MODULES'];
80 
81  if (!$this->isValidModuleRequest()) {
82  throw new Exception('The CSRF protection token for the requested module is missing or invalid', 1417988921);
83  }
84 
85  // Set to empty as it is not needed / always coming from typo3/index.php
86  $GLOBALS['BACK_PATH'] = '';
87 
88  $this->backendUserAuthentication = $GLOBALS['BE_USER'];
89 
90  $moduleName = (string)$this->request->getQueryParams()['M'];
91  if ($this->isDispatchedModule($moduleName)) {
92  return $this->dispatchModule($moduleName);
93  } else {
94  // @deprecated: This else path is deprecated and throws deprecations logs at registration time. Can be removed with TYPO3 CMS 8.
95  $isDispatched = $this->callTraditionalModule($moduleName);
96  if (!$isDispatched) {
97  throw new Exception('No module "' . $moduleName . '" could be found.', 1294585070);
98  }
99  }
100  return null;
101  }
102 
108  protected function boot()
109  {
110  // Evaluate the constant for skipping the BE user check for the bootstrap, will be done without the constant at a later point
111  if (defined('TYPO3_PROCEED_IF_NO_USER') && TYPO3_PROCEED_IF_NO_USER) {
112  $proceedIfNoUserIsLoggedIn = true;
113  } else {
114  $proceedIfNoUserIsLoggedIn = false;
115  }
116 
117  $this->bootstrap->checkLockedBackendAndRedirectOrDie()
118  ->checkBackendIpOrDie()
119  ->checkSslBackendAndRedirectIfNeeded()
120  ->initializeBackendRouter()
121  ->loadExtensionTables(true)
122  ->initializeSpriteManager()
123  ->initializeBackendUser()
124  ->initializeBackendAuthentication($proceedIfNoUserIsLoggedIn)
125  ->initializeLanguageObject()
126  ->initializeBackendTemplate()
127  ->endOutputBufferingAndCleanPreviousOutput()
128  ->initializeOutputCompression()
129  ->sendHttpHeaders();
130  }
131 
139  {
140  return $request->getAttribute('isModuleRequest', false);
141  }
142 
148  protected function isValidModuleRequest()
149  {
150  return $this->getFormProtection() instanceof BackendFormProtection
151  && $this->getFormProtection()->validateToken((string)$this->request->getQueryParams()['moduleToken'], 'moduleCall', (string)$this->request->getQueryParams()['M']);
152  }
153 
161  protected function isDispatchedModule($moduleName)
162  {
163  return empty($this->moduleRegistry['_PATHS'][$moduleName]);
164  }
165 
173  protected function dispatchModule($moduleName)
174  {
175  $moduleConfiguration = $this->getModuleConfiguration($moduleName);
176 
177  // Check permissions and exit if the user has no permission for entry
178  $this->backendUserAuthentication->modAccess($moduleConfiguration, true);
179  $id = isset($this->request->getQueryParams()['id']) ? $this->request->getQueryParams()['id'] : $this->request->getParsedBody()['id'];
180  if ($id && MathUtility::canBeInterpretedAsInteger($id)) {
181  // Check page access
182  $permClause = $this->backendUserAuthentication->getPagePermsClause(true);
183  $access = is_array(BackendUtility::readPageAccess((int)$id, $permClause));
184  if (!$access) {
185  throw new \RuntimeException('You don\'t have access to this page', 1289917924);
186  }
187  }
188 
190  $response = GeneralUtility::makeInstance(Response::class);
191 
192  // Use Core Dispatching
193  if (isset($moduleConfiguration['routeTarget'])) {
194  $dispatcher = GeneralUtility::makeInstance(Dispatcher::class);
195  $this->request = $this->request->withAttribute('target', $moduleConfiguration['routeTarget']);
196  $response = $dispatcher->dispatch($this->request, $response);
197  } else {
198  // extbase module
199  $configuration = array(
200  'extensionName' => $moduleConfiguration['extensionName'],
201  'pluginName' => $moduleName
202  );
203  if (isset($moduleConfiguration['vendorName'])) {
204  $configuration['vendorName'] = $moduleConfiguration['vendorName'];
205  }
206 
207  // Run Extbase
208  $bootstrap = GeneralUtility::makeInstance(\TYPO3\CMS\Extbase\Core\Bootstrap::class);
209  $content = $bootstrap->run('', $configuration);
210 
211  $response->getBody()->write($content);
212  }
213 
214  return $response;
215  }
216 
224  protected function callTraditionalModule($moduleName)
225  {
226  $moduleBasePath = $this->moduleRegistry['_PATHS'][$moduleName];
227  // Some modules still rely on this global configuration array in a conf.php file
228  // load configuration from an existing conf.php file inside the same directory
229  if (file_exists($moduleBasePath . 'conf.php')) {
230  require $moduleBasePath . 'conf.php';
231  $moduleConfiguration = $MCONF;
232  } else {
233  $moduleConfiguration = $this->getModuleConfiguration($moduleName);
234  }
235  $GLOBALS['MCONF'] = $moduleConfiguration;
236  if (!empty($moduleConfiguration['access'])) {
237  $this->backendUserAuthentication->modAccess($moduleConfiguration, true);
238  }
239  if (file_exists($moduleBasePath . 'index.php')) {
240  global $SOBE;
241  require $moduleBasePath . 'index.php';
242  return true;
243  }
244  return false;
245  }
246 
254  protected function getModuleConfiguration($moduleName)
255  {
256  if (!isset($this->moduleRegistry['_configuration'][$moduleName])) {
257  throw new \RuntimeException('Module ' . $moduleName . ' is not configured.', 1289918325);
258  }
259  return $this->moduleRegistry['_configuration'][$moduleName];
260  }
261 
262 
268  public function getPriority()
269  {
270  return 90;
271  }
272 
278  protected function getFormProtection()
279  {
281  }
282 }