Passed
Push — master ( d5a28b...d12ca0 )
by
unknown
17:01
created

ModuleTemplate::setContent()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 4
rs 10
c 0
b 0
f 0
cc 1
eloc 2
nc 1
nop 1
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 StandaloneView
106
     */
107
    protected $view;
108
109
    /**
110
     * Content String
111
     *
112
     * @var string
113
     */
114
    protected $content = '';
115
116
    protected IconFactory $iconFactory;
117
    protected FlashMessageService $flashMessageService;
118
    protected FlashMessageQueue $flashMessageQueue;
119
    protected ServerRequestInterface $request;
120
121
    /**
122
     * Module ID
123
     *
124
     * @var string
125
     */
126
    protected $moduleId = '';
127
128
    /**
129
     * Module Name
130
     *
131
     * @var string
132
     */
133
    protected $moduleName = '';
134
135
    /**
136
     * Title Tag
137
     *
138
     * @var string
139
     */
140
    protected $title = '';
141
142
    /**
143
     * Body Tag
144
     *
145
     * @var string
146
     */
147
    protected $bodyTag = '<body>';
148
149
    /**
150
     * Returns the current body tag
151
     *
152
     * @return string
153
     */
154
    public function getBodyTag()
155
    {
156
        return $this->bodyTag;
157
    }
158
159
    /**
160
     * Sets the body tag
161
     *
162
     * @param string $bodyTag
163
     * @return self
164
     */
165
    public function setBodyTag($bodyTag): self
166
    {
167
        $this->bodyTag = $bodyTag;
168
        return $this;
169
    }
170
171
    /**
172
     * Gets the standalone view.
173
     *
174
     * @return StandaloneView
175
     */
176
    public function getView()
177
    {
178
        return $this->view;
179
    }
180
181
    /**
182
     * Set content
183
     *
184
     * @param string $content Content of the module
185
     * @return self
186
     */
187
    public function setContent($content): self
188
    {
189
        $this->view->assign('content', $content);
190
        return $this;
191
    }
192
193
    /**
194
     * Set title tag
195
     *
196
     * @param string $title
197
     * @return self
198
     */
199
    public function setTitle($title): self
200
    {
201
        $this->title = $title;
202
        return $this;
203
    }
204
205
    public function getIconFactory(): IconFactory
206
    {
207
        return $this->iconFactory;
208
    }
209
210
    /**
211
     * Class constructor
212
     * Sets up view and property objects
213
     *
214
     * @param PageRenderer $pageRenderer
215
     * @param IconFactory $iconFactory
216
     * @param FlashMessageService $flashMessageService
217
     * @param ServerRequestInterface|null $request
218
     * @param ViewInterface|null $view
219
     */
