Passed
Push — master ( ff1a76...9dbd27 )
by
unknown
13:17
created

ShortcutRepository::addShortcut()   F

Complexity

Conditions 20
Paths 158

Size

Total Lines 112
Code Lines 74

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 74
dl 0
loc 112
rs 3.6833
c 0
b 0
f 0
cc 20
nc 158
nop 4

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
declare(strict_types=1);
4
5
/*
6
 * This file is part of the TYPO3 CMS project.
7
 *
8
 * It is free software; you can redistribute it and/or modify it under
9
 * the terms of the GNU General Public License, either version 2
10
 * of the License, or any later version.
11
 *
12
 * For the full copyright and license information, please read the
13
 * LICENSE.txt file that was distributed with this source code.
14
 *
15
 * The TYPO3 project - inspiring people to share!
16
 */
17
18
namespace TYPO3\CMS\Backend\Backend\Shortcut;
19
20
use TYPO3\CMS\Backend\Module\ModuleLoader;
21
use TYPO3\CMS\Backend\Routing\Exception\ResourceNotFoundException;
22
use TYPO3\CMS\Backend\Routing\Router;
23
use TYPO3\CMS\Backend\Routing\UriBuilder;
24
use TYPO3\CMS\Backend\Utility\BackendUtility;
25
use TYPO3\CMS\Core\Authentication\BackendUserAuthentication;
26
use TYPO3\CMS\Core\Database\Connection;
27
use TYPO3\CMS\Core\Database\ConnectionPool;
28
use TYPO3\CMS\Core\Imaging\Icon;
29
use TYPO3\CMS\Core\Imaging\IconFactory;
30
use TYPO3\CMS\Core\Localization\LanguageService;
31
use TYPO3\CMS\Core\Resource\Exception\ResourceDoesNotExistException;
32
use TYPO3\CMS\Core\Resource\ResourceFactory;
33
use TYPO3\CMS\Core\Type\Bitmask\Permission;
34
use TYPO3\CMS\Core\Utility\GeneralUtility;
35
use TYPO3\CMS\Core\Utility\MathUtility;
36
37
/**
38
 * Repository for backend shortcuts
39
 *
40
 * @internal This class is a specific Backend implementation and is not considered part of the Public TYPO3 API.
41
 */
42
class ShortcutRepository
43
{
44
    /**
45
     * @var int Number of super global (All) group
46
     */
47
    protected const SUPERGLOBAL_GROUP = -100;
48
49
    /**
50
     * @var array
51
     */
52
    protected $shortcuts;
53
54
    /**
55
     * @var array
56
     */
57
    protected $shortcutGroups;
58
59
    /**
60
     * @var IconFactory
61
     */
62
    protected $iconFactory;
63
64
    /**
65
     * @var ModuleLoader
66
     */
67
    protected $moduleLoader;
68
69
    /**
70
     * Constructor
71
     */
72
    public function __construct()
73
    {
74
        $this->iconFactory = GeneralUtility::makeInstance(IconFactory::class);
75
        $this->moduleLoader = GeneralUtility::makeInstance(ModuleLoader::class);
76
        $this->moduleLoader->load($GLOBALS['TBE_MODULES']);
77
78
        $this->shortcutGroups = $this->initShortcutGroups();
79
        $this->shortcuts = $this->initShortcuts();
80
    }
81
82
    /**
83
     * Gets a shortcut by its uid
84
     *
85
     * @param int $shortcutId Shortcut id to get the complete shortcut for
86
     * @return mixed An array containing the shortcut's data on success or FALSE on failure
87
     */
88
    public function getShortcutById(int $shortcutId)
89
    {
90
        foreach ($this->shortcuts as $shortcut) {
91
            if ($shortcut['raw']['uid'] === $shortcutId) {
92
                return $shortcut;
93
            }
94
        }
95
96
        return false;
97
    }
98
99
    /**
100
     * Gets shortcuts for a specific group
101
     *
102
     * @param int $groupId Group Id
103
     * @return array Array of shortcuts that matched the group
104
     */
105
    public function getShortcutsByGroup(int $groupId): array
106
    {
107
        $shortcuts = [];
108
109
        foreach ($this->shortcuts as $shortcut) {
110
            if ($shortcut['group'] === $groupId) {
111
                $shortcuts[] = $shortcut;
112
            }
113
        }
114
115
        return $shortcuts;
116
    }
117
118
    /**
119
     * Get shortcut groups the current user has access to
120
     *
121
     * @return array
122
     */
123
    public function getShortcutGroups(): array
124
    {
125
        $shortcutGroups = $this->shortcutGroups;
126
127
        if (!$this->getBackendUser()->isAdmin()) {
128
            foreach ($shortcutGroups as $groupId => $groupName) {
129
                if ((int)$groupId < 0) {
130
                    unset($shortcutGroups[$groupId]);
131
                }
132
            }
133
        }
134
135
        return $shortcutGroups;
136
    }
137
138
    /**
139
     * runs through the available shortcuts and collects their groups
140
     *
141
     * @return array Array of groups which have shortcuts
142
     */
143
    public function getGroupsFromShortcuts(): array
144
    {
145
        $groups = [];
146
147
        foreach ($this->shortcuts as $shortcut) {
148
            $groups[$shortcut['group']] = $this->shortcutGroups[$shortcut['group']];
149
        }
150
151
        return array_unique($groups);
152
    }
153
154
    /**
155
     * Returns if there already is a shortcut entry for a given TYPO3 URL
156
     *
157
     * @param string $url
158
     * @return bool
159
     */
160
    public function shortcutExists(string $url): bool
161
    {
162
        $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)
163
            ->getQueryBuilderForTable('sys_be_shortcuts');
164
        $queryBuilder->getRestrictions()->removeAll();
165
166
        $uid = $queryBuilder->select('uid')
167
            ->from('sys_be_shortcuts')
168
            ->where(
169
                $queryBuilder->expr()->eq(
170
                    'userid',
171
                    $queryBuilder->createNamedParameter($this->getBackendUser()->user['uid'], \PDO::PARAM_INT)
172
                ),
173
                $queryBuilder->expr()->eq(
174
                    'url',
175
                    $queryBuilder->createNamedParameter($url, \PDO::PARAM_STR)
176
                )
177
            )
178
            ->execute()
179
            ->fetchColumn();
180
181
        return (bool)$uid;
182
    }
