‪TYPO3CMS  9.5
BackendModuleRepository.php
Go to the documentation of this file.
1 <?php
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 
24 
30 {
34  protected ‪$moduleStorage;
35 
39  public function ‪__construct()
40  {
41  $this->moduleStorage = GeneralUtility::makeInstance(\‪TYPO3\CMS\Backend\Module\ModuleStorage::class);
42 
43  $rawData = $this->‪getRawModuleMenuData();
44 
47  }
48 
55  public function ‪loadAllowedModules(array $excludeGroupNames = [])
56  {
57  if (empty($excludeGroupNames)) {
58  return $this->moduleStorage->getEntries();
59  }
60 
61  $modules = new \SplObjectStorage();
62  foreach ($this->moduleStorage->getEntries() as $moduleGroup) {
63  if (!in_array($moduleGroup->getName(), $excludeGroupNames, true)) {
64  if ($moduleGroup->getChildren()->count() > 0) {
65  $modules->attach($moduleGroup);
66  }
67  }
68  }
69 
70  return $modules;
71  }
72 
77  public function ‪findByGroupName($groupName = '')
78  {
79  foreach ($this->moduleStorage->getEntries() as $moduleGroup) {
80  if ($moduleGroup->getName() === $groupName) {
81  return $moduleGroup;
82  }
83  }
84 
85  return false;
86  }
87 
94  public function ‪findByModuleName($name)
95  {
96  $entries = $this->moduleStorage->getEntries();
97  $entry = $this->‪findByModuleNameInGivenEntries($name, $entries);
98  return $entry;
99  }
100 
108  public function ‪findByModuleNameInGivenEntries($name, \SplObjectStorage $entries)
109  {
110  foreach ($entries as $entry) {
111  if ($entry->getName() === $name) {
112  return $entry;
113  }
114  $children = $entry->getChildren();
115  if (!empty($children)) {
116  $childRecord = $this->‪findByModuleNameInGivenEntries($name, $children);
117  if ($childRecord !== false) {
118  return $childRecord;
119  }
120  }
121  }
122  return false;
123  }
124 
130  protected function ‪convertRawModuleDataToModuleMenuObject(array $rawModuleData)
131  {
132  foreach ($rawModuleData as $module) {
133  $entry = $this->‪createEntryFromRawData($module);
134  if (isset($module['subitems']) && !empty($module['subitems'])) {
135  foreach ($module['subitems'] as $subitem) {
136  $subEntry = $this->‪createEntryFromRawData($subitem);
137  $entry->addChild($subEntry);
138  }
139  }
140  $this->moduleStorage->attachEntry($entry);
141  }
142  }
143 
150  protected function ‪createEntryFromRawData(array $module)
151  {
153  $entry = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance(\‪TYPO3\CMS\Backend\Domain\Model\Module\BackendModule::class);
154  if (!empty($module['name']) && is_string($module['name'])) {
155  $entry->setName($module['name']);
156  }
157  if (!empty($module['title']) && is_string($module['title'])) {
158  $entry->setTitle($this->‪getLanguageService()->sL($module['title']));
159  }
160  if (!empty($module['onclick']) && is_string($module['onclick'])) {
161  $entry->setOnClick($module['onclick']);
162  }
163  if (!empty($module['link']) && is_string($module['link'])) {
164  $entry->setLink($module['link']);
165  } elseif (empty($module['link']) && !empty($module['path']) && is_string($module['path'])) {
166  $entry->setLink($module['path']);
167  }
168  if (!empty($module['description']) && is_string($module['description'])) {
169  $entry->setDescription($this->‪getLanguageService()->sL($module['description']));
170  }
171  if (!empty($module['icon'])) {
172  $entry->setIcon($module['icon']);
173  }
174  if (!empty($module['navigationComponentId']) && is_string($module['navigationComponentId'])) {
175  $entry->setNavigationComponentId($module['navigationComponentId']);
176  }
177  if (!empty($module['navigationFrameScript']) && is_string($module['navigationFrameScript'])) {
178  $entry->setNavigationFrameScript($module['navigationFrameScript']);
179  } elseif (!empty($module['parentNavigationFrameScript']) && is_string($module['parentNavigationFrameScript'])) {
180  $entry->setNavigationFrameScript($module['parentNavigationFrameScript']);
181  }
182  if (!empty($module['navigationFrameScriptParam']) && is_string($module['navigationFrameScriptParam'])) {
183  $entry->setNavigationFrameScriptParameters($module['navigationFrameScriptParam']);
184  }
185  $moduleMenuState = json_decode($this->‪getBackendUser()->uc['modulemenu'] ?? '{}', true);
186  $entry->setCollapsed(isset($moduleMenuState[$module['name']]));
187  return $entry;
188  }
189 
194  protected function ‪createMenuEntriesForTbeModulesExt()
195  {
196  foreach (‪$GLOBALS['TBE_MODULES_EXT'] ?? [] as $mainModule => $tbeModuleExt) {
197  list($main) = explode('_', $mainModule);
198  $mainEntry = $this->‪findByModuleName($main);
199  if ($mainEntry === false) {
200  continue;
201  }
202 
203  $subEntries = $mainEntry->getChildren();
204  if (empty($subEntries)) {
205  continue;
206  }
207  $matchingSubEntry = $this->‪findByModuleName($mainModule);
208  if ($matchingSubEntry !== false) {
209  if (isset($tbeModuleExt['MOD_MENU']) && isset($tbeModuleExt['MOD_MENU']['function'])) {
210  foreach ($tbeModuleExt['MOD_MENU']['function'] as $subModule) {
211  $entry = $this->‪createEntryFromRawData($subModule);
212  $matchingSubEntry->addChild($entry);
213  }
214  }
215  }
216  }
217  }
218 
225  public function ‪getRawModuleMenuData()
226  {
227  // Loads the backend modules available for the logged in user.
229  $moduleLoader = GeneralUtility::makeInstance(ModuleLoader::class);
230  $moduleLoader->observeWorkspaces = true;
231  $moduleLoader->load(‪$GLOBALS['TBE_MODULES']);
232  $loadedModules = $moduleLoader->modules;
233 
234  $modules = [];
235 
236  // Unset modules that are meant to be hidden from the menu.
237  $loadedModules = $this->‪removeHiddenModules($loadedModules);
238  $uriBuilder = GeneralUtility::makeInstance(UriBuilder::class);
239  $dummyScript = (string)$uriBuilder->buildUriFromRoute('dummy');
240  foreach ($loadedModules as $moduleName => $moduleData) {
241  $moduleLink = '';
242  if (!is_array($moduleData['sub'])) {
243  $moduleLink = $moduleData['script'];
244  }
245  $moduleLink = GeneralUtility::resolveBackPath($moduleLink);
246  $moduleLabels = $moduleLoader->getLabelsForModule($moduleName);
247  $moduleKey = 'modmenu_' . $moduleName;
248  $modules[$moduleKey] = [
249  'name' => $moduleName,
250  'title' => $moduleLabels['title'],
251  'onclick' => 'top.goToModule(' . GeneralUtility::quoteJSvalue($moduleName) . ');',
252  'icon' => $this->‪getModuleIcon($moduleKey, $moduleData),
253  'link' => $moduleLink,
254  'description' => $moduleLabels['shortdescription']
255  ];
256  if (!is_array($moduleData['sub']) && $moduleData['script'] !== $dummyScript) {
257  // Work around for modules with own main entry, but being self the only submodule
258  $modules[$moduleKey]['subitems'][$moduleKey] = [
259  'name' => $moduleName,
260  'title' => $moduleLabels['title'],
261  'onclick' => 'top.goToModule(' . GeneralUtility::quoteJSvalue($moduleName) . ');',
262  'icon' => $this->‪getModuleIcon($moduleKey, $moduleData),
263  'link' => $moduleLink,
264  'originalLink' => $moduleLink,
265  'description' => $moduleLabels['shortdescription'],
266  'navigationFrameScript' => null,
267  'navigationFrameScriptParam' => null,
268  'navigationComponentId' => null
269  ];
270  } elseif (is_array($moduleData['sub'])) {
271  foreach ($moduleData['sub'] as $submoduleName => $submoduleData) {
272  if (isset($submoduleData['script'])) {
273  $submoduleLink = GeneralUtility::resolveBackPath($submoduleData['script']);
274  } else {
275  $submoduleLink = (string)$uriBuilder->buildUriFromRoute($submoduleData['name']);
276  }
277  $submoduleKey = $moduleName . '_' . $submoduleName;
278  $submoduleLabels = $moduleLoader->getLabelsForModule($submoduleKey);
279  $submoduleDescription = $submoduleLabels['shortdescription'];
280  $originalLink = $submoduleLink;
281  $navigationFrameScript = $submoduleData['navFrameScript'];
282  $modules[$moduleKey]['subitems'][$submoduleKey] = [
283  'name' => $moduleName . '_' . $submoduleName,
284  'title' => $submoduleLabels['title'],
285  'onclick' => 'top.goToModule(' . GeneralUtility::quoteJSvalue($moduleName . '_' . $submoduleName) . ');',
286  'icon' => $this->‪getModuleIcon($moduleKey, $submoduleData),
287  'link' => $submoduleLink,
288  'originalLink' => $originalLink,
289  'description' => $submoduleDescription,
290  'navigationFrameScript' => $navigationFrameScript,
291  'navigationFrameScriptParam' => $submoduleData['navFrameScriptParam'],
292  'navigationComponentId' => $submoduleData['navigationComponentId']
293  ];
294  // if the main module has a navframe script, inherit to the submodule,
295  // but only if it is not disabled explicitly (option is set to FALSE)
296  if ($moduleData['navFrameScript'] && $submoduleData['inheritNavigationComponentFromMainModule'] !== false) {
297  $modules[$moduleKey]['subitems'][$submoduleKey]['parentNavigationFrameScript'] = $moduleData['navFrameScript'];
298  }
299  }
300  }
301  }
302  return $modules;
303  }
304 
312  protected function ‪removeHiddenModules($loadedModules)
313  {
314  $userTsConfig = $this->‪getBackendUser()->‪getTSConfig();
315 
316  // Hide modules if set in userTS.
317  $hiddenMainModules = GeneralUtility::trimExplode(',', $userTsConfig['options.']['hideModules'] ?? '', true);
318  foreach ($hiddenMainModules as $hiddenMainModule) {
319  unset($loadedModules[$hiddenMainModule]);
320  }
321 
322  // Hide sub-modules if set in userTS.
323  $hiddenModules = $userTsConfig['options.']['hideModules.'] ?? [];
324  if (is_array($hiddenModules)) {
325  foreach ($hiddenModules as $mainModuleName => $subModules) {
326  $hiddenSubModules = GeneralUtility::trimExplode(',', $subModules, true);
327  foreach ($hiddenSubModules as $hiddenSubModule) {
328  unset($loadedModules[$mainModuleName]['sub'][$hiddenSubModule]);
329  }
330  }
331  }
332 
333  return $loadedModules;
334  }
335 
343  protected function ‪getModuleIcon($moduleKey, $moduleData)
344  {
345  $iconIdentifier = !empty($moduleData['iconIdentifier'])
346  ? $moduleData['iconIdentifier']
347  : 'module-icon-' . $moduleKey;
348  ‪$iconRegistry = GeneralUtility::makeInstance(IconRegistry::class);
349  if (‪$iconRegistry->isRegistered($iconIdentifier)) {
350  $iconFactory = GeneralUtility::makeInstance(IconFactory::class);
351  return $iconFactory->getIcon($iconIdentifier)->render();
352  }
353  return '';
354  }
355 
361  protected function ‪getLanguageService()
362  {
363  return ‪$GLOBALS['LANG'];
364  }
365 
369  protected function ‪getBackendUser(): ‪BackendUserAuthentication
370  {
371  return ‪$GLOBALS['BE_USER'];
372  }
373 }
‪TYPO3\CMS\Backend\Domain\Repository\Module\BackendModuleRepository\convertRawModuleDataToModuleMenuObject
‪convertRawModuleDataToModuleMenuObject(array $rawModuleData)
Definition: BackendModuleRepository.php:129
‪TYPO3\CMS\Backend\Domain\Repository\Module\BackendModuleRepository\createMenuEntriesForTbeModulesExt
‪createMenuEntriesForTbeModulesExt()
Definition: BackendModuleRepository.php:193
‪TYPO3\CMS\Backend\Domain\Repository\Module\BackendModuleRepository\getLanguageService
‪LanguageService getLanguageService()
Definition: BackendModuleRepository.php:360
‪TYPO3
‪TYPO3\CMS\Core\Authentication\BackendUserAuthentication\getTSConfig
‪array getTSConfig($objectString=null, $config=null)
Definition: BackendUserAuthentication.php:1232
‪TYPO3\CMS\Core\Imaging\IconFactory
Definition: IconFactory.php:31
‪TYPO3\CMS\Backend\Domain\Repository\Module\BackendModuleRepository\getRawModuleMenuData
‪array getRawModuleMenuData()
Definition: BackendModuleRepository.php:224
‪TYPO3\CMS\Backend\Domain\Repository\Module\BackendModuleRepository\getModuleIcon
‪string getModuleIcon($moduleKey, $moduleData)
Definition: BackendModuleRepository.php:342
‪TYPO3\CMS\Backend\Domain\Repository\Module\BackendModuleRepository\removeHiddenModules
‪array removeHiddenModules($loadedModules)
Definition: BackendModuleRepository.php:311
‪TYPO3\CMS\Backend\Domain\Repository\Module\BackendModuleRepository\__construct
‪__construct()
Definition: BackendModuleRepository.php:38
‪TYPO3\CMS\Backend\Domain\Repository\Module\BackendModuleRepository\$moduleStorage
‪TYPO3 CMS Backend Module ModuleStorage $moduleStorage
Definition: BackendModuleRepository.php:33
‪TYPO3\CMS\Backend\Domain\Repository\Module\BackendModuleRepository\findByGroupName
‪SplObjectStorage false findByGroupName($groupName='')
Definition: BackendModuleRepository.php:76
‪TYPO3\CMS\Backend\Domain\Repository\Module\BackendModuleRepository\createEntryFromRawData
‪TYPO3 CMS Backend Domain Model Module BackendModule createEntryFromRawData(array $module)
Definition: BackendModuleRepository.php:149
‪TYPO3\CMS\Backend\Routing\UriBuilder
Definition: UriBuilder.php:35
‪TYPO3\CMS\Backend\Module\ModuleLoader
Definition: ModuleLoader.php:32
‪TYPO3\CMS\Core\Imaging\IconRegistry
Definition: IconRegistry.php:34
‪TYPO3\CMS\Core\Authentication\BackendUserAuthentication
Definition: BackendUserAuthentication.php:45
‪TYPO3\CMS\Backend\Domain\Repository\Module\BackendModuleRepository
Definition: BackendModuleRepository.php:30
‪TYPO3\CMS\Backend\Domain\Repository\Module\BackendModuleRepository\findByModuleNameInGivenEntries
‪TYPO3 CMS Backend Domain Model Module BackendModule bool findByModuleNameInGivenEntries($name, \SplObjectStorage $entries)
Definition: BackendModuleRepository.php:107
‪TYPO3\CMS\Backend\Domain\Repository\Module\BackendModuleRepository\findByModuleName
‪TYPO3 CMS Backend Domain Model Module BackendModule bool findByModuleName($name)
Definition: BackendModuleRepository.php:93
‪TYPO3\CMS\Backend\Domain\Repository\Module\BackendModuleRepository\getBackendUser
‪BackendUserAuthentication getBackendUser()
Definition: BackendModuleRepository.php:368
‪TYPO3\CMS\Core\SingletonInterface
Definition: SingletonInterface.php:22
‪$GLOBALS
‪$GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['adminpanel']['modules']
Definition: ext_localconf.php:5
‪TYPO3\CMS\Backend\Domain\Repository\Module\BackendModuleRepository\loadAllowedModules
‪SplObjectStorage loadAllowedModules(array $excludeGroupNames=[])
Definition: BackendModuleRepository.php:54
‪TYPO3\CMS\Core\Localization\LanguageService
Definition: LanguageService.php:29
‪TYPO3\CMS\Core\Utility\GeneralUtility
Definition: GeneralUtility.php:45
‪TYPO3\CMS\Backend\Domain\Repository\Module
Definition: BackendModuleRepository.php:2
‪$iconRegistry
‪$iconRegistry
Definition: ext_localconf.php:76