220
    public function __construct(
221
        PageRenderer $pageRenderer,
222
        IconFactory $iconFactory,
223
        FlashMessageService $flashMessageService,
224
        ServerRequestInterface $request = null,
225
        ViewInterface $view = null
226
    ) {
227
        $this->pageRenderer = $pageRenderer;
228
        $this->iconFactory = $iconFactory;
229
        $this->flashMessageService = $flashMessageService;
230
        $this->request = $request ?? $GLOBALS['TYPO3_REQUEST'];
231
232
        $currentRoute = $this->request->getAttribute('route');
233
        if ($currentRoute instanceof Route) {
234
            if ($currentRoute->hasOption('module') && $currentRoute->getOption('module')) {
235
                $moduleConfiguration = $currentRoute->getOption('moduleConfiguration');
236
                if ($moduleConfiguration['name']) {
237
                    $this->setModuleName($moduleConfiguration['name']);
238
                }
239
            } else {
240
                $this->setModuleName($currentRoute->getOption('_identifier'));
241
            }
242
        }
243
        if ($view === null) {
244
            $this->view = GeneralUtility::makeInstance(StandaloneView::class);
245
            $this->view->setPartialRootPaths($this->partialRootPaths);
246
            $this->view->setTemplateRootPaths($this->templateRootPaths);
247
            $this->view->setLayoutRootPaths($this->layoutRootPaths);
248
            $this->view->setTemplate($this->templateFile);
249
        } else {
250
            $this->view = $view;
0 ignored issues
show
Documentation Bug introduced by
$view is of type TYPO3Fluid\Fluid\View\ViewInterface, but the property $view was declared to be of type TYPO3\CMS\Fluid\View\StandaloneView. Are you sure that you always receive this specific sub-class here, or does it make sense to add an instanceof check?

Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a given class or a super-class is assigned to a property that is type hinted more strictly.

Either this assignment is in error or an instanceof check should be added for that assignment.

class Alien {}

class Dalek extends Alien {}

class Plot
{
    /** @var  Dalek */
    public $villain;
}

$alien = new Alien();
$plot = new Plot();
if ($alien instanceof Dalek) {
    $plot->villain = $alien;
}
Loading history...
251
        }
252
        $this->docHeaderComponent = GeneralUtility::makeInstance(DocHeaderComponent::class);
253
        $this->setupPage();
254
        $this->loadJavaScripts();
255
        $this->loadStylesheets();
256
    }
257
258
    /**
259
     * Loads all necessary Javascript Files
260
     */
261
    protected function loadJavaScripts()
262
    {
263
        $this->pageRenderer->loadRequireJsModule('bootstrap');
264
265
        if ($this->getBackendUserAuthentication() && !empty($this->getBackendUserAuthentication()->user)) {
266
            $this->pageRenderer->loadRequireJsModule('TYPO3/CMS/Backend/ContextHelp');
267
            $this->pageRenderer->loadRequireJsModule('TYPO3/CMS/Backend/DocumentHeader');
268
        }
269
        $this->pageRenderer->loadRequireJsModule('TYPO3/CMS/Backend/GlobalEventHandler');
270
        $this->pageRenderer->loadRequireJsModule('TYPO3/CMS/Backend/ActionDispatcher');
271
        $this->pageRenderer->loadRequireJsModule('TYPO3/CMS/Backend/Element/ImmediateActionElement');
272
    }
273
274
    /**
275
     * Loads all necessary stylesheets
276
     */
277
    protected function loadStylesheets()
278
    {
279
        if (!empty($GLOBALS['TBE_STYLES']['stylesheet'])) {
280
            $this->pageRenderer->addCssFile($GLOBALS['TBE_STYLES']['stylesheet']);
281
        }
282
        if (!empty($GLOBALS['TBE_STYLES']['stylesheet2'])) {
283
            $this->pageRenderer->addCssFile($GLOBALS['TBE_STYLES']['stylesheet2']);
284
        }
285
        // Add all *.css files of the directory $path to the stylesheets
286
        foreach ($this->getRegisteredStylesheetFolders() as $folder) {
287
            // Read all files in directory and sort them alphabetically
288
            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...
289
                $this->pageRenderer->addCssFile($cssFile);
290
            }
291
        }
292
    }
293
294
    /**
295
     * Returns an array of all stylesheet directories registered via $TBE_STYLES['skins']
296
     */
297
    protected function getRegisteredStylesheetFolders(): array
298
    {
299
        $stylesheetDirectories = [];
300
        foreach ($GLOBALS['TBE_STYLES']['skins'] ?? [] as $skin) {
301
            foreach ($skin['stylesheetDirectories'] ?? [] as $stylesheetDir) {
302
                $directory = GeneralUtility::getFileAbsFileName($stylesheetDir);
303
                if (!empty($directory)) {
304
                    $stylesheetDirectories[] = $directory;
305
                }
306
            }
307
        }
308
        return $stylesheetDirectories;
309
    }
310
311
    /**
312
     * Sets mandatory parameters for the view (pageRenderer)
313
     */
314
    protected function setupPage()