183
184
    /**
185
     * Add a shortcut
186
     *
187
     * @param string $url URL of the new shortcut
188
     * @param string $module module identifier of the new shortcut
189
     * @param string $parentModule parent module identifier of the new shortcut
190
     * @param string $title title of the new shortcut
191
     * @return bool
192
     * @throws \RuntimeException if the given URL is invalid
193
     */
194
    public function addShortcut(string $url, string $module, string $parentModule = '', string $title = ''): bool
195
    {
196
        // @todo $parentModule can not longer be set using public API.
197
198
        if (empty($url) || empty($module)) {
199
            return false;
200
        }
201
202
        $queryParts = parse_url($url);
203
        $queryParameters = [];
204
        parse_str($queryParts['query'] ?? '', $queryParameters);
205
206
        if (!empty($queryParameters['scheme'])) {
207
            throw new \RuntimeException('Shortcut URLs must be relative', 1518785877);
208
        }
209
210
        $languageService = $this->getLanguageService();
211
        $titlePrefix = '';
212
        $type = 'other';
213
        $table = '';
214
        $recordId = 0;
215
        $pageId = 0;
216
217
        if (is_array($queryParameters['edit'])) {
218
            $table = (string)key($queryParameters['edit']);
219
            $recordId = (int)key($queryParameters['edit'][$table]);
220
            $pageId = (int)BackendUtility::getRecord($table, $recordId)['pid'];
221
            $languageFile = 'LLL:EXT:core/Resources/Private/Language/locallang_misc.xlf';
222
            $action = $queryParameters['edit'][$table][$recordId];
223
224
            switch ($action) {
225
                case 'edit':
226
                    $type = 'edit';
227
                    $titlePrefix = $languageService->sL($languageFile . ':shortcut_edit');
228
                    break;
229
                case 'new':
230
                    $type = 'new';
231
                    $titlePrefix = $languageService->sL($languageFile . ':shortcut_create');
232
                    break;
233
            }
234
        }
235
236
        // Only apply "magic" if title is not set
237
        // @todo This is deprecated and can be removed in v12
238
        if ($title === '') {
239
            // Check if given id is a combined identifier
240
            if (!empty($queryParameters['id']) && preg_match('/^[\d]+:/', $queryParameters['id'])) {
241
                try {
242
                    $resourceFactory = GeneralUtility::makeInstance(ResourceFactory::class);
243
                    $resource = $resourceFactory->getObjectFromCombinedIdentifier($queryParameters['id']);
244
                    $title = trim(sprintf(
245
                        '%s (%s)',
246
                        $titlePrefix,
247
                        $resource->getName()
248
                    ));
249
                } catch (ResourceDoesNotExistException $e) {
0 ignored issues
show
Coding Style Comprehensibility introduced by
Consider adding a comment why this CATCH block is empty.
Loading history...
250
                }
251
            } else {
252
                // Lookup the title of this page and use it as default description
253
                $pageId = $pageId ?: $recordId ?: $this->extractPageIdFromShortcutUrl($url);
254
                $page = $pageId ? BackendUtility::getRecord('pages', $pageId) : null;
255
256
                if (!empty($page)) {
257
                    // Set the name to the title of the page
258
                    if ($type === 'other') {
259
                        $title = sprintf(
260
                            '%s (%s)',
261
                            $title,
262
                            $page['title']
263
                        );
264
                    } else {
265
                        $title = sprintf(
266
                            '%s %s (%s)',
267
                            $titlePrefix,
268
                            $languageService->sL($GLOBALS['TCA'][$table]['ctrl']['title']),
269
                            $page['title']
270
                        );
271
                    }
272
                } elseif (!empty($table)) {
273
                    $title = trim(sprintf(
274
                        '%s %s',
275
                        $titlePrefix,
276
                        $languageService->sL($GLOBALS['TCA'][$table]['ctrl']['title'])
277
                    ));
278
                }
279
            }
280
        }
281
282
        // In case title is still empty try to set the modules short description label
283
        // @todo This is deprecated and can be removed in v12
284
        if ($title === '') {
285
            $moduleLabels = $this->moduleLoader->getLabelsForModule($module);
286
287
            if (!empty($moduleLabels['shortdescription'])) {
288
                $title = $this->getLanguageService()->sL($moduleLabels['shortdescription']);
289
            }
290
        }
291
292
        $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)
