TYPO3 CMS  TYPO3_8-7
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 
23 
29 {
33  protected $moduleStorage;
34 
38  public function __construct()
39  {
40  $this->moduleStorage = GeneralUtility::makeInstance(\TYPO3\CMS\Backend\Module\ModuleStorage::class);
41 
42  $rawData = $this->getRawModuleMenuData();
43 
46  }
47 
54  public function loadAllowedModules(array $excludeGroupNames = [])
55  {
56  if (empty($excludeGroupNames)) {
57  return $this->moduleStorage->getEntries();
58  }
59 
60  $modules = new \SplObjectStorage();
61  foreach ($this->moduleStorage->getEntries() as $moduleGroup) {
62  if (!in_array($moduleGroup->getName(), $excludeGroupNames, true)) {
63  if ($moduleGroup->getChildren()->count() > 0) {
64  $modules->attach($moduleGroup);
65  }
66  }
67  }
68 
69  return $modules;
70  }
71 
76  public function findByGroupName($groupName = '')
77  {
78  foreach ($this->moduleStorage->getEntries() as $moduleGroup) {
79  if ($moduleGroup->getName() === $groupName) {
80  return $moduleGroup;
81  }
82  }
83 
84  return false;
85  }
86 
93  public function findByModuleName($name)
94  {
95  $entries = $this->moduleStorage->getEntries();
96  $entry = $this->findByModuleNameInGivenEntries($name, $entries);
97  return $entry;
98  }
99 
107  public function findByModuleNameInGivenEntries($name, \SplObjectStorage $entries)
108  {
109  foreach ($entries as $entry) {
110  if ($entry->getName() === $name) {
111  return $entry;
112  }
113  $children = $entry->getChildren();
114  if (!empty($children)) {
115  $childRecord = $this->findByModuleNameInGivenEntries($name, $children);
116  if ($childRecord !== false) {
117  return $childRecord;
118  }
119  }
120  }
121  return false;
122  }
123 
129  protected function convertRawModuleDataToModuleMenuObject(array $rawModuleData)
130  {
131  foreach ($rawModuleData as $module) {
132  $entry = $this->createEntryFromRawData($module);
133  if (isset($module['subitems']) && !empty($module['subitems'])) {
134  foreach ($module['subitems'] as $subitem) {
135  $subEntry = $this->createEntryFromRawData($subitem);
136  $entry->addChild($subEntry);
137  }
138  }
139  $this->moduleStorage->attachEntry($entry);
140  }
141  }
142 
149  protected function createEntryFromRawData(array $module)
150  {
152  $entry = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance(\TYPO3\CMS\Backend\Domain\Model\Module\BackendModule::class);
153  if (!empty($module['name']) && is_string($module['name'])) {
154  $entry->setName($module['name']);
155  }
156  if (!empty($module['title']) && is_string($module['title'])) {
157  $entry->setTitle($this->getLanguageService()->sL($module['title']));
158  }
159  if (!empty($module['onclick']) && is_string($module['onclick'])) {
160  $entry->setOnClick($module['onclick']);
161  }
162  if (!empty($module['link']) && is_string($module['link'])) {
163  $entry->setLink($module['link']);
164  } elseif (empty($module['link']) && !empty($module['path']) && is_string($module['path'])) {
165  $entry->setLink($module['path']);
166  }
167  if (!empty($module['description']) && is_string($module['description'])) {
168  $entry->setDescription($this->getLanguageService()->sL($module['description']));
169  }
170  if (!empty($module['icon'])) {
171  $entry->setIcon($module['icon']);
172  }
173  if (!empty($module['navigationComponentId']) && is_string($module['navigationComponentId'])) {
174  $entry->setNavigationComponentId($module['navigationComponentId']);
175  }
176  if (!empty($module['navigationFrameScript']) && is_string($module['navigationFrameScript'])) {
177  $entry->setNavigationFrameScript($module['navigationFrameScript']);
178  } elseif (!empty($module['parentNavigationFrameScript']) && is_string($module['parentNavigationFrameScript'])) {
179  $entry->setNavigationFrameScript($module['parentNavigationFrameScript']);
180  }
181  if (!empty($module['navigationFrameScriptParam']) && is_string($module['navigationFrameScriptParam'])) {
182  $entry->setNavigationFrameScriptParameters($module['navigationFrameScriptParam']);
183  }
184  return $entry;
185  }
186 
192  {
193  foreach ($GLOBALS['TBE_MODULES_EXT'] ?? [] as $mainModule => $tbeModuleExt) {
194  list($main) = explode('_', $mainModule);
195  $mainEntry = $this->findByModuleName($main);
196  if ($mainEntry === false) {
197  continue;
198  }
199 
200  $subEntries = $mainEntry->getChildren();
201  if (empty($subEntries)) {
202  continue;
203  }
204  $matchingSubEntry = $this->findByModuleName($mainModule);
205  if ($matchingSubEntry !== false) {
206  if (isset($tbeModuleExt['MOD_MENU']) && isset($tbeModuleExt['MOD_MENU']['function'])) {
207  foreach ($tbeModuleExt['MOD_MENU']['function'] as $subModule) {
208  $entry = $this->createEntryFromRawData($subModule);
209  $matchingSubEntry->addChild($entry);
210  }
211  }
212  }
213  }
214  }
215 
221  protected function getLanguageService()
222  {
223  return $GLOBALS['LANG'];
224  }
225 
232  public function getRawModuleMenuData()
233  {
234  // Loads the backend modules available for the logged in user.
236  $moduleLoader = GeneralUtility::makeInstance(ModuleLoader::class);
237  $moduleLoader->observeWorkspaces = true;
238  $moduleLoader->load($GLOBALS['TBE_MODULES']);
239  $loadedModules = $moduleLoader->modules;
240 
241  $modules = [];
242 
243  // Unset modules that are meant to be hidden from the menu.
244  $loadedModules = $this->removeHiddenModules($loadedModules);
245  $dummyScript = BackendUtility::getModuleUrl('dummy');
246  foreach ($loadedModules as $moduleName => $moduleData) {
247  $moduleLink = '';
248  if (!is_array($moduleData['sub'])) {
249  $moduleLink = $moduleData['script'];
250  }
251  $moduleLink = GeneralUtility::resolveBackPath($moduleLink);
252  $moduleLabels = $moduleLoader->getLabelsForModule($moduleName);
253  $moduleKey = 'modmenu_' . $moduleName;
254  $modules[$moduleKey] = [
255  'name' => $moduleName,
256  'title' => $moduleLabels['title'],
257  'onclick' => 'top.goToModule(' . GeneralUtility::quoteJSvalue($moduleName) . ');',
258  'icon' => $this->getModuleIcon($moduleKey, $moduleData),
259  'link' => $moduleLink,
260  'description' => $moduleLabels['shortdescription']
261  ];
262  if (!is_array($moduleData['sub']) && $moduleData['script'] !== $dummyScript) {
263  // Work around for modules with own main entry, but being self the only submodule
264  $modules[$moduleKey]['subitems'][$moduleKey] = [
265  'name' => $moduleName,
266  'title' => $moduleLabels['title'],
267  'onclick' => 'top.goToModule(' . GeneralUtility::quoteJSvalue($moduleName) . ');',
268  'icon' => $this->getModuleIcon($moduleKey, $moduleData),
269  'link' => $moduleLink,
270  'originalLink' => $moduleLink,
271  'description' => $moduleLabels['shortdescription'],
272  'navigationFrameScript' => null,
273  'navigationFrameScriptParam' => null,
274  'navigationComponentId' => null
275  ];
276  } elseif (is_array($moduleData['sub'])) {
277  foreach ($moduleData['sub'] as $submoduleName => $submoduleData) {
278  if (isset($submoduleData['script'])) {
279  $submoduleLink = GeneralUtility::resolveBackPath($submoduleData['script']);
280  } else {
281  $submoduleLink = BackendUtility::getModuleUrl($submoduleData['name']);
282  }
283  $submoduleKey = $moduleName . '_' . $submoduleName;
284  $submoduleLabels = $moduleLoader->getLabelsForModule($submoduleKey);
285  $submoduleDescription = $submoduleLabels['shortdescription'];
286  $originalLink = $submoduleLink;
287  $navigationFrameScript = $submoduleData['navFrameScript'];
288  $modules[$moduleKey]['subitems'][$submoduleKey] = [
289  'name' => $moduleName . '_' . $submoduleName,
290  'title' => $submoduleLabels['title'],
291  'onclick' => 'top.goToModule(' . GeneralUtility::quoteJSvalue($moduleName . '_' . $submoduleName) . ');',
292  'icon' => $this->getModuleIcon($moduleKey, $submoduleData),
293  'link' => $submoduleLink,
294  'originalLink' => $originalLink,
295  'description' => $submoduleDescription,
296  'navigationFrameScript' => $navigationFrameScript,
297  'navigationFrameScriptParam' => $submoduleData['navFrameScriptParam'],
298  'navigationComponentId' => $submoduleData['navigationComponentId']
299  ];
300  // if the main module has a navframe script, inherit to the submodule,
301  // but only if it is not disabled explicitly (option is set to FALSE)
302  if ($moduleData['navFrameScript'] && $submoduleData['inheritNavigationComponentFromMainModule'] !== false) {
303  $modules[$moduleKey]['subitems'][$submoduleKey]['parentNavigationFrameScript'] = $moduleData['navFrameScript'];
304  }
305  }
306  }
307  }
308  return $modules;
309  }
310 
318  protected function removeHiddenModules($loadedModules)
319  {
320  $hiddenModules = $GLOBALS['BE_USER']->getTSConfig('options.hideModules');
321 
322  // Hide modules if set in userTS.
323  if (!empty($hiddenModules['value'])) {
324  $hiddenMainModules = explode(',', $hiddenModules['value']);
325  foreach ($hiddenMainModules as $hiddenMainModule) {
326  unset($loadedModules[trim($hiddenMainModule)]);
327  }
328  }
329 
330  // Hide sub-modules if set in userTS.
331  if (!empty($hiddenModules['properties']) && is_array($hiddenModules['properties'])) {
332  foreach ($hiddenModules['properties'] as $mainModuleName => $subModules) {
333  $hiddenSubModules = explode(',', $subModules);
334  foreach ($hiddenSubModules as $hiddenSubModule) {
335  unset($loadedModules[$mainModuleName]['sub'][trim($hiddenSubModule)]);
336  }
337  }
338  }
339 
340  return $loadedModules;
341  }
342 
350  protected function getModuleIcon($moduleKey, $moduleData)
351  {
352  $iconIdentifier = !(empty($moduleData['iconIdentifier']))
353  ? $moduleData['iconIdentifier']
354  : 'module-icon-' . $moduleKey;
355  $iconRegistry = GeneralUtility::makeInstance(IconRegistry::class);
356  if ($iconRegistry->isRegistered($iconIdentifier)) {
357  $iconFactory = GeneralUtility::makeInstance(IconFactory::class);
358  return $iconFactory->getIcon($iconIdentifier)->render();
359  }
360  return '';
361  }
362 }
static makeInstance($className,... $constructorArguments)
$iconRegistry
if(TYPO3_MODE==='BE') $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_tsfebeuserauth.php']['frontendEditingController']['default']