TYPO3 CMS  TYPO3_7-6
ShortcutToolbarItem.php
Go to the documentation of this file.
1 <?php
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 
31 
36 {
40  const SUPERGLOBAL_GROUP = -100;
41 
45  public $perms_clause;
46 
50  public $fieldArray;
51 
57  protected $shortcuts;
58 
62  protected $shortcutGroups;
63 
70  protected $groupLabels;
71 
75  protected $iconFactory;
76 
80  public function __construct()
81  {
82  $this->iconFactory = GeneralUtility::makeInstance(IconFactory::class);
83  if (TYPO3_REQUESTTYPE & TYPO3_REQUESTTYPE_AJAX) {
84  $this->getLanguageService()->includeLLFile('EXT:lang/locallang_misc.xlf');
85  // Needed to get the correct icons when reloading the menu after saving it
86  $loadModules = GeneralUtility::makeInstance(ModuleLoader::class);
87  $loadModules->load($GLOBALS['TBE_MODULES']);
88  }
89 
90  // By default, 5 groups are set
91  $this->shortcutGroups = [
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  $this->getPageRenderer()->loadRequireJsModule('TYPO3/CMS/Backend/Toolbar/ShortcutMenu');
102  $languageService = $this->getLanguageService();
103  $this->getPageRenderer()->addInlineLanguageLabelArray([
104  'bookmark.delete' => $languageService->sL('LLL:EXT:lang/locallang_core.xlf:toolbarItems.bookmarksDelete'),
105  'bookmark.confirmDelete' => $languageService->sL('LLL:EXT:lang/locallang_core.xlf:toolbarItems.confirmBookmarksDelete'),
106  'bookmark.create' => $languageService->sL('LLL:EXT:lang/locallang_core.xlf:toolbarItems.createBookmark'),
107  'bookmark.savedTitle' => $languageService->sL('LLL:EXT:lang/locallang_core.xlf:toolbarItems.bookmarkSavedTitle'),
108  'bookmark.savedMessage' => $languageService->sL('LLL:EXT:lang/locallang_core.xlf:toolbarItems.bookmarkSavedMessage'),
109  ]);
110  }
111 
117  public function checkAccess()
118  {
119  return (bool)$this->getBackendUser()->getTSConfigVal('options.enableBookmarks');
120  }
121 
127  public function getItem()
128  {
129  $title = $this->getLanguageService()->sL('LLL:EXT:lang/locallang_core.xlf:toolbarItems.bookmarks', true);
130  return '<span title="' . $title . '">' . $this->iconFactory->getIcon('apps-toolbar-menu-shortcut', Icon::SIZE_SMALL)->render('inline') . '</span>';
131  }
132 
138  public function getDropDown()
139  {
140  $languageService = $this->getLanguageService();
141  $shortcutGroup = $languageService->sL('LLL:EXT:lang/locallang_core.xlf:toolbarItems.bookmarksGroup', true);
142  $shortcutEdit = $languageService->sL('LLL:EXT:lang/locallang_core.xlf:toolbarItems.bookmarksEdit', true);
143  $shortcutDelete = $languageService->sL('LLL:EXT:lang/locallang_core.xlf:toolbarItems.bookmarksDelete', true);
144  $editIcon = '<a href="#" class="dropdown-list-link-edit shortcut-edit" ' . $shortcutEdit . '>'
145  . $this->iconFactory->getIcon('actions-open', Icon::SIZE_SMALL)->render('inline') . '</a>';
146  $deleteIcon = '<a href="#" class="dropdown-list-link-delete shortcut-delete" title="' . $shortcutDelete . '">'
147  . $this->iconFactory->getIcon('actions-delete', Icon::SIZE_SMALL)->render('inline') . '</a>';
148 
149  $shortcutMenu[] = '<ul class="dropdown-list">';
150 
151  // Render shortcuts with no group (group id = 0) first
152  $noGroupShortcuts = $this->getShortcutsByGroup(0);
153  foreach ($noGroupShortcuts as $shortcut) {
154  $shortcutMenu[] = '
155  <li class="shortcut" data-shortcutid="' . (int)$shortcut['raw']['uid'] . '">
156  <a class="dropdown-list-link dropdown-link-list-add-editdelete" href="#" onclick="' . htmlspecialchars($shortcut['action']) . ' return false;">' .
157  $shortcut['icon'] . ' ' .
158  htmlspecialchars($shortcut['label']) .
159  '</a>
160  ' . $editIcon . $deleteIcon . '
161  </li>';
162  }
163  // Now render groups and the contained shortcuts
164  $groups = $this->getGroupsFromShortcuts();
165  krsort($groups, SORT_NUMERIC);
166  foreach ($groups as $groupId => $groupLabel) {
167  if ($groupId != 0) {
168  $shortcutGroup = '';
169  if (count($shortcutMenu) > 1) {
170  $shortcutGroup .= '<li class="divider"></li>';
171  }
172  $shortcutGroup .= '
173  <li class="dropdown-header" id="shortcut-group-' . (int)$groupId . '">
174  ' . $groupLabel . '
175  </li>';
176  $shortcuts = $this->getShortcutsByGroup($groupId);
177  $i = 0;
178  foreach ($shortcuts as $shortcut) {
179  $i++;
180  $shortcutGroup .= '
181  <li class="shortcut" data-shortcutid="' . (int)$shortcut['raw']['uid'] . '" data-shortcutgroup="' . (int)$groupId . '">
182  <a class="dropdown-list-link dropdown-link-list-add-editdelete" href="#" onclick="' . htmlspecialchars($shortcut['action']) . ' return false;">' .
183  $shortcut['icon'] . ' ' .
184  htmlspecialchars($shortcut['label']) .
185  '</a>
186  ' . $editIcon . $deleteIcon . '
187  </li>';
188  }
189  $shortcutMenu[] = $shortcutGroup;
190  }
191  }
192  $shortcutMenu[] = '</ul>';
193 
194  if (count($shortcutMenu) === 2) {
195  // No shortcuts added yet, show a small help message how to add shortcuts
196  $title = $languageService->sL('LLL:EXT:lang/locallang_core.xlf:toolbarItems.bookmarks', true);
197  $icon = '<span title="' . $title . '">' . $this->iconFactory->getIcon('actions-system-shortcut-new', Icon::SIZE_SMALL)->render('inline') . '</span>';
198  $label = str_replace('%icon%', $icon, $languageService->sL('LLL:EXT:lang/locallang_misc.xlf:bookmarkDescription', true));
199  $compiledShortcutMenu = '<p>' . $label . '</p>';
200  } else {
201  $compiledShortcutMenu = implode(LF, $shortcutMenu);
202  }
203 
204  return $compiledShortcutMenu;
205  }
206 
214  public function menuAction(ServerRequestInterface $request, ResponseInterface $response)
215  {
216  $menuContent = $this->getDropDown();
217 
218  $response->getBody()->write($menuContent);
219  $response = $response->withHeader('Content-Type', 'text/html; charset=utf-8');
220  return $response;
221  }
222 
228  public function getAdditionalAttributes()
229  {
230  return [];
231  }
232 
238  public function hasDropDown()
239  {
240  return true;
241  }
242 
248  protected function initShortcuts()
249  {
250  $databaseConnection = $this->getDatabaseConnection();
251  $globalGroupIdList = implode(',', array_keys($this->getGlobalShortcutGroups()));
252  $backendUser = $this->getBackendUser();
253  $res = $databaseConnection->exec_SELECTquery(
254  '*',
255  'sys_be_shortcuts',
256  '(userid = ' . (int)$backendUser->user['uid'] . ' AND sc_group>=0) OR sc_group IN (' . $globalGroupIdList . ')',
257  '',
258  'sc_group,sorting'
259  );
260  // Traverse shortcuts
261  $lastGroup = 0;
262  $shortcuts = [];
263  while ($row = $databaseConnection->sql_fetch_assoc($res)) {
264  $shortcut = ['raw' => $row];
265 
266  list($row['module_name'], $row['M_module_name']) = explode('|', $row['module_name']);
267 
268  $queryParts = parse_url($row['url']);
269  $queryParameters = GeneralUtility::explodeUrl2Array($queryParts['query'], 1);
270  if ($row['module_name'] === 'xMOD_alt_doc.php' && is_array($queryParameters['edit'])) {
271  $shortcut['table'] = key($queryParameters['edit']);
272  $shortcut['recordid'] = key($queryParameters['edit'][$shortcut['table']]);
273  if ($queryParameters['edit'][$shortcut['table']][$shortcut['recordid']] === 'edit') {
274  $shortcut['type'] = 'edit';
275  } elseif ($queryParameters['edit'][$shortcut['table']][$shortcut['recordid']] === 'new') {
276  $shortcut['type'] = 'new';
277  }
278  if (substr($shortcut['recordid'], -1) === ',') {
279  $shortcut['recordid'] = substr($shortcut['recordid'], 0, -1);
280  }
281  } else {
282  $shortcut['type'] = 'other';
283  }
284  // Check for module access
285  $moduleName = $row['M_module_name'] ?: $row['module_name'];
286  if (!isset($this->getLanguageService()->moduleLabels['tabs_images'][$moduleName . '_tab'])
287  && $moduleName !== 'xMOD_alt_doc.php'
288  ) {
289  // Nice hack to check if the user has access to this module
290  // - otherwise the translation label would not have been loaded :-)
291  continue;
292  }
293  if (!$backendUser->isAdmin()) {
294  $pageId = $this->getLinkedPageId($row['url']);
296  // Check for webmount access
297  if (!$backendUser->isInWebMount($pageId)) {
298  continue;
299  }
300  // Check for record access
301  $pageRow = BackendUtility::getRecord('pages', $pageId);
302  if (!$backendUser->doesUserHaveAccess($pageRow, ($perms = 1))) {
303  continue;
304  }
305  }
306  }
307  $moduleParts = explode('_', $moduleName);
308  $shortcutGroup = (int)$row['sc_group'];
309  if ($shortcutGroup && $lastGroup !== $shortcutGroup && $shortcutGroup !== self::SUPERGLOBAL_GROUP) {
310  $shortcut['groupLabel'] = $this->getShortcutGroupLabel($shortcutGroup);
311  }
312  $lastGroup = $shortcutGroup;
313 
314  if ($row['description']) {
315  $shortcut['label'] = $row['description'];
316  } else {
317  $shortcut['label'] = GeneralUtility::fixed_lgd_cs(rawurldecode($queryParts['query']), 150);
318  }
319  $shortcut['group'] = $shortcutGroup;
320  $shortcut['icon'] = $this->getShortcutIcon($row, $shortcut);
321  $shortcut['iconTitle'] = $this->getShortcutIconTitle($shortcut['label'], $row['module_name'], $row['M_module_name']);
322  $shortcut['action'] = 'jump(' . GeneralUtility::quoteJSvalue($this->getTokenUrl($row['url'])) . ',' . GeneralUtility::quoteJSvalue($moduleName) . ',' . GeneralUtility::quoteJSvalue($moduleParts[0]) . ', ' . (int)$pageId . ');';
323 
324  $shortcuts[] = $shortcut;
325  }
326  return $shortcuts;
327  }
328 
335  protected function getTokenUrl($url)
336  {
337  $parsedUrl = parse_url($url);
338  parse_str($parsedUrl['query'], $parameters);
339 
340  // parse the returnUrl and replace the module token of it
341  if (isset($parameters['returnUrl'])) {
342  $parsedReturnUrl = parse_url($parameters['returnUrl']);
343  parse_str($parsedReturnUrl['query'], $returnUrlParameters);
344  if (strpos($parsedReturnUrl['path'], 'index.php') !== false && isset($returnUrlParameters['M'])) {
345  $module = $returnUrlParameters['M'];
346  $returnUrl = BackendUtility::getModuleUrl($module, $returnUrlParameters);
347  $parameters['returnUrl'] = $returnUrl;
348  $url = $parsedUrl['path'] . '?' . http_build_query($parameters, '', '&', PHP_QUERY_RFC3986);
349  }
350  }
351 
352  if (strpos($parsedUrl['path'], 'index.php') !== false && isset($parameters['M'])) {
353  $module = $parameters['M'];
354  $url = BackendUtility::getModuleUrl($module, $parameters);
355  } elseif (strpos($parsedUrl['path'], 'index.php') !== false && isset($parameters['route'])) {
356  $routePath = $parameters['route'];
358  $router = GeneralUtility::makeInstance(\TYPO3\CMS\Backend\Routing\Router::class);
359  try {
360  $route = $router->match($routePath);
361  if ($route) {
362  $routeIdentifier = $route->getOption('_identifier');
364  $uriBuilder = GeneralUtility::makeInstance(\TYPO3\CMS\Backend\Routing\UriBuilder::class);
365  unset($parameters['route']);
366  $url = (string)$uriBuilder->buildUriFromRoute($routeIdentifier, $parameters);
367  }
368  } catch (\TYPO3\CMS\Backend\Routing\Exception\ResourceNotFoundException $e) {
369  $url = '';
370  }
371  }
372  return $url;
373  }
374 
381  protected function getShortcutsByGroup($groupId)
382  {
383  $shortcuts = [];
384  foreach ($this->shortcuts as $shortcut) {
385  if ($shortcut['group'] == $groupId) {
386  $shortcuts[] = $shortcut;
387  }
388  }
389  return $shortcuts;
390  }
391 
398  protected function getShortcutById($shortcutId)
399  {
400  $returnShortcut = false;
401  foreach ($this->shortcuts as $shortcut) {
402  if ($shortcut['raw']['uid'] == (int)$shortcutId) {
403  $returnShortcut = $shortcut;
404  continue;
405  }
406  }
407  return $returnShortcut;
408  }
409 
415  protected function initShortcutGroups()
416  {
417  $languageService = $this->getLanguageService();
418  $backendUser = $this->getBackendUser();
419  // Groups from TSConfig
420  $bookmarkGroups = $backendUser->getTSConfigProp('options.bookmarkGroups');
421  if (is_array($bookmarkGroups) && !empty($bookmarkGroups)) {
422  foreach ($bookmarkGroups as $groupId => $label) {
423  if (!empty($label)) {
424  $this->shortcutGroups[$groupId] = (string)$label;
425  } elseif ($backendUser->isAdmin()) {
426  unset($this->shortcutGroups[$groupId]);
427  }
428  }
429  }
430  // Generate global groups, all global groups have negative IDs.
431  if (!empty($this->shortcutGroups)) {
432  $groups = $this->shortcutGroups;
433  foreach ($groups as $groupId => $groupLabel) {
434  $this->shortcutGroups[$groupId * -1] = $groupLabel;
435  }
436  }
437  // Group -100 is kind of superglobal and can't be changed.
438  $this->shortcutGroups[self::SUPERGLOBAL_GROUP] = 1;
439  // Add labels
440  foreach ($this->shortcutGroups as $groupId => $groupLabel) {
441  $groupId = (int)$groupId;
442  $label = $groupLabel;
443  if ($groupLabel == '1') {
444  $label = $languageService->sL('LLL:EXT:lang/locallang_misc.xlf:bookmark_group_' . abs($groupId), true);
445  if (empty($label)) {
446  // Fallback label
447  $label = $languageService->getLL('bookmark_group', true) . ' ' . abs($groupId);
448  }
449  }
450  if ($groupId < 0) {
451  // Global group
452  $label = $languageService->sL('LLL:EXT:lang/locallang_misc.xlf:bookmark_global', true) . ': ' . (!empty($label) ? $label : abs($groupId));
453  if ($groupId === self::SUPERGLOBAL_GROUP) {
454  $label = $languageService->getLL('bookmark_global', true) . ': ' . $languageService->getLL('bookmark_all', true);
455  }
456  }
457  $this->shortcutGroups[$groupId] = $label;
458  }
459  return $this->shortcutGroups;
460  }
461 
469  public function editFormAction(ServerRequestInterface $request, ResponseInterface $response)
470  {
471  $parsedBody = $request->getParsedBody();
472  $queryParams = $request->getQueryParams();
473 
474  $selectedShortcutId = (int)(isset($parsedBody['shortcutId']) ? $parsedBody['shortcutId'] : $queryParams['shortcutId']);
475  $selectedShortcutGroupId = (int)(isset($parsedBody['shortcutGroup']) ? $parsedBody['shortcutGroup'] : $queryParams['shortcutGroup']);
476  $selectedShortcut = $this->getShortcutById($selectedShortcutId);
477 
479  if (!$this->getBackendUser()->isAdmin()) {
480  foreach ($shortcutGroups as $groupId => $groupName) {
481  if ((int)$groupId < 0) {
482  unset($shortcutGroups[$groupId]);
483  }
484  }
485  }
486 
487  // build the form
488  $content = '
489  <form class="shortcut-form" role="form">
490  <div class="form-group">
491  <input type="text" class="form-control" name="shortcut-title" value="' . htmlspecialchars($selectedShortcut['label']) . '">
492  </div>';
493 
494  $content .= '
495  <div class="form-group">
496  <select class="form-control" name="shortcut-group">';
497  foreach ($shortcutGroups as $shortcutGroupId => $shortcutGroupTitle) {
498  $content .= '<option value="' . (int)$shortcutGroupId . '"' . ($selectedShortcutGroupId == $shortcutGroupId ? ' selected="selected"' : '') . '>' . htmlspecialchars($shortcutGroupTitle) . '</option>';
499  }
500  $content .= '
501  </select>
502  </div>
503  <input type="button" class="btn btn-default shortcut-form-cancel" value="Cancel">
504  <input type="button" class="btn btn-success shortcut-form-save" value="Save">
505  </form>';
506 
507  $response->getBody()->write($content);
508  $response = $response->withHeader('Content-Type', 'text/html; charset=utf-8');
509  return $response;
510  }
511 
519  public function removeShortcutAction(ServerRequestInterface $request, ResponseInterface $response)
520  {
521  $parsedBody = $request->getParsedBody();
522  $queryParams = $request->getQueryParams();
523 
524  $databaseConnection = $this->getDatabaseConnection();
525  $shortcutId = (int)(isset($parsedBody['shortcutId']) ? $parsedBody['shortcutId'] : $queryParams['shortcutId']);
526  $fullShortcut = $this->getShortcutById($shortcutId);
527  $success = false;
528  if ($fullShortcut['raw']['userid'] == $this->getBackendUser()->user['uid']) {
529  $databaseConnection->exec_DELETEquery('sys_be_shortcuts', 'uid = ' . $shortcutId);
530  if ($databaseConnection->sql_affected_rows() === 1) {
531  $success = true;
532  }
533  }
534  $response->getBody()->write(json_encode(['success' => $success]));
535  return $response;
536  }
537 
545  public function createShortcutAction(ServerRequestInterface $request, ResponseInterface $response)
546  {
547  $languageService = $this->getLanguageService();
548  $parsedBody = $request->getParsedBody();
549  $queryParams = $request->getQueryParams();
550 
551  // Default name
552  $shortcutName = 'Shortcut';
553  $shortcutNamePrepend = '';
554  $url = isset($parsedBody['url']) ? $parsedBody['url'] : $queryParams['url'];
555 
556  // Use given display name
557  if (!empty($parsedBody['displayName'])) {
558  $shortcutName = $parsedBody['displayName'];
559  }
560 
561  // Determine shortcut type
562  $url = rawurldecode($url);
563  $queryParts = parse_url($url);
564  $queryParameters = GeneralUtility::explodeUrl2Array($queryParts['query'], true);
565 
566  // Proceed only if no scheme is defined, as URL is expected to be relative
567  if (empty($queryParts['scheme'])) {
568  if (is_array($queryParameters['edit'])) {
569  $shortcut['table'] = key($queryParameters['edit']);
570  $shortcut['recordid'] = key($queryParameters['edit'][$shortcut['table']]);
571  $shortcut['pid'] = BackendUtility::getRecord($shortcut['table'], $shortcut['recordid'])['pid'];
572  if ($queryParameters['edit'][$shortcut['table']][$shortcut['recordid']] == 'edit') {
573  $shortcut['type'] = 'edit';
574  $shortcutNamePrepend = $languageService->getLL('shortcut_edit', true);
575  } elseif ($queryParameters['edit'][$shortcut['table']][$shortcut['recordid']] == 'new') {
576  $shortcut['type'] = 'new';
577  $shortcutNamePrepend = $languageService->getLL('shortcut_create', true);
578  }
579  } else {
580  $shortcut['type'] = 'other';
581  $shortcut['table'] = '';
582  $shortcut['recordid'] = 0;
583  }
584 
585  // Check if given id is a combined identifier
586  if (!empty($queryParameters['id']) && preg_match('/^[0-9]+:/', $queryParameters['id'])) {
587  try {
588  $resourceFactory = ResourceFactory::getInstance();
589  $resource = $resourceFactory->getObjectFromCombinedIdentifier($queryParameters['id']);
590  $shortcutName = trim($shortcutNamePrepend . ' ' . $resource->getName());
591  } catch (ResourceDoesNotExistException $e) {
592  }
593  } else {
594  // Lookup the title of this page and use it as default description
595  $pageId = (int)($shortcut['pid'] ?: ($shortcut['recordid'] ?: $this->getLinkedPageId($url)));
596  $page = false;
597  if ($pageId) {
598  $page = BackendUtility::getRecord('pages', $pageId);
599  }
600  if (!empty($page)) {
601  // Set the name to the title of the page
602  if ($shortcut['type'] === 'other') {
603  if (empty($shortcutName)) {
604  $shortcutName = $page['title'];
605  } else {
606  $shortcutName .= ' (' . $page['title'] . ')';
607  }
608  } else {
609  $shortcutName = $shortcutNamePrepend . ' ' .
610  $languageService->sL($GLOBALS['TCA'][$shortcut['table']]['ctrl']['title']) .
611  ' (' . $page['title'] . ')';
612  }
613  } elseif ($shortcut['table'] !== '' && $shortcut['type'] !== 'other') {
614  $shortcutName = $shortcutNamePrepend . ' ' .
615  $languageService->sL($GLOBALS['TCA'][$shortcut['table']]['ctrl']['title']);
616  }
617  }
618 
619  return $this->tryAddingTheShortcut($response, $url, $shortcutName);
620  }
621  }
622 
631  protected function tryAddingTheShortcut(ResponseInterface $response, $url, $shortcutName)
632  {
633  $module = GeneralUtility::_POST('module');
634  $shortcutCreated = 'failed';
635 
636  if (!empty($module) && !empty($url)) {
637  $shortcutCreated = 'alreadyExists';
638 
639  if (!BackendUtility::shortcutExists($url)) {
640  $shortcutCreated = $this->addShortcut($url, $shortcutName, $module);
641  }
642  }
643 
644  $response->getBody()->write($shortcutCreated);
645  $response = $response->withHeader('Content-Type', 'text/html; charset=utf-8');
646  return $response;
647  }
648 
658  protected function addShortcut($url, $shortcutName, $module)
659  {
660  // Shorts
661  $db = $this->getDatabaseConnection();
662  $lS = $this->getLanguageService();
663 
664  if ($shortcutName === 'Shortcut' && !empty($lS->moduleLabels['labels'][$module . '_tablabel'])) {
665  $shortcutName = $lS->moduleLabels['labels'][$module . '_tablabel'];
666  }
667 
668  $motherModule = GeneralUtility::_POST('motherModName');
669  $fieldValues = [
670  'userid' => $this->getBackendUser()->user['uid'],
671  'module_name' => $module . '|' . $motherModule,
672  'url' => $url,
673  'description' => $shortcutName,
674  'sorting' => $GLOBALS['EXEC_TIME']
675  ];
676 
677  $db->exec_INSERTquery('sys_be_shortcuts', $fieldValues);
678 
679  $shortcutCreated = 'failed';
680  if ($db->sql_affected_rows() === 1) {
681  $shortcutCreated = 'success';
682  }
683 
684  return $shortcutCreated;
685  }
686 
694  protected function shortcutExists($url)
695  {
696  $statement = $this->getDatabaseConnection()->prepare_SELECTquery(
697  'uid',
698  'sys_be_shortcuts',
699  'userid = :userid AND url = :url'
700  );
701 
702  $statement->bindValues([
703  ':userid' => $this->getBackendUser()->user['uid'],
704  ':url' => $url
705  ]);
706 
707  $statement->execute();
708  $rows = $statement->fetch(PreparedStatement::FETCH_ASSOC);
709  $statement->free();
710 
711  return !empty($rows);
712  }
713 
722  public function saveFormAction(ServerRequestInterface $request, ResponseInterface $response)
723  {
724  $parsedBody = $request->getParsedBody();
725  $queryParams = $request->getQueryParams();
726 
727  $databaseConnection = $this->getDatabaseConnection();
728  $backendUser = $this->getBackendUser();
729  $shortcutId = (int)(isset($parsedBody['shortcutId']) ? $parsedBody['shortcutId'] : $queryParams['shortcutId']);
730  $shortcutName = strip_tags(isset($parsedBody['shortcutTitle']) ? $parsedBody['shortcutTitle'] : $queryParams['shortcutTitle']);
731  $shortcutGroupId = (int)(isset($parsedBody['shortcutGroup']) ? $parsedBody['shortcutGroup'] : $queryParams['shortcutGroup']);
732  // Users can only modify their own shortcuts (except admins)
733  $addUserWhere = !$backendUser->isAdmin() ? ' AND userid=' . (int)$backendUser->user['uid'] : '';
734  $fieldValues = [
735  'description' => $shortcutName,
736  'sc_group' => $shortcutGroupId
737  ];
738  if ($fieldValues['sc_group'] < 0 && !$backendUser->isAdmin()) {
739  $fieldValues['sc_group'] = 0;
740  }
741  $databaseConnection->exec_UPDATEquery('sys_be_shortcuts', 'uid=' . $shortcutId . $addUserWhere, $fieldValues);
742  $affectedRows = $databaseConnection->sql_affected_rows();
743  if ($affectedRows == 1) {
744  $response->getBody()->write($shortcutName);
745  } else {
746  $response->getBody()->write('failed');
747  }
748  return $response->withHeader('Content-Type', 'text/html; charset=utf-8');
749  }
750 
757  protected function getShortcutGroupLabel($groupId)
758  {
759  return isset($this->shortcutGroups[$groupId]) ? $this->shortcutGroups[$groupId] : '';
760  }
761 
767  protected function getGlobalShortcutGroups()
768  {
769  $globalGroups = [];
770  foreach ($this->shortcutGroups as $groupId => $groupLabel) {
771  if ($groupId < 0) {
772  $globalGroups[$groupId] = $groupLabel;
773  }
774  }
775  return $globalGroups;
776  }
777 
783  protected function getGroupsFromShortcuts()
784  {
785  $groups = [];
786  foreach ($this->shortcuts as $shortcut) {
787  $groups[$shortcut['group']] = $this->shortcutGroups[$shortcut['group']];
788  }
789  return array_unique($groups);
790  }
791 
799  protected function getShortcutIcon($row, $shortcut)
800  {
801  $databaseConnection = $this->getDatabaseConnection();
802  $languageService = $this->getLanguageService();
803  $titleAttribute = $languageService->sL('LLL:EXT:lang/locallang_core.xlf:toolbarItems.shortcut', true);
804  switch ($row['module_name']) {
805  case 'xMOD_alt_doc.php':
806  $table = $shortcut['table'];
807  $recordid = $shortcut['recordid'];
808  $icon = '';
809  if ($shortcut['type'] == 'edit') {
810  // Creating the list of fields to include in the SQL query:
811  $selectFields = $this->fieldArray;
812  $selectFields[] = 'uid';
813  $selectFields[] = 'pid';
814  if ($table == 'pages') {
815  $selectFields[] = 'module';
816  $selectFields[] = 'extendToSubpages';
817  $selectFields[] = 'doktype';
818  }
819  if (is_array($GLOBALS['TCA'][$table]['ctrl']['enablecolumns'])) {
820  $selectFields = array_merge($selectFields, $GLOBALS['TCA'][$table]['ctrl']['enablecolumns']);
821  }
822  if ($GLOBALS['TCA'][$table]['ctrl']['typeicon_column']) {
823  $selectFields[] = $GLOBALS['TCA'][$table]['ctrl']['typeicon_column'];
824  }
825  if ($GLOBALS['TCA'][$table]['ctrl']['versioningWS']) {
826  $selectFields[] = 't3ver_state';
827  }
828  // Unique list!
829  $selectFields = array_unique($selectFields);
830  $permissionClause = $table === 'pages' && $this->perms_clause ? ' AND ' . $this->perms_clause : '';
831  $sqlQueryParts = [
832  'SELECT' => implode(',', $selectFields),
833  'FROM' => $table,
834  'WHERE' => 'uid IN (' . $recordid . ') ' . $permissionClause . BackendUtility::deleteClause($table) . BackendUtility::versioningPlaceholderClause($table)
835  ];
836  $result = $databaseConnection->exec_SELECT_queryArray($sqlQueryParts);
837  $row = $databaseConnection->sql_fetch_assoc($result);
838  $icon = '<span title="' . $titleAttribute . '">' . $this->iconFactory->getIconForRecord($table, (array)$row, Icon::SIZE_SMALL)->render() . '</span>';
839  } elseif ($shortcut['type'] == 'new') {
840  $icon = '<span title="' . $titleAttribute . '">' . $this->iconFactory->getIconForRecord($table, [], Icon::SIZE_SMALL)->render() . '</span>';
841  }
842  break;
843  case 'file_edit':
844  $icon = '<span title="' . $titleAttribute . '">' . $this->iconFactory->getIcon('mimetypes-text-html', Icon::SIZE_SMALL)->render() . '</span>';
845  break;
846  case 'wizard_rte':
847  $icon = '<span title="' . $titleAttribute . '">' . $this->iconFactory->getIcon('mimetypes-word', Icon::SIZE_SMALL)->render() . '</span>';
848  break;
849  default:
850  if ($languageService->moduleLabels['tabs_images'][$row['module_name'] . '_tab']) {
851  $icon = $languageService->moduleLabels['tabs_images'][$row['module_name'] . '_tab'];
852  // Change icon of fileadmin references - otherwise it doesn't differ with Web->List
853  $icon = str_replace('mod/file/list/list.gif', 'mod/file/file.gif', $icon);
854  if (GeneralUtility::isAbsPath($icon)) {
855  $icon = '../' . PathUtility::stripPathSitePrefix($icon);
856  }
857  // @todo: hardcoded width as we don't have a way to address module icons with an API yet.
858  $icon = '<img src="' . htmlspecialchars($icon) . '" alt="' . $titleAttribute . '" width="16">';
859  } else {
860  $icon = '<span title="' . $titleAttribute . '">' . $this->iconFactory->getIcon('empty-empty', Icon::SIZE_SMALL)->render() . '</span>';
861  }
862  }
863  return $icon;
864  }
865 
874  protected function getShortcutIconTitle($shortcutLabel, $moduleName, $parentModuleName = '')
875  {
876  $languageService = $this->getLanguageService();
877  if (substr($moduleName, 0, 5) == 'xMOD_') {
878  $title = substr($moduleName, 5);
879  } else {
880  $splitModuleName = explode('_', $moduleName);
881  $title = $languageService->moduleLabels['tabs'][$splitModuleName[0] . '_tab'];
882  if (count($splitModuleName) > 1) {
883  $title .= '>' . $languageService->moduleLabels['tabs'][$moduleName . '_tab'];
884  }
885  }
886  if ($parentModuleName) {
887  $title .= ' (' . $parentModuleName . ')';
888  }
889  $title .= ': ' . $shortcutLabel;
890  return $title;
891  }
892 
899  protected function getLinkedPageId($url)
900  {
901  return preg_replace('/.*[\\?&]id=([^&]+).*/', '$1', $url);
902  }
903 
909  public function getIndex()
910  {
911  return 20;
912  }
913 
919  protected function getBackendUser()
920  {
921  return $GLOBALS['BE_USER'];
922  }
923 
929  protected function getPageRenderer()
930  {
931  return GeneralUtility::makeInstance(PageRenderer::class);
932  }
933 
939  protected function getLanguageService()
940  {
941  return $GLOBALS['LANG'];
942  }
943 
949  protected function getDatabaseConnection()
950  {
951  return $GLOBALS['TYPO3_DB'];
952  }
953 }
if(!defined("DB_ERROR")) define("DB_ERROR"
tryAddingTheShortcut(ResponseInterface $response, $url, $shortcutName)
saveFormAction(ServerRequestInterface $request, ResponseInterface $response)
editFormAction(ServerRequestInterface $request, ResponseInterface $response)
menuAction(ServerRequestInterface $request, ResponseInterface $response)
getShortcutIconTitle($shortcutLabel, $moduleName, $parentModuleName='')
static explodeUrl2Array($string, $multidim=false)
createShortcutAction(ServerRequestInterface $request, ResponseInterface $response)
static fixed_lgd_cs($string, $chars, $appendString='...')
removeShortcutAction(ServerRequestInterface $request, ResponseInterface $response)
static getRecord($table, $uid, $fields=' *', $where='', $useDeleteClause=true)
if(TYPO3_MODE==='BE') $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_tsfebeuserauth.php']['frontendEditingController']['default']
static deleteClause($table, $tableAlias='')