293
            ->getQueryBuilderForTable('sys_be_shortcuts');
294
        $affectedRows = $queryBuilder
295
            ->insert('sys_be_shortcuts')
296
            ->values([
297
                'userid' => $this->getBackendUser()->user['uid'],
298
                'module_name' => $module . '|' . $parentModule,
299
                'url' => $url,
300
                'description' => $title ?: 'Shortcut',
301
                'sorting' => $GLOBALS['EXEC_TIME'],
302
            ])
303
            ->execute();
304
305
        return $affectedRows === 1;
306
    }
307
308
    /**
309
     * Update a shortcut
310
     *
311
     * @param int $id identifier of a shortcut
312
     * @param string $title new title of the shortcut
313
     * @param int $groupId new group identifier of the shortcut
314
     * @return bool
315
     */
316
    public function updateShortcut(int $id, string $title, int $groupId): bool
317
    {
318
        $backendUser = $this->getBackendUser();
319
        $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)
320
            ->getQueryBuilderForTable('sys_be_shortcuts');
321
        $queryBuilder->update('sys_be_shortcuts')
322
            ->where(
323
                $queryBuilder->expr()->eq(
324
                    'uid',
325
                    $queryBuilder->createNamedParameter($id, \PDO::PARAM_INT)
326
                )
327
            )
328
            ->set('description', $title)
329
            ->set('sc_group', $groupId);
330
331
        if (!$backendUser->isAdmin()) {
332
            // Users can only modify their own shortcuts
333
            $queryBuilder->andWhere(
334
                $queryBuilder->expr()->eq(
335
                    'userid',
336
                    $queryBuilder->createNamedParameter($backendUser->user['uid'], \PDO::PARAM_INT)
337
                )
338
            );
339
340
            if ($groupId < 0) {
341
                $queryBuilder->set('sc_group', 0);
342
            }
343
        }
344
345
        $affectedRows = $queryBuilder->execute();
346
347
        return $affectedRows === 1;
348
    }
349
350
    /**
351
     * Remove a shortcut
352
     *
353
     * @param int $id identifier of a shortcut
354
     * @return bool
355
     */
356
    public function removeShortcut(int $id): bool
