[TASK] Make file_edit.php dispatched
[Packages/TYPO3.CMS.git] / typo3 / sysext / backend / Classes / Toolbar / ShortcutToolbarItem.php
1 <?php
2 namespace TYPO3\CMS\Backend\Toolbar;
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
17 use TYPO3\CMS\Backend\Utility\BackendUtility;
18 use TYPO3\CMS\Backend\Utility\IconUtility;
19 use TYPO3\CMS\Core\Utility\GeneralUtility;
20 use TYPO3\CMS\Core\Utility\MathUtility;
21
22 /**
23 * Class to render the shortcut menu
24 *
25 * @author Ingo Renner <ingo@typo3.org>
26 */
27 class ShortcutToolbarItem implements \TYPO3\CMS\Backend\Toolbar\ToolbarItemHookInterface {
28
29 const SUPERGLOBAL_GROUP = -100;
30
31 /**
32 * @var string
33 * @todo define visibility
34 */
35 public $perms_clause;
36
37 /**
38 * @var string
39 * @todo define visibility
40 */
41 public $backPath;
42
43 /**
44 * @var array
45 * @todo define visibility
46 */
47 public $fieldArray;
48
49 /**
50 * All available shortcuts
51 *
52 * @var array
53 */
54 protected $shortcuts;
55
56 /**
57 * @var array
58 */
59 protected $shortcutGroups;
60
61 /**
62 * Labels of all groups.
63 * If value is 1, the system will try to find a label in the locallang array.
64 *
65 * @var array
66 */
67 protected $groupLabels;
68
69 /**
70 * Reference back to the backend object
71 *
72 * @var \TYPO3\CMS\Backend\Controller\BackendController
73 */
74 protected $backendReference;
75
76 /**
77 * Constructor
78 *
79 * @param \TYPO3\CMS\Backend\Controller\BackendController $backendReference TYPO3 backend object reference
80 */
81 public function __construct(\TYPO3\CMS\Backend\Controller\BackendController &$backendReference = NULL) {
82 if (TYPO3_REQUESTTYPE & TYPO3_REQUESTTYPE_AJAX) {
83 $GLOBALS['LANG']->includeLLFile('EXT:lang/locallang_misc.xlf');
84 // Needed to get the correct icons when reloading the menu after saving it
85 $loadModules = GeneralUtility::makeInstance('TYPO3\\CMS\\Backend\\Module\\ModuleLoader');
86 $loadModules->load($GLOBALS['TBE_MODULES']);
87 }
88 $this->backendReference = $backendReference;
89 $this->shortcuts = array();
90 // By default, 5 groups are set
91 $this->shortcutGroups = array(
92 1 => '1',
93 2 => '1',
94 3 => '1',
95 4 => '1',
96 5 => '1'
97 );
98 $this->shortcutGroups = $this->initShortcutGroups();
99 $this->shortcuts = $this->initShortcuts();
100 }
101
102 /**
103 * Checks whether the user has access to this toolbar item
104 *
105 * @return boolean TRUE if user has access, FALSE if not
106 */
107 public function checkAccess() {
108 return (bool) $GLOBALS['BE_USER']->getTSConfigVal('options.enableBookmarks');
109 }
110
111 /**
112 * Creates the shortcut menu (default renderer)
113 *
114 * @return string Workspace selector as HTML select
115 */
116 public function render() {
117 $title = $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.xlf:toolbarItems.bookmarks', TRUE);
118 $this->addJavascriptToBackend();
119 $shortcutMenu = array();
120 $shortcutMenu[] = '<a href="#" class="toolbar-item">' . IconUtility::getSpriteIcon('apps-toolbar-menu-shortcut', array('title' => $title)) . '</a>';
121 $shortcutMenu[] = '<div class="toolbar-item-menu" style="display: none;">';
122 $shortcutMenu[] = $this->renderMenu();
123 $shortcutMenu[] = '</div>';
124 return implode(LF, $shortcutMenu);
125 }
126
127 /**
128 * Renders the pure contents of the menu
129 *
130 * @return string The menu's content
131 */
132 public function renderMenu() {
133 $shortcutGroup = $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.xlf:toolbarItems.bookmarksGroup', TRUE);
134 $shortcutEdit = $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.xlf:toolbarItems.bookmarksEdit', TRUE);
135 $shortcutDelete = $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.xlf:toolbarItems.bookmarksDelete', TRUE);
136 $groupIcon = '<img' . IconUtility::skinImg($this->backPath, 'gfx/i/sysf.gif', 'width="18" height="16"') . ' title="' . $shortcutGroup . '" alt="' . $shortcutGroup . '" />';
137 $editIcon = '<img' . IconUtility::skinImg($this->backPath, 'gfx/edit2.gif', 'width="11" height="12"') . ' title="' . $shortcutEdit . '" alt="' . $shortcutEdit . '"';
138 $deleteIcon = '<img' . IconUtility::skinImg($this->backPath, 'gfx/garbage.gif', 'width="11" height="12"') . ' title="' . $shortcutDelete . '" alt="' . $shortcutDelete . '" />';
139 $shortcutMenu[] = '<table border="0" cellspacing="0" cellpadding="0" class="shortcut-list">';
140 // Render shortcuts with no group (group id = 0) first
141 $noGroupShortcuts = $this->getShortcutsByGroup(0);
142 foreach ($noGroupShortcuts as $shortcut) {
143 $shortcutMenu[] = '
144 <tr id="shortcut-' . $shortcut['raw']['uid'] . '" class="shortcut">
145 <td class="shortcut-icon">' . $shortcut['icon'] . '</td>
146 <td class="shortcut-label">
147 <a id="shortcut-label-' . $shortcut['raw']['uid'] . '" href="#" onclick="' . $shortcut['action'] . '; return false;">' . htmlspecialchars($shortcut['label']) . '</a>
148 </td>
149 <td class="shortcut-edit">' . $editIcon . ' id="shortcut-edit-' . $shortcut['raw']['uid'] . '" /></td>
150 <td class="shortcut-delete">' . $deleteIcon . '</td>
151 </tr>';
152 }
153 // Now render groups and the contained shortcuts
154 $groups = $this->getGroupsFromShortcuts();
155 krsort($groups, SORT_NUMERIC);
156 foreach ($groups as $groupId => $groupLabel) {
157 if ($groupId != 0) {
158 $shortcutGroup = '
159 <tr class="shortcut-group" id="shortcut-group-' . $groupId . '">
160 <td class="shortcut-group-icon">' . $groupIcon . '</td>
161 <td class="shortcut-group-label">' . $groupLabel . '</td>
162 <td colspan="2">&nbsp;</td>
163 </tr>';
164 $shortcuts = $this->getShortcutsByGroup($groupId);
165 $i = 0;
166 foreach ($shortcuts as $shortcut) {
167 $i++;
168 $firstRow = '';
169 if ($i == 1) {
170 $firstRow = ' first-row';
171 }
172 $shortcutGroup .= '
173 <tr id="shortcut-' . $shortcut['raw']['uid'] . '" class="shortcut' . $firstRow . '">
174 <td class="shortcut-icon">' . $shortcut['icon'] . '</td>
175 <td class="shortcut-label">
176 <a id="shortcut-label-' . $shortcut['raw']['uid'] . '" href="#" onclick="' . $shortcut['action'] . '; return false;">' . htmlspecialchars($shortcut['label']) . '</a>
177 </td>
178 <td class="shortcut-edit">' . $editIcon . ' id="shortcut-edit-' . $shortcut['raw']['uid'] . '" /></td>
179 <td class="shortcut-delete">' . $deleteIcon . '</td>
180 </tr>';
181 }
182 $shortcutMenu[] = $shortcutGroup;
183 }
184 }
185 if (count($shortcutMenu) == 1) {
186 // No shortcuts added yet, show a small help message how to add shortcuts
187 $title = $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.xlf:toolbarItems.bookmarks', TRUE);
188 $icon = IconUtility::getSpriteIcon('actions-system-shortcut-new', array(
189 'title' => $title
190 ));
191 $label = str_replace('%icon%', $icon, $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_misc.xlf:bookmarkDescription'));
192 $shortcutMenu[] = '<tr><td style="padding:1px 2px; color: #838383;">' . $label . '</td></tr>';
193 }
194 $shortcutMenu[] = '</table>';
195 $compiledShortcutMenu = implode(LF, $shortcutMenu);
196 return $compiledShortcutMenu;
197 }
198
199 /**
200 * Renders the menu so that it can be returned as response to an AJAX call
201 *
202 * @param array $params Array of parameters from the AJAX interface, currently unused
203 * @param \TYPO3\CMS\Core\Http\AjaxRequestHandler $ajaxObj Object of type AjaxRequestHandler
204 * @return void
205 */
206 public function renderAjax($params = array(), \TYPO3\CMS\Core\Http\AjaxRequestHandler &$ajaxObj = NULL) {
207 $menuContent = $this->renderMenu();
208 $ajaxObj->addContent('shortcutMenu', $menuContent);
209 }
210
211 /**
212 * Adds the necessary JavaScript to the backend
213 *
214 * @return void
215 */
216 protected function addJavascriptToBackend() {
217 $this->backendReference->addJavascriptFile('sysext/backend/Resources/Public/JavaScript/shortcutmenu.js');
218 }
219
220 /**
221 * Returns additional attributes for the list item in the toolbar
222 *
223 * @return string List item HTML attibutes
224 */
225 public function getAdditionalAttributes() {
226 return 'id="shortcut-menu"';
227 }
228
229 /**
230 * Retrieves the shortcuts for the current user
231 *
232 * @return array Array of shortcuts
233 */
234 protected function initShortcuts() {
235 $globalGroupIdList = implode(',', array_keys($this->getGlobalShortcutGroups()));
236 $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery(
237 '*',
238 'sys_be_shortcuts',
239 '(userid = ' . (int)$GLOBALS['BE_USER']->user['uid'] . ' AND sc_group>=0) OR sc_group IN (' . $globalGroupIdList . ')',
240 '',
241 'sc_group,sorting'
242 );
243 // Traverse shortcuts
244 $lastGroup = 0;
245 $shortcuts = array();
246 while ($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res)) {
247 $shortcut = array('raw' => $row);
248
249 list($row['module_name'], $row['M_module_name']) = explode('|', $row['module_name']);
250
251 $queryParts = parse_url($row['url']);
252 $queryParameters = GeneralUtility::explodeUrl2Array($queryParts['query'], 1);
253 if ($row['module_name'] === 'xMOD_alt_doc.php' && is_array($queryParameters['edit'])) {
254 $shortcut['table'] = key($queryParameters['edit']);
255 $shortcut['recordid'] = key($queryParameters['edit'][$shortcut['table']]);
256 if ($queryParameters['edit'][$shortcut['table']][$shortcut['recordid']] === 'edit') {
257 $shortcut['type'] = 'edit';
258 } elseif ($queryParameters['edit'][$shortcut['table']][$shortcut['recordid']] === 'new') {
259 $shortcut['type'] = 'new';
260 }
261 if (substr($shortcut['recordid'], -1) === ',') {
262 $shortcut['recordid'] = substr($shortcut['recordid'], 0, -1);
263 }
264 } else {
265 $shortcut['type'] = 'other';
266 }
267 // Check for module access
268 $moduleName = $row['M_module_name'] ?: $row['module_name'];
269 $pageId = $this->getLinkedPageId($row['url']);
270 if (!$GLOBALS['BE_USER']->isAdmin()) {
271 if (!isset($GLOBALS['LANG']->moduleLabels['tabs_images'][$moduleName . '_tab'])) {
272 // Nice hack to check if the user has access to this module
273 // - otherwise the translation label would not have been loaded :-)
274 continue;
275 }
276 if (MathUtility::canBeInterpretedAsInteger($pageId)) {
277 // Check for webmount access
278 if (!$GLOBALS['BE_USER']->isInWebMount($pageId)) {
279 continue;
280 }
281 // Check for record access
282 $pageRow = BackendUtility::getRecord('pages', $pageId);
283 if (!$GLOBALS['BE_USER']->doesUserHaveAccess($pageRow, ($perms = 1))) {
284 continue;
285 }
286 }
287 }
288 $moduleParts = explode('_', $moduleName);
289 $shortcutGroup = (int)$row['sc_group'];
290 if ($shortcutGroup && $lastGroup !== $shortcutGroup && $shortcutGroup !== self::SUPERGLOBAL_GROUP) {
291 $shortcut['groupLabel'] = $this->getShortcutGroupLabel($shortcutGroup);
292 }
293 $lastGroup = $shortcutGroup;
294
295 if ($row['description']) {
296 $shortcut['label'] = $row['description'];
297 } else {
298 $shortcut['label'] = GeneralUtility::fixed_lgd_cs(rawurldecode($queryParts['query']), 150);
299 }
300 $shortcut['group'] = $shortcutGroup;
301 $shortcut['icon'] = $this->getShortcutIcon($row, $shortcut);
302 $shortcut['iconTitle'] = $this->getShortcutIconTitle($shortcut['label'], $row['module_name'], $row['M_module_name']);
303 $shortcut['action'] = 'jump(unescape(\'' . rawurlencode($this->getTokenUrl($row['url'])) . '\'),\'' . $moduleName . '\',\'' . $moduleParts[0] . '\', ' . (int)$pageId . ');';
304
305 $shortcuts[] = $shortcut;
306 }
307 return $shortcuts;
308 }
309
310 /**
311 * Adds the correct token, if the url is a mod.php script
312 *
313 * @param string $url
314 * @return string
315 */
316 protected function getTokenUrl($url) {
317 $parsedUrl = parse_url($url);
318 parse_str($parsedUrl['query'], $parameters);
319
320 // parse the returnUrl and replace the module token of it
321 if (isset($parameters['returnUrl'])) {
322 $parsedReturnUrl = parse_url($parameters['returnUrl']);
323 parse_str($parsedReturnUrl['query'], $returnUrlParameters);
324 if (strpos($parsedReturnUrl['path'], 'mod.php') !== FALSE && isset($returnUrlParameters['M'])) {
325 $module = $returnUrlParameters['M'];
326 $returnUrl = BackendUtility::getModuleUrl($module, $returnUrlParameters);
327 $parameters['returnUrl'] = $returnUrl;
328 $url = $parsedUrl['path'] . '?' . http_build_query($parameters);
329 }
330 }
331
332 if (strpos($parsedUrl['path'], 'mod.php') !== FALSE && isset($parameters['M'])) {
333 $module = $parameters['M'];
334 $url = str_replace('mod.php', '', $parsedUrl['path']) . BackendUtility::getModuleUrl($module, $parameters);
335 }
336 return $url;
337 }
338
339 /**
340 * Gets shortcuts for a specific group
341 *
342 * @param integer $groupId Group Id
343 * @return array Array of shortcuts that matched the group
344 */
345 protected function getShortcutsByGroup($groupId) {
346 $shortcuts = array();
347 foreach ($this->shortcuts as $shortcut) {
348 if ($shortcut['group'] == $groupId) {
349 $shortcuts[] = $shortcut;
350 }
351 }
352 return $shortcuts;
353 }
354
355 /**
356 * Gets a shortcut by its uid
357 *
358 * @param integer $shortcutId Shortcut id to get the complete shortcut for
359 * @return mixed An array containing the shortcut's data on success or FALSE on failure
360 */
361 protected function getShortcutById($shortcutId) {
362 $returnShortcut = FALSE;
363 foreach ($this->shortcuts as $shortcut) {
364 if ($shortcut['raw']['uid'] == (int)$shortcutId) {
365 $returnShortcut = $shortcut;
366 continue;
367 }
368 }
369 return $returnShortcut;
370 }
371
372 /**
373 * Gets the available shortcut groups from default groups, user TSConfig, and global groups
374 *
375 * @return array
376 */
377 protected function initShortcutGroups() {
378 // Groups from TSConfig
379 $bookmarkGroups = $GLOBALS['BE_USER']->getTSConfigProp('options.bookmarkGroups');
380 if (is_array($bookmarkGroups) && count($bookmarkGroups)) {
381 foreach ($bookmarkGroups as $groupId => $label) {
382 if (!empty($label)) {
383 $this->shortcutGroups[$groupId] = (string)$label;
384 } elseif ($GLOBALS['BE_USER']->isAdmin()) {
385 unset($this->shortcutGroups[$groupId]);
386 }
387 }
388 }
389 // Generate global groups, all global groups have negative IDs.
390 if (count($this->shortcutGroups)) {
391 $groups = $this->shortcutGroups;
392 foreach ($groups as $groupId => $groupLabel) {
393 $this->shortcutGroups[$groupId * -1] = $groupLabel;
394 }
395 }
396 // Group -100 is kind of superglobal and can't be changed.
397 $this->shortcutGroups[self::SUPERGLOBAL_GROUP] = 1;
398 // Add labels
399 foreach ($this->shortcutGroups as $groupId => $groupLabel) {
400 $groupId = (int)$groupId;
401 $label = $groupLabel;
402 if ($groupLabel == '1') {
403 $label = $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_misc.xlf:bookmark_group_' . abs($groupId), TRUE);
404 if (empty($label)) {
405 // Fallback label
406 $label = $GLOBALS['LANG']->getLL('bookmark_group', 1) . ' ' . abs($groupId);
407 }
408 }
409 if ($groupId < 0) {
410 // Global group
411 $label = $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_misc.xlf:bookmark_global', TRUE) . ': ' . (!empty($label) ? $label : abs($groupId));
412 if ($groupId === self::SUPERGLOBAL_GROUP) {
413 $label = $GLOBALS['LANG']->getLL('bookmark_global', 1) . ': ' . $GLOBALS['LANG']->getLL('bookmark_all', 1);
414 }
415 }
416 $this->shortcutGroups[$groupId] = $label;
417 }
418 return $this->shortcutGroups;
419 }
420
421 /**
422 * gets the available shortcut groups
423 *
424 * @param array $params Array of parameters from the AJAX interface, currently unused
425 * @param \TYPO3\CMS\Core\Http\AjaxRequestHandler $ajaxObj Object of type AjaxRequestHandler
426 * @return void
427 */
428 public function getAjaxShortcutGroups($params = array(), \TYPO3\CMS\Core\Http\AjaxRequestHandler &$ajaxObj = NULL) {
429 $shortcutGroups = $this->shortcutGroups;
430 if (!$GLOBALS['BE_USER']->isAdmin()) {
431 foreach ($shortcutGroups as $groupId => $groupName) {
432 if ((int)$groupId < 0) {
433 unset($shortcutGroups[$groupId]);
434 }
435 }
436 }
437 $ajaxObj->addContent('shortcutGroups', $shortcutGroups);
438 $ajaxObj->setContentFormat('json');
439 }
440
441 /**
442 * Deletes a shortcut through an AJAX call
443 *
444 * @param array $params Array of parameters from the AJAX interface, currently unused
445 * @param \TYPO3\CMS\Core\Http\AjaxRequestHandler $ajaxObj Object of type AjaxRequestHandler
446 * @return void
447 */
448 public function deleteAjaxShortcut($params = array(), \TYPO3\CMS\Core\Http\AjaxRequestHandler &$ajaxObj = NULL) {
449 $shortcutId = (int)GeneralUtility::_POST('shortcutId');
450 $fullShortcut = $this->getShortcutById($shortcutId);
451 $ajaxReturn = 'failed';
452 if ($fullShortcut['raw']['userid'] == $GLOBALS['BE_USER']->user['uid']) {
453 $GLOBALS['TYPO3_DB']->exec_DELETEquery('sys_be_shortcuts', 'uid = ' . $shortcutId);
454 if ($GLOBALS['TYPO3_DB']->sql_affected_rows() == 1) {
455 $ajaxReturn = 'deleted';
456 }
457 }
458 $ajaxObj->addContent('delete', $ajaxReturn);
459 }
460
461 /**
462 * Creates a shortcut through an AJAX call
463 *
464 * @param array $params Array of parameters from the AJAX interface, currently unused
465 * @param \TYPO3\CMS\Core\Http\AjaxRequestHandler $ajaxObj Oject of type AjaxRequestHandler
466 * @return void
467 */
468 public function createAjaxShortcut($params = array(), \TYPO3\CMS\Core\Http\AjaxRequestHandler &$ajaxObj = NULL) {
469 $shortcutCreated = 'failed';
470 // Default name
471 $shortcutName = 'Shortcut';
472 $shortcutNamePrepend = '';
473 $url = GeneralUtility::_POST('url');
474 $module = GeneralUtility::_POST('module');
475 $motherModule = GeneralUtility::_POST('motherModName');
476 // Determine shortcut type
477 $queryParts = parse_url($url);
478 $queryParameters = GeneralUtility::explodeUrl2Array($queryParts['query'], 1);
479 // Proceed only if no scheme is defined, as URL is expected to be relative
480 if (empty($queryParts['scheme'])) {
481 if (is_array($queryParameters['edit'])) {
482 $shortcut['table'] = key($queryParameters['edit']);
483 $shortcut['recordid'] = key($queryParameters['edit'][$shortcut['table']]);
484 if ($queryParameters['edit'][$shortcut['table']][$shortcut['recordid']] == 'edit') {
485 $shortcut['type'] = 'edit';
486 $shortcutNamePrepend = $GLOBALS['LANG']->getLL('shortcut_edit', 1);
487 } elseif ($queryParameters['edit'][$shortcut['table']][$shortcut['recordid']] == 'new') {
488 $shortcut['type'] = 'new';
489 $shortcutNamePrepend = $GLOBALS['LANG']->getLL('shortcut_create', 1);
490 }
491 } else {
492 $shortcut['type'] = 'other';
493 }
494 // Lookup the title of this page and use it as default description
495 $pageId = $shortcut['recordid'] ? $shortcut['recordid'] : $this->getLinkedPageId($url);
496 if (MathUtility::canBeInterpretedAsInteger($pageId)) {
497 $page = BackendUtility::getRecord('pages', $pageId);
498 if (count($page)) {
499 // Set the name to the title of the page
500 if ($shortcut['type'] == 'other') {
501 $shortcutName = $page['title'];
502 } else {
503 $shortcutName = $shortcutNamePrepend . ' ' . $GLOBALS['LANG']->sL($GLOBALS['TCA'][$shortcut['table']]['ctrl']['title']) . ' (' . $page['title'] . ')';
504 }
505 }
506 } else {
507 $dirName = urldecode($pageId);
508 if (preg_match('/\\/$/', $dirName)) {
509 // If $pageId is a string and ends with a slash,
510 // assume it is a fileadmin reference and set
511 // the description to the basename of that path
512 $shortcutName .= ' ' . basename($dirName);
513 }
514 }
515 // adding the shortcut
516 if ($module && $url) {
517 $fieldValues = array(
518 'userid' => $GLOBALS['BE_USER']->user['uid'],
519 'module_name' => $module . '|' . $motherModule,
520 'url' => $url,
521 'description' => $shortcutName,
522 'sorting' => $GLOBALS['EXEC_TIME']
523 );
524 $GLOBALS['TYPO3_DB']->exec_INSERTquery('sys_be_shortcuts', $fieldValues);
525 if ($GLOBALS['TYPO3_DB']->sql_affected_rows() == 1) {
526 $shortcutCreated = 'success';
527 }
528 }
529 $ajaxObj->addContent('create', $shortcutCreated);
530 }
531 }
532
533 /**
534 * Gets called when a shortcut is changed, checks whether the user has
535 * permissions to do so and saves the changes if everything is ok
536 *
537 * @param array $params Array of parameters from the AJAX interface, currently unused
538 * @param \TYPO3\CMS\Core\Http\AjaxRequestHandler $ajaxObj Object of type AjaxRequestHandler
539 * @return void
540 */
541 public function setAjaxShortcut($params = array(), \TYPO3\CMS\Core\Http\AjaxRequestHandler &$ajaxObj = NULL) {
542 $shortcutId = (int)GeneralUtility::_POST('shortcutId');
543 $shortcutName = strip_tags(GeneralUtility::_POST('value'));
544 $shortcutGroupId = (int)GeneralUtility::_POST('shortcut-group');
545 if ($shortcutGroupId > 0 || $GLOBALS['BE_USER']->isAdmin()) {
546 // Users can delete only their own shortcuts (except admins)
547 $addUserWhere = !$GLOBALS['BE_USER']->isAdmin() ? ' AND userid=' . (int)$GLOBALS['BE_USER']->user['uid'] : '';
548 $fieldValues = array(
549 'description' => $shortcutName,
550 'sc_group' => $shortcutGroupId
551 );
552 if ($fieldValues['sc_group'] < 0 && !$GLOBALS['BE_USER']->isAdmin()) {
553 $fieldValues['sc_group'] = 0;
554 }
555 $GLOBALS['TYPO3_DB']->exec_UPDATEquery('sys_be_shortcuts', 'uid=' . $shortcutId . $addUserWhere, $fieldValues);
556 $affectedRows = $GLOBALS['TYPO3_DB']->sql_affected_rows();
557 if ($affectedRows == 1) {
558 $ajaxObj->addContent('shortcut', $shortcutName);
559 } else {
560 $ajaxObj->addContent('shortcut', 'failed');
561 }
562 }
563 $ajaxObj->setContentFormat('plain');
564 }
565
566 /**
567 * Gets the label for a shortcut group
568 *
569 * @param integer $groupId A shortcut group id
570 * @return string The shortcut group label, can be an empty string if no group was found for the id
571 */
572 protected function getShortcutGroupLabel($groupId) {
573 return isset($this->shortcutGroups[$groupId]) ? $this->shortcutGroups[$groupId] : '';
574 }
575
576 /**
577 * Gets a list of global groups, shortcuts in these groups are available to all users
578 *
579 * @return array Array of global groups
580 */
581 protected function getGlobalShortcutGroups() {
582 $globalGroups = array();
583 foreach ($this->shortcutGroups as $groupId => $groupLabel) {
584 if ($groupId < 0) {
585 $globalGroups[$groupId] = $groupLabel;
586 }
587 }
588 return $globalGroups;
589 }
590
591 /**
592 * runs through the available shortcuts an collects their groups
593 *
594 * @return array Array of groups which have shortcuts
595 */
596 protected function getGroupsFromShortcuts() {
597 $groups = array();
598 foreach ($this->shortcuts as $shortcut) {
599 $groups[$shortcut['group']] = $this->shortcutGroups[$shortcut['group']];
600 }
601 return array_unique($groups);
602 }
603
604 /**
605 * Gets the icon for the shortcut
606 *
607 * @param array $row
608 * @param array $shortcut
609 * @return string Shortcut icon as img tag
610 */
611 protected function getShortcutIcon($row, $shortcut) {
612 switch ($row['module_name']) {
613 case 'xMOD_alt_doc.php':
614 $table = $shortcut['table'];
615 $recordid = $shortcut['recordid'];
616 $icon = '';
617 if ($shortcut['type'] == 'edit') {
618 // Creating the list of fields to include in the SQL query:
619 $selectFields = $this->fieldArray;
620 $selectFields[] = 'uid';
621 $selectFields[] = 'pid';
622 if ($table == 'pages') {
623 $selectFields[] = 'module';
624 $selectFields[] = 'extendToSubpages';
625 $selectFields[] = 'doktype';
626 }
627 if (is_array($GLOBALS['TCA'][$table]['ctrl']['enablecolumns'])) {
628 $selectFields = array_merge($selectFields, $GLOBALS['TCA'][$table]['ctrl']['enablecolumns']);
629 }
630 if ($GLOBALS['TCA'][$table]['ctrl']['type']) {
631 $selectFields[] = $GLOBALS['TCA'][$table]['ctrl']['type'];
632 }
633 if ($GLOBALS['TCA'][$table]['ctrl']['typeicon_column']) {
634 $selectFields[] = $GLOBALS['TCA'][$table]['ctrl']['typeicon_column'];
635 }
636 if ($GLOBALS['TCA'][$table]['ctrl']['versioningWS']) {
637 $selectFields[] = 't3ver_state';
638 }
639 // Unique list!
640 $selectFields = array_unique($selectFields);
641 $permissionClause = $table === 'pages' && $this->perms_clause ? ' AND ' . $this->perms_clause : '';
642 $sqlQueryParts = array(
643 'SELECT' => implode(',', $selectFields),
644 'FROM' => $table,
645 'WHERE' => 'uid IN (' . $recordid . ') ' . $permissionClause . BackendUtility::deleteClause($table) . BackendUtility::versioningPlaceholderClause($table)
646 );
647 $result = $GLOBALS['TYPO3_DB']->exec_SELECT_queryArray($sqlQueryParts);
648 $row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($result);
649 $icon = IconUtility::getIcon($table, $row, $this->backPath);
650 } elseif ($shortcut['type'] == 'new') {
651 $icon = IconUtility::getIcon($table, array(), $this->backPath);
652 }
653 $icon = IconUtility::skinImg($this->backPath, $icon, '', 1);
654 break;
655 case 'file_edit':
656 $icon = 'gfx/edit_file.gif';
657 break;
658 case 'wizard_rte':
659 $icon = 'gfx/edit_rtewiz.gif';
660 break;
661 default:
662 if ($GLOBALS['LANG']->moduleLabels['tabs_images'][$row['module_name'] . '_tab']) {
663 $icon = $GLOBALS['LANG']->moduleLabels['tabs_images'][$row['module_name'] . '_tab'];
664 // Change icon of fileadmin references - otherwise it doesn't differ with Web->List
665 $icon = str_replace('mod/file/list/list.gif', 'mod/file/file.gif', $icon);
666 if (GeneralUtility::isAbsPath($icon)) {
667 $icon = '../' . \TYPO3\CMS\Core\Utility\PathUtility::stripPathSitePrefix($icon);
668 }
669 } else {
670 $icon = 'gfx/dummy_module.gif';
671 }
672 }
673 return '<img src="' . $icon . '" alt="' . $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.xlf:toolbarItems.shortcut', TRUE) . '" title="' . $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.xlf:toolbarItems.shortcut', TRUE) . '" />';
674 }
675
676 /**
677 * Returns title for the shortcut icon
678 *
679 * @param string $shortcutLabel Shortcut label
680 * @param string $moduleName Backend module name (key)
681 * @param string $parentModuleName Parent module label
682 * @return string Title for the shortcut icon
683 */
684 protected function getShortcutIconTitle($shortcutLabel, $moduleName, $parentModuleName = '') {
685 $title = '';
686 if (substr($moduleName, 0, 5) == 'xMOD_') {
687 $title = substr($moduleName, 5);
688 } else {
689 $splitModuleName = explode('_', $moduleName);
690 $title = $GLOBALS['LANG']->moduleLabels['tabs'][$splitModuleName[0] . '_tab'];
691 if (count($splitModuleName) > 1) {
692 $title .= '>' . $GLOBALS['LANG']->moduleLabels['tabs'][($moduleName . '_tab')];
693 }
694 }
695 if ($parentModuleName) {
696 $title .= ' (' . $parentModuleName . ')';
697 }
698 $title .= ': ' . $shortcutLabel;
699 return $title;
700 }
701
702 /**
703 * Return the ID of the page in the URL if found.
704 *
705 * @param string $url The URL of the current shortcut link
706 * @return string If a page ID was found, it is returned. Otherwise: 0
707 */
708 protected function getLinkedPageId($url) {
709 return preg_replace('/.*[\\?&]id=([^&]+).*/', '$1', $url);
710 }
711
712 }