37b7931b4c7b1f8a61a4c7664d61293dded95af5
[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\Toolbar\ClearCacheActionsHookInterface;
18 use TYPO3\CMS\Backend\Toolbar\ToolbarItemInterface;
19 use TYPO3\CMS\Backend\Utility\BackendUtility;
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 // Clear all page-related caches
52 if ($backendUser->isAdmin() || $backendUser->getTSConfigVal('options.clearCache.pages')) {
53 $this->cacheActions[] = [
54 'id' => 'pages',
55 'title' => 'LLL:EXT:lang/Resources/Private/Language/locallang_core.xlf:flushPageCachesTitle',
56 'description' => 'LLL:EXT:lang/Resources/Private/Language/locallang_core.xlf:flushPageCachesDescription',
57 'href' => BackendUtility::getModuleUrl('tce_db', ['cacheCmd' => 'pages']),
58 'iconIdentifier' => 'actions-system-cache-clear-impact-low'
59 ];
60 $this->optionValues[] = 'pages';
61 }
62
63 // Clearing of all caches is only shown if explicitly enabled via TSConfig
64 // or if BE-User is admin and the TSconfig explicitly disables the possibility for admins.
65 // This is useful for big production systems where admins accidentally could slow down the system.
66 if ($backendUser->getTSConfigVal('options.clearCache.all') || ($backendUser->isAdmin() && $backendUser->getTSConfigVal('options.clearCache.all') !== '0')) {
67 $this->cacheActions[] = [
68 'id' => 'all',
69 'title' => 'LLL:EXT:lang/Resources/Private/Language/locallang_core.xlf:flushAllCachesTitle2',
70 'description' => 'LLL:EXT:lang/Resources/Private/Language/locallang_core.xlf:flushAllCachesDescription2',
71 'href' => BackendUtility::getModuleUrl('tce_db', ['cacheCmd' => 'all']),
72 'iconIdentifier' => 'actions-system-cache-clear-impact-high'
73 ];
74 $this->optionValues[] = 'all';
75 }
76
77 // Hook for manipulating cacheActions
78 foreach ($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['additionalBackendItems']['cacheActions'] ?? [] as $cacheAction) {
79 $hookObject = GeneralUtility::makeInstance($cacheAction);
80 if (!$hookObject instanceof ClearCacheActionsHookInterface) {
81 throw new \UnexpectedValueException($cacheAction . ' must implement interface ' . ClearCacheActionsHookInterface::class, 1228262000);
82 }
83 $hookObject->manipulateCacheActions($this->cacheActions, $this->optionValues);
84 }
85 }
86
87 /**
88 * Checks whether the user has access to this toolbar item
89 *
90 * @return bool TRUE if user has access, FALSE if not
91 */
92 public function checkAccess()
93 {
94 $backendUser = $this->getBackendUser();
95 if ($backendUser->isAdmin()) {
96 return true;
97 }
98 foreach ($this->optionValues as $value) {
99 if ($backendUser->getTSConfigVal('options.clearCache.' . $value)) {
100 return true;
101 }
102 }
103 return false;
104 }
105
106 /**
107 * Render clear cache icon, based on the option if there is more than one icon or just one.
108 *
109 * @return string Icon HTML
110 */
111 public function getItem()
112 {
113 if ($this->hasDropDown()) {
114 return $this->getFluidTemplateObject('ClearCacheToolbarItem.html')->render();
115 }
116 $view = $this->getFluidTemplateObject('ClearCacheToolbarItemSingle.html');
117 $cacheAction = end($this->cacheActions);
118 $view->assignMultiple([
119 'link' => $cacheAction['href'],
120 'title' => $cacheAction['title'],
121 'iconIdentifier' => $cacheAction['iconIdentifier'],
122 ]);
123 return $view->render();
124 }
125
126 /**
127 * Render drop down
128 *
129 * @return string Drop down HTML
130 */
131 public function getDropDown()
132 {
133 $view = $this->getFluidTemplateObject('ClearCacheToolbarItemDropDown.html');
134 $view->assign('cacheActions', $this->cacheActions);
135 return $view->render();
136 }
137
138 /**
139 * No additional attributes needed.
140 *
141 * @return array
142 */
143 public function getAdditionalAttributes()
144 {
145 return [];
146 }
147
148 /**
149 * This item has a drop down if there is more than one cache action available for the current Backend user.
150 *
151 * @return bool
152 */
153 public function hasDropDown()
154 {
155 return count($this->cacheActions) > 1;
156 }
157
158 /**
159 * Position relative to others
160 *
161 * @return int
162 */
163 public function getIndex()
164 {
165 return 25;
166 }
167
168 /**
169 * Returns the current BE user.
170 *
171 * @return BackendUserAuthentication
172 */
173 protected function getBackendUser()
174 {
175 return $GLOBALS['BE_USER'];
176 }
177
178 /**
179 * @return PageRenderer
180 */
181 protected function getPageRenderer()
182 {
183 return GeneralUtility::makeInstance(PageRenderer::class);
184 }
185
186 /**
187 * Returns a new standalone view, shorthand function
188 *
189 * @param string $filename Which templateFile should be used.
190 * @return StandaloneView
191 */
192 protected function getFluidTemplateObject(string $filename): StandaloneView
193 {
194 $view = GeneralUtility::makeInstance(StandaloneView::class);
195 $view->setLayoutRootPaths(['EXT:backend/Resources/Private/Layouts']);
196 $view->setPartialRootPaths(['EXT:backend/Resources/Private/Partials/ToolbarItems']);
197 $view->setTemplateRootPaths(['EXT:backend/Resources/Private/Templates/ToolbarItems']);
198
199 $view->setTemplate($filename);
200
201 $view->getRequest()->setControllerExtensionName('Backend');
202 return $view;
203 }
204 }