30e75b3d54f6b4c29a38913fd20814be723836cc
[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 $cache = GeneralUtility::makeInstance(CacheManager::class)->getCache('cache_pages');
132 $cache->flushByTag('pageId_' . $pageId);
133 }
134 }
135
136 /**
137 * @param string $option
138 * @return string
139 */
140 protected function getConfigOptionForModule(string $option): string
141 {
142 return $this->configurationService->getConfigurationOption(
143 'preview',
144 $option
145 );
146 }
147
148 /**
149 * @return TypoScriptFrontendController
150 */
151 protected function getTypoScriptFrontendController(): TypoScriptFrontendController
152 {
153 return $GLOBALS['TSFE'];
154 }
155
156 /**
157 * Initialize frontend preview functionality incl.
158 * simulation of users or time
159 *
160 * @param bool $showHiddenPages
161 * @param bool $showHiddenRecords
162 * @param string $simulateDate
163 * @param string $simulateUserGroup
164 */
165 protected function initializeFrontendPreview(
166 bool $showHiddenPages,
167 bool $showHiddenRecords,
168 string $simulateDate,
169 string $simulateUserGroup
170 ): void {
171 $context = GeneralUtility::makeInstance(Context::class);
172 $tsfe = $this->getTypoScriptFrontendController();
173 $tsfe->clear_preview();
174 $tsfe->fePreview = 1;
175 // Simulate date
176 $simTime = null;
177 if ($simulateDate) {
178 $simTime = $this->parseDate($simulateDate);
179 }
180 if ($simTime) {
181 $GLOBALS['SIM_EXEC_TIME'] = $simTime;
182 $GLOBALS['SIM_ACCESS_TIME'] = $simTime - $simTime % 60;
183 $context->setAspect('date', GeneralUtility::makeInstance(DateTimeAspect::class, new \DateTimeImmutable('@' . $GLOBALS['SIM_EXEC_TIME'])));
184 }
185 $context->setAspect('visibility', GeneralUtility::makeInstance(VisibilityAspect::class, $showHiddenPages, $showHiddenRecords));
186 // simulate user
187 $tsfe->simUserGroup = $simulateUserGroup;
188 if ($tsfe->simUserGroup) {
189 if ($tsfe->fe_user->user) {
190 $tsfe->fe_user->user[$tsfe->fe_user->usergroup_column] = $tsfe->simUserGroup;
191 } else {
192 $tsfe->fe_user = GeneralUtility::makeInstance(FrontendUserAuthentication::class);
193 $tsfe->fe_user->user = [
194 $tsfe->fe_user->usergroup_column => $tsfe->simUserGroup,
195 ];
196 }
197 $context->setAspect('frontend.user', GeneralUtility::makeInstance(UserAspect::class, $tsfe->fe_user ?: null));
198 }
199 if (!$tsfe->simUserGroup && !$simTime && !$showHiddenPages && !$showHiddenRecords) {
200 $tsfe->fePreview = 0;
201 }
202 }
203
204 /**
205 * @return array
206 */
207 public function getJavaScriptFiles(): array
208 {
209 return ['EXT:adminpanel/Resources/Public/JavaScript/Modules/Preview.js'];
210 }
211
212 /**
213 * @param string $simulateDate
214 * @return int
215 */
216 protected function parseDate(string $simulateDate): ?int
217 {
218 $date = false;
219 try {
220 $date = new \DateTime($simulateDate);
221 } catch (\Exception $e) {
222 if (is_numeric($simulateDate)) {
223 try {
224 $date = new \DateTime('@' . $simulateDate);
225 } catch (\Exception $e) {
226 $date = false;
227 }
228 }
229 }
230 if ($date !== false) {
231 $simTime = $date->getTimestamp();
232 }
233 return $simTime ?? null;
234 }
235 }