357
    {
358
        $shortcut = $this->getShortcutById($id);
359
        $success = false;
360
361
        if ($shortcut['raw']['userid'] == $this->getBackendUser()->user['uid']) {
362
            $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)
363
                ->getQueryBuilderForTable('sys_be_shortcuts');
364
            $affectedRows = $queryBuilder->delete('sys_be_shortcuts')
365
                ->where(
366
                    $queryBuilder->expr()->eq(
367
                        'uid',
368
                        $queryBuilder->createNamedParameter($id, \PDO::PARAM_INT)
369
                    )
370
                )
371
                ->execute();
372
373
            if ($affectedRows === 1) {
374
                $success = true;
375
            }
376
        }
377
378
        return $success;
379
    }
380
381
    /**
382
     * Gets the available shortcut groups from default groups, user TSConfig, and global groups
383
     *
384
     * @return array
385
     */
386
    protected function initShortcutGroups(): array
387
    {
388
        $languageService = $this->getLanguageService();
389
        $backendUser = $this->getBackendUser();
390
        // By default, 5 groups are set
391
        $shortcutGroups = [
392
            1 => '1',
393
            2 => '1',
394
            3 => '1',
395
            4 => '1',
396
            5 => '1',
397
        ];
398
399
        // Groups from TSConfig
400
        $bookmarkGroups = $backendUser->getTSConfig()['options.']['bookmarkGroups.'] ?? [];
401
402
        if (is_array($bookmarkGroups)) {
403
            foreach ($bookmarkGroups as $groupId => $label) {
404
                if (!empty($label)) {
405
                    $label = (string)$label;
406
                    $shortcutGroups[$groupId] = strpos($label, 'LLL:') === 0 ? $languageService->sL($label) : $label;
407
                } elseif ($backendUser->isAdmin()) {
408
                    unset($shortcutGroups[$groupId]);
409
                }
410
            }
411
        }
412
413
        // Generate global groups, all global groups have negative IDs.
414
        if (!empty($shortcutGroups)) {
415
            foreach ($shortcutGroups as $groupId => $groupLabel) {
416
                $shortcutGroups[$groupId * -1] = $groupLabel;
417
            }
418
        }
419
420
        // Group -100 is kind of superglobal and can't be changed.
421
        $shortcutGroups[self::SUPERGLOBAL_GROUP] = '1';
422
423
        // Add labels
424
        $languageFile = 'LLL:EXT:core/Resources/Private/Language/locallang_misc.xlf';
425
426
        foreach ($shortcutGroups as $groupId => $groupLabel) {
427
            $groupId = (int)$groupId;
428
            $label = $groupLabel;
429
430
            if ($groupLabel === '1') {
431
                $label = $languageService->sL($languageFile . ':bookmark_group_' . abs($groupId));
432
433
                if (empty($label)) {
434
                    // Fallback label
435
                    $label = $languageService->sL($languageFile . ':bookmark_group') . ' ' . abs($groupId);
436
                }
437
            }
438
439
            if ($groupId < 0) {
440
                // Global group
441
                $label = $languageService->sL($languageFile . ':bookmark_global') . ': ' . (!empty($label) ? $label : abs($groupId));
442
443
                if ($groupId === self::SUPERGLOBAL_GROUP) {
444
                    $label = $languageService->sL($languageFile . ':bookmark_global') . ': ' . $languageService->sL($languageFile . ':bookmark_all');
445
                }
446
            }
447
448
            $shortcutGroups[$groupId] = htmlspecialchars($label);
449
        }
450
451
        return $shortcutGroups;
452
    }
453
454
    /**
455
     * Retrieves the shortcuts for the current user
456
     *
457
     * @return array Array of shortcuts
458
     */
459
    protected function initShortcuts(): array
460
    {
461
        $backendUser = $this->getBackendUser();
462
        // Traverse shortcuts
463
        $lastGroup = 0;
464
        $shortcuts = [];
465
        $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)
466
            ->getQueryBuilderForTable('sys_be_shortcuts');
467
        $result = $queryBuilder->select('*')
468
            ->from('sys_be_shortcuts')
469
            ->where(
470
                $queryBuilder->expr()->andX(
471
                    $queryBuilder->expr()->eq(
472
                        'userid',
473
                        $queryBuilder->createNamedParameter($backendUser->user['uid'], \PDO::PARAM_INT)
474
                    ),
475
                    $queryBuilder->expr()->gte(
476
                        'sc_group',
477
                        $queryBuilder->createNamedParameter(0, \PDO::PARAM_INT)
478
                    )
479
                )
480
            )
