TYPO3  7.6
ModuleMenuView.php
Go to the documentation of this file.
1 <?php
2 namespace TYPO3\CMS\Backend\View;
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 
19 
24 {
30  protected $moduleLoader;
31 
35  protected $backPath;
36 
40  protected $linkModules;
41 
45  protected $loadedModules;
46 
51  public function __construct()
52  {
54  if (TYPO3_REQUESTTYPE & TYPO3_REQUESTTYPE_AJAX) {
55  $GLOBALS['LANG']->includeLLFile('EXT:lang/locallang_misc.xlf');
56  }
57  $this->backPath = '';
58  $this->linkModules = true;
59  // Loads the backend modules available for the logged in user.
60  $this->moduleLoader = GeneralUtility::makeInstance(\TYPO3\CMS\Backend\Module\ModuleLoader::class);
61  $this->moduleLoader->observeWorkspaces = true;
62  $this->moduleLoader->load($GLOBALS['TBE_MODULES']);
63  $this->loadedModules = $this->moduleLoader->modules;
64  }
65 
73  public function setBackPath($backPath)
74  {
75  if (!is_string($backPath)) {
76  throw new \InvalidArgumentException('parameter $backPath must be of type string', 1193315266);
77  }
78  $this->backPath = $backPath;
79  }
80 
86  protected function getCollapsedStates()
87  {
88  $collapsedStates = array();
89  if ($GLOBALS['BE_USER']->uc['moduleData']['moduleMenu']) {
90  $collapsedStates = $GLOBALS['BE_USER']->uc['moduleData']['moduleMenu'];
91  }
92  return $collapsedStates;
93  }
94 
102  public function getModuleData($params, $ajaxObj)
103  {
104  $data = array('success' => true, 'root' => array());
105  $rawModuleData = $this->getRawModuleData();
106  $index = 0;
107  $dummyLink = BackendUtility::getModuleUrl('dummy');
108  foreach ($rawModuleData as $moduleKey => $moduleData) {
109  $key = substr($moduleKey, 8);
110  $num = count($data['root']);
111  if ($moduleData['link'] != $dummyLink || $moduleData['link'] == $dummyLink && is_array($moduleData['subitems'])) {
112  $data['root'][$num]['key'] = $key;
113  $data['root'][$num]['menuState'] = $GLOBALS['BE_USER']->uc['moduleData']['menuState'][$moduleKey];
114  $data['root'][$num]['label'] = $moduleData['title'];
115  $data['root'][$num]['subitems'] = is_array($moduleData['subitems']) ? count($moduleData['subitems']) : 0;
116  if ($moduleData['link'] && $this->linkModules) {
117  $data['root'][$num]['link'] = 'top.goToModule(' . GeneralUtility::quoteJSvalue($moduleData['name']) . ')';
118  }
119  // Traverse submodules
120  if (is_array($moduleData['subitems'])) {
121  foreach ($moduleData['subitems'] as $subKey => $subData) {
122  $data['root'][$num]['sub'][] = array(
123  'name' => $subData['name'],
124  'description' => $subData['description'],
125  'label' => $subData['title'],
126  'icon' => $subData['icon']['filename'],
127  'navframe' => $subData['parentNavigationFrameScript'],
128  'link' => $subData['link'],
129  'originalLink' => $subData['originalLink'],
130  'index' => $index++,
131  'navigationFrameScript' => $subData['navigationFrameScript'],
132  'navigationFrameScriptParam' => $subData['navigationFrameScriptParam'],
133  'navigationComponentId' => $subData['navigationComponentId']
134  );
135  }
136  }
137  }
138  }
139  if ($ajaxObj) {
140  $ajaxObj->setContent($data);
141  $ajaxObj->setContentFormat('jsonbody');
142  } else {
143  return $data;
144  }
145  }
146 
152  public function getLoadedModules()
153  {
154  return $this->loadedModules;
155  }
156 
164  public function saveMenuState($params, $ajaxObj)
165  {
166  $menuItem = GeneralUtility::_POST('menuid');
167  $state = GeneralUtility::_POST('state') === 'true' ? 1 : 0;
168  $GLOBALS['BE_USER']->uc['moduleData']['menuState'][$menuItem] = $state;
169  $GLOBALS['BE_USER']->writeUC();
170  }
171 
178  protected function unsetHiddenModules()
179  {
180  // Hide modules if set in userTS.
181  $hiddenModules = $GLOBALS['BE_USER']->getTSConfig('options.hideModules');
182  if (!empty($hiddenModules['value'])) {
183  $hiddenMainModules = GeneralUtility::trimExplode(',', $hiddenModules['value'], true);
184  foreach ($hiddenMainModules as $hiddenMainModule) {
185  unset($this->loadedModules[$hiddenMainModule]);
186  }
187  }
188 
189  // Hide sub-modules if set in userTS.
190  if (!empty($hiddenModules['properties']) && is_array($hiddenModules['properties'])) {
191  foreach ($hiddenModules['properties'] as $mainModuleName => $subModules) {
192  $hiddenSubModules = GeneralUtility::trimExplode(',', $subModules, true);
193  foreach ($hiddenSubModules as $hiddenSubModule) {
194  unset($this->loadedModules[$mainModuleName]['sub'][$hiddenSubModule]);
195  }
196  }
197  }
198  }
199 
205  public function getRawModuleData()
206  {
207  $modules = array();
208 
209  // Unset modules that are meant to be hidden from the menu.
210  $this->unsetHiddenModules();
211  $dummyScript = BackendUtility::getModuleUrl('dummy');
212  foreach ($this->loadedModules as $moduleName => $moduleData) {
213  $moduleLink = '';
214  if (!is_array($moduleData['sub'])) {
215  $moduleLink = $moduleData['script'];
216  }
217  $moduleLink = GeneralUtility::resolveBackPath($moduleLink);
218  $moduleKey = 'modmenu_' . $moduleName;
219  $moduleIcon = $this->getModuleIcon($moduleKey);
220  $modules[$moduleKey] = array(
221  'name' => $moduleName,
222  'title' => $GLOBALS['LANG']->moduleLabels['tabs'][$moduleName . '_tab'],
223  'onclick' => 'top.goToModule(' . GeneralUtility::quoteJSvalue($moduleName) . ');',
224  'icon' => $moduleIcon,
225  'link' => $moduleLink,
226  'description' => $GLOBALS['LANG']->moduleLabels['labels'][$moduleKey . 'label']
227  );
228  if (!is_array($moduleData['sub']) && $moduleData['script'] != $dummyScript) {
229  // Work around for modules with own main entry, but being self the only submodule
230  $modules[$moduleKey]['subitems'][$moduleKey] = array(
231  'name' => $moduleName,
232  'title' => $GLOBALS['LANG']->moduleLabels['tabs'][$moduleName . '_tab'],
233  'onclick' => 'top.goToModule(' . GeneralUtility::quoteJSvalue($moduleName) . ');',
234  'icon' => $this->getModuleIcon($moduleName . '_tab'),
235  'link' => $moduleLink,
236  'originalLink' => $moduleLink,
237  'description' => $GLOBALS['LANG']->moduleLabels['labels'][$moduleKey . 'label'],
238  'navigationFrameScript' => null,
239  'navigationFrameScriptParam' => null,
240  'navigationComponentId' => null
241  );
242  } elseif (is_array($moduleData['sub'])) {
243  foreach ($moduleData['sub'] as $submoduleName => $submoduleData) {
244  if (isset($submoduleData['script'])) {
245  $submoduleLink = GeneralUtility::resolveBackPath($submoduleData['script']);
246  } else {
247  $submoduleLink = BackendUtility::getModuleUrl($submoduleData['name']);
248  }
249  $submoduleKey = $moduleName . '_' . $submoduleName . '_tab';
250  $submoduleIcon = $this->getModuleIcon($submoduleKey);
251  $submoduleDescription = $GLOBALS['LANG']->moduleLabels['labels'][$submoduleKey . 'label'];
252  $originalLink = $submoduleLink;
253  $navigationFrameScript = $submoduleData['navFrameScript'];
254  $modules[$moduleKey]['subitems'][$submoduleKey] = array(
255  'name' => $moduleName . '_' . $submoduleName,
256  'title' => $GLOBALS['LANG']->moduleLabels['tabs'][$submoduleKey],
257  'onclick' => 'top.goToModule(' . GeneralUtility::quoteJSvalue($moduleName . '_' . $submoduleName) . ');',
258  'icon' => $submoduleIcon,
259  'link' => $submoduleLink,
260  'originalLink' => $originalLink,
261  'description' => $submoduleDescription,
262  'navigationFrameScript' => $navigationFrameScript,
263  'navigationFrameScriptParam' => $submoduleData['navFrameScriptParam'],
264  'navigationComponentId' => $submoduleData['navigationComponentId']
265  );
266  // if the main module has a navframe script, inherit to the submodule,
267  // but only if it is not disabled explicitly (option is set to FALSE)
268  if ($moduleData['navFrameScript'] && $submoduleData['inheritNavigationComponentFromMainModule'] !== false) {
269  $modules[$moduleKey]['subitems'][$submoduleKey]['parentNavigationFrameScript'] = $moduleData['navFrameScript'];
270  }
271  }
272  }
273  }
274  return $modules;
275  }
276 
283  protected function getModuleIcon($moduleKey)
284  {
285  $icon = array(
286  'filename' => '',
287  'size' => '',
288  'title' => '',
289  'html' => ''
290  );
291 
292  if (!empty($GLOBALS['LANG']->moduleLabels['tabs_images'][$moduleKey])) {
293  $imageReference = $GLOBALS['LANG']->moduleLabels['tabs_images'][$moduleKey];
294  $iconFileRelative = $this->getModuleIconRelative($imageReference);
295  if (!empty($iconFileRelative)) {
296  $iconTitle = $GLOBALS['LANG']->moduleLabels['tabs'][$moduleKey];
297  $iconFileAbsolute = $this->getModuleIconAbsolute($imageReference);
298  $iconSizes = @getimagesize($iconFileAbsolute);
299  $icon['filename'] = $iconFileRelative;
300  $icon['size'] = $iconSizes[3];
301  $icon['title'] = htmlspecialchars($iconTitle);
302  $icon['html'] = '<img src="' . $iconFileRelative . '" ' . $iconSizes[3] . ' title="' . htmlspecialchars($iconTitle) . '" alt="' . htmlspecialchars($iconTitle) . '" />';
303  }
304  }
305  return $icon;
306  }
307 
317  protected function getModuleIconAbsolute($iconFilename)
318  {
319  if (!GeneralUtility::isAbsPath($iconFilename)) {
320  $iconFilename = $this->backPath . $iconFilename;
321  }
322  return $iconFilename;
323  }
324 
332  protected function getModuleIconRelative($iconFilename)
333  {
334  if (GeneralUtility::isAbsPath($iconFilename)) {
335  $iconFilename = '../' . \TYPO3\CMS\Core\Utility\PathUtility::stripPathSitePrefix($iconFilename);
336  }
337  return $this->backPath . $iconFilename;
338  }
339 
346  protected function appendQuestionmarkToLink($link)
347  {
348  if (!strstr($link, '?')) {
349  $link .= '?';
350  }
351  return $link;
352  }
353 
359  public function renderLogoutButton()
360  {
361  $buttonLabel = $GLOBALS['BE_USER']->user['ses_backuserid'] ? 'LLL:EXT:lang/locallang_core.xlf:buttons.exit' : 'LLL:EXT:lang/locallang_core.xlf:buttons.logout';
362  $buttonForm = '
363  <form action="' . htmlspecialchars(BackendUtility::getModuleUrl('logout')) . '" target="_top">
364  <input class="btn btn-default" type="submit" id="logout-submit-button" value="' . $GLOBALS['LANG']->sL($buttonLabel, true) . '" />
365  </form>';
366  return $buttonForm;
367  }
368 
376  public function setLinkModules($linkModules)
377  {
378  if (!is_bool($linkModules)) {
379  throw new \InvalidArgumentException('parameter $linkModules must be of type bool', 1193326558);
380  }
381  $this->linkModules = $linkModules;
382  }
383 }