315
    {
316
        // Yes, hardcoded on purpose
317
        $this->pageRenderer->setXmlPrologAndDocType('<!DOCTYPE html>');
318
        $this->pageRenderer->setCharSet('utf-8');
319
        $this->pageRenderer->setLanguage($this->getLanguageService()->lang);
320
        $this->pageRenderer->setMetaTag('name', 'viewport', 'width=device-width, initial-scale=1');
321
        $this->pageRenderer->setFavIcon($this->getBackendFavicon());
322
        $this->pageRenderer->enableConcatenateCss();
323
        $this->pageRenderer->enableConcatenateJavascript();
324
        $this->pageRenderer->enableCompressCss();
325
        $this->pageRenderer->enableCompressJavascript();
326
        $languageCode = $this->pageRenderer->getLanguage() === 'default' ? 'en' : $this->pageRenderer->getLanguage();
327
        $this->pageRenderer->setHtmlTag('<html lang="' . htmlspecialchars($languageCode) . '">');
328
        if ($GLOBALS['TYPO3_CONF_VARS']['BE']['debug']) {
329
            $this->pageRenderer->enableDebugMode();
330
        }
331
    }
332
333
    /**
334
     * Wrapper function for adding JS inline blocks
335
     */
336
    protected function setJavaScriptCodeArray()
337
    {
338
        foreach ($this->javascriptCodeArray as $name => $code) {
339
            $this->pageRenderer->addJsInlineCode($name, $code, false);
340
        }
341
    }
342
343
    /**
344
     * Adds JS inline blocks of code to the internal registry
345
     *
346
     * @param string $name Javascript code block name
347
     * @param string $code Inline Javascript
348
     * @return self
349
     */
350
    public function addJavaScriptCode($name = '', $code = ''): self
351
    {
352
        $this->javascriptCodeArray[$name] = $code;
353
        return $this;
354
    }
355
356
    /**
357
     * Get the DocHeader
358
     *
359
     * @return DocHeaderComponent
360
     */
361
    public function getDocHeaderComponent()
362
    {
363
        return $this->docHeaderComponent;
364
    }
365
366
    /**
367
     * Returns the fully rendered view
368
     *
369
     * @return string
370
     */
371
    public function renderContent()
372
    {
373
        $this->setJavaScriptCodeArray();
374
        $this->pageRenderer->setTitle($this->title);
375
376
        $this->view->assign('docHeader', $this->docHeaderComponent->docHeaderContent());
377
        if ($this->moduleId) {
378
            $this->view->assign('moduleId', $this->moduleId);
379
        }
380
        if ($this->moduleName) {
381
            $this->view->assign('moduleName', $this->moduleName);
382
        }
383
        $this->view->assign('uiBlock', $this->uiBlock);
384
        $this->view->assign('flashMessageQueueIdentifier', $this->getFlashMessageQueue()->getIdentifier());
385
        $this->pageRenderer->addBodyContent($this->bodyTag . $this->view->render());
386
        $this->pageRenderer->addJsFooterInlineCode('updateSignals', BackendUtility::getUpdateSignalCode());
387
        return $this->pageRenderer->render();
388
    }
389
390
    public function getPageRenderer(): PageRenderer
391
    {
392
        return $this->pageRenderer;
393
    }
394
395
    /**
396
     * Set form tag
397
     *
398
     * @param string $formTag Form tag to add
399
     * @return self
400
     */
401
    public function setForm($formTag = ''): self
402
    {
403
        $this->view->assign('formTag', $formTag);
404
        return $this;
405
    }
406
407
    /**
408
     * Sets the ModuleId
409
     *
410
     * @param string $moduleId ID of the module
411
     * @return self
412
     */
413
    public function setModuleId($moduleId): self
414
    {
415
        $this->moduleId = $moduleId;
416
        $this->registerModuleMenu($moduleId);
417
        return $this;
418
    }
