Passed
Push — master ( 62e46d...e4833f )
by
unknown
15:08
created

ShortcutButton::setSetVariables()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 2
nc 1
nop 1
dl 0
loc 4
rs 10
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\Components\Buttons\Action;
17
18
use TYPO3\CMS\Backend\Backend\Shortcut\ShortcutRepository;
19
use TYPO3\CMS\Backend\Routing\Router;
20
use TYPO3\CMS\Backend\Template\Components\ButtonBar;
21
use TYPO3\CMS\Backend\Template\Components\Buttons\ButtonInterface;
22
use TYPO3\CMS\Backend\Template\Components\Buttons\PositionInterface;
23
use TYPO3\CMS\Backend\Template\ModuleTemplate;
24
use TYPO3\CMS\Core\Authentication\BackendUserAuthentication;
25
use TYPO3\CMS\Core\Imaging\Icon;
26
use TYPO3\CMS\Core\Imaging\IconFactory;
27
use TYPO3\CMS\Core\Localization\LanguageService;
28
use TYPO3\CMS\Core\Utility\GeneralUtility;
29
30
/**
31
 * ShortcutButton
32
 *
33
 * Renders a shortcut button in the DocHeader which will be rendered
34
 * to the right position using button group "91".
35
 *
36
 * EXAMPLE USAGE TO ADD A SHORTCUT BUTTON:
37
 *
38
 * $buttonBar = $this->moduleTemplate->getDocHeaderComponent()->getButtonBar();
39
 * $pageId = (int)($request->getQueryParams()['id'] ?? 0);
40
 * $myButton = $buttonBar->makeShortcutButton()
41
 *       ->setRouteIdentifier('web_view')
42
 *       ->setDisplayName('View page ' . $pageId)
43
 *       ->setArguments([
44
 *          'id' => $pageId
45
 *       ]);
46
 * $buttonBar->addButton($myButton);
47
 */
