[TASK] Stabilize / Solidify public API of adminPanel
[Packages/TYPO3.CMS.git] / typo3 / sysext / adminpanel / Classes / Modules / PreviewModule.php
1 <?php
2 declare(strict_types = 1);
3
4 namespace TYPO3\CMS\Adminpanel\Modules;
5
6 /*
7 * This file is part of the TYPO3 CMS project.
8 *
9 * It is free software; you can redistribute it and/or modify it under
10 * the terms of the GNU General Public License, either version 2
11 * of the License, or any later version.
12 *
13 * For the full copyright and license information, please read the
14 * LICENSE.txt file that was distributed with this source code.
15 *
16 * The TYPO3 project - inspiring people to share!
17 */
18
19 use Psr\Http\Message\ServerRequestInterface;
20 use TYPO3\CMS\Adminpanel\Repositories\FrontendGroupsRepository;
21 use TYPO3\CMS\Core\Cache\CacheManager;
22 use TYPO3\CMS\Core\Context\Context;
23 use TYPO3\CMS\Core\Context\DateTimeAspect;
24 use TYPO3\CMS\Core\Context\UserAspect;
25 use TYPO3\CMS\Core\Context\VisibilityAspect;
26 use TYPO3\CMS\Core\Utility\GeneralUtility;
27 use TYPO3\CMS\Fluid\View\StandaloneView;
28 use TYPO3\CMS\Frontend\Authentication\FrontendUserAuthentication;
29 use TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController;
30
31 /**
32 * Admin Panel Preview Module
33 */
34 class PreviewModule extends AbstractModule
35 {
36 /**
37 * module configuration, set on initialize
38 *
39 * @var array
40 */
41 protected $config;
42
43 /**
44 * @inheritdoc
45 */
46 public function getIconIdentifier(): string
47 {
48 return 'actions-preview';
49 }
50
51 /**
52 * @inheritdoc
53 */
54 public function getIdentifier(): string
55 {
56 return 'preview';
57 }
58
59 /**
60 * @inheritdoc
61 */
62 public function getLabel(): string
63 {
64 return $this->getLanguageService()->sL(
65 'LLL:' . $this->extResources . '/Language/locallang_preview.xlf:module.label'
66 );
67 }
68
69 /**
70 * @inheritdoc
71 */
72 public function initializeModule(ServerRequestInterface $request): void
73 {
74 $this->config = [
75 'showHiddenPages' => (bool)$this->getConfigOptionForModule('showHiddenPages'),
76 'simulateDate' => $this->getConfigOptionForModule('simulateDate'),
77 'showHiddenRecords' => (bool)$this->getConfigOptionForModule('showHiddenRecords'),
78 'simulateUserGroup' => $this->getConfigOptionForModule('simulateUserGroup'),
79 'showFluidDebug' => (bool)$this->getConfigOptionForModule('showFluidDebug'),
80 ];
81 $this->initializeFrontendPreview(
82 $this->config['showHiddenPages'],
83 $this->config['showHiddenRecords'],
84 $this->config['simulateDate'],
85 $this->config['simulateUserGroup']
86 );
87 }
88
89 /**
90 * @inheritdoc
91 */
92 public function getSettings(): string
93 {
94 $view = GeneralUtility::makeInstance(StandaloneView::class);
95 $templateNameAndPath = $this->extResources . '/Templates/Modules/Settings/Preview.html';
96 $view->setTemplatePathAndFilename(GeneralUtility::getFileAbsFileName($templateNameAndPath));
97 $view->setPartialRootPaths([$this->extResources . '/Partials']);
98
99 $frontendGroupsRepository = GeneralUtility::makeInstance(FrontendGroupsRepository::class);
100
101 $view->assignMultiple(
102 [
103 'show' => [
104 'pageId' => (int)$this->getTypoScriptFrontendController()->id,
105 'hiddenPages' => $this->config['showHiddenPages'],
106 'hiddenRecords' => $this->config['showHiddenRecords'],
107 'fluidDebug' => $this->config['showFluidDebug'],
108 ],
109 'simulateDate' => $this->config['simulateDate'],
110 'frontendUserGroups' => [
111 'availableGroups' => $frontendGroupsRepository->getAvailableFrontendUserGroups(),
112 'selected' => $this->config['simulateUserGroup'],
113 ],
114 ]
115 );
116 return $view->render();
117 }
118
119 /**
120 * Clear page cache if fluid debug output is enabled
121 *
122 * @param array $input
123 * @param ServerRequestInterface $request
124 * @throws \TYPO3\CMS\Core\Cache\Exception\NoSuchCacheException
125 */
126 public function onSubmit(array $input, ServerRequestInterface $request): void
127 {
128 $activeConfiguration = (int)$this->getConfigOptionForModule('showFluidDebug');
129 if (isset($input['preview_showFluidDebug']) && (int)$input['preview_showFluidDebug'] !== $activeConfiguration) {
130 $pageId = (int)$request->getParsedBody()['TSFE_ADMIN_PANEL']['preview_clearCacheId'];
131 $cacheManager = GeneralUtility::makeInstance(CacheManager::class);
132 $cacheManager->getCache('cache_pages')->flushByTag('pageId_' . $pageId);
133 $cacheManager->getCache('fluid_template')->flush();
134 }
135 }
136
137 /**
138 * @param string $option
139 * @return string
140 */
141 protected function getConfigOptionForModule(string $option): string
142 {
143 return $this->configurationService->getConfigurationOption(
144 'preview',
145 $option
146 );
147 }
148
149 /**
150 * @return TypoScriptFrontendController
151 */
152 protected function getTypoScriptFrontendController(): TypoScriptFrontendController
153 {
154 return $GLOBALS['TSFE'];
155 }
156
157 /**
158 * Initialize frontend preview functionality incl.
159 * simulation of users or time
160 *
161 * @param bool $showHiddenPages
162 * @param bool $showHiddenRecords
163 * @param string $simulateDate
164 * @param string $simulateUserGroup
165 */
166 protected function initializeFrontendPreview(
167 bool $showHiddenPages,
168 bool $showHiddenRecords,
169 string $simulateDate,
170 string $simulateUserGroup
171 ): void {
172 $context = GeneralUtility::makeInstance(Context::class);
173 $tsfe = $this->getTypoScriptFrontendController();
174 $tsfe->clear_preview();
175 $tsfe->fePreview = 1;
176 // Simulate date
177 $simTime = null;
178 if ($simulateDate) {
179 $simTime = $this->parseDate($simulateDate);
180 }
181 if ($simTime) {
182 $GLOBALS['SIM_EXEC_TIME'] = $simTime;
183 $GLOBALS['SIM_ACCESS_TIME'] = $simTime - $simTime % 60;
184 $context->setAspect('date', GeneralUtility::makeInstance(DateTimeAspect::class, new \DateTimeImmutable('@' . $GLOBALS['SIM_EXEC_TIME'])));
185 }
186 $context->setAspect('visibility', GeneralUtility::makeInstance(VisibilityAspect::class, $showHiddenPages, $showHiddenRecords));
187 // simulate user
188 $tsfe->simUserGroup = $simulateUserGroup;
189 if ($tsfe->simUserGroup) {
190 if ($tsfe->fe_user->user) {
191 $tsfe->fe_user->user[$tsfe->fe_user->usergroup_column] = $tsfe->simUserGroup;
192 } else {
193 $tsfe->fe_user = GeneralUtility::makeInstance(FrontendUserAuthentication::class);
194 $tsfe->fe_user->user = [
195 $tsfe->fe_user->usergroup_column => $tsfe->simUserGroup,
196 ];
197 }
198 $context->setAspect('frontend.user', GeneralUtility::makeInstance(UserAspect::class, $tsfe->fe_user ?: null));
199 }
200 if (!$tsfe->simUserGroup && !$simTime && !$showHiddenPages && !$showHiddenRecords) {
201 $tsfe->fePreview = 0;
202 }
203 }
204
205 /**
206 * @return array
207 */
208 public function getJavaScriptFiles(): array
209 {
210 return ['EXT:adminpanel/Resources/Public/JavaScript/Modules/Preview.js'];
211 }
212
213 /**
214 * @param string $simulateDate
215 * @return int
216 */
217 protected function parseDate(string $simulateDate): ?int
218 {
219 $date = false;
220 try {
221 $date = new \DateTime($simulateDate);
222 } catch (\Exception $e) {
223 if (is_numeric($simulateDate)) {
224 try {
225 $date = new \DateTime('@' . $simulateDate);
226 } catch (\Exception $e) {
227 $date = false;
228 }
229 }
230 }
231 if ($date !== false) {
232 $simTime = $date->getTimestamp();
233 }
234 return $simTime ?? null;
235 }
236 }