419
420
    /**
421
     * Sets the ModuleName
422
     *
423
     * @param string $moduleName Name of the module
424
     * @return self
425
     */
426
    public function setModuleName($moduleName): self
427
    {
428
        $this->moduleName = $moduleName;
429
        return $this;
430
    }
431
432
    /**
433
     * Generates the Menu for things like Web->Info
434
     *
435
     * @param string $moduleMenuIdentifier
436
     * @return self
437
     */
438
    public function registerModuleMenu($moduleMenuIdentifier): self
439
    {
440
        if (isset($GLOBALS['TBE_MODULES_EXT'][$moduleMenuIdentifier])) {
441
            $menuEntries =
442
                $GLOBALS['TBE_MODULES_EXT'][$moduleMenuIdentifier]['MOD_MENU']['function'];
443
            $menu = $this->getDocHeaderComponent()->getMenuRegistry()->makeMenu()->setIdentifier('MOD_FUNC');
444
            foreach ($menuEntries as $menuEntry) {
445
                $menuItem = $menu->makeMenuItem()
446
                    ->setTitle($menuEntry['title'])
447
                    ->setHref('#');
448
                $menu->addMenuItem($menuItem);
449
            }
450
            $this->docHeaderComponent->getMenuRegistry()->addMenu($menu);
451
        }
452
        return $this;
453
    }
454
455
    /**
456
     * Creates a tab menu where the tabs or collapsible are rendered with bootstrap markup
457
     *
458
     * @param array $menuItems Tab elements, each element is an array with "label" and "content"
459
     * @param string $domId DOM id attribute, will be appended with an iteration number per tab.
460
     * @param int $defaultTabIndex Default tab to open (for toggle <=0). Value corresponds to integer-array index + 1
461
     *                             (index zero is "1", index "1" is 2 etc.). A value of zero (or something non-existing
462
     *                             will result in no default tab open.
463
     * @param bool $collapsible If set, the tabs are rendered as headers instead over each sheet. Effectively this means
464
     *                          there is no tab menu, but rather a foldout/fold-in menu.
465
     * @param bool $wrapContent If set, the content is wrapped in div structure which provides a padding and border
466
     *                          style. Set this FALSE to get unstyled content pane with fullsize content area.
467
     * @param bool $storeLastActiveTab If set, the last open tab is stored in local storage and will be re-open again.
468
     *                                 If you don't need this feature, e.g. for wizards like import/export you can
469
     *                                 disable this behaviour.
470
     * @return string
471
     */
472
    public function getDynamicTabMenu(array $menuItems, $domId, $defaultTabIndex = 1, $collapsible = false, $wrapContent = true, $storeLastActiveTab = true)
473
    {
474
        $this->pageRenderer->loadRequireJsModule('TYPO3/CMS/Backend/Tabs');
475
        $templatePath = ExtensionManagementUtility::extPath('backend')
476
            . 'Resources/Private/Templates/DocumentTemplate/';
477
        $view = GeneralUtility::makeInstance(StandaloneView::class);
478
        $view->setTemplatePathAndFilename($templatePath . ($collapsible ? 'Collapse.html' : 'Tabs.html'));
479
        $view->setPartialRootPaths([$templatePath . 'Partials']);
480
        $view->assignMultiple([
481
            'id' => 'DTM-' . GeneralUtility::shortMD5($domId),
482
            'items' => $menuItems,
483
            'defaultTabIndex' => $defaultTabIndex,
484
            'wrapContent' => $wrapContent,
485
            'storeLastActiveTab' => $storeLastActiveTab,
486
        ]);
487
        return $view->render();
488
    }
489
490
    /*******************************************
491
     * THE FOLLOWING METHODS ARE SUBJECT TO BE DEPRECATED / DROPPED!
492
     *
493
     * These methods have been copied over from DocumentTemplate and enables
494
     * core modules to drop the dependency to DocumentTemplate altogether without
495
     * rewriting these modules now.
496
     * The methods below are marked as internal and will be removed
497
     * one-by-one with further refactoring of modules.
498
     *
499
     * Do not use these methods within own extensions if possible or
500
     * be prepared to change this later again.
501
     *******************************************/
