‪TYPO3CMS  10.4
ModuleLoader.php
Go to the documentation of this file.
1 <?php
2 
3 /*
4  * This file is part of the TYPO3 CMS project.
5  *
6  * It is free software; you can redistribute it and/or modify it under
7  * the terms of the GNU General Public License, either version 2
8  * of the License, or any later version.
9  *
10  * For the full copyright and license information, please read the
11  * LICENSE.txt file that was distributed with this source code.
12  *
13  * The TYPO3 project - inspiring people to share!
14  */
15 
17 
22 
34 {
40  public ‪$modules = [];
41 
47  public ‪$modListGroup = [];
48 
54  public ‪$modListUser = [];
55 
61  public ‪$BE_USER;
62 
68  public ‪$observeWorkspaces = false;
69 
75  protected ‪$navigationComponents = [];
76 
81  protected ‪$moduleLabels = [];
82 
91  public function ‪load($modulesArray, ‪BackendUserAuthentication $beUser = null)
92  {
93  // Setting the backend user for use internally
94  $this->BE_USER = $beUser ?: ‪$GLOBALS['BE_USER'];
95 
96  // Unset the array for calling backend modules based on external backend module dispatchers in typo3/index.php
97  unset($modulesArray['_configuration']);
98  $this->navigationComponents = $modulesArray['_navigationComponents'];
99  unset($modulesArray['_navigationComponents']);
100  $mainModules = $this->‪parseModulesArray($modulesArray);
101 
102  // Traverses the module setup and creates the internal array $this->modules
103  foreach ($mainModules as $mainModuleName => $subModules) {
104  $mainModuleConfiguration = $this->‪checkMod($mainModuleName);
105  // If $mainModuleConfiguration is not set (FALSE) there is no access to the module !(?)
106  if (is_array($mainModuleConfiguration)) {
107  $this->modules[$mainModuleName] = $mainModuleConfiguration;
108  // Load the submodules
109  if (is_array($subModules)) {
110  foreach ($subModules as $subModuleName) {
111  $subModuleConfiguration = $this->‪checkMod($mainModuleName . '_' . $subModuleName);
112  if (is_array($subModuleConfiguration)) {
113  $this->modules[$mainModuleName]['sub'][$subModuleName] = $subModuleConfiguration;
114  }
115  }
116  }
117  } elseif ($mainModuleConfiguration !== false) {
118  // Although the configuration was not found, still check if there are submodules
119  // This must be done in order to fill out the select-lists for modules correctly!!
120  if (is_array($subModules)) {
121  foreach ($subModules as $subModuleName) {
122  $this->‪checkMod($mainModuleName . '_' . $subModuleName);
123  }
124  }
125  }
126  }
127  }
128 
140  public function ‪checkMod($name)
141  {
142  // merge configuration and labels into one array
143  $setupInformation = $this->‪getModuleSetupInformation($name);
144 
145  // clean up the configuration part
146  if (empty($setupInformation['configuration'])) {
147  return 'notFound';
148  }
149  $finalModuleConfiguration = $setupInformation['configuration'];
150  if (!empty($finalModuleConfiguration['shy'])
151  || !$this->‪checkModAccess($name, $setupInformation['configuration'])
152  || !$this->‪checkModWorkspace($name, $setupInformation['configuration'])
153  ) {
154  return false;
155  }
156  $finalModuleConfiguration['name'] = $name;
157  // Language processing. This will add module labels and image reference to the internal ->moduleLabels array of the LANG object.
158  $this->‪addLabelsForModule($name, $finalModuleConfiguration['labels'] ?? $setupInformation['labels']);
160  $uriBuilder = GeneralUtility::makeInstance(UriBuilder::class);
161  if (isset($setupInformation['configuration']['routeTarget'])) {
162  $finalModuleConfiguration['script'] = (string)$uriBuilder->buildUriFromRoute($name);
163  } else {
164  $finalModuleConfiguration['script'] = (string)$uriBuilder->buildUriFromRoute('dummy');
165  }
166 
167  if (!empty($setupInformation['configuration']['navigationFrameModule'])) {
168  $finalModuleConfiguration['navFrameScript'] = (string)$uriBuilder->buildUriFromRoute(
169  $setupInformation['configuration']['navigationFrameModule'],
170  !empty($setupInformation['configuration']['navigationFrameModuleParameters'])
171  ? $setupInformation['configuration']['navigationFrameModuleParameters']
172  : []
173  );
174  }
175 
176  // Check if this is a submodule
177  $mainModule = '';
178  if (strpos($name, '_') !== false) {
179  [$mainModule, ] = explode('_', $name, 2);
180  }
181 
182  // check if there is a navigation component (like the pagetree)
183  if (is_array($this->navigationComponents[$name] ?? false)) {
184  $finalModuleConfiguration['navigationComponentId'] = $this->navigationComponents[$name]['componentId'];
185  } elseif ($mainModule
186  && is_array($this->navigationComponents[$mainModule] ?? false)
187  && $setupInformation['configuration']['inheritNavigationComponentFromMainModule'] !== false) {
188 
189  // navigation component can be overridden by the main module component
190  $finalModuleConfiguration['navigationComponentId'] = $this->navigationComponents[$mainModule]['componentId'];
191  }
192  return $finalModuleConfiguration;
193  }
194 
202  protected function ‪getModuleSetupInformation($moduleName)
203  {
204  $moduleSetupInformation = [
205  'configuration' => [],
206  'labels' => []
207  ];
208 
209  $moduleConfiguration = !empty(‪$GLOBALS['TBE_MODULES']['_configuration'][$moduleName])
210  ? ‪$GLOBALS['TBE_MODULES']['_configuration'][$moduleName]
211  : null;
212  if ($moduleConfiguration !== null) {
213  // Overlay setup with additional labels
214  if (!empty($moduleConfiguration['labels']) && is_array($moduleConfiguration['labels'])) {
215  if (empty($moduleSetupInformation['labels']['default']) || !is_array($moduleSetupInformation['labels']['default'])) {
216  $moduleSetupInformation['labels']['default'] = $moduleConfiguration['labels'];
217  } else {
218  $moduleSetupInformation['labels']['default'] = array_replace_recursive($moduleSetupInformation['labels']['default'], $moduleConfiguration['labels']);
219  }
220  unset($moduleConfiguration['labels']);
221  }
222  // Overlay setup with additional configuration
223  if (is_array($moduleConfiguration)) {
224  $moduleSetupInformation['configuration'] = array_replace_recursive($moduleSetupInformation['configuration'], $moduleConfiguration);
225  }
226  }
227 
228  // Add some default configuration
229  if ($moduleSetupInformation['configuration'] !== [] && !isset($moduleSetupInformation['configuration']['inheritNavigationComponentFromMainModule'])) {
230  $moduleSetupInformation['configuration']['inheritNavigationComponentFromMainModule'] = true;
231  }
232 
233  return $moduleSetupInformation;
234  }
235 
243  public function ‪checkModAccess($name, $MCONF)
244  {
245  if (empty($MCONF['access'])) {
246  return true;
247  }
248  $access = strtolower($MCONF['access']);
249  // Check if this module is only allowed by system maintainers (= admins who are in the list of system maintainers)
250  if (strpos($MCONF['access'], ‪BackendUserAuthentication::ROLE_SYSTEMMAINTAINER) !== false) {
251  return $this->BE_USER->isSystemMaintainer();
252  }
253  // Checking if admin-access is required
254  // If admin-permissions is required then return TRUE if user is admin
255  if (strpos($access, 'admin') !== false && $this->BE_USER->isAdmin()) {
256  return true;
257  }
258  // This will add modules to the select-lists of user and groups
259  if (strpos($access, 'user') !== false) {
260  $this->modListUser[] = $name;
261  }
262  if (strpos($access, 'group') !== false) {
263  $this->modListGroup[] = $name;
264  }
265  // This checks if a user is permitted to access the module
266  if ($this->BE_USER->isAdmin() || $this->BE_USER->check('modules', $name)) {
267  return true;
268  }
269  return false;
270  }
271 
280  public function ‪checkModWorkspace($name, $MCONF)
281  {
282  if (!$this->observeWorkspaces) {
283  return true;
284  }
285  $status = true;
286  if (!empty($MCONF['workspaces'])) {
287  $status = $this->BE_USER->workspace === 0 && GeneralUtility::inList($MCONF['workspaces'], 'online')
288  || $this->BE_USER->workspace === -1 && GeneralUtility::inList($MCONF['workspaces'], 'offline')
289  || $this->BE_USER->workspace > 0 && GeneralUtility::inList($MCONF['workspaces'], 'custom');
290  } elseif ($this->BE_USER->workspace === -99) {
291  $status = false;
292  }
293  return $status;
294  }
295 
303  public function ‪parseModulesArray($arr)
304  {
305  $theMods = [];
306  if (is_array($arr)) {
307  foreach ($arr as $mod => $subs) {
308  // Clean module name to alphanum
309  $mod = $this->‪cleanName($mod);
310  if ($mod) {
311  if ($subs) {
312  $subsArr = ‪GeneralUtility::trimExplode(',', $subs);
313  foreach ($subsArr as $subMod) {
314  $subMod = $this->‪cleanName($subMod);
315  if ($subMod) {
316  $theMods[$mod][] = $subMod;
317  }
318  }
319  } else {
320  $theMods[$mod] = 1;
321  }
322  }
323  }
324  }
325  return $theMods;
326  }
327 
335  public function ‪cleanName($str)
336  {
337  return preg_replace('/[^a-z0-9]/i', '', $str);
338  }
339 
353  public function ‪addLabelsForModule($moduleName, $labels)
354  {
355  // If LOCAL_LANG references are used for labels of the module:
356  if (is_string($labels)) {
357  // Extbase-based modules
358  $this->moduleLabels[$moduleName] = [
359  'shortdescription' => $labels . ':mlang_labels_tablabel',
360  'description' => $labels . ':mlang_labels_tabdescr',
361  'title' => $labels . ':mlang_tabs_tab',
362  ];
363  } elseif (isset($labels['title'])) {
364  // New way, where all labels can be LLL references
365  $this->moduleLabels[$moduleName] = $labels;
366  } elseif (isset($labels['ll_ref'])) {
367  // Classic, non-extbase module labels
368  $this->‪addLabelsForModule($moduleName, $labels['ll_ref']);
369  } else {
370  // Very old obsolete approach, don't use anymore, use one of the ways above.
371  if (is_object($this->‪getLanguageService())) {
372  $language = $this->‪getLanguageService()->lang;
373  } else {
374  $language = 'default';
375  }
376 
377  if (isset($labels[$language]['ll_ref'])) {
378  $this->‪addLabelsForModule($moduleName, $labels[$language]['ll_ref']);
379  } elseif (isset($labels['default']['ll_ref'])) {
380  $this->‪addLabelsForModule($moduleName, $labels['default']['ll_ref']);
381  } else {
382  $this->moduleLabels[$moduleName] = [
383  'shortdescription' => $labels[$language]['labels']['tablabel'] ?? $labels['default']['labels']['tablabel'],
384  'description' => $labels[$language]['labels']['tabdescr'] ?? $labels['default']['labels']['tabdescr'],
385  'title' => $labels[$language]['tabs']['tab'] ?? $labels['default']['tabs']['tab'],
386  ];
387  }
388  }
389  }
390 
397  public function ‪getLabelsForModule($moduleName)
398  {
399  return $this->moduleLabels[$moduleName] ?? [];
400  }
401 
405  protected function ‪getLanguageService()
406  {
407  return ‪$GLOBALS['LANG'];
408  }
409 }
‪TYPO3\CMS\Backend\Module\ModuleLoader\load
‪load($modulesArray, BackendUserAuthentication $beUser=null)
Definition: ModuleLoader.php:84
‪TYPO3\CMS\Backend\Module\ModuleLoader\checkModWorkspace
‪bool checkModWorkspace($name, $MCONF)
Definition: ModuleLoader.php:273
‪TYPO3\CMS\Backend\Module\ModuleLoader\cleanName
‪string cleanName($str)
Definition: ModuleLoader.php:328
‪TYPO3\CMS\Backend\Module\ModuleLoader\$observeWorkspaces
‪bool $observeWorkspaces
Definition: ModuleLoader.php:63
‪TYPO3\CMS\Core\Authentication\BackendUserAuthentication\ROLE_SYSTEMMAINTAINER
‪const ROLE_SYSTEMMAINTAINER
Definition: BackendUserAuthentication.php:63
‪TYPO3\CMS\Backend\Routing\UriBuilder
Definition: UriBuilder.php:38
‪TYPO3\CMS\Backend\Module\ModuleLoader
Definition: ModuleLoader.php:34
‪TYPO3\CMS\Core\Authentication\BackendUserAuthentication
Definition: BackendUserAuthentication.php:62
‪TYPO3\CMS\Backend\Module\ModuleLoader\getModuleSetupInformation
‪array getModuleSetupInformation($moduleName)
Definition: ModuleLoader.php:195
‪TYPO3\CMS\Backend\Module\ModuleLoader\$modListGroup
‪array $modListGroup
Definition: ModuleLoader.php:45
‪TYPO3\CMS\Core\Utility\GeneralUtility\trimExplode
‪static string[] trimExplode($delim, $string, $removeEmptyValues=false, $limit=0)
Definition: GeneralUtility.php:1059
‪TYPO3\CMS\Backend\Module\ModuleLoader\$moduleLabels
‪array $moduleLabels
Definition: ModuleLoader.php:74
‪TYPO3\CMS\Backend\Module\ModuleLoader\parseModulesArray
‪array parseModulesArray($arr)
Definition: ModuleLoader.php:296
‪TYPO3\CMS\Backend\Module\ModuleLoader\getLanguageService
‪LanguageService getLanguageService()
Definition: ModuleLoader.php:398
‪$GLOBALS
‪$GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['adminpanel']['modules']
Definition: ext_localconf.php:5
‪TYPO3\CMS\Backend\Module\ModuleLoader\$navigationComponents
‪array $navigationComponents
Definition: ModuleLoader.php:69
‪TYPO3\CMS\Backend\Module\ModuleLoader\$modules
‪array $modules
Definition: ModuleLoader.php:39
‪TYPO3\CMS\Backend\Module\ModuleLoader\$BE_USER
‪TYPO3 CMS Core Authentication BackendUserAuthentication $BE_USER
Definition: ModuleLoader.php:57
‪TYPO3\CMS\Core\Localization\LanguageService
Definition: LanguageService.php:42
‪TYPO3\CMS\Backend\Module\ModuleLoader\addLabelsForModule
‪addLabelsForModule($moduleName, $labels)
Definition: ModuleLoader.php:346
‪TYPO3\CMS\Core\Utility\GeneralUtility
Definition: GeneralUtility.php:46
‪TYPO3\CMS\Backend\Module\ModuleLoader\$modListUser
‪array $modListUser
Definition: ModuleLoader.php:51
‪TYPO3\CMS\Backend\Module\ModuleLoader\checkModAccess
‪bool checkModAccess($name, $MCONF)
Definition: ModuleLoader.php:236
‪TYPO3\CMS\Backend\Module
Definition: ModuleLoader.php:16
‪TYPO3\CMS\Backend\Module\ModuleLoader\getLabelsForModule
‪array getLabelsForModule($moduleName)
Definition: ModuleLoader.php:390
‪TYPO3\CMS\Backend\Module\ModuleLoader\checkMod
‪string bool array checkMod($name)
Definition: ModuleLoader.php:133