TYPO3 CMS  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 
30 
36 {
40  protected $bootstrap;
41 
45  protected $moduleRegistry = [];
46 
51 
56  protected $request;
57 
63  public function __construct(Bootstrap $bootstrap)
64  {
65  $this->bootstrap = $bootstrap;
66  }
67 
75  public function handleRequest(ServerRequestInterface $request)
76  {
77  $this->request = $request;
78  $this->boot();
79 
80  $this->moduleRegistry = $GLOBALS['TBE_MODULES'];
81 
82  if (!$this->isValidModuleRequest()) {
83  throw new Exception('The CSRF protection token for the requested module is missing or invalid', 1417988921);
84  }
85 
86  // Set to empty as it is not needed / always coming from typo3/index.php
87  $GLOBALS['BACK_PATH'] = '';
88 
89  $this->backendUserAuthentication = $GLOBALS['BE_USER'];
90 
91  $moduleName = (string)$this->request->getQueryParams()['M'];
92  if ($this->isDispatchedModule($moduleName)) {
93  return $this->dispatchModule($moduleName);
94  } else {
95  // @deprecated: This else path is deprecated and throws deprecations logs at registration time. Can be removed with TYPO3 CMS 8.
96  $isDispatched = $this->callTraditionalModule($moduleName);
97  if (!$isDispatched) {
98  throw new Exception('No module "' . $moduleName . '" could be found.', 1294585070);
99  }
100  }
101  return null;
102  }
103 
109  protected function boot()
110  {
111  // Evaluate the constant for skipping the BE user check for the bootstrap, will be done without the constant at a later point
112  if (defined('TYPO3_PROCEED_IF_NO_USER') && TYPO3_PROCEED_IF_NO_USER) {
113  $proceedIfNoUserIsLoggedIn = true;
114  } else {
115  $proceedIfNoUserIsLoggedIn = false;
116  }
117 
118  $this->bootstrap->checkLockedBackendAndRedirectOrDie()
119  ->checkBackendIpOrDie()
120  ->checkSslBackendAndRedirectIfNeeded()
121  ->initializeBackendRouter()
122  ->loadExtensionTables(true)
123  ->initializeSpriteManager()
124  ->initializeBackendUser()
125  ->initializeBackendAuthentication($proceedIfNoUserIsLoggedIn)
126  ->initializeLanguageObject()
127  ->initializeBackendTemplate()
128  ->endOutputBufferingAndCleanPreviousOutput()
129  ->initializeOutputCompression()
130  ->sendHttpHeaders();
131  }
132 
139  public function canHandleRequest(ServerRequestInterface $request)
140  {
141  return $request->getAttribute('isModuleRequest', false);
142  }
143 
149  protected function isValidModuleRequest()
150  {
151  return $this->getFormProtection() instanceof BackendFormProtection
152  && $this->getFormProtection()->validateToken((string)$this->request->getQueryParams()['moduleToken'], 'moduleCall', (string)$this->request->getQueryParams()['M']);
153  }
154 
162  protected function isDispatchedModule($moduleName)
163  {
164  return empty($this->moduleRegistry['_PATHS'][$moduleName]);
165  }
166 
174  protected function dispatchModule($moduleName)
175  {
176  $moduleConfiguration = $this->getModuleConfiguration($moduleName);
177 
179  $response = GeneralUtility::makeInstance(Response::class);
180 
181  // Check permissions and exit if the user has no permission for entry
182  $this->backendUserAuthentication->modAccess($moduleConfiguration, true);
183  $id = isset($this->request->getQueryParams()['id']) ? $this->request->getQueryParams()['id'] : $this->request->getParsedBody()['id'];
184  if ($id && MathUtility::canBeInterpretedAsInteger($id)) {
185  $permClause = $this->backendUserAuthentication->getPagePermsClause(Permission::PAGE_SHOW);
186  // Check page access
187  $access = is_array(BackendUtility::readPageAccess((int)$id, $permClause));
188  if (!$access) {
189  // Check if page has been deleted
190  $deleteField = $GLOBALS['TCA']['pages']['ctrl']['delete'];
191  $pageInfo = BackendUtility::getRecord('pages', (int)$id, $deleteField, $permClause ? ' AND ' . $permClause : '', false);
192  if (!$pageInfo[$deleteField]) {
193  throw new \RuntimeException('You don\'t have access to this page', 1289917924);
194  }
195  }
196  }
197 
198  // Use Core Dispatching
199  if (isset($moduleConfiguration['routeTarget'])) {
200  $dispatcher = GeneralUtility::makeInstance(Dispatcher::class);
201  $this->request = $this->request->withAttribute('target', $moduleConfiguration['routeTarget']);
202  $response = $dispatcher->dispatch($this->request, $response);
203  } else {
204  // extbase module
205  $configuration = [
206  'extensionName' => $moduleConfiguration['extensionName'],
207  'pluginName' => $moduleName
208  ];
209  if (isset($moduleConfiguration['vendorName'])) {
210  $configuration['vendorName'] = $moduleConfiguration['vendorName'];
211  }
212 
213  // Run Extbase
214  $bootstrap = GeneralUtility::makeInstance(\TYPO3\CMS\Extbase\Core\Bootstrap::class);
215  $content = $bootstrap->run('', $configuration);
216 
217  $response->getBody()->write($content);
218  }
219 
220  return $response;
221  }
222 
230  protected function callTraditionalModule($moduleName)
231  {
232  $moduleBasePath = $this->moduleRegistry['_PATHS'][$moduleName];
233  // Some modules still rely on this global configuration array in a conf.php file
234  // load configuration from an existing conf.php file inside the same directory
235  if (file_exists($moduleBasePath . 'conf.php')) {
236  require $moduleBasePath . 'conf.php';
237  $moduleConfiguration = $MCONF;
238  } else {
239  $moduleConfiguration = $this->getModuleConfiguration($moduleName);
240  }
241  $GLOBALS['MCONF'] = $moduleConfiguration;
242  if (!empty($moduleConfiguration['access'])) {
243  $this->backendUserAuthentication->modAccess($moduleConfiguration, true);
244  }
245  if (file_exists($moduleBasePath . 'index.php')) {
246  global $SOBE;
247  require $moduleBasePath . 'index.php';
248  return true;
249  }
250  return false;
251  }
252 
260  protected function getModuleConfiguration($moduleName)
261  {
262  if (!isset($this->moduleRegistry['_configuration'][$moduleName])) {
263  throw new \RuntimeException('Module ' . $moduleName . ' is not configured.', 1289918325);
264  }
265  return $this->moduleRegistry['_configuration'][$moduleName];
266  }
267 
273  public function getPriority()
274  {
275  return 90;
276  }
277 
283  protected function getFormProtection()
284  {
286  }
287 }
static readPageAccess($id, $perms_clause)
$MCONF
Definition: conf.php:2
static getRecord($table, $uid, $fields=' *', $where='', $useDeleteClause=true)
if(TYPO3_MODE==='BE') $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_tsfebeuserauth.php']['frontendEditingController']['default']