502
    /**
503
     * Returns a linked shortcut-icon which will call the shortcut frame and set a
504
     * shortcut there back to the calling page/module
505
     *
506
     * @param string $gvList Is the list of GET variables to store (if any)
507
     * @param string $setList Is the list of SET[] variables to store
508
     * (if any) - SET[] variables a stored in $GLOBALS["SOBE"]->MOD_SETTINGS
509
     * for backend modules
510
     * @param string $modName Module name string
511
     * @param string|int $motherModName Is used to enter the "parent module
512
     * name" if the module is a submodule under eg. Web>* or File>*. You
513
     * can also set this value to 1 in which case the currentLoadedModule
514
     * is sent to the shortcut script (so - not a fixed value!) - that is used
515
     * in file_edit and wizard_rte modules where those are really running as
516
     * a part of another module.
517
     * @param string $displayName When given this name is used instead of the
518
     * module name.
519
     * @param string $classes Additional CSS classes for the link around the icon
520
     *
521
     * @return string HTML content
522
     * @todo Make this thing return a button object
523
     * @internal
524
     * @deprecated since v11, will be removed in v12
525
     */
526
    public function makeShortcutIcon($gvList, $setList, $modName, $motherModName = '', $displayName = '', $classes = 'btn btn-default btn-sm')
527
    {
528
        trigger_error('Method makeShortcutIcon() is deprecated and will be removed in v12. Please use ShortcutButton->setArguments() instead.', E_USER_DEPRECATED);
529
        $gvList = 'route,id,' . $gvList;
530
        $storeUrl = $this->makeShortcutUrl($gvList, $setList);
531
        $pathInfo = parse_url($GLOBALS['TYPO3_REQUEST']->getAttribute('normalizedParams')->getRequestUri());
532
        // Fallback for alt_mod. We still pass in the old xMOD... stuff,
533
        // but TBE_MODULES only knows about "record_edit".
534
        // We still need to pass the xMOD name to createShortcut below,
535
        // since this is used for icons.
536
        $moduleName = $modName === 'xMOD_alt_doc.php' ? 'record_edit' : $modName;
537
        // Add the module identifier automatically if typo3/index.php is used:
538
        // @todo: routing
539
        if (GeneralUtility::_GET('route') !== null) {
540
            $storeUrl = '&route=' . $moduleName . $storeUrl;
541
        }
542
543
        $shortcutUrl = $pathInfo['path'] . '?' . $storeUrl;
544
545
        // We simply let the above functionality as it is for maximum backwards compatibility and now
546
        // just process the generated $shortcutUrl to match the new format (routeIdentifier & arguments)
547
        [$routeIdentifier, $arguments] = $this->getCreateShortcutProperties($shortcutUrl);
548
549
        if (GeneralUtility::makeInstance(ShortcutRepository::class)->shortcutExists($routeIdentifier, $arguments)) {
550
            return '<a class="active ' . htmlspecialchars($classes) . '" title="">' .
551
            $this->iconFactory->getIcon('actions-system-shortcut-active', Icon::SIZE_SMALL)->render() . '</a>';
552
        }
553
554
        $confirmationText =  $this->getLanguageService()->sL('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:labels.makeBookmark');
555
        $onClick = 'top.TYPO3.ShortcutMenu.createShortcut('
556
            . GeneralUtility::quoteJSvalue($routeIdentifier)
557
            . ', ' . GeneralUtility::quoteJSvalue($arguments)
558
            . ', ' . GeneralUtility::quoteJSvalue($displayName)
559
            . ', ' . GeneralUtility::quoteJSvalue($confirmationText)
560
            . ', this);return false;';
561
562
        return '<a href="#" class="' . htmlspecialchars($classes) . '" onclick="' . htmlspecialchars($onClick) . '" title="' .
563
        htmlspecialchars($confirmationText) . '">' .
564
        $this->iconFactory->getIcon('actions-system-shortcut-new', Icon::SIZE_SMALL)->render() . '</a>';
565
    }
