[TASK] Reduce concatenation CGL violations in /typo3/classes/
[Packages/TYPO3.CMS.git] / typo3 / classes / class.modulemenu.php
1 <?php
2 /***************************************************************
3 * Copyright notice
4 *
5 * (c) 2007-2011 Ingo Renner <ingo@typo3.org>
6 * All rights reserved
7 *
8 * This script is part of the TYPO3 project. The TYPO3 project is
9 * free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * The GNU General Public License can be found at
15 * http://www.gnu.org/copyleft/gpl.html.
16 * A copy is found in the textfile GPL.txt and important notices to the license
17 * from the author is found in LICENSE.txt distributed with these scripts.
18 *
19 *
20 * This script is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
24 *
25 * This copyright notice MUST APPEAR in all copies of the script!
26 ***************************************************************/
27
28 if (TYPO3_REQUESTTYPE & TYPO3_REQUESTTYPE_AJAX) {
29 $GLOBALS['LANG']->includeLLFile('EXT:lang/locallang_misc.xml');
30 }
31
32 /**
33 * class to render the TYPO3 backend menu for the modules
34 *
35 * @author Ingo Renner <ingo@typo3.org>
36 * @package TYPO3
37 * @subpackage core
38 */
39 class ModuleMenu {
40
41 /**
42 * Module loading object
43 *
44 * @var t3lib_loadModules
45 */
46 protected $moduleLoader;
47
48 protected $backPath;
49 protected $linkModules;
50 protected $loadedModules;
51
52 /**
53 * Constructor, initializes several variables
54 */
55 public function __construct() {
56
57 $this->backPath = '';
58 $this->linkModules = TRUE;
59
60 // Loads the backend modules available for the logged in user.
61 $this->moduleLoader = t3lib_div::makeInstance('t3lib_loadModules');
62 $this->moduleLoader->observeWorkspaces = TRUE;
63 $this->moduleLoader->load($GLOBALS['TBE_MODULES']);
64 $this->loadedModules = $this->moduleLoader->modules;
65 }
66
67 /**
68 * sets the path back to /typo3/
69 *
70 * @param string $backPath Path back to /typo3/
71 * @throws InvalidArgumentException
72 * @return void
73 */
74 public function setBackPath($backPath) {
75 if (!is_string($backPath)) {
76 throw new InvalidArgumentException('parameter $backPath must be of type string', 1193315266);
77 }
78
79 $this->backPath = $backPath;
80 }
81
82 /**
83 * loads the collapse states for the main modules from user's configuration (uc)
84 *
85 * @return array Collapse states
86 */
87 protected function getCollapsedStates() {
88
89 $collapsedStates = array();
90 if ($GLOBALS['BE_USER']->uc['moduleData']['moduleMenu']) {
91 $collapsedStates = $GLOBALS['BE_USER']->uc['moduleData']['moduleMenu'];
92 }
93
94 return $collapsedStates;
95 }
96
97 /**
98 * ModuleMenu Store loading data
99 *
100 * @param array $params
101 * @param TYPO3AJAX $ajaxObj
102 * @return array
103 */
104 public function getModuleData($params, $ajaxObj) {
105 $data = array('success' => TRUE, 'root' => array());
106 $rawModuleData = $this->getRawModuleData();
107 $index = 0;
108 foreach ($rawModuleData as $moduleKey => $moduleData) {
109 $key = substr($moduleKey, 8);
110 $num = count($data['root']);
111 if ($moduleData['link'] != 'dummy.php' || ($moduleData['link'] == 'dummy.php' && 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
117 if ($moduleData['link'] && $this->linkModules) {
118 $data['root'][$num]['link'] = 'top.goToModule(\'' . $moduleData['name'] . '\')';
119 }
120
121 // Traverse submodules
122 if (is_array($moduleData['subitems'])) {
123 foreach($moduleData['subitems'] as $subKey => $subData) {
124 $data['root'][$num]['sub'][] = array(
125 'name' => $subData['name'],
126 'description' => $subData['description'],
127 'label' => $subData['title'],
128 'icon' => $subData['icon']['filename'],
129 'navframe' => $subData['parentNavigationFrameScript'],
130 'link' => $subData['link'],
131 'originalLink' => $subData['originalLink'],
132 'index' => $index++,
133 'navigationFrameScript' => $subData['navigationFrameScript'],
134 'navigationFrameScriptParam' => $subData['navigationFrameScriptParam'],
135 'navigationComponentId' => $subData['navigationComponentId'],
136 );
137 }
138 }
139 }
140 }
141 if ($ajaxObj) {
142 $ajaxObj->setContent($data);
143 $ajaxObj->setContentFormat('jsonbody');
144 } else {
145 return $data;
146 }
147 }
148
149 /**
150 * Returns the loaded modules
151 *
152 * @return array Array of loaded modules
153 */
154 public function getLoadedModules() {
155 return $this->loadedModules;
156 }
157
158 /**
159 * saves the menu's toggle state in the backend user's uc
160 *
161 * @param array $params Array of parameters from the AJAX interface, currently unused
162 * @param TYPO3AJAX $ajaxObj Object of type TYPO3AJAX
163 * @return void
164 */
165 public function saveMenuState($params, $ajaxObj) {
166 $menuItem = t3lib_div::_POST('menuid');
167 $state = t3lib_div::_POST('state') === 'true' ? 1 : 0;
168
169 $GLOBALS['BE_USER']->uc['moduleData']['menuState'][$menuItem] = $state;
170 $GLOBALS['BE_USER']->writeUC();
171 }
172
173 /**
174 * gets the raw module data
175 *
176 * @return array Multi dimension array with module data
177 */
178 public function getRawModuleData() {
179 $modules = array();
180
181 // Remove the 'doc' module?
182 if ($GLOBALS['BE_USER']->getTSConfigVal('options.disableDocModuleInAB')) {
183 unset($this->loadedModules['doc']);
184 }
185
186 foreach ($this->loadedModules as $moduleName => $moduleData) {
187 $moduleLink = '';
188 if (!is_array($moduleData['sub'])) {
189 $moduleLink = $moduleData['script'];
190 }
191 $moduleLink = t3lib_div::resolveBackPath($moduleLink);
192
193 $moduleKey = 'modmenu_' . $moduleName;
194 $moduleIcon = $this->getModuleIcon($moduleKey);
195
196 $modules[$moduleKey] = array(
197 'name' => $moduleName,
198 'title' => $GLOBALS['LANG']->moduleLabels['tabs'][$moduleName . '_tab'],
199 'onclick' => 'top.goToModule(\'' . $moduleName . '\');',
200 'icon' => $moduleIcon,
201 'link' => $moduleLink,
202 'description' => $GLOBALS['LANG']->moduleLabels['labels'][$moduleKey.'label']
203 );
204
205 if (!is_array($moduleData['sub']) && $moduleData['script'] != 'dummy.php') {
206 // Work around for modules with own main entry, but being self the only submodule
207 $modules[$moduleKey]['subitems'][$moduleKey] = array(
208 'name' => $moduleName,
209 'title' => $GLOBALS['LANG']->moduleLabels['tabs'][$moduleName . '_tab'],
210 'onclick' => 'top.goToModule(\'' . $moduleName . '\');',
211 'icon' => $this->getModuleIcon($moduleName . '_tab'),
212 'link' => $moduleLink,
213 'originalLink' => $moduleLink,
214 'description' => $GLOBALS['LANG']->moduleLabels['labels'][$moduleKey . 'label'],
215 'navigationFrameScript' => NULL,
216 'navigationFrameScriptParam' => NULL,
217 'navigationComponentId' => NULL,
218 );
219 } elseif (is_array($moduleData['sub'])) {
220 foreach($moduleData['sub'] as $submoduleName => $submoduleData) {
221 $submoduleLink = t3lib_div::resolveBackPath($submoduleData['script']);
222
223 $submoduleKey = $moduleName . '_' . $submoduleName . '_tab';
224 $submoduleIcon = $this->getModuleIcon($submoduleKey);
225 $submoduleDescription = $GLOBALS['LANG']->moduleLabels['labels'][$submoduleKey . 'label'];
226
227 $originalLink = $submoduleLink;
228
229 $modules[$moduleKey]['subitems'][$submoduleKey] = array(
230 'name' => $moduleName . '_' . $submoduleName,
231 'title' => $GLOBALS['LANG']->moduleLabels['tabs'][$submoduleKey],
232 'onclick' => 'top.goToModule(\'' . $moduleName . '_' . $submoduleName . '\');',
233 'icon' => $submoduleIcon,
234 'link' => $submoduleLink,
235 'originalLink' => $originalLink,
236 'description' => $submoduleDescription,
237 'navigationFrameScript' => $submoduleData['navFrameScript'],
238 'navigationFrameScriptParam' => $submoduleData['navFrameScriptParam'],
239 'navigationComponentId' => $submoduleData['navigationComponentId'],
240 );
241
242 if ($moduleData['navFrameScript']) {
243 $modules[$moduleKey]['subitems'][$submoduleKey]['parentNavigationFrameScript'] = $moduleData['navFrameScript'];
244 }
245 }
246 }
247 }
248
249 return $modules;
250 }
251
252 /**
253 * gets the module icon and its size
254 *
255 * @param string $moduleKey Module key
256 * @return array Icon data array with 'filename', 'size', and 'html'
257 */
258 protected function getModuleIcon($moduleKey) {
259 $icon = array(
260 'filename' => '',
261 'size' => '',
262 'title' => '',
263 'html' => ''
264 );
265
266 $iconFileRelative = $this->getModuleIconRelative($GLOBALS['LANG']->moduleLabels['tabs_images'][$moduleKey]);
267 $iconFileAbsolute = $this->getModuleIconAbsolute($GLOBALS['LANG']->moduleLabels['tabs_images'][$moduleKey]);
268 $iconSizes = @getimagesize($iconFileAbsolute);
269 $iconTitle = $GLOBALS['LANG']->moduleLabels['tabs'][$moduleKey];
270
271 if (!empty($iconFileRelative)) {
272 $icon['filename'] = $iconFileRelative;
273 $icon['size'] = $iconSizes[3];
274 $icon['title'] = htmlspecialchars($iconTitle);
275 $icon['html'] = '<img src="' . $iconFileRelative . '" ' . $iconSizes[3] .
276 ' title="' . htmlspecialchars($iconTitle) . '" alt="' . htmlspecialchars($iconTitle) . '" />';
277 }
278
279 return $icon;
280 }
281
282 /**
283 * Returns the filename readable for the script from PATH_typo3.
284 * That means absolute names are just returned while relative names are
285 * prepended with the path pointing back to typo3/ dir
286 *
287 * @param string $iconFilename Icon filename
288 * @return string Icon filename with absolute path
289 * @see getModuleIconRelative()
290 */
291 protected function getModuleIconAbsolute($iconFilename) {
292
293 if (!t3lib_div::isAbsPath($iconFilename)) {
294 $iconFilename = $this->backPath . $iconFilename;
295 }
296
297 return $iconFilename;
298 }
299
300 /**
301 * Returns relative path to the icon filename for use in img-tags
302 *
303 * @param string $iconFilename Icon filename
304 * @return string Icon filename with relative path
305 * @see getModuleIconAbsolute()
306 */
307 protected function getModuleIconRelative($iconFilename) {
308 if (t3lib_div::isAbsPath($iconFilename)) {
309 $iconFilename = '../' . substr($iconFilename, strlen(PATH_site));
310 }
311 return $this->backPath.$iconFilename;
312 }
313
314 /**
315 * Appends a '?' if there is none in the string already
316 *
317 * @param string $link Link URL
318 * @return string Link URl appended with ? if there wasn't one
319 */
320 protected function appendQuestionmarkToLink($link) {
321 if (!strstr($link, '?')) {
322 $link .= '?';
323 }
324
325 return $link;
326 }
327
328 /**
329 * renders the logout button form
330 *
331 * @return string Html code snippet displaying the logout button
332 */
333 public function renderLogoutButton() {
334 $buttonLabel = $GLOBALS['BE_USER']->user['ses_backuserid'] ? 'LLL:EXT:lang/locallang_core.php:buttons.exit' : 'LLL:EXT:lang/locallang_core.php:buttons.logout';
335
336 $buttonForm = '
337 <form action="logout.php" target="_top">
338 <input type="submit" value="&nbsp;' . $GLOBALS['LANG']->sL($buttonLabel, 1) . '&nbsp;" />
339 </form>';
340
341 return $buttonForm;
342 }
343
344 /**
345 * turns linking of modules on or off
346 *
347 * @param boolean $linkModules Status for linking modules with a-tags, set to FALSE to turn lining off
348 * @throws InvalidArgumentException
349 * @return void
350 */
351 public function setLinkModules($linkModules) {
352 if (!is_bool($linkModules)) {
353 throw new InvalidArgumentException('parameter $linkModules must be of type bool', 1193326558);
354 }
355
356 $this->linkModules = $linkModules;
357 }
358
359 }
360 ?>