Passed
Push — master ( 24f438...f79d5d )
by
unknown
15:07
created

ModuleTemplate::getDynamicTabMenu()   A

Complexity

Conditions 2
Paths 1

Size

Total Lines 16
Code Lines 13

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 13
nc 1
nop 6
dl 0
loc 16
rs 9.8333
c 0
b 0
f 0
1
<?php
2
3
/*
4
 * This file is part of the TYPO3 CMS project.
5
 *
6
 * It is free software; you can redistribute it and/or modify it under
7
 * the terms of the GNU General Public License, either version 2
8
 * of the License, or any later version.
9
 *
10
 * For the full copyright and license information, please read the
11
 * LICENSE.txt file that was distributed with this source code.
12
 *
13
 * The TYPO3 project - inspiring people to share!
14
 */
15
16
namespace TYPO3\CMS\Backend\Template;
17
18
use Psr\Http\Message\ServerRequestInterface;
19
use TYPO3\CMS\Backend\Backend\Shortcut\ShortcutRepository;
20
use TYPO3\CMS\Backend\Routing\Route;
21
use TYPO3\CMS\Backend\Routing\Router;
22
use TYPO3\CMS\Backend\Template\Components\DocHeaderComponent;
23
use TYPO3\CMS\Backend\Utility\BackendUtility;
24
use TYPO3\CMS\Core\Authentication\BackendUserAuthentication;
25
use TYPO3\CMS\Core\Configuration\ExtensionConfiguration;
26
use TYPO3\CMS\Core\Imaging\Icon;
27
use TYPO3\CMS\Core\Imaging\IconFactory;
28
use TYPO3\CMS\Core\Localization\LanguageService;
29
use TYPO3\CMS\Core\Messaging\AbstractMessage;
30
use TYPO3\CMS\Core\Messaging\FlashMessage;
31
use TYPO3\CMS\Core\Messaging\FlashMessageQueue;
32
use TYPO3\CMS\Core\Messaging\FlashMessageService;
33
use TYPO3\CMS\Core\Page\PageRenderer;
34
use TYPO3\CMS\Core\Utility\ExtensionManagementUtility;
35
use TYPO3\CMS\Core\Utility\GeneralUtility;
36
use TYPO3\CMS\Core\Utility\HttpUtility;
37
use TYPO3\CMS\Core\Utility\PathUtility;
38
use TYPO3\CMS\Fluid\View\StandaloneView;
39
use TYPO3Fluid\Fluid\View\ViewInterface;
40
41
/**
42
 * A class taking care of the "outer" HTML of a module, especially
43
 * the doc header and other related parts.
44
 */