566
567
    /**
568
     * MAKE url for storing
569
     * Internal func
570
     *
571
     * @param string $gvList Is the list of GET variables to store (if any)
572
     * @param string $setList Is the list of SET[] variables to store (if any)
573
     * - SET[] variables a stored in $GLOBALS["SOBE"]->MOD_SETTINGS for backend
574
     * modules
575
     *
576
     * @return string GET-parameters for the shortcut-url only(!). String starts with '&'
577
     * @internal
578
     * @deprecated since v11, will be removed in v12. Deprecation logged by parent method makeShortcutIcon()
579
     */
580
    public function makeShortcutUrl($gvList, $setList)
581
    {
582
        $getParams = GeneralUtility::_GET();
583
        $storeArray = array_merge(
584
            GeneralUtility::compileSelectedGetVarsFromArray($gvList, $getParams),
585
            ['SET' => GeneralUtility::compileSelectedGetVarsFromArray($setList, (array)($GLOBALS['SOBE']->MOD_SETTINGS ?? []))]
586
        );
587
        return HttpUtility::buildQueryString($storeArray, '&');
588
    }
589
590
    /**
591
     * Process the generated shortcut url and return properties needed for the
592
     * shortcut registration with route identifier and JSON encoded arguments.
593
     *
594
     * @param string $shortcutUrl
595
     *
596
     * @return array
597
     * @deprecated Only for backwards compatibility. Can be removed in v12
598
     */
599
    protected function getCreateShortcutProperties(string $shortcutUrl): array
600
    {
601
        $routeIdentifier = '';
602
        $arguments = [];
603
604
        parse_str(parse_url($shortcutUrl)['query'] ?? '', $arguments);
605
        $routePath = (string)($arguments['route'] ?? '');
606
607
        if ($routePath !== '') {
608
            foreach (GeneralUtility::makeInstance(Router::class)->getRoutes() as $identifier => $route) {
609
                if ($route->getPath() === $routePath
610
                    && (
611
                        $route->hasOption('moduleName')
612
                        || in_array($identifier, ['record_edit', 'file_edit', 'wizard_rte'], true)
613
                    )
614
                ) {
615
                    $routeIdentifier = $identifier;
616
                }
617
            }
618
        }
619
620
        unset($arguments['route'], $arguments['returnUrl']);
621
622
        return [$routeIdentifier, json_encode($arguments)];
623
    }
624
625
    /**
626
     * Retrieves configured favicon for backend (with fallback)
627
     *
628
     * @return string
629
     */
630
    protected function getBackendFavicon()
631
    {
632
        $backendFavicon = GeneralUtility::makeInstance(ExtensionConfiguration::class)->get('backend', 'backendFavicon');
633
        if (!empty($backendFavicon)) {
634
            $path = $this->getUriForFileName($backendFavicon);
635
        } else {
636
            $path = ExtensionManagementUtility::extPath('backend') . 'Resources/Public/Icons/favicon.ico';
637
        }
638
        return PathUtility::getAbsoluteWebPath($path);
639
    }
640
641
    /**
642
     * Returns the uri of a relative reference, resolves the "EXT:" prefix
643
     * (way of referring to files inside extensions) and checks that the file is inside
644
     * the project root of the TYPO3 installation
645
     *
646
     * @param string $filename The input filename/filepath to evaluate
647
     * @return string Returns the filename of $filename if valid, otherwise blank string.
648
     */
649
    protected function getUriForFileName($filename)