48
class ShortcutButton implements ButtonInterface, PositionInterface
49
{
50
    /**
51
     * @var string The route identifier of the shortcut
52
     */
53
    protected string $routeIdentifier = '';
54
55
    /**
56
     * @var string
57
     * @deprecated since v11, will be removed in v12
58
     */
59
    protected $moduleName = '';
60
61
    /**
62
     * @var string
63
     */
64
    protected $displayName = '';
65
66
    /**
67
     * @var array List of parameter/value pairs relevant for this shortcut
68
     */
69
    protected $arguments = [];
70
71
    /**
72
     * @var array
73
     * @deprecated since v11, will be removed in v12
74
     */
75
    protected $setVariables = [];
76
77
    /**
78
     * @var array
79
     * @deprecated since v11, will be removed in v12
80
     */
81
    protected $getVariables = [];
82
83
    /**
84
     * Gets the route identifier for the shortcut.
85
     *
86
     * @return string
87
     */
88
    public function getRouteIdentifier(): string
89
    {
90
        return $this->routeIdentifier;
91
    }
92
93
    /**
94
     * Sets the route identifier for the shortcut.
95
     *
96
     * @param string $routeIdentifier
97
     * @return ShortcutButton
98
     */
99
    public function setRouteIdentifier(string $routeIdentifier): self
100
    {
101
        $this->routeIdentifier = $routeIdentifier;
102
        return $this;
103
    }
104
105
    /**
106
     * Gets the name of the module.
107
     *
108
     * @return string
109
     * @deprecated since v11, will be removed in v12
110
     */
111
    public function getModuleName()
112
    {
113
        trigger_error('Method getModuleName() is deprecated and will be removed in v12. Use getRouteIdentifier() instead.', E_USER_DEPRECATED);
114
        return $this->moduleName;
115
    }
116
117
    /**
118
     * Sets the name of the module.
119
     *
120
     * @param string $moduleName
121
     * @return ShortcutButton
122
     * @deprecated since v11, will be removed in v12
123
     */
124
    public function setModuleName($moduleName)
125
    {
126
        trigger_error('Method setModuleName() is deprecated and will be removed in v12. Use setRouteIdentifier() instead.', E_USER_DEPRECATED);
127
        $this->moduleName = $moduleName;
128
        return $this;
129
    }
130
131
    /**
132
     * Gets the display name of the module.
133
     *
134
     * @return string
135
     */
136
    public function getDisplayName()
137
    {
138
        return $this->displayName;
139
    }
140
141
    /**
142
     * Sets the display name of the module.
143
     *
144
     * @param string $displayName
145
     * @return ShortcutButton
146
     */
147
    public function setDisplayName($displayName)
148
    {
149
        $this->displayName = $displayName;
150
        return $this;
151
    }
152
153
    /**
154
     * @param array $arguments
155
     * @return $this
156
     */
157
    public function setArguments(array $arguments): self
158
    {
159
        $this->arguments = $arguments;
160
        return $this;
161
    }
162
163
    /**
164
     * Gets the SET variables.
165
     *
166
     * @return array
167
     * @deprecated since v11, will be removed in v12
168
     */
169
    public function getSetVariables()
170
    {
171
        trigger_error('Method getSetVariables() is deprecated and will be removed in v12. Please use ShortcutButton->setArguments() instead.', E_USER_DEPRECATED);
172
        return $this->setVariables;
173
    }
174
175
    /**
176
     * Sets the SET variables.
177
     *
178
     * @param array $setVariables
179
     * @return ShortcutButton
180
     * @deprecated since v11, will be removed in v12. Deprecation logged by ModuleTemplate->makeShortcutIcon()
181
     */
182
    public function setSetVariables(array $setVariables)
183
    {
184
        $this->setVariables = $setVariables;
185
        return $this;
186
    }
187
188
    /**
189
     * Gets the GET variables.
190
     *
191
     * @return array
192
     * @deprecated since v11, will be removed in v12
193
     */
194
    public function getGetVariables()
195
    {
196
        trigger_error('Method getGetVariables() is deprecated and will be removed in v12. Please use ShortcutButton->setArguments() instead.', E_USER_DEPRECATED);
197
        return $this->getVariables;
198
    }
199
200
    /**
201
     * Sets the GET variables.
202
     *
203
     * @param array $getVariables
204
     * @return ShortcutButton
205
     * @deprecated since v11, will be removed in v12. Deprecation logged by ModuleTemplate->makeShortcutIcon()
206
     */
207
    public function setGetVariables(array $getVariables)
208
    {
209
        $this->getVariables = $getVariables;
210
        return $this;
211
    }
212
213
    /**
214
     * Gets the button position.
215
     *
216
     * @return string
217
     */
218
    public function getPosition()
219
    {
220
        return ButtonBar::BUTTON_POSITION_RIGHT;
221
    }
222
223
    /**
224
     * Gets the button group.
225
     *
226
     * @return int
227
     */
228
    public function getGroup()
229
    {
230
        return 91;
231
    }
232
233
    /**
234
     * Gets the type of the button
235
     *
236
     * @return string
237
     */
238
    public function getType()
239
    {
240
        return static::class;
241
    }
242
243
    /**
244
     * Determines whether the button shall be rendered.
245
     *
246
     * @return bool
247
     */
248
    public function isValid()
249
    {
250
        return $this->moduleName !== '' || $this->routeIdentifier !== '' || (string)($this->arguments['route'] ?? '') !== '';
251
    }
252
253
    /**
254
     * Renders the button
255
     *
256
     * @return string
257
     */
258
    public function __toString()
259
    {
260
        return $this->render();
261
    }
262
263
    /**
264
     * Renders the button
265
     *
266
     * @return string
267
     */
268
    public function render()
269
    {
270
        if ($this->getBackendUser()->mayMakeShortcut()) {
271
            if ($this->displayName === '') {
272
                trigger_error('Creating a shortcut button without a display name is deprecated and fallbacks will be removed in v12. Please use ShortcutButton->setDisplayName() to set a display name.', E_USER_DEPRECATED);
273
            }
274
            if (!empty($this->routeIdentifier) || !empty($this->arguments)) {
275
                $shortcutMarkup = $this->createShortcutMarkup();
276
            } else {
277
                // @deprecated since v11, the else branch will be removed in v12. Deprecation thrown by makeShortcutIcon() below
278
                if (empty($this->getVariables)) {
279
                    $this->getVariables = ['id', 'route'];
280
                }
281
                $moduleTemplate = GeneralUtility::makeInstance(ModuleTemplate::class);
282
                $shortcutMarkup = $moduleTemplate->makeShortcutIcon(
283
                    implode(',', $this->getVariables),
284
                    implode(',', $this->setVariables),
285
                    $this->moduleName,
286
                    '',
287
                    $this->displayName
288
                );
289
            }
290
        } else {
291
            $shortcutMarkup = '';
292
        }
293
        return $shortcutMarkup;
294
    }
295
296
    protected function createShortcutMarkup(): string
297
    {
298
        $routeIdentifier = $this->routeIdentifier;
299
        $arguments = $this->arguments;
300
        $iconFactory = GeneralUtility::makeInstance(IconFactory::class);
301
302
        if (strpos($routeIdentifier, '/') !== false) {
303
            trigger_error('Automatic fallback for the route path is deprecated and will be removed in v12.', E_USER_DEPRECATED);
304
            $routeIdentifier = $this->getRouteIdentifierByRoutePath($routeIdentifier);
305
        }
306
307
        if ($routeIdentifier === '' && $this->moduleName !== '') {
308
            trigger_error('Using ShortcutButton::$moduleNname is deprecated and will be removed in v12. Use ShortcutButton::$routeIdentifier instead.', E_USER_DEPRECATED);
309
            $routeIdentifier = $this->getRouteIdentifierByModuleName($this->moduleName);
310
        }
311
312
        if (isset($arguments['route'])) {
313
            trigger_error('Using route as an argument is deprecated and will be removed in v12. Set the route identifier with ShortcutButton::setRouteIdentifier() instead.', E_USER_DEPRECATED);
314
            if ($routeIdentifier === '' && is_string($arguments['route'])) {
315
                $routeIdentifier = $this->getRouteIdentifierByRoutePath($arguments['route']);
316
            }
317
            unset($arguments['route']);
318
        }
319
320
        // No route found so no shortcut button will be rendered
321
        if ($routeIdentifier === '' || !$this->routeExists($routeIdentifier)) {
322
            return '';
323
        }
324
325
        // returnUrl will not longer be stored in the database
326
        unset($arguments['returnUrl']);
327
328
        // Encode arguments to be stored in the database
329
        $arguments = json_encode($arguments);
330
331
        if (GeneralUtility::makeInstance(ShortcutRepository::class)->shortcutExists($routeIdentifier, $arguments)) {
332
            return '<a class="active btn btn-default btn-sm" title="">'
333
                . $iconFactory->getIcon('actions-system-shortcut-active', Icon::SIZE_SMALL)->render()
334
                . '</a>';
335
        }
336
337
        $confirmationText = $this->getLanguageService()->sL('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:labels.makeBookmark');
338
        $onClick = 'top.TYPO3.ShortcutMenu.createShortcut('
339
            . GeneralUtility::quoteJSvalue($routeIdentifier)
340
            . ', ' . GeneralUtility::quoteJSvalue($arguments)
341
            . ', ' . GeneralUtility::quoteJSvalue($this->displayName)
342
            . ', ' . GeneralUtility::quoteJSvalue($confirmationText)
343
            . ', this);return false;';
344
345
        return '<a href="#" class="btn btn-default btn-sm" onclick="' . htmlspecialchars($onClick) . '" title="' . htmlspecialchars($confirmationText) . '">'
346
            . $iconFactory->getIcon('actions-system-shortcut-new', Icon::SIZE_SMALL)->render()
347
            . '</a>';
348
    }
349
350
    /**
351
     * Map a given route path to its route identifier
352
     *
353
     * @param string $routePath
354
     * @return string
355
     * @deprecated Only for backwards compatibility. Can be removed in v12.
356
     */
357
    protected function getRouteIdentifierByRoutePath(string $routePath): string
358
    {
359
        foreach ($this->getRoutes() as $identifier => $route) {
360
            if ($route->getPath() === $routePath
361
                && (
362
                    $route->hasOption('moduleName')
363
                    || in_array($identifier, ['record_edit', 'file_edit', 'wizard_rte'], true)
364
                )
365
            ) {
366
                return $identifier;
367
            }
368
        }
369
370
        return '';
371
    }
372
373
    /**
374
     * Map a given module name to its route identifier by respecting some special cases
375
     *
376
     * @param string $moduleName
377
     * @return string
378
     * @deprecated Only for backwards compatibility. Can be removed in v12.
379
     */
380
    protected function getRouteIdentifierByModuleName(string $moduleName): string
381
    {
382
        $identifier = '';
383
384
        // Special case module names
385
        switch ($moduleName) {
386
            case 'xMOD_alt_doc.php':
387
                $identifier = 'record_edit';
388
                break;
389
            case 'file_edit':
390
            case 'wizard_rte':
391
                $identifier = $moduleName;
392
                break;
393
        }
394
395
        if ($identifier !== '') {
396
            return $identifier;
397
        }
398
399
        foreach ($this->getRoutes() as $identifier => $route) {
400
            if ($route->hasOption('moduleName') && $route->getOption('moduleName') === $moduleName) {
401
                return $identifier;
402
            }
403
        }
404
405
        return '';
406
    }
407
408
    protected function routeExists(string $routeIdentifier): bool
409
    {
410
        return (bool)($this->getRoutes()[$routeIdentifier] ?? false);
411
    }
412
413
    protected function getRoutes(): iterable
414
    {
415
        return GeneralUtility::makeInstance(Router::class)->getRoutes();
416
    }
417
418
    protected function getBackendUser(): BackendUserAuthentication
419
    {
420
        return $GLOBALS['BE_USER'];
421
    }
422
423
    protected function getLanguageService(): LanguageService
424
    {
425
        return $GLOBALS['LANG'];
426
    }
427
}
428