‪TYPO3CMS  ‪main
PreviewModule.php
Go to the documentation of this file.
1 <?php
2 
3 declare(strict_types=1);
4 
5 /*
6  * This file is part of the TYPO3 CMS project.
7  *
8  * It is free software; you can redistribute it and/or modify it under
9  * the terms of the GNU General Public License, either version 2
10  * of the License, or any later version.
11  *
12  * For the full copyright and license information, please read the
13  * LICENSE.txt file that was distributed with this source code.
14  *
15  * The TYPO3 project - inspiring people to share!
16  */
17 
19 
20 use Psr\Http\Message\ServerRequestInterface;
21 use Psr\Log\LoggerAwareInterface;
22 use Psr\Log\LoggerAwareTrait;
41 
46 {
47  use LoggerAwareTrait;
48 
61  protected array ‪$config;
62 
63  public function ‪__construct(
64  protected readonly ‪CacheManager $cacheManager,
65  ) {}
66 
67  public function ‪getIconIdentifier(): string
68  {
69  return 'actions-preview';
70  }
71 
72  public function ‪getIdentifier(): string
73  {
74  return 'preview';
75  }
76 
77  public function ‪getLabel(): string
78  {
79  return $this->‪getLanguageService()->sL(
80  'LLL:EXT:adminpanel/Resources/Private/Language/locallang_preview.xlf:module.label'
81  );
82  }
83 
84  public function ‪enrich(ServerRequestInterface $request): ServerRequestInterface
85  {
86  // Backend preview params (ADMCMD_) take precedence over configured admin panel values
87  $simulateGroupByRequest = (int)($request->getQueryParams()['ADMCMD_simUser'] ?? 0);
88  $simulateTimeByRequest = (int)($request->getQueryParams()['ADMCMD_simTime'] ?? 0);
89  $this->config = [
90  'showHiddenPages' => (bool)$this->‪getConfigOptionForModule('showHiddenPages'),
91  'simulateDate' => $simulateTimeByRequest ?: (int)$this->‪getConfigOptionForModule('simulateDate'),
92  'showHiddenRecords' => (bool)$this->‪getConfigOptionForModule('showHiddenRecords'),
93  'showScheduledRecords' => (bool)$this->‪getConfigOptionForModule('showScheduledRecords'),
94  'simulateUserGroup' => $simulateGroupByRequest ?: (int)$this->‪getConfigOptionForModule('simulateUserGroup'),
95  'showFluidDebug' => (bool)$this->‪getConfigOptionForModule('showFluidDebug'),
96  ];
97  if ($this->config['showFluidDebug']) {
98  // forcibly unset fluid caching as it does not care about the tsfe based caching settings
99  // @todo: Useless?! CacheManager is initialized via bootstrap already, TYPO3_CONF_VARS is not read again?
100  unset(‪$GLOBALS['TYPO3_CONF_VARS']['SYS']['caching']['cacheConfigurations']['fluid_template']['frontend']);
101  $cacheInstruction = $request->getAttribute('frontend.cache.instruction', new ‪CacheInstruction());
102  $cacheInstruction->disableCache('EXT:adminpanel: "Show fluid debug output" disables cache.');
103  $request = $request->withAttribute('frontend.cache.instruction', $cacheInstruction);
104  }
106  $this->config['showHiddenPages'],
107  $this->config['showHiddenRecords'],
108  $this->config['showScheduledRecords'],
109  $this->config['simulateDate'],
110  $this->config['simulateUserGroup'],
111  $request
112  );
113 
114  return $request;
115  }
116 
117  public function ‪getPageSettings(): string
118  {
119  $view = GeneralUtility::makeInstance(StandaloneView::class);
120  $templateNameAndPath = 'EXT:adminpanel/Resources/Private/Templates/Modules/Settings/Preview.html';
121  $view->setTemplatePathAndFilename(GeneralUtility::getFileAbsFileName($templateNameAndPath));
122  $view->setPartialRootPaths(['EXT:adminpanel/Resources/Private/Partials']);
123 
124  $frontendGroupsRepository = GeneralUtility::makeInstance(FrontendGroupsRepository::class);
125 
126  $pageId = 0;
127  $pageArguments = ‪$GLOBALS['TYPO3_REQUEST']->getAttribute('routing');
128  if ($pageArguments instanceof ‪PageArguments) {
129  $pageId = $pageArguments->getPageId();
130  }
131 
132  $view->assignMultiple(
133  [
134  'show' => [
135  'pageId' => $pageId,
136  'hiddenPages' => $this->config['showHiddenPages'] ?? false,
137  'hiddenRecords' => $this->config['showHiddenRecords'] ?? false,
138  'showScheduledRecords' => $this->config['showScheduledRecords'] ?? false,
139  'fluidDebug' => $this->config['showFluidDebug'] ?? false,
140  ],
141  'simulateDate' => (int)($this->config['simulateDate'] ?? 0),
142  'frontendUserGroups' => [
143  'availableGroups' => $frontendGroupsRepository->getAvailableFrontendUserGroups(),
144  'selected' => (int)($this->config['simulateUserGroup'] ?? 0),
145  ],
146  'languageKey' => $this->getBackendUser()->user['lang'] ?? null,
147  ]
148  );
149  return $view->render();
150  }
151 
152  protected function ‪getConfigOptionForModule(string $option): string
153  {
154  return $this->configurationService->getConfigurationOption(
155  'preview',
156  $option
157  );
158  }
159 
166  protected function ‪initializeFrontendPreview(
167  bool $showHiddenPages,
168  bool $showHiddenRecords,
169  bool $showScheduledRecords,
170  int $simulateDate,
171  int $simulateUserGroup,
172  ServerRequestInterface $request
173  ): void {
174  $context = GeneralUtility::makeInstance(Context::class);
175  $this->‪clearPreviewSettings($context);
176 
177  // Modify visibility settings (hidden pages + hidden content)
178  $context->setAspect(
179  'visibility',
180  GeneralUtility::makeInstance(VisibilityAspect::class, $showHiddenPages, $showHiddenRecords, false, $showScheduledRecords)
181  );
182 
183  // Simulate date
184  $simTime = null;
185  if ($simulateDate) {
186  $simTime = max($simulateDate, 60);
187  ‪$GLOBALS['SIM_EXEC_TIME'] = $simTime;
188  ‪$GLOBALS['SIM_ACCESS_TIME'] = $simTime - $simTime % 60;
189  $context->setAspect(
190  'date',
191  GeneralUtility::makeInstance(
192  DateTimeAspect::class,
193  (new \DateTimeImmutable())->setTimestamp($simTime)
194  )
195  );
196  }
197  // simulate usergroup
198  if ($simulateUserGroup) {
199  $frontendUser = $request->getAttribute('frontend.user');
200  $frontendUser->user[$frontendUser->usergroup_column] = $simulateUserGroup;
201  $frontendUser->userGroups[$simulateUserGroup] = [
202  'uid' => $simulateUserGroup,
203  'title' => '_PREVIEW_',
204  ];
205  // let's fake having a user with that group, too
206  // This can be removed once #90989 is fixed
207  $frontendUser->user['uid'] = PHP_INT_MAX;
208  $context->setAspect(
209  'frontend.user',
210  GeneralUtility::makeInstance(
211  UserAspect::class,
212  $frontendUser,
213  [$simulateUserGroup]
214  )
215  );
216  }
217  $isPreview = $simulateUserGroup || $simTime || $showHiddenPages || $showHiddenRecords || $showScheduledRecords;
218  if ($context->hasAspect('frontend.preview')) {
220  $existingPreviewAspect = $context->getAspect('frontend.preview');
221  $isPreview = $existingPreviewAspect->isPreview() || $isPreview;
222  }
223  $previewAspect = GeneralUtility::makeInstance(PreviewAspect::class, $isPreview);
224  $context->setAspect('frontend.preview', $previewAspect);
225  }
226 
227  public function ‪getJavaScriptFiles(): array
228  {
229  return ['EXT:adminpanel/Resources/Public/JavaScript/modules/preview.js'];
230  }
231 
232  protected function ‪clearPreviewSettings(‪Context $context): void
233  {
234  ‪$GLOBALS['SIM_EXEC_TIME'] = ‪$GLOBALS['EXEC_TIME'];
235  ‪$GLOBALS['SIM_ACCESS_TIME'] = ‪$GLOBALS['ACCESS_TIME'];
236  $context->‪setAspect(
237  'date',
238  GeneralUtility::makeInstance(
239  DateTimeAspect::class,
240  (new \DateTimeImmutable())->setTimestamp(‪$GLOBALS['SIM_EXEC_TIME'])
241  )
242  );
243  $context->‪setAspect('visibility', GeneralUtility::makeInstance(VisibilityAspect::class));
244  }
245 
249  public function ‪getCssFiles(): array
250  {
251  return [];
252  }
253 
254  public function ‪onSubmit(array $configurationToSave, ServerRequestInterface $request): void
255  {
256  if (!array_key_exists('preview_showFluidDebug', $configurationToSave)) {
257  return;
258  }
259 
260  $currentShowFluidDebug = $this->‪getConfigOptionForModule('showFluidDebug');
261 
262  if ($configurationToSave['preview_showFluidDebug'] === $currentShowFluidDebug) {
263  return;
264  }
265 
266  $pageId = (int)$request->getParsedBody()['TSFE_ADMIN_PANEL']['preview_clearCacheId'];
267 
268  try {
269  $this->cacheManager->flushCachesInGroupByTag('pages', 'pageId_' . $pageId);
270  $this->cacheManager->getCache('fluid_template')->flush();
272  if ($this->logger !== null) {
273  $this->logger->error($exception->getMessage(), ['exception' => $exception]);
274  }
275  }
276  }
277 }
‪TYPO3\CMS\Adminpanel\Modules\PreviewModule\$config
‪array $config
Definition: PreviewModule.php:61
‪TYPO3\CMS\Core\Routing\PageArguments
Definition: PageArguments.php:26
‪TYPO3\CMS\Core\Context\VisibilityAspect
Definition: VisibilityAspect.php:31
‪TYPO3\CMS\Adminpanel\Modules\PreviewModule\initializeFrontendPreview
‪initializeFrontendPreview(bool $showHiddenPages, bool $showHiddenRecords, bool $showScheduledRecords, int $simulateDate, int $simulateUserGroup, ServerRequestInterface $request)
Definition: PreviewModule.php:166
‪TYPO3\CMS\Adminpanel\Modules\PreviewModule\onSubmit
‪onSubmit(array $configurationToSave, ServerRequestInterface $request)
Definition: PreviewModule.php:254
‪TYPO3\CMS\Adminpanel\ModuleApi\AbstractModule
Definition: AbstractModule.php:29
‪TYPO3\CMS\Adminpanel\Modules\PreviewModule\getPageSettings
‪getPageSettings()
Definition: PreviewModule.php:117
‪TYPO3\CMS\Adminpanel\Modules\PreviewModule\getIdentifier
‪getIdentifier()
Definition: PreviewModule.php:72
‪TYPO3\CMS\Core\Cache\Exception\NoSuchCacheException
Definition: NoSuchCacheException.php:23
‪TYPO3\CMS\Adminpanel\ModuleApi\AbstractModule\getLanguageService
‪getLanguageService()
Definition: AbstractModule.php:95
‪TYPO3\CMS\Adminpanel\Repositories\FrontendGroupsRepository
Definition: FrontendGroupsRepository.php:31
‪TYPO3\CMS\Adminpanel\ModuleApi\ResourceProviderInterface
Definition: ResourceProviderInterface.php:27
‪TYPO3\CMS\Core\Context\Context
Definition: Context.php:54
‪TYPO3\CMS\Core\Context\Context\setAspect
‪setAspect(string $name, AspectInterface $aspect)
Definition: Context.php:131
‪TYPO3\CMS\Adminpanel\Modules\PreviewModule\enrich
‪enrich(ServerRequestInterface $request)
Definition: PreviewModule.php:84
‪TYPO3\CMS\Adminpanel\Modules\PreviewModule\getCssFiles
‪getCssFiles()
Definition: PreviewModule.php:249
‪TYPO3\CMS\Adminpanel\Modules
Definition: CacheModule.php:18
‪TYPO3\CMS\Adminpanel\Modules\PreviewModule\getConfigOptionForModule
‪getConfigOptionForModule(string $option)
Definition: PreviewModule.php:152
‪TYPO3\CMS\Core\Cache\CacheManager
Definition: CacheManager.php:36
‪TYPO3\CMS\Fluid\View\StandaloneView
Definition: StandaloneView.php:30
‪TYPO3\CMS\Adminpanel\Modules\PreviewModule\__construct
‪__construct(protected readonly CacheManager $cacheManager,)
Definition: PreviewModule.php:63
‪TYPO3\CMS\Adminpanel\ModuleApi\PageSettingsProviderInterface
Definition: PageSettingsProviderInterface.php:32
‪TYPO3\CMS\Adminpanel\Modules\PreviewModule\getIconIdentifier
‪getIconIdentifier()
Definition: PreviewModule.php:67
‪$GLOBALS
‪$GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['adminpanel']['modules']
Definition: ext_localconf.php:25
‪TYPO3\CMS\Frontend\Cache\CacheInstruction
Definition: CacheInstruction.php:29
‪TYPO3\CMS\Adminpanel\Modules\PreviewModule\clearPreviewSettings
‪clearPreviewSettings(Context $context)
Definition: PreviewModule.php:232
‪TYPO3\CMS\Adminpanel\ModuleApi\OnSubmitActorInterface
Definition: OnSubmitActorInterface.php:27
‪TYPO3\CMS\Core\Cache\Exception\NoSuchCacheGroupException
Definition: NoSuchCacheGroupException.php:23
‪TYPO3\CMS\Adminpanel\Modules\PreviewModule
Definition: PreviewModule.php:46
‪TYPO3\CMS\Core\Utility\GeneralUtility
Definition: GeneralUtility.php:52
‪TYPO3\CMS\Frontend\Aspect\PreviewAspect
Definition: PreviewAspect.php:30
‪TYPO3\CMS\Adminpanel\Modules\PreviewModule\getJavaScriptFiles
‪getJavaScriptFiles()
Definition: PreviewModule.php:227
‪TYPO3\CMS\Core\Context\DateTimeAspect
Definition: DateTimeAspect.php:35
‪TYPO3\CMS\Adminpanel\Modules\PreviewModule\getLabel
‪getLabel()
Definition: PreviewModule.php:77
‪TYPO3\CMS\Core\Context\UserAspect
Definition: UserAspect.php:37
‪TYPO3\CMS\Adminpanel\ModuleApi\RequestEnricherInterface
Definition: RequestEnricherInterface.php:37