TYPO3  7.6
BackendModuleRepository.php
Go to the documentation of this file.
1 <?php
2 namespace TYPO3\CMS\Backend\Domain\Repository\Module;
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 = array())
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  foreach ($GLOBALS['TBE_MODULES_EXT'] as $mainModule => $tbeModuleExt) {
195  list($main) = explode('_', $mainModule);
196  $mainEntry = $this->findByModuleName($main);
197  if ($mainEntry === false) {
198  continue;
199  }
200 
201  $subEntries = $mainEntry->getChildren();
202  if (empty($subEntries)) {
203  continue;
204  }
205  $matchingSubEntry = $this->findByModuleName($mainModule);
206  if ($matchingSubEntry !== false) {
207  if (isset($tbeModuleExt['MOD_MENU']) && isset($tbeModuleExt['MOD_MENU']['function'])) {
208  foreach ($tbeModuleExt['MOD_MENU']['function'] as $subModule) {
209  $entry = $this->createEntryFromRawData($subModule);
210  $matchingSubEntry->addChild($entry);
211  }
212  }
213  }
214  }
215  }
216 
222  protected function getLanguageService()
223  {
224  return $GLOBALS['LANG'];
225  }
226 
233  public function getRawModuleMenuData()
234  {
235  // Loads the backend modules available for the logged in user.
236  $moduleLoader = GeneralUtility::makeInstance(\TYPO3\CMS\Backend\Module\ModuleLoader::class);
237  $moduleLoader->observeWorkspaces = true;
238  $moduleLoader->load($GLOBALS['TBE_MODULES']);
239  $loadedModules = $moduleLoader->modules;
240 
241  $modules = array();
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  $moduleKey = 'modmenu_' . $moduleName;
253  $modules[$moduleKey] = array(
254  'name' => $moduleName,
255  'title' => $GLOBALS['LANG']->moduleLabels['tabs'][$moduleName . '_tab'],
256  'onclick' => 'top.goToModule(' . GeneralUtility::quoteJSvalue($moduleName) . ');',
257  'icon' => $this->getModuleIcon($moduleName . '_tab', $moduleData),
258  'link' => $moduleLink,
259  'description' => $GLOBALS['LANG']->moduleLabels['labels'][$moduleKey . 'label']
260  );
261  if (!is_array($moduleData['sub']) && $moduleData['script'] !== $dummyScript) {
262  // Work around for modules with own main entry, but being self the only submodule
263  $modules[$moduleKey]['subitems'][$moduleKey] = array(
264  'name' => $moduleName,
265  'title' => $GLOBALS['LANG']->moduleLabels['tabs'][$moduleName . '_tab'],
266  'onclick' => 'top.goToModule(' . GeneralUtility::quoteJSvalue($moduleName) . ');',
267  'icon' => $this->getModuleIcon($moduleName . '_tab', $moduleData),
268  'link' => $moduleLink,
269  'originalLink' => $moduleLink,
270  'description' => $GLOBALS['LANG']->moduleLabels['labels'][$moduleKey . 'label'],
271  'navigationFrameScript' => null,
272  'navigationFrameScriptParam' => null,
273  'navigationComponentId' => null
274  );
275  } elseif (is_array($moduleData['sub'])) {
276  foreach ($moduleData['sub'] as $submoduleName => $submoduleData) {
277  if (isset($submoduleData['script'])) {
278  $submoduleLink = GeneralUtility::resolveBackPath($submoduleData['script']);
279  } else {
280  $submoduleLink = BackendUtility::getModuleUrl($submoduleData['name']);
281  }
282  $submoduleKey = $moduleName . '_' . $submoduleName . '_tab';
283  $submoduleDescription = $GLOBALS['LANG']->moduleLabels['labels'][$submoduleKey . 'label'];
284  $originalLink = $submoduleLink;
285  $navigationFrameScript = $submoduleData['navFrameScript'];
286  $modules[$moduleKey]['subitems'][$submoduleKey] = array(
287  'name' => $moduleName . '_' . $submoduleName,
288  'title' => $GLOBALS['LANG']->moduleLabels['tabs'][$submoduleKey],
289  'onclick' => 'top.goToModule(' . GeneralUtility::quoteJSvalue($moduleName . '_' . $submoduleName) . ');',
290  'icon' => $this->getModuleIcon($submoduleKey, $submoduleData),
291  'link' => $submoduleLink,
292  'originalLink' => $originalLink,
293  'description' => $submoduleDescription,
294  'navigationFrameScript' => $navigationFrameScript,
295  'navigationFrameScriptParam' => $submoduleData['navFrameScriptParam'],
296  'navigationComponentId' => $submoduleData['navigationComponentId']
297  );
298  // if the main module has a navframe script, inherit to the submodule,
299  // but only if it is not disabled explicitly (option is set to FALSE)
300  if ($moduleData['navFrameScript'] && $submoduleData['inheritNavigationComponentFromMainModule'] !== false) {
301  $modules[$moduleKey]['subitems'][$submoduleKey]['parentNavigationFrameScript'] = $moduleData['navFrameScript'];
302  }
303  }
304  }
305  }
306  return $modules;
307  }
308 
316  protected function removeHiddenModules($loadedModules)
317  {
318  $hiddenModules = $GLOBALS['BE_USER']->getTSConfig('options.hideModules');
319 
320  // Hide modules if set in userTS.
321  if (!empty($hiddenModules['value'])) {
322  $hiddenMainModules = explode(',', $hiddenModules['value']);
323  foreach ($hiddenMainModules as $hiddenMainModule) {
324  unset($loadedModules[trim($hiddenMainModule)]);
325  }
326  }
327 
328  // Hide sub-modules if set in userTS.
329  if (!empty($hiddenModules['properties']) && is_array($hiddenModules['properties'])) {
330  foreach ($hiddenModules['properties'] as $mainModuleName => $subModules) {
331  $hiddenSubModules = explode(',', $subModules);
332  foreach ($hiddenSubModules as $hiddenSubModule) {
333  unset($loadedModules[$mainModuleName]['sub'][trim($hiddenSubModule)]);
334  }
335  }
336  }
337 
338  return $loadedModules;
339  }
340 
348  protected function getModuleIcon($moduleKey, $moduleData)
349  {
350  $icon = '';
351 
352  // add as a sprite icon
353  if (!empty($moduleData['iconIdentifier'])) {
354  $iconFactory = GeneralUtility::makeInstance(IconFactory::class);
355  $icon = $iconFactory->getIcon($moduleData['iconIdentifier'])->render();
356  } elseif (!empty($GLOBALS['LANG']->moduleLabels['tabs_images'][$moduleKey])) {
357  $imageReference = $GLOBALS['LANG']->moduleLabels['tabs_images'][$moduleKey];
358  $iconFileRelative = $this->getModuleIconRelative($imageReference);
359  if (!empty($iconFileRelative)) {
360  $iconTitle = $GLOBALS['LANG']->moduleLabels['tabs'][$moduleKey];
361  $iconSizes = @getimagesize($this->getModuleIconAbsolute($imageReference));
362  $icon = '<img src="' . $iconFileRelative . '" ' . $iconSizes[3] . ' title="' . htmlspecialchars($iconTitle) . '" alt="' . htmlspecialchars($iconTitle) . '" />';
363  }
364  }
365  return $icon;
366  }
367 
377  protected function getModuleIconAbsolute($iconFilename)
378  {
379  if (!GeneralUtility::isAbsPath($iconFilename)) {
380  $iconFilename = $GLOBALS['BACK_PATH'] . $iconFilename;
381  }
382  return $iconFilename;
383  }
384 
392  protected function getModuleIconRelative($iconFilename)
393  {
394  if (GeneralUtility::isAbsPath($iconFilename)) {
395  $iconFilename = '../' . \TYPO3\CMS\Core\Utility\PathUtility::stripPathSitePrefix($iconFilename);
396  }
397  return $iconFilename;
398  }
399 }