Passed
Push — master ( 4a1204...a560b9 )
by
unknown
15:38
created

ModuleTemplate::setModuleClass()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

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