TYPO3 CMS  TYPO3_7-6
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 
21 
27 {
31  protected $moduleStorage;
32 
36  public function __construct()
37  {
38  $this->moduleStorage = GeneralUtility::makeInstance(\TYPO3\CMS\Backend\Module\ModuleStorage::class);
39 
40  $rawData = $this->getRawModuleMenuData();
41 
44  }
45 
52  public function loadAllowedModules(array $excludeGroupNames = [])
53  {
54  if (empty($excludeGroupNames)) {
55  return $this->moduleStorage->getEntries();
56  }
57 
58  $modules = new \SplObjectStorage();
59  foreach ($this->moduleStorage->getEntries() as $moduleGroup) {
60  if (!in_array($moduleGroup->getName(), $excludeGroupNames, true)) {
61  if ($moduleGroup->getChildren()->count() > 0) {
62  $modules->attach($moduleGroup);
63  }
64  }
65  }
66 
67  return $modules;
68  }
69 
74  public function findByGroupName($groupName = '')
75  {
76  foreach ($this->moduleStorage->getEntries() as $moduleGroup) {
77  if ($moduleGroup->getName() === $groupName) {
78  return $moduleGroup;
79  }
80  }
81 
82  return false;
83  }
84 
91  public function findByModuleName($name)
92  {
93  $entries = $this->moduleStorage->getEntries();
94  $entry = $this->findByModuleNameInGivenEntries($name, $entries);
95  return $entry;
96  }
97 
105  public function findByModuleNameInGivenEntries($name, \SplObjectStorage $entries)
106  {
107  foreach ($entries as $entry) {
108  if ($entry->getName() === $name) {
109  return $entry;
110  }
111  $children = $entry->getChildren();
112  if (!empty($children)) {
113  $childRecord = $this->findByModuleNameInGivenEntries($name, $children);
114  if ($childRecord !== false) {
115  return $childRecord;
116  }
117  }
118  }
119  return false;
120  }
121 
128  protected function convertRawModuleDataToModuleMenuObject(array $rawModuleData)
129  {
130  foreach ($rawModuleData as $module) {
131  $entry = $this->createEntryFromRawData($module);
132  if (isset($module['subitems']) && !empty($module['subitems'])) {
133  foreach ($module['subitems'] as $subitem) {
134  $subEntry = $this->createEntryFromRawData($subitem);
135  $entry->addChild($subEntry);
136  }
137  }
138  $this->moduleStorage->attachEntry($entry);
139  }
140  }
141 
148  protected function createEntryFromRawData(array $module)
149  {
151  $entry = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance(\TYPO3\CMS\Backend\Domain\Model\Module\BackendModule::class);
152  if (!empty($module['name']) && is_string($module['name'])) {
153  $entry->setName($module['name']);
154  }
155  if (!empty($module['title']) && is_string($module['title'])) {
156  $entry->setTitle($this->getLanguageService()->sL($module['title']));
157  }
158  if (!empty($module['onclick']) && is_string($module['onclick'])) {
159  $entry->setOnClick($module['onclick']);
160  }
161  if (!empty($module['link']) && is_string($module['link'])) {
162  $entry->setLink($module['link']);
163  } elseif (empty($module['link']) && !empty($module['path']) && is_string($module['path'])) {
164  $entry->setLink($module['path']);
165  }
166  if (!empty($module['description']) && is_string($module['description'])) {
167  $entry->setDescription($module['description']);
168  }
169  if (!empty($module['icon'])) {
170  $entry->setIcon($module['icon']);
171  }
172  if (!empty($module['navigationComponentId']) && is_string($module['navigationComponentId'])) {
173  $entry->setNavigationComponentId($module['navigationComponentId']);
174  }
175  if (!empty($module['navigationFrameScript']) && is_string($module['navigationFrameScript'])) {
176  $entry->setNavigationFrameScript($module['navigationFrameScript']);
177  } elseif (!empty($module['parentNavigationFrameScript']) && is_string($module['parentNavigationFrameScript'])) {
178  $entry->setNavigationFrameScript($module['parentNavigationFrameScript']);
179  }
180  if (!empty($module['navigationFrameScriptParam']) && is_string($module['navigationFrameScriptParam'])) {
181  $entry->setNavigationFrameScriptParameters($module['navigationFrameScriptParam']);
182  }
183  return $entry;
184  }
185 
193  {
194  if (isset($GLOBALS['TBE_MODULES_EXT'])) {
195  foreach ((array)$GLOBALS['TBE_MODULES_EXT'] as $mainModule => $tbeModuleExt) {
196  list($main) = explode('_', $mainModule);
197  $mainEntry = $this->findByModuleName($main);
198  if ($mainEntry === false) {
199  continue;
200  }
201 
202  $subEntries = $mainEntry->getChildren();
203  if (empty($subEntries)) {
204  continue;
205  }
206  $matchingSubEntry = $this->findByModuleName($mainModule);
207  if ($matchingSubEntry !== false) {
208  if (isset($tbeModuleExt['MOD_MENU']) && isset($tbeModuleExt['MOD_MENU']['function'])) {
209  foreach ($tbeModuleExt['MOD_MENU']['function'] as $subModule) {
210  $entry = $this->createEntryFromRawData($subModule);
211  $matchingSubEntry->addChild($entry);
212  }
213  }
214  }
215  }
216  }
217  }
218 
224  protected function getLanguageService()
225  {
226  return $GLOBALS['LANG'];
227  }
228 
235  public function getRawModuleMenuData()
236  {
237  // Loads the backend modules available for the logged in user.
238  $moduleLoader = GeneralUtility::makeInstance(\TYPO3\CMS\Backend\Module\ModuleLoader::class);
239  $moduleLoader->observeWorkspaces = true;
240  $moduleLoader->load($GLOBALS['TBE_MODULES']);
241  $loadedModules = $moduleLoader->modules;
242 
243  $modules = [];
244 
245  // Unset modules that are meant to be hidden from the menu.
246  $loadedModules = $this->removeHiddenModules($loadedModules);
247  $dummyScript = BackendUtility::getModuleUrl('dummy');
248  foreach ($loadedModules as $moduleName => $moduleData) {
249  $moduleLink = '';
250  if (!is_array($moduleData['sub'])) {
251  $moduleLink = $moduleData['script'];
252  }
253  $moduleLink = GeneralUtility::resolveBackPath($moduleLink);
254  $moduleKey = 'modmenu_' . $moduleName;
255  $modules[$moduleKey] = [
256  'name' => $moduleName,
257  'title' => $GLOBALS['LANG']->moduleLabels['tabs'][$moduleName . '_tab'],
258  'onclick' => 'top.goToModule(' . GeneralUtility::quoteJSvalue($moduleName) . ');',
259  'icon' => $this->getModuleIcon($moduleName . '_tab', $moduleData),
260  'link' => $moduleLink,
261  'description' => $GLOBALS['LANG']->moduleLabels['labels'][$moduleKey . 'label']
262  ];
263  if (!is_array($moduleData['sub']) && $moduleData['script'] !== $dummyScript) {
264  // Work around for modules with own main entry, but being self the only submodule
265  $modules[$moduleKey]['subitems'][$moduleKey] = [
266  'name' => $moduleName,
267  'title' => $GLOBALS['LANG']->moduleLabels['tabs'][$moduleName . '_tab'],
268  'onclick' => 'top.goToModule(' . GeneralUtility::quoteJSvalue($moduleName) . ');',
269  'icon' => $this->getModuleIcon($moduleName . '_tab', $moduleData),
270  'link' => $moduleLink,
271  'originalLink' => $moduleLink,
272  'description' => $GLOBALS['LANG']->moduleLabels['labels'][$moduleKey . 'label'],
273  'navigationFrameScript' => null,
274  'navigationFrameScriptParam' => null,
275  'navigationComponentId' => null
276  ];
277  } elseif (is_array($moduleData['sub'])) {
278  foreach ($moduleData['sub'] as $submoduleName => $submoduleData) {
279  if (isset($submoduleData['script'])) {
280  $submoduleLink = GeneralUtility::resolveBackPath($submoduleData['script']);
281  } else {
282  $submoduleLink = BackendUtility::getModuleUrl($submoduleData['name']);
283  }
284  $submoduleKey = $moduleName . '_' . $submoduleName . '_tab';
285  $submoduleDescription = $GLOBALS['LANG']->moduleLabels['labels'][$submoduleKey . 'label'];
286  $originalLink = $submoduleLink;
287  $navigationFrameScript = $submoduleData['navFrameScript'];
288  $modules[$moduleKey]['subitems'][$submoduleKey] = [
289  'name' => $moduleName . '_' . $submoduleName,
290  'title' => $GLOBALS['LANG']->moduleLabels['tabs'][$submoduleKey],
291  'onclick' => 'top.goToModule(' . GeneralUtility::quoteJSvalue($moduleName . '_' . $submoduleName) . ');',
292  'icon' => $this->getModuleIcon($submoduleKey, $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  $icon = '';
353 
354  // add as a sprite icon
355  if (!empty($moduleData['iconIdentifier'])) {
356  $iconFactory = GeneralUtility::makeInstance(IconFactory::class);
357  $icon = $iconFactory->getIcon($moduleData['iconIdentifier'])->render();
358  } elseif (!empty($GLOBALS['LANG']->moduleLabels['tabs_images'][$moduleKey])) {
359  $imageReference = $GLOBALS['LANG']->moduleLabels['tabs_images'][$moduleKey];
360  $iconFileRelative = $this->getModuleIconRelative($imageReference);
361  if (!empty($iconFileRelative)) {
362  $iconTitle = $GLOBALS['LANG']->moduleLabels['tabs'][$moduleKey];
363  $iconSizes = @getimagesize($this->getModuleIconAbsolute($imageReference));
364  $icon = '<img src="' . $iconFileRelative . '" ' . $iconSizes[3] . ' title="' . htmlspecialchars($iconTitle) . '" alt="' . htmlspecialchars($iconTitle) . '" />';
365  }
366  }
367  return $icon;
368  }
369 
379  protected function getModuleIconAbsolute($iconFilename)
380  {
381  if (!GeneralUtility::isAbsPath($iconFilename)) {
382  $iconFilename = $GLOBALS['BACK_PATH'] . $iconFilename;
383  }
384  return $iconFilename;
385  }
386 
394  protected function getModuleIconRelative($iconFilename)
395  {
396  if (GeneralUtility::isAbsPath($iconFilename)) {
397  $iconFilename = '../' . \TYPO3\CMS\Core\Utility\PathUtility::stripPathSitePrefix($iconFilename);
398  }
399  return $iconFilename;
400  }
401 }
if(TYPO3_MODE==='BE') $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_tsfebeuserauth.php']['frontendEditingController']['default']