5a46e369418ac07010ae2e245f430f1f690c3cfe
[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 if (is_array($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['additionalBackendItems']['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 /**
90 * Checks whether the user has access to this toolbar item
91 *
92 * @return bool TRUE if user has access, FALSE if not
93 */
94 public function checkAccess()
95 {
96 $backendUser = $this->getBackendUser();
97 if ($backendUser->isAdmin()) {
98 return true;
99 }
100 foreach ($this->optionValues as $value) {
101 if ($backendUser->getTSConfigVal('options.clearCache.' . $value)) {
102 return true;
103 }
104 }
105 return false;
106 }
107
108 /**
109 * Render clear cache icon, based on the option if there is more than one icon or just one.
110 *
111 * @return string Icon HTML
112 */
113 public function getItem()
114 {
115 if ($this->hasDropDown()) {
116 return $this->getFluidTemplateObject('ClearCacheToolbarItem.html')->render();
117 } else {
118 $view = $this->getFluidTemplateObject('ClearCacheToolbarItemSingle.html');
119 $cacheAction = end($this->cacheActions);
120 $view->assignMultiple([
121 'link' => $cacheAction['href'],
122 'title' => $cacheAction['title'],
123 'iconIdentifier' => $cacheAction['iconIdentifier'],
124 ]);
125 return $view->render();
126 }
127 }
128
129 /**
130 * Render drop down
131 *
132 * @return string Drop down HTML
133 */
134 public function getDropDown()
135 {
136 $view = $this->getFluidTemplateObject('ClearCacheToolbarItemDropDown.html');
137 $view->assign('cacheActions', $this->cacheActions);
138 return $view->render();
139 }
140
141 /**
142 * No additional attributes needed.
143 *
144 * @return array
145 */
146 public function getAdditionalAttributes()
147 {
148 return [];
149 }
150
151 /**
152 * This item has a drop down if there is more than one cache action available for the current Backend user.
153 *
154 * @return bool
155 */
156 public function hasDropDown()
157 {
158 return count($this->cacheActions) > 1;
159 }
160
161 /**
162 * Position relative to others
163 *
164 * @return int
165 */
166 public function getIndex()
167 {
168 return 25;
169 }
170
171 /**
172 * Returns the current BE user.
173 *
174 * @return BackendUserAuthentication
175 */
176 protected function getBackendUser()
177 {
178 return $GLOBALS['BE_USER'];
179 }
180
181 /**
182 * @return PageRenderer
183 */
184 protected function getPageRenderer()
185 {
186 return GeneralUtility::makeInstance(PageRenderer::class);
187 }
188
189 /**
190 * Returns a new standalone view, shorthand function
191 *
192 * @param string $filename Which templateFile should be used.
193 * @return StandaloneView
194 */
195 protected function getFluidTemplateObject(string $filename): StandaloneView
196 {
197 $view = GeneralUtility::makeInstance(StandaloneView::class);
198 $view->setLayoutRootPaths(['EXT:backend/Resources/Private/Layouts']);
199 $view->setPartialRootPaths(['EXT:backend/Resources/Private/Partials/ToolbarItems']);
200 $view->setTemplateRootPaths(['EXT:backend/Resources/Private/Templates/ToolbarItems']);
201
202 $view->setTemplate($filename);
203
204 $view->getRequest()->setControllerExtensionName('Backend');
205 return $view;
206 }
207 }