481
            ->orWhere(
482
                $queryBuilder->expr()->in(
483
                    'sc_group',
484
                    $queryBuilder->createNamedParameter(
485
                        array_keys($this->getGlobalShortcutGroups()),
486
                        Connection::PARAM_INT_ARRAY
487
                    )
488
                )
489
            )
490
            ->orderBy('sc_group')
491
            ->addOrderBy('sorting')
492
            ->execute();
493
494
        while ($row = $result->fetch()) {
495
            $shortcut = ['raw' => $row];
496
497
            [$row['module_name'], $row['M_module_name']] = explode('|', $row['module_name']);
498
499
            $queryParts = parse_url($row['url']);
500
            // Explode GET vars recursively
501
            $queryParameters = [];
502
            parse_str($queryParts['query'] ?? '', $queryParameters);
503
504
            if ($row['module_name'] === 'xMOD_alt_doc.php' && is_array($queryParameters['edit'])) {
505
                $shortcut['table'] = key($queryParameters['edit']);
506
                $shortcut['recordid'] = key($queryParameters['edit'][$shortcut['table']]);
507
508
                if ($queryParameters['edit'][$shortcut['table']][$shortcut['recordid']] === 'edit') {
509
                    $shortcut['type'] = 'edit';
510
                } elseif ($queryParameters['edit'][$shortcut['table']][$shortcut['recordid']] === 'new') {
511
                    $shortcut['type'] = 'new';
512
                }
513
514
                if (substr((string)$shortcut['recordid'], -1) === ',') {
515
                    $shortcut['recordid'] = substr((string)$shortcut['recordid'], 0, -1);
516
                }
517
            } else {
518
                $shortcut['type'] = 'other';
519
            }
520
521
            // Check for module access
522
            $moduleName = $row['M_module_name'] ?: $row['module_name'];
523
524
            // Check if the user has access to this module
525
            // @todo Hack for EditDocumentController / FormEngine, see issues #91368 and #91210
526
            if (!is_array($this->moduleLoader->checkMod($moduleName)) && $moduleName !== 'xMOD_alt_doc.php') {
527
                continue;
528
            }
529
530
            $pageId = $this->extractPageIdFromShortcutUrl($row['url']);
531
532
            if (!$backendUser->isAdmin()) {
533
                if (MathUtility::canBeInterpretedAsInteger($pageId)) {
534
                    // Check for webmount access
535
                    if ($backendUser->isInWebMount($pageId) === null) {
536
                        continue;
537
                    }
538
                    // Check for record access
539
                    $pageRow = BackendUtility::getRecord('pages', $pageId);
540
541
                    if ($pageRow === null) {
542
                        continue;
543
                    }
544
545
                    if (!$backendUser->doesUserHaveAccess($pageRow, Permission::PAGE_SHOW)) {
546
                        continue;
547
                    }
548
                }
549
            }
550
551
            $moduleParts = explode('_', $moduleName);
552
            $shortcutGroup = (int)$row['sc_group'];
553
554
            if ($shortcutGroup && $lastGroup !== $shortcutGroup && $shortcutGroup !== self::SUPERGLOBAL_GROUP) {
555
                $shortcut['groupLabel'] = $this->getShortcutGroupLabel($shortcutGroup);
556
            }
557
558
            $lastGroup = $shortcutGroup;
559
560
            if ($row['description']) {
561
                $shortcut['label'] = $row['description'];
562
            } else {
563
                $shortcut['label'] = GeneralUtility::fixed_lgd_cs(rawurldecode($queryParts['query']), 150);
564
            }
565
566
            $shortcut['group'] = $shortcutGroup;
567
            $shortcut['icon'] = $this->getShortcutIcon($row, $shortcut);
568
            $shortcut['iconTitle'] = $this->getShortcutIconTitle($shortcut['label'], $row['module_name'], $row['M_module_name']);
569
            $shortcut['action'] = 'jump(' . GeneralUtility::quoteJSvalue($this->getTokenUrl($row['url'])) . ',' . GeneralUtility::quoteJSvalue($moduleName) . ',' . GeneralUtility::quoteJSvalue($moduleParts[0]) . ', ' . (int)$pageId . ');';
570
571
            $shortcuts[] = $shortcut;
572
        }
573
574
        return $shortcuts;
575
    }
576
577
    /**
578
     * Gets a list of global groups, shortcuts in these groups are available to all users
579
     *
580
     * @return array Array of global groups
581
     */
