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