650
    {
651
        if (strpos($filename, '://')) {
652
            return $filename;
653
        }
654
        $urlPrefix = '';
655
        if (strpos($filename, 'EXT:') === 0) {
656
            $absoluteFilename = GeneralUtility::getFileAbsFileName($filename);
657
            $filename = '';
658
            if ($absoluteFilename !== '') {
659
                $filename = PathUtility::getAbsoluteWebPath($absoluteFilename);
660
            }
661
        } elseif (strpos($filename, '/') !== 0) {
662
            $urlPrefix = GeneralUtility::getIndpEnv('TYPO3_SITE_PATH');
663
        }
664
        return $urlPrefix . $filename;
665
    }
666
667
    /**
668
     * Returns the BE USER Object
669
     *
670
     * @return BackendUserAuthentication
671
     */
672
    protected function getBackendUserAuthentication()
673
    {
674
        return $GLOBALS['BE_USER'];
675
    }
676
677
    /**
678
     * Returns the LanguageService
679
     *
680
     * @return LanguageService
681
     */
682
    protected function getLanguageService()
683
    {
684
        return $GLOBALS['LANG'];
685
    }
686
687
    /**
688
     * Returns the header-bar in the top of most backend modules
689
     * Closes section if open.
690
     *
691
     * @param string $text The text string for the header
692
     * @return string HTML content
693
     * @internal
694
     */
695
    public function header($text)
696
    {
697
        return '
698
699
	<!-- MAIN Header in page top -->
700
	<h1 class="t3js-title-inlineedit">' . htmlspecialchars($text) . '</h1>
701
';
702
    }
703
704
    /**
705
     * Creates a Message object and adds it to the FlashMessageQueue.
706
     *
707
     * @param string $messageBody The message
708
     * @param string $messageTitle Optional message title
709
     * @param int $severity Optional severity, must be one of \TYPO3\CMS\Core\Messaging\FlashMessage constants
710
     * @param bool $storeInSession Optional, defines whether the message should be stored in the session (default)
711
     * @throws \InvalidArgumentException if the message body is no string
712
     * @return self
713
     */
714
    public function addFlashMessage($messageBody, $messageTitle = '', $severity = AbstractMessage::OK, $storeInSession = true): self
715
    {
716
        if (!is_string($messageBody)) {
0 ignored issues
show
introduced by
The condition is_string($messageBody) is always true.
Loading history...
717
            throw new \InvalidArgumentException('The message body must be of type string, "' . gettype($messageBody) . '" given.', 1446483133);
718
        }
719
        /* @var \TYPO3\CMS\Core\Messaging\FlashMessage $flashMessage */
720
        $flashMessage = GeneralUtility::makeInstance(
721
            FlashMessage::class,
722
            $messageBody,
723
            $messageTitle,
724
            $severity,
725
            $storeInSession
726
        );
727
        $this->getFlashMessageQueue()->enqueue($flashMessage);
728
        return $this;
729
    }
730
731
    /**
732
     * @param FlashMessageQueue $flashMessageQueue
733
     * @return self
734
     */
735
    public function setFlashMessageQueue($flashMessageQueue): self
736
    {
737
        $this->flashMessageQueue = $flashMessageQueue;
738
        return $this;
739
    }
740
741
    /**
742
     * @return FlashMessageQueue
743
     */
744
    protected function getFlashMessageQueue()
745
    {
746
        if (!isset($this->flashMessageQueue)) {
747
            $this->flashMessageQueue = $this->flashMessageService->getMessageQueueByIdentifier();
748
        }
749
        return $this->flashMessageQueue;
750
    }
751
752
    /**
753
     * @return bool
754
     */
755
    public function isUiBlock(): bool
756
    {
757
        return $this->uiBlock;
758
    }
759
760
    /**
761
     * @param bool $uiBlock
762
     * @return self
763
     */
764
    public function setUiBlock(bool $uiBlock): self
765
    {
766
        $this->uiBlock = $uiBlock;
767
        return $this;
768
    }
769
}
770