582
    protected function getGlobalShortcutGroups(): array
583
    {
584
        $globalGroups = [];
585
586
        foreach ($this->shortcutGroups as $groupId => $groupLabel) {
587
            if ($groupId < 0) {
588
                $globalGroups[$groupId] = $groupLabel;
589
            }
590
        }
591
592
        return $globalGroups;
593
    }
594
595
    /**
596
     * Gets the label for a shortcut group
597
     *
598
     * @param int $groupId A shortcut group id
599
     * @return string The shortcut group label, can be an empty string if no group was found for the id
600
     */
601
    protected function getShortcutGroupLabel(int $groupId): string
602
    {
603
        return $this->shortcutGroups[$groupId] ?? '';
604
    }
605
606
    /**
607
     * Gets the icon for the shortcut
608
     *
609
     * @param array $row
610
     * @param array $shortcut
611
     * @return string Shortcut icon as img tag
612
     */
613
    protected function getShortcutIcon(array $row, array $shortcut): string
614
    {
615
        $selectFields = [];
616
        switch ($row['module_name']) {
617
            case 'xMOD_alt_doc.php':
618
                $table = $shortcut['table'];
619
                $recordid = $shortcut['recordid'];
620
                $icon = '';
621
622
                if ($shortcut['type'] === 'edit') {
623
                    // Creating the list of fields to include in the SQL query:
624
                    $selectFields[] = 'uid';
625
                    $selectFields[] = 'pid';
626
627
                    if ($table === 'pages') {
628
                        $selectFields[] = 'module';
629
                        $selectFields[] = 'extendToSubpages';
630
                        $selectFields[] = 'doktype';
631
                    }
632
633
                    if (is_array($GLOBALS['TCA'][$table]['ctrl']['enablecolumns'])) {
634
                        $selectFields = array_merge($selectFields, $GLOBALS['TCA'][$table]['ctrl']['enablecolumns']);
635
                    }
636
637
                    if ($GLOBALS['TCA'][$table]['ctrl']['typeicon_column']) {
638
                        $selectFields[] = $GLOBALS['TCA'][$table]['ctrl']['typeicon_column'];
639
                    }
640
641
                    if (BackendUtility::isTableWorkspaceEnabled($table)) {
642
                        $selectFields[] = 't3ver_state';
643
                        $selectFields[] = 't3ver_wsid';
644
                        $selectFields[] = 't3ver_oid';
645
                    }
646
647
                    $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)
648
                        ->getQueryBuilderForTable($table);
649
                    $queryBuilder->select(...array_unique(array_values($selectFields)))
650
                        ->from($table)
651
                        ->where(
652
                            $queryBuilder->expr()->in(
653
                                'uid',
654
                                $queryBuilder->createNamedParameter($recordid, \PDO::PARAM_INT)
655
                            )
656
                        );
657
658
                    $row = $queryBuilder->execute()->fetch();
659
660
                    $icon = $this->iconFactory->getIconForRecord($table, (array)$row, Icon::SIZE_SMALL)->render();
661
                } elseif ($shortcut['type'] === 'new') {
662
                    $icon = $this->iconFactory->getIconForRecord($table, [], Icon::SIZE_SMALL)->render();
663
                }
664
                break;
665
            case 'file_edit':
666
                $icon = $this->iconFactory->getIcon('mimetypes-text-html', Icon::SIZE_SMALL)->render();
667
                break;
668
            case 'wizard_rte':
669
                $icon = $this->iconFactory->getIcon('mimetypes-word', Icon::SIZE_SMALL)->render();
670
                break;
671
            default:
672
                $iconIdentifier = '';
673
                $moduleName = $row['module_name'];
674
675
                if (strpos($moduleName, '_') !== false) {
676
                    [$mainModule, $subModule] = explode('_', $moduleName, 2);
677
                    $iconIdentifier = $this->moduleLoader->modules[$mainModule]['sub'][$subModule]['iconIdentifier'];
678
                } elseif (!empty($moduleName)) {
679
                    $iconIdentifier = $this->moduleLoader->modules[$moduleName]['iconIdentifier'];
680
                }
681
682
                if (!$iconIdentifier) {
683
                    $iconIdentifier = 'empty-empty';
684
                }
685
686
                $icon = $this->iconFactory->getIcon($iconIdentifier, Icon::SIZE_SMALL)->render();
687
        }
688
689
        return $icon;