45
class ModuleTemplate
46
{
47
    /**
48
     * DocHeaderComponent
49
     *
50
     * @var DocHeaderComponent
51
     */
52
    protected $docHeaderComponent;
53
54
    /**
55
     * Javascript Code Array
56
     * Used for inline JS
57
     *
58
     * @var array
59
     */
60
    protected $javascriptCodeArray = [];
61
62
    /**
63
     * Expose the pageRenderer
64
     *
65
     * @var PageRenderer
66
     */
67
    protected $pageRenderer;
68
69
    /**
70
     * @var bool
71
     */
72
    protected $uiBlock = false;
73
74
    /**
75
     * TemplateRootPath
76
     *
77
     * @var string[]
78
     */
79
    protected $templateRootPaths = ['EXT:backend/Resources/Private/Templates'];
80
81
    /**
82
     * PartialRootPath
83
     *
84
     * @var string[]
85
     */
86
    protected $partialRootPaths = ['EXT:backend/Resources/Private/Partials'];
87
88
    /**
89
     * LayoutRootPath
90
     *
91
     * @var string[]
92
     */
93
    protected $layoutRootPaths = ['EXT:backend/Resources/Private/Layouts'];
94
95
    /**
96
     * Template name
97
     *
98
     * @var string
99
     */
100
    protected $templateFile = 'Module.html';
101
102
    /**
103
     * Fluid Standalone View
104
     *
105
     * @var ViewInterface
106
     */
107
    protected $view;
108
109
    /**
110
     * Content String
111
     *
112
     * @var string
113
     */
114
    protected $content = '';
115
116
    protected IconFactory $iconFactory;
117
    protected FlashMessageQueue $flashMessageQueue;
118
    protected ServerRequestInterface $request;
119
120
    /**
121
     * Module ID
122
     *
123
     * @var string
124
     */
125
    protected $moduleId = '';
126
127
    /**
128
     * Module Name
129
     *
130
     * @var string
131
     */
132
    protected $moduleName = '';
133
134
    /**
135
     * Module Class
136
     *
137
     * @var string
138
     */
139
    protected $moduleClass = '';
140
141
    /**
142
     * Title Tag
143
     *
144
     * @var string
145
     */
146
    protected $title = '';
147
148
    /**
149
     * Body Tag
150
     *
151
     * @var string
152
     */
153
    protected $bodyTag = '<body>';
154
155
    /**
156
     * Returns the current body tag
157
     *
158
     * @return string
159
     */
160
    public function getBodyTag()
161
    {
162
        return $this->bodyTag;
163
    }
164
165
    /**
166
     * Sets the body tag
167
     *
168
     * @param string $bodyTag
169
     * @return self
170
     */
171
    public function setBodyTag($bodyTag): self
172
    {
173
        $this->bodyTag = $bodyTag;
174
        return $this;
175
    }
176
177
    /**
178
     * Gets the standalone view.
179
     *
180
     * @return StandaloneView
181
     */
182
    public function getView()
183
    {
184
        return $this->view;
185
    }
186
187
    /**
188
     * Set content
189
     *
190
     * @param string $content Content of the module
191
     * @return self
192
     */
193
    public function setContent($content): self
194
    {
195
        $this->view->assign('content', $content);
196
        return $this;
197
    }
198
199
    /**
200
     * Set title tag
201
     *
202
     * @param string $title
203
     * @param string $context
204
     * @return self
205
     */
206
    public function setTitle($title, $context = ''): self
207
    {
208
        $titleComponents = [
209
            $title
210
        ];
211
        if ($context !== '') {
212
            $titleComponents[] = $context;
213
        }
214
        $this->title = implode(' · ', $titleComponents);
215
        return $this;
216
    }
217
218
    public function getIconFactory(): IconFactory
219
    {
220
        return $this->iconFactory;
221
    }
222
223
    /**
224
     * Class constructor
225
     * Sets up view and property objects
226
     *
227
     * @param PageRenderer $pageRenderer
228
     * @param IconFactory $iconFactory
229
     * @param FlashMessageService $flashMessageService
230
     * @param ServerRequestInterface|null $request
231
     * @param ViewInterface|null $view
232
     */
233
    public function __construct(
234
        PageRenderer $pageRenderer,
235
        IconFactory $iconFactory,
236
        FlashMessageService $flashMessageService,
237
        ServerRequestInterface $request = null,
238
        ViewInterface $view = null
239
    ) {
240
        $this->pageRenderer = $pageRenderer;
241
        $this->iconFactory = $iconFactory;
242
        $this->flashMessageQueue = $flashMessageService->getMessageQueueByIdentifier();
243
        $this->request = $request ?? $GLOBALS['TYPO3_REQUEST'];
244
245
        $currentRoute = $this->request->getAttribute('route');
246
        if ($currentRoute instanceof Route) {
247
            if ($currentRoute->hasOption('module') && $currentRoute->getOption('module')) {
248
                $moduleConfiguration = $currentRoute->getOption('moduleConfiguration');
249
                if ($moduleConfiguration['name']) {
250
                    $this->setModuleName($moduleConfiguration['name']);
251
                }
252
            } else {
253
                $this->setModuleName($currentRoute->getOption('_identifier'));
254
            }
255
        }
256
        if ($view === null) {
257
            $this->view = GeneralUtility::makeInstance(StandaloneView::class);
258
            $this->view->setPartialRootPaths($this->partialRootPaths);
259
            $this->view->setTemplateRootPaths($this->templateRootPaths);
260
            $this->view->setLayoutRootPaths($this->layoutRootPaths);
261
            $this->view->setTemplate($this->templateFile);
262
        } else {
263
            $this->view = $view;
264
        }
265
        $this->docHeaderComponent = GeneralUtility::makeInstance(DocHeaderComponent::class);
266
        $this->setupPage();
267
        $this->loadJavaScripts();
268
        $this->loadStylesheets();
269
    }
270
271
    /**
272
     * Loads all necessary Javascript Files
273
     */
274
    protected function loadJavaScripts()
275
    {
276
        $this->pageRenderer->loadRequireJsModule('bootstrap');
277
278
        if ($this->getBackendUserAuthentication() && !empty($this->getBackendUserAuthentication()->user)) {
279
            $this->pageRenderer->loadRequireJsModule('TYPO3/CMS/Backend/ContextHelp');
280
            $this->pageRenderer->loadRequireJsModule('TYPO3/CMS/Backend/DocumentHeader');
281
        }
282
        $this->pageRenderer->loadRequireJsModule('TYPO3/CMS/Backend/GlobalEventHandler');
283
        $this->pageRenderer->loadRequireJsModule('TYPO3/CMS/Backend/ActionDispatcher');
284
        $this->pageRenderer->loadRequireJsModule('TYPO3/CMS/Backend/Element/ImmediateActionElement');
285
    }
286
287
    /**
288
     * Loads all necessary stylesheets
289
     */
290
    protected function loadStylesheets()
291
    {
292
        if (!empty($GLOBALS['TBE_STYLES']['stylesheet'])) {
293
            $this->pageRenderer->addCssFile($GLOBALS['TBE_STYLES']['stylesheet']);
294
        }
295
        if (!empty($GLOBALS['TBE_STYLES']['stylesheet2'])) {
296
            $this->pageRenderer->addCssFile($GLOBALS['TBE_STYLES']['stylesheet2']);
297
        }
298
        // Add all *.css files of the directory $path to the stylesheets
299
        foreach ($this->getRegisteredStylesheetFolders() as $folder) {
300
            // Read all files in directory and sort them alphabetically
301
            foreach (GeneralUtility::getFilesInDir($folder, 'css', true) as $cssFile) {
0 ignored issues
show
Bug introduced by
The expression TYPO3\CMS\Core\Utility\G...r($folder, 'css', true) of type string is not traversable.
Loading history...
302
                $this->pageRenderer->addCssFile($cssFile);
303
            }
304
        }
305
    }
306
307
    /**
308
     * Returns an array of all stylesheet directories registered via $TBE_STYLES['skins']
309
     */
310
    protected function getRegisteredStylesheetFolders(): array
311
    {
312
        $stylesheetDirectories = [];
313
        foreach ($GLOBALS['TBE_STYLES']['skins'] ?? [] as $skin) {
314
            foreach ($skin['stylesheetDirectories'] ?? [] as $stylesheetDir) {
315
                $directory = GeneralUtility::getFileAbsFileName($stylesheetDir);
316
                if (!empty($directory)) {
317
                    $stylesheetDirectories[] = $directory;
318
                }
319
            }
320
        }
321
        return $stylesheetDirectories;
322
    }
323
324
    /**
325
     * Sets mandatory parameters for the view (pageRenderer)
326
     */
327
    protected function setupPage()
328
    {
329
        // Yes, hardcoded on purpose
330
        $this->pageRenderer->setXmlPrologAndDocType('<!DOCTYPE html>');
331
        $this->pageRenderer->setCharSet('utf-8');
332
        $this->pageRenderer->setLanguage($this->getLanguageService()->lang);
333
        $this->pageRenderer->setMetaTag('name', 'viewport', 'width=device-width, initial-scale=1');
334
        $this->pageRenderer->setFavIcon($this->getBackendFavicon());
335
        $this->pageRenderer->enableConcatenateCss();
336
        $this->pageRenderer->enableConcatenateJavascript();
337
        $this->pageRenderer->enableCompressCss();
338
        $this->pageRenderer->enableCompressJavascript();
339
        $languageCode = $this->pageRenderer->getLanguage() === 'default' ? 'en' : $this->pageRenderer->getLanguage();
340
        $this->pageRenderer->setHtmlTag('<html lang="' . htmlspecialchars($languageCode) . '">');
341
        if ($GLOBALS['TYPO3_CONF_VARS']['BE']['debug']) {
342
            $this->pageRenderer->enableDebugMode();
343
        }
344
    }
345
346
    /**
347
     * Wrapper function for adding JS inline blocks
348
     */
349
    protected function setJavaScriptCodeArray()
350
    {
351
        foreach ($this->javascriptCodeArray as $name => $code) {
352
            $this->pageRenderer->addJsInlineCode($name, $code, false);
353
        }
354
    }
355
356
    /**
357
     * Adds JS inline blocks of code to the internal registry
358
     *
359
     * @param string $name Javascript code block name
360
     * @param string $code Inline Javascript
361
     * @return self
362
     */
363
    public function addJavaScriptCode($name = '', $code = ''): self
364
    {
365
        $this->javascriptCodeArray[$name] = $code;
366
        return $this;
367
    }
368
369
    /**
370
     * Get the DocHeader
371
     *
372
     * @return DocHeaderComponent
373
     */
374
    public function getDocHeaderComponent()
375
    {
376
        return $this->docHeaderComponent;
377
    }
378
379
    /**
380
     * Returns the fully rendered view
381
     *
382
     * @return string
383
     */
384
    public function renderContent()
385
    {
386
        $this->setJavaScriptCodeArray();
387
        $this->pageRenderer->setTitle($this->title);
388
389
        $this->view->assign('docHeader', $this->docHeaderComponent->docHeaderContent());
390
        if ($this->moduleId) {
391
            $this->view->assign('moduleId', $this->moduleId);
392
        }
393
        if ($this->moduleName) {
394
            $this->view->assign('moduleName', $this->moduleName);
395
        }
396
        if ($this->moduleClass) {
397
            $this->view->assign('moduleClass', $this->moduleClass);
398
        }
399
        $this->view->assign('uiBlock', $this->uiBlock);
400
        $this->view->assign('flashMessageQueueIdentifier', $this->flashMessageQueue->getIdentifier());
401
        $this->pageRenderer->addBodyContent($this->bodyTag . $this->view->render());
402
        $this->pageRenderer->addJsFooterInlineCode('updateSignals', BackendUtility::getUpdateSignalCode());
403
        return $this->pageRenderer->render();
404
    }
405
406
    public function getPageRenderer(): PageRenderer
407
    {
408
        return $this->pageRenderer;
409
    }
410
411
    /**
412
     * Set form tag
413
     *
414
     * @param string $formTag Form tag to add
415
     * @return self
416
     */
417
    public function setForm($formTag = ''): self
418
    {
419
        $this->view->assign('formTag', $formTag);
420
        return $this;
421
    }
422
423
    /**
424
     * Sets the ModuleId
425
     *
426
     * @param string $moduleId ID of the module
427
     * @return self
428
     */
429
    public function setModuleId($moduleId): self
430
    {
431
        $this->moduleId = $moduleId;
432
        $this->registerModuleMenu($moduleId);
433
        return $this;
434
    }
435
436
    /**
437
     * Sets the ModuleName
438
     *
439
     * @param string $moduleName Name of the module
440
     * @return self
441
     */
442
    public function setModuleName($moduleName): self
443
    {
444
        $this->moduleName = $moduleName;
445
        return $this;
446
    }
447
448
    /**
449
     * Sets the ModuleClass
450
     *
451
     * @param string $moduleClass Class of the module
452
     * @return self
453
     */
454
    public function setModuleClass($moduleClass): self
455
    {
456
        $this->moduleClass = $moduleClass;
457
        return $this;
458
    }
459
460
    /**
461
     * Generates the Menu for things like Web->Info
462
     *
463
     * @param string $moduleMenuIdentifier
464
     * @return self
465
     */
466
    public function registerModuleMenu($moduleMenuIdentifier): self
467
    {
468
        if (isset($GLOBALS['TBE_MODULES_EXT'][$moduleMenuIdentifier])) {
469
            $menuEntries =
470
                $GLOBALS['TBE_MODULES_EXT'][$moduleMenuIdentifier]['MOD_MENU']['function'];
471
            $menu = $this->getDocHeaderComponent()->getMenuRegistry()->makeMenu()->setIdentifier('MOD_FUNC');
472
            foreach ($menuEntries as $menuEntry) {
473
                $menuItem = $menu->makeMenuItem()
474
                    ->setTitle($menuEntry['title'])
475
                    ->setHref('#');
476
                $menu->addMenuItem($menuItem);
477
            }
478
            $this->docHeaderComponent->getMenuRegistry()->addMenu($menu);
479
        }
480
        return $this;
481
    }
482
483
    /**
484
     * Creates a tab menu where the tabs or collapsible are rendered with bootstrap markup
485
     *
486
     * @param array $menuItems Tab elements, each element is an array with "label" and "content"
487
     * @param string $domId DOM id attribute, will be appended with an iteration number per tab.
488
     * @param int $defaultTabIndex Default tab to open (for toggle <=0). Value corresponds to integer-array index + 1
489
     *                             (index zero is "1", index "1" is 2 etc.). A value of zero (or something non-existing
490
     *                             will result in no default tab open.
491
     * @param bool $collapsible If set, the tabs are rendered as headers instead over each sheet. Effectively this means
492
     *                          there is no tab menu, but rather a foldout/fold-in menu.
493
     * @param bool $wrapContent If set, the content is wrapped in div structure which provides a padding and border
494
     *                          style. Set this FALSE to get unstyled content pane with fullsize content area.
495
     * @param bool $storeLastActiveTab If set, the last open tab is stored in local storage and will be re-open again.
496
     *                                 If you don't need this feature, e.g. for wizards like import/export you can
497
     *                                 disable this behaviour.
498
     * @return string
499
     */
500
    public function getDynamicTabMenu(array $menuItems, $domId, $defaultTabIndex = 1, $collapsible = false, $wrapContent = true, $storeLastActiveTab = true)
501
    {
502
        $this->pageRenderer->loadRequireJsModule('TYPO3/CMS/Backend/Tabs');
503
        $templatePath = ExtensionManagementUtility::extPath('backend')
504
            . 'Resources/Private/Templates/DocumentTemplate/';
505
        $view = GeneralUtility::makeInstance(StandaloneView::class);
506
        $view->setTemplatePathAndFilename($templatePath . ($collapsible ? 'Collapse.html' : 'Tabs.html'));
507
        $view->setPartialRootPaths([$templatePath . 'Partials']);
508
        $view->assignMultiple([
509
            'id' => 'DTM-' . GeneralUtility::shortMD5($domId),
510
            'items' => $menuItems,
511
            'defaultTabIndex' => $defaultTabIndex,
512
            'wrapContent' => $wrapContent,
513
            'storeLastActiveTab' => $storeLastActiveTab,
514
        ]);
515
        return $view->render();
516
    }
517
518
    /*******************************************
519
     * THE FOLLOWING METHODS ARE SUBJECT TO BE DEPRECATED / DROPPED!
520
     *
521
     * These methods have been copied over from DocumentTemplate and enables
522
     * core modules to drop the dependency to DocumentTemplate altogether without
523
     * rewriting these modules now.
524
     * The methods below are marked as internal and will be removed
525
     * one-by-one with further refactoring of modules.
526
     *
527
     * Do not use these methods within own extensions if possible or
528
     * be prepared to change this later again.
529
     *******************************************/
530
    /**
531
     * Returns a linked shortcut-icon which will call the shortcut frame and set a
532
     * shortcut there back to the calling page/module
533
     *
534
     * @param string $gvList Is the list of GET variables to store (if any)
535
     * @param string $setList Is the list of SET[] variables to store
536
     * (if any) - SET[] variables a stored in $GLOBALS["SOBE"]->MOD_SETTINGS
537
     * for backend modules
538
     * @param string $modName Module name string
539
     * @param string|int $motherModName Is used to enter the "parent module
540
     * name" if the module is a submodule under eg. Web>* or File>*. You
541
     * can also set this value to 1 in which case the currentLoadedModule
542
     * is sent to the shortcut script (so - not a fixed value!) - that is used
543
     * in file_edit and wizard_rte modules where those are really running as
544
     * a part of another module.
545
     * @param string $displayName When given this name is used instead of the
546
     * module name.
547
     * @param string $classes Additional CSS classes for the link around the icon
548
     *
549
     * @return string HTML content
550
     * @todo Make this thing return a button object
551
     * @internal
552
     * @deprecated since v11, will be removed in v12
553
     */
554
    public function makeShortcutIcon($gvList, $setList, $modName, $motherModName = '', $displayName = '', $classes = 'btn btn-default btn-sm')
555
    {
556
        trigger_error('Method makeShortcutIcon() is deprecated and will be removed in v12. Please use ShortcutButton->setArguments() instead.', E_USER_DEPRECATED);
557
        $gvList = 'route,id,' . $gvList;
558
        $storeUrl = $this->makeShortcutUrl($gvList, $setList);
559
        $pathInfo = parse_url($GLOBALS['TYPO3_REQUEST']->getAttribute('normalizedParams')->getRequestUri());
560
        // Fallback for alt_mod. We still pass in the old xMOD... stuff,
561
        // but TBE_MODULES only knows about "record_edit".
562
        // We still need to pass the xMOD name to createShortcut below,
563
        // since this is used for icons.
564
        $moduleName = $modName === 'xMOD_alt_doc.php' ? 'record_edit' : $modName;
565
        // Add the module identifier automatically if typo3/index.php is used:
566
        // @todo: routing
567
        if (GeneralUtility::_GET('route') !== null) {
568
            $storeUrl = '&route=' . $moduleName . $storeUrl;
569
        }
570
571
        $shortcutUrl = $pathInfo['path'] . '?' . $storeUrl;
572
573
        // We simply let the above functionality as it is for maximum backwards compatibility and now
574
        // just process the generated $shortcutUrl to match the new format (routeIdentifier & arguments)
575
        [$routeIdentifier, $arguments] = $this->getCreateShortcutProperties($shortcutUrl);
576
577
        if (GeneralUtility::makeInstance(ShortcutRepository::class)->shortcutExists($routeIdentifier, $arguments)) {
578
            return '<a class="active ' . htmlspecialchars($classes) . '" title="">' .
579
            $this->iconFactory->getIcon('actions-system-shortcut-active', Icon::SIZE_SMALL)->render() . '</a>';
580
        }
581
582
        $confirmationText =  $this->getLanguageService()->sL('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:labels.makeBookmark');
583
        $onClick = 'top.TYPO3.ShortcutMenu.createShortcut('
584
            . GeneralUtility::quoteJSvalue($routeIdentifier)
585
            . ', ' . GeneralUtility::quoteJSvalue($arguments)
586
            . ', ' . GeneralUtility::quoteJSvalue($displayName)
587
            . ', ' . GeneralUtility::quoteJSvalue($confirmationText)
588
            . ', this);return false;';
589
590
        return '<a href="#" class="' . htmlspecialchars($classes) . '" onclick="' . htmlspecialchars($onClick) . '" title="' .
591
        htmlspecialchars($confirmationText) . '">' .
592
        $this->iconFactory->getIcon('actions-system-shortcut-new', Icon::SIZE_SMALL)->render() . '</a>';
593
    }
594
595
    /**
596
     * MAKE url for storing
597
     * Internal func
598
     *
599
     * @param string $gvList Is the list of GET variables to store (if any)
600
     * @param string $setList Is the list of SET[] variables to store (if any)
601
     * - SET[] variables a stored in $GLOBALS["SOBE"]->MOD_SETTINGS for backend
602
     * modules
603
     *
604
     * @return string GET-parameters for the shortcut-url only(!). String starts with '&'
605
     * @internal
606
     * @deprecated since v11, will be removed in v12. Deprecation logged by parent method makeShortcutIcon()
607
     */
608
    public function makeShortcutUrl($gvList, $setList)
609
    {
610
        $getParams = GeneralUtility::_GET();
611
        $storeArray = array_merge(
612
            GeneralUtility::compileSelectedGetVarsFromArray($gvList, $getParams),
613
            ['SET' => GeneralUtility::compileSelectedGetVarsFromArray($setList, (array)($GLOBALS['SOBE']->MOD_SETTINGS ?? []))]
614
        );
615
        return HttpUtility::buildQueryString($storeArray, '&');
616
    }
617
618
    /**
619
     * Process the generated shortcut url and return properties needed for the
620
     * shortcut registration with route identifier and JSON encoded arguments.
621
     *
622
     * @param string $shortcutUrl
623
     *
624
     * @return array
625
     * @deprecated Only for backwards compatibility. Can be removed in v12
626
     */
627
    protected function getCreateShortcutProperties(string $shortcutUrl): array
628
    {
629
        $routeIdentifier = '';
630
        $arguments = [];
631
632
        parse_str(parse_url($shortcutUrl)['query'] ?? '', $arguments);
633
        $routePath = (string)($arguments['route'] ?? '');
634
635
        if ($routePath !== '') {
636
            foreach (GeneralUtility::makeInstance(Router::class)->getRoutes() as $identifier => $route) {
637
                if ($route->getPath() === $routePath
638
                    && (
639
                        $route->hasOption('moduleName')
640
                        || in_array($identifier, ['record_edit', 'file_edit', 'wizard_rte'], true)
641
                    )
642
                ) {
643
                    $routeIdentifier = $identifier;
644
                }
645
            }
646
        }
647
648
        unset($arguments['route'], $arguments['returnUrl']);
649
650
        return [$routeIdentifier, json_encode($arguments)];
651
    }
652
653
    /**
654
     * Retrieves configured favicon for backend (with fallback)
655
     *
656
     * @return string
657
     */
658
    protected function getBackendFavicon()
659
    {
660
        $backendFavicon = GeneralUtility::makeInstance(ExtensionConfiguration::class)->get('backend', 'backendFavicon');
661
        if (!empty($backendFavicon)) {
662
            $path = $this->getUriForFileName($backendFavicon);
663
        } else {
664
            $path = ExtensionManagementUtility::extPath('backend') . 'Resources/Public/Icons/favicon.ico';
665
        }
666
        return PathUtility::getAbsoluteWebPath($path);
667
    }
668
669
    /**
670
     * Returns the uri of a relative reference, resolves the "EXT:" prefix
671
     * (way of referring to files inside extensions) and checks that the file is inside
672
     * the project root of the TYPO3 installation
673
     *
674
     * @param string $filename The input filename/filepath to evaluate
675
     * @return string Returns the filename of $filename if valid, otherwise blank string.
676
     */
677
    protected function getUriForFileName($filename)
678
    {
679
        if (strpos($filename, '://')) {
680
            return $filename;
681
        }
682
        $urlPrefix = '';
683
        if (strpos($filename, 'EXT:') === 0) {
684
            $absoluteFilename = GeneralUtility::getFileAbsFileName($filename);
685
            $filename = '';
686
            if ($absoluteFilename !== '') {
687
                $filename = PathUtility::getAbsoluteWebPath($absoluteFilename);
688
            }
689
        } elseif (strpos($filename, '/') !== 0) {
690
            $urlPrefix = GeneralUtility::getIndpEnv('TYPO3_SITE_PATH');
691
        }
692
        return $urlPrefix . $filename;
693
    }
694
695
    /**
696
     * Returns the BE USER Object
697
     *
698
     * @return BackendUserAuthentication
699
     */
700
    protected function getBackendUserAuthentication()
701
    {
702
        return $GLOBALS['BE_USER'];
703
    }
704
705
    /**
706
     * Returns the LanguageService
707
     *
708
     * @return LanguageService
709
     */
710
    protected function getLanguageService()
711
    {
712
        return $GLOBALS['LANG'];
713
    }
714
715
    /**
716
     * Returns the header-bar in the top of most backend modules
717
     * Closes section if open.
718
     *
719
     * @param string $text The text string for the header
720
     * @return string HTML content
721
     * @internal
722
     */
723
    public function header($text)
724
    {
725
        return '
726
727
	<!-- MAIN Header in page top -->
728
	<h1 class="t3js-title-inlineedit">' . htmlspecialchars($text) . '</h1>
729
';
730
    }
731
732
    /**
733
     * Creates a Message object and adds it to the FlashMessageQueue.
734
     *
735
     * @param string $messageBody The message
736
     * @param string $messageTitle Optional message title
737
     * @param int $severity Optional severity, must be one of \TYPO3\CMS\Core\Messaging\FlashMessage constants
738
     * @param bool $storeInSession Optional, defines whether the message should be stored in the session (default)
739
     * @throws \InvalidArgumentException if the message body is no string
740
     * @return self
741
     */
742
    public function addFlashMessage($messageBody, $messageTitle = '', $severity = AbstractMessage::OK, $storeInSession = true): self
743
    {
744
        if (!is_string($messageBody)) {
0 ignored issues
show
introduced by
The condition is_string($messageBody) is always true.
Loading history...
745
            throw new \InvalidArgumentException('The message body must be of type string, "' . gettype($messageBody) . '" given.', 1446483133);
746
        }
747
        /* @var \TYPO3\CMS\Core\Messaging\FlashMessage $flashMessage */
748
        $flashMessage = GeneralUtility::makeInstance(
749
            FlashMessage::class,
750
            $messageBody,
751
            $messageTitle,
752
            $severity,
753
            $storeInSession
754
        );
755
        $this->flashMessageQueue->enqueue($flashMessage);
756
        return $this;
757
    }
758
759
    /**
760
     * @param FlashMessageQueue $flashMessageQueue
761
     * @return self
762
     */
763
    public function setFlashMessageQueue($flashMessageQueue): self
764
    {
765
        $this->flashMessageQueue = $flashMessageQueue;
766
        return $this;
767
    }
768
769
    /**
770
     * @return bool
771
     */
772
    public function isUiBlock(): bool
773
    {
774
        return $this->uiBlock;
775
    }
776
777
    /**
778
     * @param bool $uiBlock
779
     * @return self
780
     */
781
    public function setUiBlock(bool $uiBlock): self
782
    {
783
        $this->uiBlock = $uiBlock;
784
        return $this;
785
    }
786
}
787