[TASK] Use BE Routing / PSR-7 instead of BackendUtility::getModuleUrl
[Packages/TYPO3.CMS.git] / typo3 / sysext / backend / Classes / Backend / ToolbarItems / ClearCacheToolbarItem.php
1 <?php
2 namespace TYPO3\CMS\Backend\Backend\ToolbarItems;
3
4 /*
5 * This file is part of the TYPO3 CMS project.
6 *
7 * It is free software; you can redistribute it and/or modify it under
8 * the terms of the GNU General Public License, either version 2
9 * of the License, or any later version.
10 *
11 * For the full copyright and license information, please read the
12 * LICENSE.txt file that was distributed with this source code.
13 *
14 * The TYPO3 project - inspiring people to share!
15 */
16
17 use TYPO3\CMS\Backend\Routing\UriBuilder;
18 use TYPO3\CMS\Backend\Toolbar\ClearCacheActionsHookInterface;
19 use TYPO3\CMS\Backend\Toolbar\ToolbarItemInterface;
20 use TYPO3\CMS\Core\Authentication\BackendUserAuthentication;
21 use TYPO3\CMS\Core\Page\PageRenderer;
22 use TYPO3\CMS\Core\Utility\GeneralUtility;
23 use TYPO3\CMS\Fluid\View\StandaloneView;
24
25 /**
26 * Render cache clearing toolbar item
27 * Adds a dropdown if there are more than one item to clear (usually for admins to render the flush all caches)
28 *
29 * The dropdown items can be extended via a hook named "cacheActions".
30 */
31 class ClearCacheToolbarItem implements ToolbarItemInterface
32 {
33 /**
34 * @var array
35 */
36 protected $cacheActions = [];
37
38 /**
39 * @var array
40 */
41 protected $optionValues = [];
42
43 /**
44 * @throws \UnexpectedValueException
45 */
46 public function __construct()
47 {
48 $this->getPageRenderer()->loadRequireJsModule('TYPO3/CMS/Backend/Toolbar/ClearCacheMenu');
49 $backendUser = $this->getBackendUser();
50
51 $uriBuilder = GeneralUtility::makeInstance(UriBuilder::class);
52 // Clear all page-related caches
53 if ($backendUser->isAdmin() || $backendUser->getTSConfigVal('options.clearCache.pages')) {
54 $this->cacheActions[] = [
55 'id' => 'pages',
56 'title' => 'LLL:EXT:lang/Resources/Private/Language/locallang_core.xlf:flushPageCachesTitle',
57 'description' => 'LLL:EXT:lang/Resources/Private/Language/locallang_core.xlf:flushPageCachesDescription',
58 'href' => (string)$uriBuilder->buildUriFromRoute('tce_db', ['cacheCmd' => 'pages']),
59 'iconIdentifier' => 'actions-system-cache-clear-impact-low'
60 ];
61 $this->optionValues[] = 'pages';
62 }
63
64 // Clearing of all caches is only shown if explicitly enabled via TSConfig
65 // or if BE-User is admin and the TSconfig explicitly disables the possibility for admins.
66 // This is useful for big production systems where admins accidentally could slow down the system.
67 if ($backendUser->getTSConfigVal('options.clearCache.all') || ($backendUser->isAdmin() && $backendUser->getTSConfigVal('options.clearCache.all') !== '0')) {
68 $this->cacheActions[] = [
69 'id' => 'all',
70 'title' => 'LLL:EXT:lang/Resources/Private/Language/locallang_core.xlf:flushAllCachesTitle2',
71 'description' => 'LLL:EXT:lang/Resources/Private/Language/locallang_core.xlf:flushAllCachesDescription2',
72 'href' => (string)$uriBuilder->buildUriFromRoute('tce_db', ['cacheCmd' => 'all']),
73 'iconIdentifier' => 'actions-system-cache-clear-impact-high'
74 ];
75 $this->optionValues[] = 'all';
76 }
77
78 // Hook for manipulating cacheActions
79 foreach ($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['additionalBackendItems']['cacheActions'] ?? [] as $cacheAction) {
80 $hookObject = GeneralUtility::makeInstance($cacheAction);
81 if (!$hookObject instanceof ClearCacheActionsHookInterface) {
82 throw new \UnexpectedValueException($cacheAction . ' must implement interface ' . ClearCacheActionsHookInterface::class, 1228262000);
83 }
84 $hookObject->manipulateCacheActions($this->cacheActions, $this->optionValues);
85 }
86 }
87
88 /**
89 * Checks whether the user has access to this toolbar item
90 *
91 * @return bool TRUE if user has access, FALSE if not
92 */
93 public function checkAccess()
94 {
95 $backendUser = $this->getBackendUser();
96 if ($backendUser->isAdmin()) {
97 return true;
98 }
99 foreach ($this->optionValues as $value) {
100 if ($backendUser->getTSConfigVal('options.clearCache.' . $value)) {
101 return true;
102 }
103 }
104 return false;
105 }
106
107 /**
108 * Render clear cache icon, based on the option if there is more than one icon or just one.
109 *
110 * @return string Icon HTML
111 */
112 public function getItem()
113 {
114 if ($this->hasDropDown()) {
115 return $this->getFluidTemplateObject('ClearCacheToolbarItem.html')->render();
116 }
117 $view = $this->getFluidTemplateObject('ClearCacheToolbarItemSingle.html');
118 $cacheAction = end($this->cacheActions);
119 $view->assignMultiple([
120 'link' => $cacheAction['href'],
121 'title' => $cacheAction['title'],
122 'iconIdentifier' => $cacheAction['iconIdentifier'],
123 ]);
124 return $view->render();
125 }
126
127 /**
128 * Render drop down
129 *
130 * @return string Drop down HTML
131 */
132 public function getDropDown()
133 {
134 $view = $this->getFluidTemplateObject('ClearCacheToolbarItemDropDown.html');
135 $view->assign('cacheActions', $this->cacheActions);
136 return $view->render();
137 }
138
139 /**
140 * No additional attributes needed.
141 *
142 * @return array
143 */
144 public function getAdditionalAttributes()
145 {
146 return [];
147 }
148
149 /**
150 * This item has a drop down if there is more than one cache action available for the current Backend user.
151 *
152 * @return bool
153 */
154 public function hasDropDown()
155 {
156 return count($this->cacheActions) > 1;
157 }
158
159 /**
160 * Position relative to others
161 *
162 * @return int
163 */
164 public function getIndex()
165 {
166 return 25;
167 }
168
169 /**
170 * Returns the current BE user.
171 *
172 * @return BackendUserAuthentication
173 */
174 protected function getBackendUser()
175 {
176 return $GLOBALS['BE_USER'];
177 }
178
179 /**
180 * @return PageRenderer
181 */
182 protected function getPageRenderer()
183 {
184 return GeneralUtility::makeInstance(PageRenderer::class);
185 }
186
187 /**
188 * Returns a new standalone view, shorthand function
189 *
190 * @param string $filename Which templateFile should be used.
191 * @return StandaloneView
192 */
193 protected function getFluidTemplateObject(string $filename): StandaloneView
194 {
195 $view = GeneralUtility::makeInstance(StandaloneView::class);
196 $view->setLayoutRootPaths(['EXT:backend/Resources/Private/Layouts']);
197 $view->setPartialRootPaths(['EXT:backend/Resources/Private/Partials/ToolbarItems']);
198 $view->setTemplateRootPaths(['EXT:backend/Resources/Private/Templates/ToolbarItems']);
199
200 $view->setTemplate($filename);
201
202 $view->getRequest()->setControllerExtensionName('Backend');
203 return $view;
204 }
205 }