690
    }
691
692
    /**
693
     * Returns title for the shortcut icon
694
     *
695
     * @param string $shortcutLabel Shortcut label
696
     * @param string $moduleName Backend module name (key)
697
     * @param string $parentModuleName Parent module label
698
     * @return string Title for the shortcut icon
699
     */
700
    protected function getShortcutIconTitle(string $shortcutLabel, string $moduleName, string $parentModuleName = ''): string
701
    {
702
        $languageService = $this->getLanguageService();
703
704
        if (strpos($moduleName, 'xMOD_') === 0) {
705
            $title = substr($moduleName, 5);
706
        } else {
707
            [$mainModule, $subModule] = explode('_', $moduleName);
708
            $mainModuleLabels = $this->moduleLoader->getLabelsForModule($mainModule);
709
            $title = $languageService->sL($mainModuleLabels['title']);
710
711
            if (!empty($subModule)) {
712
                $subModuleLabels = $this->moduleLoader->getLabelsForModule($moduleName);
713
                $title .= '>' . $languageService->sL($subModuleLabels['title']);
714
            }
715
        }
716
717
        if ($parentModuleName) {
718
            $title .= ' (' . $parentModuleName . ')';
719
        }
720
721
        $title .= ': ' . $shortcutLabel;
722
723
        return $title;
724
    }
725
726
    /**
727
     * Return the ID of the page in the URL if found.
728
     *
729
     * @param string $url The URL of the current shortcut link
730
     * @return int If a page ID was found, it is returned. Otherwise: 0
731
     */
732
    protected function extractPageIdFromShortcutUrl(string $url): int
733
    {
734
        return (int)preg_replace('/.*[\\?&]id=([^&]+).*/', '$1', $url);
735
    }
736
737
    /**
738
     * Adds the correct token, if the url is an index.php script
739
     * @todo: this needs love
740
     *
741
     * @param string $url
742
     * @return string
743
     */
744
    protected function getTokenUrl(string $url): string
745
    {
746
        $parsedUrl = parse_url($url);
747
        $parameters = [];
748
        parse_str($parsedUrl['query'] ?? '', $parameters);
749
750
        $uriBuilder = GeneralUtility::makeInstance(UriBuilder::class);
751
        // parse the returnUrl and replace the module token of it
752
        if (!empty($parameters['returnUrl'])) {
753
            $parsedReturnUrl = parse_url($parameters['returnUrl']);
754
            $returnUrlParameters = [];
755
            parse_str($parsedReturnUrl['query'] ?? '', $returnUrlParameters);
756
757
            if (strpos($parsedReturnUrl['path'] ?? '', 'index.php') !== false && !empty($returnUrlParameters['route'])) {
758
                $module = $returnUrlParameters['route'];
759
                $parameters['returnUrl'] = (string)$uriBuilder->buildUriFromRoutePath($module, $returnUrlParameters);
760
                $url = $parsedUrl['path'] . '?' . http_build_query($parameters, '', '&', PHP_QUERY_RFC3986);
761
            }
762
        }
763
764
        if (strpos($parsedUrl['path'], 'index.php') !== false && isset($parameters['route'])) {
765
            $routePath = $parameters['route'];
766
            /** @var \TYPO3\CMS\Backend\Routing\Router $router */
767
            $router = GeneralUtility::makeInstance(Router::class);
768
769
            try {
770
                $route = $router->match($routePath);
771
772
                if ($route) {
0 ignored issues
show
introduced by
$route is of type TYPO3\CMS\Backend\Routing\Route, thus it always evaluated to true.
Loading history...
773
                    $routeIdentifier = $route->getOption('_identifier');
774
                    unset($parameters['route']);
775
                    $url = (string)$uriBuilder->buildUriFromRoute($routeIdentifier, $parameters);
776
                }
777
            } catch (ResourceNotFoundException $e) {
778
                $url = '';
779
            }
780
        }
781
        return $url;
782
    }
783
784
    /**
785
     * Returns the current BE user.
786
     *
787
     * @return BackendUserAuthentication
788
     */
789
    protected function getBackendUser(): BackendUserAuthentication
790
    {
791
        return $GLOBALS['BE_USER'];
792
    }
793
794
    /**
795
     * @return LanguageService
796
     */
797
    protected function getLanguageService(): LanguageService
798
    {
799
        return $GLOBALS['LANG'];
800
    }
801
}
802