‪TYPO3CMS  10.4
TypoScriptFrontendController.php
Go to the documentation of this file.
1 <?php
2 
3 /*
4  * This file is part of the TYPO3 CMS project.
5  *
6  * It is free software; you can redistribute it and/or modify it under
7  * the terms of the GNU General Public License, either version 2
8  * of the License, or any later version.
9  *
10  * For the full copyright and license information, please read the
11  * LICENSE.txt file that was distributed with this source code.
12  *
13  * The TYPO3 project - inspiring people to share!
14  */
15 
17 
18 use Psr\Http\Message\ResponseInterface;
19 use Psr\Http\Message\ServerRequestInterface;
20 use Psr\Log\LoggerAwareInterface;
21 use Psr\Log\LoggerAwareTrait;
81 
97 class ‪TypoScriptFrontendController implements LoggerAwareInterface
98 {
99  use LoggerAwareTrait;
101 
106  'imagesOnPage' => 'Using TSFE->imagesOnPage is deprecated and will no longer work with TYPO3 v11.0. Use AssetCollector()->getMedia() instead.',
107  'lastImageInfo' => 'Using TSFE->lastImageInfo is deprecated and will no longer work with TYPO3 v11.0.'
108  ];
109 
114  public ‪$id = '';
115 
120  public ‪$type = '';
121 
125  protected ‪$site;
126 
130  protected ‪$language;
131 
138  protected ‪$cHash = '';
139 
144  protected ‪$pageArguments;
145 
151  public ‪$no_cache = false;
152 
157  public ‪$rootLine = [];
158 
163  public ‪$page = [];
164 
170  public ‪$contentPid = 0;
171 
179  protected ‪$originalMountPointPage;
180 
189  protected ‪$originalShortcutPage;
190 
196  public ‪$sys_page = '';
197 
203  public ‪$pageNotFound = 0;
204 
211  protected ‪$domainStartPage = 0;
212 
217  protected ‪$pageAccessFailureHistory = [];
218 
223  public ‪$MP = '';
224 
230  public ‪$fe_user = '';
231 
236  protected ‪$loginAllowedInBranch = true;
237 
244 
253  protected ‪$fePreview = 0;
254 
260  public ‪$simUserGroup = 0;
261 
267  public ‪$config = [];
268 
274  public ‪$tmpl;
275 
282  protected ‪$cacheTimeOutDefault = 86400;
283 
290  protected ‪$cacheContentFlag = false;
291 
297  protected ‪$cacheExpires = 0;
298 
304  protected ‪$isClientCachable = false;
305 
313  public ‪$all = [];
314 
320  public ‪$sPre = '';
321 
328  public ‪$pSetup = '';
329 
336  public ‪$newHash = '';
337 
346  protected ‪$no_cacheBeforePageGen = false;
347 
353  private ‪$forceTemplateParsing = false;
354 
361  protected ‪$cHash_array = [];
362 
368  protected ‪$pagesTSconfig = '';
369 
383  public ‪$additionalHeaderData = [];
384 
389  public ‪$additionalFooterData = [];
390 
398  public ‪$additionalJavaScript = [];
399 
406  public ‪$additionalCSS = [];
407 
412  public ‪$JSCode;
413 
418  public ‪$inlineJS;
419 
425  public ‪$divSection = '';
426 
431  public ‪$intTarget = '';
432 
437  public ‪$extTarget = '';
438 
443  public ‪$fileTarget = '';
444 
450 
455  public ‪$absRefPrefix = '';
456 
461  public ‪$ATagParams = '';
462 
470  public ‪$sWordRegEx = '';
471 
478  public ‪$sWordList = '';
479 
486  public ‪$linkVars = '';
487 
493  public ‪$displayEditIcons = '';
494 
502 
508  protected ‪$sys_language_isocode = '';
509 
515  public ‪$applicationData = [];
516 
520  public ‪$register = [];
521 
527  public ‪$registerStack = [];
528 
534  public ‪$cObjectDepthCounter = 50;
535 
541  public ‪$recordRegister = [];
542 
550  public ‪$currentRecord = '';
551 
557  public ‪$accessKey = [];
558 
565  private ‪$imagesOnPage = [];
566 
573  private ‪$lastImageInfo = [];
574 
581  protected ‪$uniqueCounter = 0;
582 
587  protected ‪$uniqueString = '';
588 
595  public ‪$indexedDocTitle = '';
596 
601  public ‪$baseUrl = '';
602 
608  public ‪$cObj;
609 
614  public ‪$content = '';
615 
622  public ‪$metaCharset = 'utf-8';
623 
629  protected ‪$languageService;
630 
634  protected ‪$locks = [];
635 
639  protected ‪$pageRenderer;
640 
647  protected ‪$pageCache;
648 
652  protected ‪$pageCacheTags = [];
653 
661  protected ‪$contentType = 'text/html';
662 
668  public ‪$xhtmlDoctype = '';
669 
673  public ‪$xhtmlVersion;
674 
680  protected ‪$requestedId;
681 
688  protected ‪$context;
689 
710  public function ‪__construct(‪$context = null, $siteOrId = null, $siteLanguageOrType = null, ‪$pageArguments = null, $cHashOrFrontendUser = null, $_2 = null, ‪$MP = null)
711  {
713 
714  // Fetch the request for fetching data (site/language/pageArguments) for compatibility reasons, not needed
715  // in TYPO3 v11.0 anymore.
717  $request = ‪$GLOBALS['TYPO3_REQUEST'] ?? ‪ServerRequestFactory::fromGlobals();
718 
719  $this->‪initializeSiteWithCompatibility($siteOrId, $request);
720  $this->‪initializeSiteLanguageWithCompatibility($siteLanguageOrType, $request);
724 
726 
727  $this->uniqueString = md5(microtime());
728  $this->‪initPageRenderer();
729  $this->‪initCaches();
730  // Initialize LLL behaviour
731  $this->‪setOutputLanguage();
732  }
733 
744  {
745  if (‪$context instanceof ‪Context) {
746  $this->context = ‪$context;
747  } else {
748  // Use the global context for now
749  trigger_error('TypoScriptFrontendController requires a context object as first constructor argument in TYPO3 v11.0, now falling back to the global Context. This fallback layer will be removed in TYPO3 v11.0', E_USER_DEPRECATED);
750  $this->context = GeneralUtility::makeInstance(Context::class);
751  }
752  if (!$this->context->hasAspect('frontend.preview')) {
753  $this->context->setAspect('frontend.preview', GeneralUtility::makeInstance(PreviewAspect::class));
754  }
755  }
756 
765  private function ‪initializeSiteWithCompatibility($siteOrId, ServerRequestInterface $request): void
766  {
767  if ($siteOrId instanceof ‪SiteInterface) {
768  $this->site = $siteOrId;
769  } else {
770  trigger_error('TypoScriptFrontendController should evaluate the parameter "id" by the PageArguments object, not by a separate constructor argument. This functionality will be removed in TYPO3 v11.0', E_USER_DEPRECATED);
771  $this->id = $siteOrId;
772  if ($request->getAttribute('site') instanceof SiteInterface) {
773  $this->site = $request->getAttribute('site');
774  } else {
775  throw new \InvalidArgumentException('TypoScriptFrontendController must be constructed with a valid Site object or a resolved site in the current request as fallback. None given.', 1561583122);
776  }
777  }
778  }
779 
788  private function ‪initializeSiteLanguageWithCompatibility($siteLanguageOrType, ServerRequestInterface $request): void
789  {
790  if ($siteLanguageOrType instanceof SiteLanguage) {
791  $this->language = $siteLanguageOrType;
792  } else {
793  trigger_error('TypoScriptFrontendController should evaluate the parameter "type" by the PageArguments object, not by a separate constructor argument. This functionality will be removed in TYPO3 v11.0', E_USER_DEPRECATED);
794  $this->type = (int)$siteLanguageOrType;
795  if ($request->getAttribute('language') instanceof SiteLanguage) {
796  $this->language = $request->getAttribute('language');
797  } else {
798  throw new \InvalidArgumentException('TypoScriptFrontendController must be constructed with a valid SiteLanguage object or a resolved site in the current request as fallback. None given.', 1561583127);
799  }
800  }
801  }
802 
812  private function ‪buildPageArgumentsWithFallback(‪$pageArguments, ServerRequestInterface $request): PageArguments
813  {
814  if (‪$pageArguments instanceof PageArguments) {
815  return ‪$pageArguments;
816  }
817  if ($request->getAttribute('routing') instanceof PageArguments) {
818  return $request->getAttribute('routing');
819  }
820  trigger_error('TypoScriptFrontendController must be constructed with a valid PageArguments object or a resolved page argument in the current request as fallback. None given.', E_USER_DEPRECATED);
821  $queryParams = $request->getQueryParams();
822  $pageId = $this->id ?: ($queryParams['id'] ?? $request->getParsedBody()['id'] ?? 0);
823  $pageType = $this->type ?: ($queryParams['type'] ?? $request->getParsedBody()['type'] ?? 0);
824  return new ‪PageArguments((int)$pageId, (string)$pageType, [], $queryParams);
825  }
826 
838  {
839  if ($cHashOrFrontendUser === null) {
840  return ‪$pageArguments;
841  }
842  if ($cHashOrFrontendUser instanceof FrontendUserAuthentication) {
843  $this->fe_user = $cHashOrFrontendUser;
845  }
846  trigger_error('TypoScriptFrontendController should evaluate the parameter "cHash" by the PageArguments object, not by a separate constructor argument. This functionality will be removed in TYPO3 v11.0', E_USER_DEPRECATED);
847  return new ‪PageArguments(
850  ‪$pageArguments->getRouteArguments(),
851  array_replace_recursive(‪$pageArguments->getStaticArguments(), ['cHash' => $cHashOrFrontendUser]),
852  ‪$pageArguments->getDynamicArguments()
853  );
854  }
855 
865  private function ‪initializeLegacyMountPointArgument(?string ‪$MP, PageArguments ‪$pageArguments): PageArguments
866  {
867  if (‪$MP === null) {
868  return ‪$pageArguments;
869  }
870  trigger_error('TypoScriptFrontendController should evaluate the MountPoint Parameter "MP" by the PageArguments object, not by a separate constructor argument. This functionality will be removed in TYPO3 v11.0', E_USER_DEPRECATED);
871  if (!‪$GLOBALS['TYPO3_CONF_VARS']['FE']['enable_mount_pids']) {
872  return ‪$pageArguments;
873  }
874  return new PageArguments(
877  ‪$pageArguments->getRouteArguments(),
878  array_replace_recursive(‪$pageArguments->getStaticArguments(), ['MP' => ‪$MP]),
879  ‪$pageArguments->getDynamicArguments()
880  );
881  }
882 
886  protected function ‪initPageRenderer()
887  {
888  if ($this->pageRenderer !== null) {
889  return;
890  }
891  $this->pageRenderer = GeneralUtility::makeInstance(PageRenderer::class);
892  $this->pageRenderer->setTemplateFile('EXT:frontend/Resources/Private/Templates/MainPage.html');
893  // As initPageRenderer could be called in constructor and for USER_INTs, this information is only set
894  // once - in order to not override any previous settings of PageRenderer.
895  if ($this->language instanceof ‪SiteLanguage) {
896  $this->pageRenderer->setLanguage($this->language->getTypo3Language());
897  }
898  }
899 
905  {
906  $this->contentType = ‪$contentType;
907  }
908 
909  /********************************************
910  *
911  * Initializing, resolving page id
912  *
913  ********************************************/
917  protected function ‪initCaches()
918  {
919  $this->pageCache = GeneralUtility::makeInstance(CacheManager::class)->getCache('pages');
920  }
921 
926  public function ‪initUserGroups()
927  {
928  $userGroups = [0];
929  // This affects the hidden-flag selecting the fe_groups for the user!
930  $this->fe_user->showHiddenRecords = $this->context->getPropertyFromAspect('visibility', 'includeHiddenContent', false);
931  // no matter if we have an active user we try to fetch matching groups which can be set without an user (simulation for instance!)
932  $this->fe_user->fetchGroupData();
933  $isUserAndGroupSet = is_array($this->fe_user->user) && !empty($this->fe_user->groupData['uid']);
934  if ($isUserAndGroupSet) {
935  // group -2 is not an existing group, but denotes a 'default' group when a user IS logged in.
936  // This is used to let elements be shown for all logged in users!
937  $userGroups[] = -2;
938  $groupsFromUserRecord = $this->fe_user->groupData['uid'];
939  } else {
940  // group -1 is not an existing group, but denotes a 'default' group when not logged in.
941  // This is used to let elements be hidden, when a user is logged in!
942  $userGroups[] = -1;
943  if ($this->loginAllowedInBranch) {
944  // For cases where logins are not banned from a branch usergroups can be set based on IP masks so we should add the usergroups uids.
945  $groupsFromUserRecord = $this->fe_user->groupData['uid'];
946  } else {
947  // Set to blank since we will NOT risk any groups being set when no logins are allowed!
948  $groupsFromUserRecord = [];
949  }
950  }
951  // Clean up.
952  // Make unique and sort the groups
953  $groupsFromUserRecord = array_unique($groupsFromUserRecord);
954  if (!empty($groupsFromUserRecord) && !$this->loginAllowedInBranch_mode) {
955  sort($groupsFromUserRecord);
956  $userGroups = array_merge($userGroups, array_map('intval', $groupsFromUserRecord));
957  }
958 
959  $this->context->setAspect('frontend.user', GeneralUtility::makeInstance(UserAspect::class, $this->fe_user ?: null, $userGroups));
960 
961  // For every 60 seconds the is_online timestamp for a logged-in user is updated
962  if ($isUserAndGroupSet) {
963  $this->fe_user->updateOnlineTimestamp();
964  }
965 
966  $this->logger->debug('Valid usergroups for TSFE: ' . implode(',', $userGroups));
967  }
968 
974  public function ‪isUserOrGroupSet()
975  {
977  $userAspect = $this->context->getAspect('frontend.user');
978  return $userAspect->isUserOrGroupSet();
979  }
980 
986  public function ‪clear_preview()
987  {
988  if ($this->‪isInPreviewMode()) {
989  ‪$GLOBALS['SIM_EXEC_TIME'] = ‪$GLOBALS['EXEC_TIME'];
990  ‪$GLOBALS['SIM_ACCESS_TIME'] = ‪$GLOBALS['ACCESS_TIME'];
991  $this->context->setAspect('frontend.preview', GeneralUtility::makeInstance(PreviewAspect::class));
992  $this->context->setAspect('date', GeneralUtility::makeInstance(DateTimeAspect::class, new \DateTimeImmutable('@' . ‪$GLOBALS['SIM_EXEC_TIME'])));
993  $this->context->setAspect('visibility', GeneralUtility::makeInstance(VisibilityAspect::class));
994  }
995  }
996 
1002  public function ‪isBackendUserLoggedIn()
1003  {
1004  return (bool)$this->context->getPropertyFromAspect('backend.user', 'isLoggedIn', false);
1005  }
1006 
1015  public function ‪determineId(ServerRequestInterface $request = null)
1016  {
1017  $request = $request ?? ‪$GLOBALS['TYPO3_REQUEST'] ?? ‪ServerRequestFactory::fromGlobals();
1018  // Call pre processing function for id determination
1019  foreach (‪$GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['tslib/class.tslib_fe.php']['determineId-PreProcessing'] ?? [] as $functionReference) {
1020  $parameters = ['parentObject' => $this];
1021  GeneralUtility::callUserFunction($functionReference, $parameters, $this);
1022  }
1023  // If there is a Backend login we are going to check for any preview settings
1024  $originalFrontendUserGroups = $this->‪applyPreviewSettings($this->‪getBackendUser());
1025  // If the front-end is showing a preview, caching MUST be disabled.
1026  $isPreview = $this->‪isInPreviewMode();
1027  if ($isPreview) {
1028  $this->‪disableCache();
1029  }
1030  // Now, get the id, validate access etc:
1031  $this->‪fetch_the_id($request);
1032  // Check if backend user has read access to this page. If not, recalculate the id.
1033  if ($this->‪isBackendUserLoggedIn() && $isPreview && !$this->‪getBackendUser()->doesUserHaveAccess($this->page, ‪Permission::PAGE_SHOW)) {
1034  // Resetting
1035  $this->‪clear_preview();
1036  $this->fe_user->user[$this->fe_user->usergroup_column] = $originalFrontendUserGroups;
1037  // Fetching the id again, now with the preview settings reset.
1038  $this->‪fetch_the_id($request);
1039  }
1040  // Checks if user logins are blocked for a certain branch and if so, will unset user login and re-fetch ID.
1041  $this->loginAllowedInBranch = $this->‪checkIfLoginAllowedInBranch();
1042  // Logins are not allowed, but there is a login, so will we run this.
1043  if (!$this->loginAllowedInBranch && $this->‪isUserOrGroupSet()) {
1044  if ($this->loginAllowedInBranch_mode === 'all') {
1045  // Clear out user and group:
1046  $this->fe_user->hideActiveLogin();
1047  $userGroups = [0, -1];
1048  } else {
1049  $userGroups = [0, -2];
1050  }
1051  $this->context->setAspect('frontend.user', GeneralUtility::makeInstance(UserAspect::class, $this->fe_user ?: null, $userGroups));
1052  // Fetching the id again, now with the preview settings reset.
1053  $this->‪fetch_the_id($request);
1054  }
1055  // Final cleaning.
1056  // Make sure it's an integer
1057  $this->id = ($this->contentPid = (int)$this->id);
1058  // Make sure it's an integer
1059  $this->type = (int)$this->type;
1060  // Call post processing function for id determination:
1061  $_params = ['pObj' => &$this];
1062  foreach (‪$GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['tslib/class.tslib_fe.php']['determineId-PostProc'] ?? [] as $_funcRef) {
1063  GeneralUtility::callUserFunction($_funcRef, $_params, $this);
1064  }
1065  }
1066 
1080  protected function ‪applyPreviewSettings($backendUser = null)
1081  {
1082  if (!$backendUser) {
1083  return null;
1084  }
1085  $originalFrontendUserGroup = null;
1086  if ($this->fe_user->user) {
1087  $originalFrontendUserGroup = $this->context->getPropertyFromAspect('frontend.user', 'groupIds');
1088  }
1089 
1090  // The preview flag is set if the current page turns out to be hidden
1091  if ($this->id && $this->‪determineIdIsHiddenPage()) {
1092  $this->context->setAspect('frontend.preview', GeneralUtility::makeInstance(PreviewAspect::class, true));
1094  $aspect = $this->context->getAspect('visibility');
1095  $newAspect = GeneralUtility::makeInstance(VisibilityAspect::class, true, $aspect->includeHiddenContent(), $aspect->includeDeletedRecords());
1096  $this->context->setAspect('visibility', $newAspect);
1097  }
1098  // The preview flag will be set if an offline workspace will be previewed
1099  if ($this->‪whichWorkspace() > 0) {
1100  $this->context->setAspect('frontend.preview', GeneralUtility::makeInstance(PreviewAspect::class, true));
1101  }
1102  return $this->context->getPropertyFromAspect('frontend.preview', 'preview', false) ? $originalFrontendUserGroup : null;
1103  }
1104 
1111  protected function ‪determineIdIsHiddenPage()
1112  {
1113  $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)
1114  ->getQueryBuilderForTable('pages');
1115  $queryBuilder
1116  ->getRestrictions()
1117  ->removeAll()
1118  ->add(GeneralUtility::makeInstance(DeletedRestriction::class));
1119 
1120  $queryBuilder
1121  ->select('uid', 'hidden', 'starttime', 'endtime')
1122  ->from('pages')
1123  ->where(
1124  $queryBuilder->expr()->gte('pid', $queryBuilder->createNamedParameter(0, \PDO::PARAM_INT))
1125  )
1126  ->setMaxResults(1);
1127 
1128  // $this->id always points to the ID of the default language page, so we check
1129  // the current site language to determine if we need to fetch a translation but consider fallbacks
1130  if ($this->language->getLanguageId() > 0) {
1131  $languagesToCheck = array_merge([$this->language->getLanguageId()], $this->language->getFallbackLanguageIds());
1132  // Check for the language and all its fallbacks
1133  $constraint = $queryBuilder->expr()->andX(
1134  $queryBuilder->expr()->eq('l10n_parent', $queryBuilder->createNamedParameter($this->id, \PDO::PARAM_INT)),
1135  $queryBuilder->expr()->in('sys_language_uid', $queryBuilder->createNamedParameter(array_filter($languagesToCheck), Connection::PARAM_INT_ARRAY))
1136  );
1137  // If the fallback language Ids also contains the default language, this needs to be considered
1138  if (in_array(0, $languagesToCheck, true)) {
1139  $constraint = $queryBuilder->expr()->orX(
1140  $constraint,
1141  // Ensure to also fetch the default record
1142  $queryBuilder->expr()->andX(
1143  $queryBuilder->expr()->eq('uid', $queryBuilder->createNamedParameter($this->id, \PDO::PARAM_INT)),
1144  $queryBuilder->expr()->in('sys_language_uid', 0)
1145  )
1146  );
1147  }
1148  // Ensure that the translated records are shown first (maxResults is set to 1)
1149  $queryBuilder->orderBy('sys_language_uid', 'DESC');
1150  } else {
1151  $constraint = $queryBuilder->expr()->eq('uid', $queryBuilder->createNamedParameter($this->id, \PDO::PARAM_INT));
1152  }
1153  $queryBuilder->andWhere($constraint);
1154 
1155  ‪$page = $queryBuilder->execute()->fetch();
1156 
1157  if ($this->‪whichWorkspace() > 0) {
1158  // Fetch overlay of page if in workspace and check if it is hidden
1159  $customContext = clone ‪$this->context;
1160  $customContext->‪setAspect('workspace', GeneralUtility::makeInstance(WorkspaceAspect::class, $this->‪whichWorkspace()));
1161  $customContext->setAspect('visibility', GeneralUtility::makeInstance(VisibilityAspect::class));
1162  $pageSelectObject = GeneralUtility::makeInstance(PageRepository::class, $customContext);
1163  $targetPage = $pageSelectObject->getWorkspaceVersionOfRecord($this->‪whichWorkspace(), 'pages', ‪$page['uid']);
1164  // Also checks if the workspace version is NOT hidden but the live version is in fact still hidden
1165  $result = $targetPage === -1 || $targetPage === -2 || (is_array($targetPage) && $targetPage['hidden'] == 0 && ‪$page['hidden'] == 1);
1166  } else {
1167  $result = is_array(‪$page) && (‪$page['hidden'] || ‪$page['starttime'] > ‪$GLOBALS['SIM_EXEC_TIME'] || ‪$page['endtime'] != 0 && ‪$page['endtime'] <= ‪$GLOBALS['SIM_EXEC_TIME']);
1168  }
1169  return $result;
1170  }
1171 
1231  public function ‪fetch_the_id(ServerRequestInterface $request = null)
1232  {
1233  $request = $request ?? ‪$GLOBALS['TYPO3_REQUEST'] ?? ‪ServerRequestFactory::fromGlobals();
1234  $timeTracker = $this->‪getTimeTracker();
1235  $timeTracker->push('fetch_the_id initialize/');
1236  // Set the valid usergroups for FE
1237  $this->‪initUserGroups();
1238  // Initialize the PageRepository has to be done after the frontend usergroups are initialized / resolved, as
1239  // frontend group aspect is modified before
1240  $this->sys_page = GeneralUtility::makeInstance(PageRepository::class, $this->context);
1241  // The id and type is set to the integer-value - just to be sure...
1242  $this->id = (int)$this->id;
1243  $this->type = (int)$this->type;
1244  $timeTracker->pull();
1245  // We find the first page belonging to the current domain
1246  $timeTracker->push('fetch_the_id domain/');
1247  if (!$this->id) {
1248  // If the id was not previously set, set it to the root page id of the site.
1249  $this->id = $this->site->getRootPageId();
1250  }
1251  $timeTracker->pull();
1252  $timeTracker->push('fetch_the_id rootLine/');
1253  // We store the originally requested id
1254  $this->requestedId = ‪$this->id;
1255  try {
1256  $this->‪getPageAndRootlineWithDomain($this->site->getRootPageId(), $request);
1257  } catch (ShortcutTargetPageNotFoundException $e) {
1258  $this->pageNotFound = 1;
1259  }
1260  $timeTracker->pull();
1261  if ($this->pageNotFound) {
1262  switch ($this->pageNotFound) {
1263  case 1:
1264  $response = GeneralUtility::makeInstance(ErrorController::class)->accessDeniedAction(
1265  $request,
1266  'ID was not an accessible page',
1268  );
1269  break;
1270  case 2:
1271  $response = GeneralUtility::makeInstance(ErrorController::class)->accessDeniedAction(
1272  $request,
1273  'Subsection was found and not accessible',
1275  );
1276  break;
1277  case 3:
1278  $response = GeneralUtility::makeInstance(ErrorController::class)->pageNotFoundAction(
1279  $request,
1280  'ID was outside the domain',
1282  );
1283  break;
1284  default:
1285  $response = GeneralUtility::makeInstance(ErrorController::class)->pageNotFoundAction(
1286  $request,
1287  'Unspecified error',
1289  );
1290  }
1291  throw new ‪ImmediateResponseException($response, 1533931329);
1292  }
1293 
1294  $this->‪setRegisterValueForSysLastChanged($this->page);
1295 
1296  foreach (‪$GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['tslib/class.tslib_fe.php']['fetchPageId-PostProcessing'] ?? [] as $functionReference) {
1297  $parameters = ['parentObject' => $this];
1298  GeneralUtility::callUserFunction($functionReference, $parameters, $this);
1299  }
1300  }
1301 
1346  protected function ‪getPageAndRootline(ServerRequestInterface $request)
1347  {
1348  $requestedPageRowWithoutGroupCheck = [];
1349  $this->‪resolveTranslatedPageId();
1350  if (empty($this->page)) {
1351  // If no page, we try to find the page above in the rootLine.
1352  // Page is 'not found' in case the id itself was not an accessible page. code 1
1353  $this->pageNotFound = 1;
1354  $requestedPageIsHidden = false;
1355  try {
1356  $hiddenField = ‪$GLOBALS['TCA']['pages']['ctrl']['enablecolumns']['disabled'] ?? '';
1357  $includeHiddenPages = $this->context->getPropertyFromAspect('visibility', 'includeHiddenPages') || $this->‪isBackendUserLoggedIn();
1358  if (!empty($hiddenField) && !$includeHiddenPages) {
1359  // Page is "hidden" => 404 (deliberately done in default language, as this cascades to language overlays)
1360  $rawPageRecord = $this->sys_page->getPage_noCheck($this->id);
1361  $requestedPageIsHidden = (bool)$rawPageRecord[$hiddenField];
1362  }
1363 
1364  $requestedPageRowWithoutGroupCheck = $this->sys_page->getPage($this->id, true);
1365  if (!empty($requestedPageRowWithoutGroupCheck)) {
1366  $this->pageAccessFailureHistory['direct_access'][] = $requestedPageRowWithoutGroupCheck;
1367  }
1368  $this->rootLine = GeneralUtility::makeInstance(RootlineUtility::class, $this->id, $this->MP, $this->context)->get();
1369  if (!empty($this->rootLine)) {
1370  $c = count($this->rootLine) - 1;
1371  while ($c > 0) {
1372  // Add to page access failure history:
1373  $this->pageAccessFailureHistory['direct_access'][] = $this->rootLine[$c];
1374  // Decrease to next page in rootline and check the access to that, if OK, set as page record and ID value.
1375  $c--;
1376  $this->id = $this->rootLine[$c]['uid'];
1377  $this->page = $this->sys_page->getPage($this->id);
1378  if (!empty($this->page)) {
1379  break;
1380  }
1381  }
1382  }
1383  } catch (RootLineException $e) {
1384  $this->rootLine = [];
1385  }
1386  // If still no page...
1387  if ($requestedPageIsHidden || (empty($requestedPageRowWithoutGroupCheck) && empty($this->page))) {
1388  $message = 'The requested page does not exist!';
1389  try {
1390  $response = GeneralUtility::makeInstance(ErrorController::class)->pageNotFoundAction(
1391  $request,
1392  $message,
1394  );
1395  throw new ImmediateResponseException($response, 1533931330);
1396  } catch (PageNotFoundException $e) {
1397  throw new PageNotFoundException($message, 1301648780);
1398  }
1399  }
1400  }
1401  // Spacer and sysfolders is not accessible in frontend
1402  $isSpacerOrSysfolder = $this->page['doktype'] == ‪PageRepository::DOKTYPE_SPACER || $this->page['doktype'] == ‪PageRepository::DOKTYPE_SYSFOLDER;
1403  // Page itself is not accessible, but the parent page is a spacer/sysfolder
1404  if ($isSpacerOrSysfolder && !empty($requestedPageRowWithoutGroupCheck)) {
1405  try {
1406  $response = GeneralUtility::makeInstance(ErrorController::class)->accessDeniedAction(
1407  $request,
1408  'Subsection was found and not accessible',
1410  );
1411  throw new ImmediateResponseException($response, 1633171038);
1412  } catch (PageNotFoundException $e) {
1413  throw new PageNotFoundException('Subsection was found and not accessible', 1633171172);
1414  }
1415  }
1416 
1417  if ($isSpacerOrSysfolder) {
1418  $message = 'The requested page does not exist!';
1419  try {
1420  $response = GeneralUtility::makeInstance(ErrorController::class)->pageNotFoundAction(
1421  $request,
1422  $message,
1424  );
1425  throw new ImmediateResponseException($response, 1533931343);
1426  } catch (PageNotFoundException $e) {
1427  throw new PageNotFoundException($message, 1301648781);
1428  }
1429  }
1430  // Is the ID a link to another page??
1431  if ($this->page['doktype'] == ‪PageRepository::DOKTYPE_SHORTCUT) {
1432  // We need to clear MP if the page is a shortcut. Reason is if the short cut goes to another page, then we LEAVE the rootline which the MP expects.
1433  $this->MP = '';
1434  // saving the page so that we can check later - when we know
1435  // about languages - whether we took the correct shortcut or
1436  // whether a translation of the page overwrites the shortcut
1437  // target and we need to follow the new target
1438  $this->originalShortcutPage = ‪$this->page;
1439  $this->page = $this->sys_page->getPageShortcut($this->page['shortcut'], $this->page['shortcut_mode'], $this->page['uid']);
1440  $this->id = $this->page['uid'];
1441  }
1442  // If the page is a mountpoint which should be overlaid with the contents of the mounted page,
1443  // it must never be accessible directly, but only in the mountpoint context. Therefore we change
1444  // the current ID and the user is redirected by checkPageForMountpointRedirect().
1445  if ($this->page['doktype'] == ‪PageRepository::DOKTYPE_MOUNTPOINT && $this->page['mount_pid_ol']) {
1446  $this->originalMountPointPage = ‪$this->page;
1447  $this->page = $this->sys_page->getPage($this->page['mount_pid']);
1448  if (empty($this->page)) {
1449  $message = 'This page (ID ' . $this->originalMountPointPage['uid'] . ') is of type "Mount point" and '
1450  . 'mounts a page which is not accessible (ID ' . $this->originalMountPointPage['mount_pid'] . ').';
1451  throw new ‪PageNotFoundException($message, 1402043263);
1452  }
1453  // If the current page is a shortcut, the MP parameter will be replaced
1454  if ($this->MP === '' || !empty($this->originalShortcutPage)) {
1455  $this->MP = $this->page['uid'] . '-' . $this->originalMountPointPage['uid'];
1456  } else {
1457  $this->MP .= ',' . $this->page['uid'] . '-' . $this->originalMountPointPage['uid'];
1458  }
1459  $this->id = $this->page['uid'];
1460  }
1461  // Gets the rootLine
1462  try {
1463  $this->rootLine = GeneralUtility::makeInstance(RootlineUtility::class, $this->id, $this->MP, $this->context)->get();
1464  } catch (RootLineException $e) {
1465  $this->rootLine = [];
1466  }
1467  // If not rootline we're off...
1468  if (empty($this->rootLine)) {
1469  $message = 'The requested page didn\'t have a proper connection to the tree-root!';
1470  $this->logger->error($message);
1471  try {
1472  $response = GeneralUtility::makeInstance(ErrorController::class)->internalErrorAction(
1473  $request,
1474  $message,
1476  );
1477  throw new ‪ImmediateResponseException($response, 1533931350);
1478  } catch (‪AbstractServerErrorException $e) {
1479  $this->logger->error($message);
1480  $exceptionClass = get_class($e);
1481  throw new $exceptionClass($message, 1301648167);
1482  }
1483  }
1484  // Checking for include section regarding the hidden/starttime/endtime/fe_user (that is access control of a whole subbranch!)
1485  if ($this->‪checkRootlineForIncludeSection()) {
1486  if (empty($this->rootLine)) {
1487  $message = 'The requested page does not exist!';
1488  try {
1489  $response = GeneralUtility::makeInstance(ErrorController::class)->pageNotFoundAction(
1490  $request,
1491  $message,
1493  );
1494  throw new ImmediateResponseException($response, 1533931351);
1495  } catch (AbstractServerErrorException $e) {
1496  $this->logger->warning($message);
1497  $exceptionClass = get_class($e);
1498  throw new $exceptionClass($message, 1301648234);
1499  }
1500  } else {
1501  $el = reset($this->rootLine);
1502  $this->id = $el['uid'];
1503  $this->page = $this->sys_page->getPage($this->id);
1504  try {
1505  $this->rootLine = GeneralUtility::makeInstance(RootlineUtility::class, $this->id, $this->MP, $this->context)->get();
1506  } catch (RootLineException $e) {
1507  $this->rootLine = [];
1508  }
1509  }
1510  }
1511  }
1512 
1519  protected function ‪resolveTranslatedPageId()
1520  {
1521  $this->page = $this->sys_page->getPage($this->id);
1522  // Accessed a default language page record, nothing to resolve
1523  if (empty($this->page) || (int)$this->page[‪$GLOBALS['TCA']['pages']['ctrl']['languageField']] === 0) {
1524  return;
1525  }
1526  $languageId = (int)$this->page[‪$GLOBALS['TCA']['pages']['ctrl']['languageField']];
1527  $this->page = $this->sys_page->getPage($this->page[‪$GLOBALS['TCA']['pages']['ctrl']['transOrigPointerField']]);
1528  $this->context->setAspect('language', GeneralUtility::makeInstance(LanguageAspect::class, $languageId));
1529  $this->id = $this->page['uid'];
1530  }
1531 
1556  protected function ‪checkRootlineForIncludeSection(): bool
1557  {
1558  $c = count($this->rootLine);
1559  $removeTheRestFlag = false;
1560  for ($a = 0; $a < $c; $a++) {
1561  if (!$this->‪checkPagerecordForIncludeSection($this->rootLine[$a])) {
1562  // Add to page access failure history and mark the page as not found
1563  // Keep the rootline however to trigger an access denied error instead of a service unavailable error
1564  $this->pageAccessFailureHistory['sub_section'][] = $this->rootLine[$a];
1565  $this->pageNotFound = 2;
1566  }
1567 
1568  if ((int)$this->rootLine[$a]['doktype'] === ‪PageRepository::DOKTYPE_BE_USER_SECTION) {
1569  // If there is a backend user logged in, check if they have read access to the page:
1570  if ($this->‪isBackendUserLoggedIn()) {
1571  $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)
1572  ->getQueryBuilderForTable('pages');
1573 
1574  $queryBuilder
1575  ->getRestrictions()
1576  ->removeAll();
1577 
1578  $row = $queryBuilder
1579  ->select('uid')
1580  ->from('pages')
1581  ->where(
1582  $queryBuilder->expr()->eq(
1583  'uid',
1584  $queryBuilder->createNamedParameter($this->id, \PDO::PARAM_INT)
1585  ),
1586  $this->getBackendUser()->getPagePermsClause(‪Permission::PAGE_SHOW)
1587  )
1588  ->execute()
1589  ->fetch();
1590 
1591  // versionOL()?
1592  if (!$row) {
1593  // If there was no page selected, the user apparently did not have read access to the current PAGE (not position in rootline) and we set the remove-flag...
1594  $removeTheRestFlag = true;
1595  }
1596  } else {
1597  // Don't go here, if there is no backend user logged in.
1598  $removeTheRestFlag = true;
1599  }
1600  } elseif ((int)$this->rootLine[$a]['doktype'] === ‪PageRepository::DOKTYPE_RECYCLER) {
1601  // page is in a recycler
1602  $removeTheRestFlag = true;
1603  }
1604  if ($removeTheRestFlag) {
1605  // Page is 'not found' in case a subsection was found and not accessible, code 2
1606  $this->pageNotFound = 2;
1607  unset($this->rootLine[$a]);
1608  }
1609  }
1610  return $removeTheRestFlag;
1611  }
1612 
1624  public function ‪checkEnableFields($row, $bypassGroupCheck = false)
1625  {
1626  $_params = ['pObj' => $this, 'row' => &$row, 'bypassGroupCheck' => &$bypassGroupCheck];
1627  foreach (‪$GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['tslib/class.tslib_fe.php']['hook_checkEnableFields'] ?? [] as $_funcRef) {
1628  // Call hooks: If one returns FALSE, method execution is aborted with result "This record is not available"
1629  $return = GeneralUtility::callUserFunction($_funcRef, $_params, $this);
1630  if ($return === false) {
1631  return false;
1632  }
1633  }
1634  if ((!$row['hidden'] || $this->context->getPropertyFromAspect('visibility', 'includeHiddenPages', false))
1635  && $row['starttime'] <= ‪$GLOBALS['SIM_ACCESS_TIME']
1636  && ($row['endtime'] == 0 || $row['endtime'] > ‪$GLOBALS['SIM_ACCESS_TIME'])
1637  && ($bypassGroupCheck || $this->checkPageGroupAccess($row))) {
1638  return true;
1639  }
1640  return false;
1641  }
1642 
1650  public function ‪checkPageGroupAccess($row)
1651  {
1653  $userAspect = $this->context->getAspect('frontend.user');
1654  $pageGroupList = explode(',', $row['fe_group'] ?: 0);
1655  return count(array_intersect($userAspect->getGroupIds(), $pageGroupList)) > 0;
1656  }
1657 
1673  public function ‪checkPagerecordForIncludeSection(array $row): bool
1674  {
1675  return !$row['extendToSubpages'] || $this->‪checkEnableFields($row);
1676  }
1677 
1683  public function ‪checkIfLoginAllowedInBranch()
1684  {
1685  // Initialize:
1686  $c = count($this->rootLine);
1687  $loginAllowed = true;
1688  // Traverse root line from root and outwards:
1689  for ($a = 0; $a < $c; $a++) {
1690  // If a value is set for login state:
1691  if ($this->rootLine[$a]['fe_login_mode'] > 0) {
1692  // Determine state from value:
1693  if ((int)$this->rootLine[$a]['fe_login_mode'] === 1) {
1694  $loginAllowed = false;
1695  $this->loginAllowedInBranch_mode = 'all';
1696  } elseif ((int)$this->rootLine[$a]['fe_login_mode'] === 3) {
1697  $loginAllowed = false;
1698  $this->loginAllowedInBranch_mode = 'groups';
1699  } else {
1700  $loginAllowed = true;
1701  }
1702  }
1703  }
1704  return $loginAllowed;
1705  }
1706 
1713  public function ‪getPageAccessFailureReasons(string $failureReasonCode = null)
1714  {
1715  ‪$output = [];
1716  if ($failureReasonCode) {
1717  ‪$output['code'] = $failureReasonCode;
1718  }
1719  $combinedRecords = array_merge(is_array($this->pageAccessFailureHistory['direct_access']) ? $this->pageAccessFailureHistory['direct_access'] : [['fe_group' => 0]], is_array($this->pageAccessFailureHistory['sub_section']) ? $this->pageAccessFailureHistory['sub_section'] : []);
1720  if (!empty($combinedRecords)) {
1721  foreach ($combinedRecords as $k => $pagerec) {
1722  // If $k=0 then it is the very first page the original ID was pointing at and that will get a full check of course
1723  // If $k>0 it is parent pages being tested. They are only significant for the access to the first page IF they had the extendToSubpages flag set, hence checked only then!
1724  if (!$k || $pagerec['extendToSubpages']) {
1725  if ($pagerec['hidden']) {
1726  ‪$output['hidden'][$pagerec['uid']] = true;
1727  }
1728  if ($pagerec['starttime'] > ‪$GLOBALS['SIM_ACCESS_TIME']) {
1729  ‪$output['starttime'][$pagerec['uid']] = $pagerec['starttime'];
1730  }
1731  if ($pagerec['endtime'] != 0 && $pagerec['endtime'] <= ‪$GLOBALS['SIM_ACCESS_TIME']) {
1732  ‪$output['endtime'][$pagerec['uid']] = $pagerec['endtime'];
1733  }
1734  if (!$this->‪checkPageGroupAccess($pagerec)) {
1735  ‪$output['fe_group'][$pagerec['uid']] = $pagerec['fe_group'];
1736  }
1737  }
1738  }
1739  }
1740  return ‪$output;
1741  }
1742 
1750  public function ‪getPageAndRootlineWithDomain($rootPageId, ServerRequestInterface $request)
1751  {
1752  $this->‪getPageAndRootline($request);
1753  // Checks if the $domain-startpage is in the rootLine. This is necessary so that references to page-id's via ?id=123 from other sites are not possible.
1754  if (is_array($this->rootLine) && $this->rootLine !== []) {
1755  $idFound = false;
1756  foreach ($this->rootLine as $key => $val) {
1757  if ($val['uid'] == $rootPageId) {
1758  $idFound = true;
1759  break;
1760  }
1761  }
1762  if (!$idFound) {
1763  // Page is 'not found' in case the id was outside the domain, code 3
1764  $this->pageNotFound = 3;
1765  $this->id = $rootPageId;
1766  // re-get the page and rootline if the id was not found.
1767  $this->‪getPageAndRootline($request);
1768  }
1769  }
1770  }
1771 
1772  /********************************************
1773  *
1774  * Template and caching related functions.
1775  *
1776  *******************************************/
1783  public function ‪reqCHash()
1784  {
1785  trigger_error('TypoScriptFrontendController->reqCHash() is not needed anymore, as all functionality is handled via the PSR-15 PageArgumentValidator middleware already.', E_USER_DEPRECATED);
1786  if (!empty($this->pageArguments->getArguments()['cHash']) || empty($this->pageArguments->getDynamicArguments())) {
1787  return;
1788  }
1789  $queryParams = $this->pageArguments->getDynamicArguments();
1790  $queryParams['id'] = $this->pageArguments->getPageId();
1791  $argumentsThatWouldRequireCacheHash = GeneralUtility::makeInstance(CacheHashCalculator::class)
1792  ->getRelevantParameters(‪HttpUtility::buildQueryString($queryParams));
1793  if (empty($argumentsThatWouldRequireCacheHash)) {
1794  return;
1795  }
1796  if (‪$GLOBALS['TYPO3_CONF_VARS']['FE']['pageNotFoundOnCHashError']) {
1797  $response = GeneralUtility::makeInstance(ErrorController::class)->pageNotFoundAction(
1798  ‪$GLOBALS['TYPO3_REQUEST'],
1799  'Request parameters could not be validated (&cHash empty)',
1801  );
1802  throw new ImmediateResponseException($response, 1533931354);
1803  }
1804  $this->‪disableCache();
1805  $this->‪getTimeTracker()->‪setTSlogMessage('TSFE->reqCHash(): No &cHash parameter was sent for GET vars though required so caching is disabled', 2);
1806  }
1807 
1808  protected function ‪setPageArguments(PageArguments ‪$pageArguments): void
1809  {
1810  $this->pageArguments = ‪$pageArguments;
1811  $this->id = $pageArguments->‪getPageId();
1812  $this->type = ‪$pageArguments->‪getPageType() ?: 0;
1813  if (‪$GLOBALS['TYPO3_CONF_VARS']['FE']['enable_mount_pids']) {
1814  $this->MP = (string)(‪$pageArguments->getArguments()['MP'] ?? '');
1815  // Ensure no additional arguments are given via the &MP=123-345,908-172 (e.g. "/")
1816  $this->MP = preg_replace('/[^0-9,-]/', '', $this->MP);
1817  }
1818  }
1819 
1827  protected function ‪getRelevantParametersForCachingFromPageArguments(PageArguments ‪$pageArguments): array
1828  {
1829  $queryParams = ‪$pageArguments->getDynamicArguments();
1830  if (!empty($queryParams) && (‪$pageArguments->getArguments()['cHash'] ?? false)) {
1831  $queryParams['id'] = ‪$pageArguments->‪getPageId();
1832  return GeneralUtility::makeInstance(CacheHashCalculator::class)
1833  ->getRelevantParameters(‪HttpUtility::buildQueryString($queryParams));
1834  }
1835  return [];
1836  }
1837 
1845  public function ‪getFromCache(ServerRequestInterface $request = null)
1846  {
1847  // clearing the content-variable, which will hold the pagecontent
1848  $this->content = '';
1849  // Unsetting the lowlevel config
1850  $this->config = [];
1851  $this->cacheContentFlag = false;
1852 
1853  if ($this->no_cache) {
1854  return;
1855  }
1856 
1857  if (!$this->tmpl instanceof ‪TemplateService) {
1858  $this->tmpl = GeneralUtility::makeInstance(TemplateService::class, $this->context, null, $this);
1859  }
1860 
1861  $pageSectionCacheContent = $this->tmpl->getCurrentPageData((int)$this->id, (string)$this->MP);
1862  if (!is_array($pageSectionCacheContent)) {
1863  // Nothing in the cache, we acquire an "exclusive lock" for the key now.
1864  // We use the Registry to store this lock centrally,
1865  // but we protect the access again with a global exclusive lock to avoid race conditions
1866 
1867  $this->‪acquireLock('pagesection', $this->id . '::' . $this->MP);
1868  //
1869  // from this point on we're the only one working on that page ($key)
1870  //
1871 
1872  // query the cache again to see if the page data are there meanwhile
1873  $pageSectionCacheContent = $this->tmpl->getCurrentPageData((int)$this->id, (string)$this->MP);
1874  if (is_array($pageSectionCacheContent)) {
1875  // we have the content, nice that some other process did the work for us already
1876  $this->‪releaseLock('pagesection');
1877  }
1878  // We keep the lock set, because we are the ones generating the page now and filling the cache.
1879  // This indicates that we have to release the lock later in releaseLocks()
1880  }
1881 
1882  if (is_array($pageSectionCacheContent)) {
1883  // BE CAREFUL to change the content of the cc-array. This array is serialized and an md5-hash based on this is used for caching the page.
1884  // If this hash is not the same in here in this section and after page-generation, then the page will not be properly cached!
1885  // This array is an identification of the template. If $this->all is empty it's because the template-data is not cached, which it must be.
1886  $pageSectionCacheContent = $this->tmpl->matching($pageSectionCacheContent);
1887  ksort($pageSectionCacheContent);
1888  $this->all = $pageSectionCacheContent;
1889  }
1890 
1891  // Look for page in cache only if a shift-reload is not sent to the server.
1892  $lockHash = $this->‪getLockHash();
1893  if (!$this->‪headerNoCache($request) && $this->all) {
1894  // we got page section information (TypoScript), so lets see if there is also a cached version
1895  // of this page in the pages cache.
1896  $this->newHash = $this->‪getHash();
1897  $this->‪getTimeTracker()->‪push('Cache Row');
1898  $row = $this->‪getFromCache_queryRow();
1899  if (!is_array($row)) {
1900  // nothing in the cache, we acquire an exclusive lock now
1901  $this->‪acquireLock('pages', $lockHash);
1902  //
1903  // from this point on we're the only one working on that page ($lockHash)
1904  //
1905 
1906  // query the cache again to see if the data are there meanwhile
1907  $row = $this->‪getFromCache_queryRow();
1908  if (is_array($row)) {
1909  // we have the content, nice that some other process did the work for us
1910  $this->‪releaseLock('pages');
1911  }
1912  // We keep the lock set, because we are the ones generating the page now and filling the cache.
1913  // This indicates that we have to release the lock later in releaseLocks()
1914  }
1915  if (is_array($row)) {
1916  $this->‪populatePageDataFromCache($row);
1917  }
1918  $this->‪getTimeTracker()->‪pull();
1919  } else {
1920  // the user forced rebuilding the page cache or there was no pagesection information
1921  // get a lock for the page content so other processes will not interrupt the regeneration
1922  $this->‪acquireLock('pages', $lockHash);
1923  }
1924  }
1925 
1931  public function ‪getFromCache_queryRow()
1932  {
1933  $this->‪getTimeTracker()->‪push('Cache Query');
1934  $row = $this->pageCache->get($this->newHash);
1935  $this->‪getTimeTracker()->‪pull();
1936  return $row;
1937  }
1938 
1949  protected function ‪populatePageDataFromCache(array $cachedData): void
1950  {
1951  // Call hook when a page is retrieved from cache
1952  $_params = ['pObj' => &$this, 'cache_pages_row' => &$cachedData];
1953  foreach (‪$GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['tslib/class.tslib_fe.php']['pageLoadedFromCache'] ?? [] as $_funcRef) {
1954  GeneralUtility::callUserFunction($_funcRef, $_params, $this);
1955  }
1956  // Fetches the lowlevel config stored with the cached data
1957  $this->config = $cachedData['cache_data'];
1958  // Getting the content
1959  $this->content = $cachedData['content'];
1960  // Setting flag, so we know, that some cached content has been loaded
1961  $this->cacheContentFlag = true;
1962  $this->cacheExpires = $cachedData['expires'];
1963  // Restore the current tags as they can be retrieved by getPageCacheTags()
1964  $this->pageCacheTags = $cachedData['cacheTags'] ?? [];
1965 
1966  // Restore page title information, this is needed to generate the page title for
1967  // partially cached pages.
1968  $this->page['title'] = $cachedData['pageTitleInfo']['title'];
1969  $this->indexedDocTitle = $cachedData['pageTitleInfo']['indexedDocTitle'];
1970 
1971  if (isset($this->config['config']['debug'])) {
1972  $debugCacheTime = (bool)$this->config['config']['debug'];
1973  } else {
1974  $debugCacheTime = !empty(‪$GLOBALS['TYPO3_CONF_VARS']['FE']['debug']);
1975  }
1976  if ($debugCacheTime) {
1977  $dateFormat = ‪$GLOBALS['TYPO3_CONF_VARS']['SYS']['ddmmyy'];
1978  $timeFormat = ‪$GLOBALS['TYPO3_CONF_VARS']['SYS']['hhmm'];
1979  $this->content .= LF . '<!-- Cached page generated ' . date($dateFormat . ' ' . $timeFormat, $cachedData['tstamp']) . '. Expires ' . date($dateFormat . ' ' . $timeFormat, $cachedData['expires']) . ' -->';
1980  }
1981  }
1982 
1991  public function ‪headerNoCache(ServerRequestInterface $request = null)
1992  {
1993  if ($request instanceof ServerRequestInterface) {
1994  $serverParams = $request->getServerParams();
1995  } else {
1996  $serverParams = $_SERVER;
1997  }
1998  $disableAcquireCacheData = false;
1999  if ($this->‪isBackendUserLoggedIn()) {
2000  if (strtolower($serverParams['HTTP_CACHE_CONTROL'] ?? '') === 'no-cache' || strtolower($serverParams['HTTP_PRAGMA'] ?? '') === 'no-cache') {
2001  $disableAcquireCacheData = true;
2002  }
2003  }
2004  // Call hook for possible by-pass of requiring of page cache (for recaching purpose)
2005  $_params = ['pObj' => &$this, 'disableAcquireCacheData' => &$disableAcquireCacheData];
2006  foreach (‪$GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['tslib/class.tslib_fe.php']['headerNoCache'] ?? [] as $_funcRef) {
2007  GeneralUtility::callUserFunction($_funcRef, $_params, $this);
2008  }
2009  return $disableAcquireCacheData;
2010  }
2011 
2021  protected function ‪getHash()
2022  {
2023  return md5($this->‪createHashBase(false));
2024  }
2025 
2034  protected function ‪getLockHash()
2035  {
2036  $lockHash = $this->‪createHashBase(true);
2037  return md5($lockHash);
2038  }
2039 
2050  protected function ‪createHashBase($createLockHashBase = false)
2051  {
2052  // Fetch the list of user groups
2054  $userAspect = $this->context->getAspect('frontend.user');
2055  $hashParameters = [
2056  'id' => (int)$this->id,
2057  'type' => (int)‪$this->type,
2058  'groupIds' => (string)implode(',', $userAspect->getGroupIds()),
2059  'MP' => (string)‪$this->MP,
2060  'site' => $this->site->getIdentifier(),
2061  // Ensure the language base is used for the hash base calculation as well, otherwise TypoScript and page-related rendering
2062  // is not cached properly as we don't have any language-specific conditions anymore
2063  'siteBase' => (string)$this->language->getBase(),
2064  // additional variation trigger for static routes
2065  'staticRouteArguments' => $this->pageArguments->getStaticArguments(),
2066  // dynamic route arguments (if route was resolved)
2067  'dynamicArguments' => $this->‪getRelevantParametersForCachingFromPageArguments($this->pageArguments),
2068  ];
2069  // Include the template information if we shouldn't create a lock hash
2070  if (!$createLockHashBase) {
2071  $hashParameters['all'] = ‪$this->all;
2072  }
2073  // Call hook to influence the hash calculation
2074  $_params = [
2075  'hashParameters' => &$hashParameters,
2076  'createLockHashBase' => $createLockHashBase
2077  ];
2078  foreach (‪$GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['tslib/class.tslib_fe.php']['createHashBase'] ?? [] as $_funcRef) {
2079  GeneralUtility::callUserFunction($_funcRef, $_params, $this);
2080  }
2081  return serialize($hashParameters);
2082  }
2083 
2091  public function ‪getConfigArray(ServerRequestInterface $request = null)
2092  {
2093  $request = $request ?? ‪$GLOBALS['TYPO3_REQUEST'] ?? ‪ServerRequestFactory::fromGlobals();
2094  if (!$this->tmpl instanceof TemplateService) {
2095  $this->tmpl = GeneralUtility::makeInstance(TemplateService::class, $this->context, null, $this);
2096  }
2097 
2098  // If config is not set by the cache (which would be a major mistake somewhere) OR if INTincScripts-include-scripts have been registered, then we must parse the template in order to get it
2099  if (empty($this->config) || $this->‪isINTincScript() || $this->context->getPropertyFromAspect('typoscript', 'forcedTemplateParsing')) {
2100  $timeTracker = $this->‪getTimeTracker();
2101  $timeTracker->push('Parse template');
2102  // Start parsing the TS template. Might return cached version.
2103  $this->tmpl->start($this->rootLine);
2104  $timeTracker->pull();
2105  // At this point we have a valid pagesection_cache (generated in $this->tmpl->start()),
2106  // so let all other processes proceed now. (They are blocked at the pagessection_lock in getFromCache())
2107  $this->‪releaseLock('pagesection');
2108  if ($this->tmpl->loaded) {
2109  $timeTracker->push('Setting the config-array');
2110  // toplevel - objArrayName
2111  $typoScriptPageTypeName = $this->tmpl->setup['types.'][‪$this->type];
2112  $this->sPre = $typoScriptPageTypeName;
2113  $this->pSetup = $this->tmpl->setup[$typoScriptPageTypeName . '.'];
2114  if (!is_array($this->pSetup)) {
2115  $message = 'The page is not configured! [type=' . $this->type . '][' . $typoScriptPageTypeName . '].';
2116  $this->logger->alert($message);
2117  try {
2118  $response = GeneralUtility::makeInstance(ErrorController::class)->internalErrorAction(
2119  $request,
2120  $message,
2122  );
2123  throw new ImmediateResponseException($response, 1533931374);
2124  } catch (AbstractServerErrorException $e) {
2125  $explanation = 'This means that there is no TypoScript object of type PAGE with typeNum=' . $this->type . ' configured.';
2126  $exceptionClass = get_class($e);
2127  throw new $exceptionClass($message . ' ' . $explanation, 1294587217);
2128  }
2129  } else {
2130  if (!isset($this->config['config'])) {
2131  $this->config['config'] = [];
2132  }
2133  // Filling the config-array, first with the main "config." part
2134  if (is_array($this->tmpl->setup['config.'] ?? null)) {
2135  ‪ArrayUtility::mergeRecursiveWithOverrule($this->tmpl->setup['config.'], $this->config['config']);
2136  $this->config['config'] = $this->tmpl->setup['config.'];
2137  }
2138  // override it with the page/type-specific "config."
2139  if (is_array($this->pSetup['config.'] ?? null)) {
2140  ‪ArrayUtility::mergeRecursiveWithOverrule($this->config['config'], $this->pSetup['config.']);
2141  }
2142  // Set default values for removeDefaultJS and inlineStyle2TempFile so CSS and JS are externalized if compatversion is higher than 4.0
2143  if (!isset($this->config['config']['removeDefaultJS'])) {
2144  $this->config['config']['removeDefaultJS'] = 'external';
2145  }
2146  if (!isset($this->config['config']['inlineStyle2TempFile'])) {
2147  $this->config['config']['inlineStyle2TempFile'] = 1;
2148  }
2149 
2150  if (!isset($this->config['config']['compressJs'])) {
2151  $this->config['config']['compressJs'] = 0;
2152  }
2153  // Rendering charset of HTML page.
2154  if (isset($this->config['config']['metaCharset']) && $this->config['config']['metaCharset'] !== 'utf-8') {
2155  $this->metaCharset = $this->config['config']['metaCharset'];
2156  }
2157  // Setting default cache_timeout
2158  if (isset($this->config['config']['cache_period'])) {
2159  $this->‪set_cache_timeout_default((int)$this->config['config']['cache_period']);
2160  }
2161 
2162  // Processing for the config_array:
2163  $this->config['rootLine'] = $this->tmpl->rootLine;
2164  // Class for render Header and Footer parts
2165  if ($this->pSetup['pageHeaderFooterTemplateFile'] ?? false) {
2166  try {
2167  $file = GeneralUtility::makeInstance(FilePathSanitizer::class)
2168  ->sanitize((string)$this->pSetup['pageHeaderFooterTemplateFile']);
2169  $this->pageRenderer->setTemplateFile($file);
2170  } catch (Exception $e) {
2171  // do nothing
2172  }
2173  }
2174  }
2175  $timeTracker->pull();
2176  } else {
2177  $message = 'No TypoScript template found!';
2178  $this->logger->alert($message);
2179  try {
2180  $response = GeneralUtility::makeInstance(ErrorController::class)->internalErrorAction(
2181  $request,
2182  $message,
2184  );
2185  throw new ImmediateResponseException($response, 1533931380);
2186  } catch (AbstractServerErrorException $e) {
2187  $exceptionClass = get_class($e);
2188  throw new $exceptionClass($message, 1294587218);
2189  }
2190  }
2191  }
2192 
2193  // No cache
2194  // Set $this->no_cache TRUE if the config.no_cache value is set!
2195  if ($this->config['config']['no_cache']) {
2196  $this->‪set_no_cache('config.no_cache is set', true);
2197  }
2198 
2199  // Auto-configure settings when a site is configured
2200  $this->config['config']['absRefPrefix'] = $this->config['config']['absRefPrefix'] ?? 'auto';
2201 
2202  // Hook for postProcessing the configuration array
2203  $params = ['config' => &$this->config['config']];
2204  foreach (‪$GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['tslib/class.tslib_fe.php']['configArrayPostProc'] ?? [] as $funcRef) {
2205  GeneralUtility::callUserFunction($funcRef, $params, $this);
2206  }
2207  }
2208 
2209  /********************************************
2210  *
2211  * Further initialization and data processing
2212  *
2213  *******************************************/
2221  public function ‪settingLanguage(ServerRequestInterface $request = null)
2222  {
2223  $request = $request ?? ‪$GLOBALS['TYPO3_REQUEST'] ?? ‪ServerRequestFactory::fromGlobals();
2224  $_params = [];
2225  foreach (‪$GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['tslib/class.tslib_fe.php']['settingLanguage_preProcess'] ?? [] as $_funcRef) {
2226  $ref = $this; // introduced for phpstan to not lose type information when passing $this into callUserFunction
2227  GeneralUtility::callUserFunction($_funcRef, $_params, $ref);
2228  }
2229 
2230  // Get values from site language
2231  $languageAspect = ‪LanguageAspectFactory::createFromSiteLanguage($this->language);
2232 
2233  $languageId = $languageAspect->getId();
2234  $languageContentId = $languageAspect->getContentId();
2235 
2236  // If sys_language_uid is set to another language than default:
2237  if ($languageAspect->getId() > 0) {
2238  // check whether a shortcut is overwritten by a translated page
2239  // we can only do this now, as this is the place where we get
2240  // to know about translations
2241  $this->‪checkTranslatedShortcut($languageAspect->getId(), $request);
2242  // Request the overlay record for the sys_language_uid:
2243  $olRec = $this->sys_page->getPageOverlay($this->id, $languageAspect->getId());
2244  if (empty($olRec)) {
2245  // If requested translation is not available:
2246  if (GeneralUtility::hideIfNotTranslated($this->page['l18n_cfg'])) {
2247  $response = GeneralUtility::makeInstance(ErrorController::class)->pageNotFoundAction(
2248  $request,
2249  'Page is not available in the requested language.',
2251  );
2252  throw new ImmediateResponseException($response, 1533931388);
2253  }
2254  switch ((string)$languageAspect->getLegacyLanguageMode()) {
2255  case 'strict':
2256  $response = GeneralUtility::makeInstance(ErrorController::class)->pageNotFoundAction(
2257  $request,
2258  'Page is not available in the requested language (strict).',
2260  );
2261  throw new ImmediateResponseException($response, 1533931395);
2262  case 'fallback':
2263  case 'content_fallback':
2264  // Setting content uid (but leaving the sys_language_uid) when a content_fallback
2265  // value was found.
2266  foreach ($languageAspect->getFallbackChain() ?? [] as $orderValue) {
2267  if ($orderValue === '0' || $orderValue === 0 || $orderValue === '') {
2268  $languageContentId = 0;
2269  break;
2270  }
2271  if (‪MathUtility::canBeInterpretedAsInteger($orderValue) && !empty($this->sys_page->getPageOverlay($this->id, (int)$orderValue))) {
2272  $languageContentId = (int)$orderValue;
2273  break;
2274  }
2275  if ($orderValue === 'pageNotFound') {
2276  // The existing fallbacks have not been found, but instead of continuing
2277  // page rendering with default language, a "page not found" message should be shown
2278  // instead.
2279  $response = GeneralUtility::makeInstance(ErrorController::class)->pageNotFoundAction(
2280  $request,
2281  'Page is not available in the requested language (fallbacks did not apply).',
2283  );
2284  throw new ‪ImmediateResponseException($response, 1533931402);
2285  }
2286  }
2287  break;
2288  case 'ignore':
2289  $languageContentId = $languageAspect->getId();
2290  break;
2291  default:
2292  // Default is that everything defaults to the default language...
2293  $languageId = ($languageContentId = 0);
2294  }
2295  }
2296 
2297  // Define the language aspect again now
2298  $languageAspect = GeneralUtility::makeInstance(
2299  LanguageAspect::class,
2300  $languageId,
2301  $languageContentId,
2302  $languageAspect->getOverlayType(),
2303  $languageAspect->getFallbackChain()
2304  );
2305 
2306  // Setting sys_language if an overlay record was found (which it is only if a language is used)
2307  // We'll do this every time since the language aspect might have changed now
2308  // Doing this ensures that page properties like the page title are returned in the correct language
2309  $this->page = $this->sys_page->getPageOverlay($this->page, $languageAspect->getContentId());
2310 
2311  // Update SYS_LASTCHANGED for localized page record
2312  $this->‪setRegisterValueForSysLastChanged($this->page);
2313  }
2314 
2315  // Set the language aspect
2316  $this->context->setAspect('language', $languageAspect);
2318  // Setting sys_language_uid inside sys-page by creating a new page repository
2319  $this->sys_page = GeneralUtility::makeInstance(PageRepository::class, $this->context);
2320  // If default language is not available:
2321  if ((!$languageAspect->getContentId() || !$languageAspect->getId())
2322  && GeneralUtility::hideIfDefaultLanguage($this->page['l18n_cfg'] ?? 0)
2323  ) {
2324  $message = 'Page is not available in default language.';
2325  $response = GeneralUtility::makeInstance(ErrorController::class)->pageNotFoundAction(
2326  $request,
2327  $message,
2329  );
2330  throw new ‪ImmediateResponseException($response, 1533931423);
2331  }
2332 
2333  if ($languageAspect->getId() > 0) {
2335  }
2336 
2337  $_params = [];
2338  foreach (‪$GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['tslib/class.tslib_fe.php']['settingLanguage_postProcess'] ?? [] as $_funcRef) {
2339  GeneralUtility::callUserFunction($_funcRef, $_params, $this);
2340  }
2341  }
2342 
2346  protected function ‪updateRootLinesWithTranslations()
2347  {
2348  try {
2349  $this->rootLine = GeneralUtility::makeInstance(RootlineUtility::class, $this->id, $this->MP, $this->context)->get();
2350  } catch (RootLineException $e) {
2351  $this->rootLine = [];
2352  }
2353  $this->tmpl->updateRootlineData($this->rootLine);
2354  }
2355 
2360  public function ‪settingLocale()
2361  {
2362  trigger_error('TSFE->settingLocale() will be removed in TYPO3 v11.0. Use Locales::setSystemLocaleFromSiteLanguage() instead, as this functionality is independent of TSFE.', E_USER_DEPRECATED);
2363  if ($this->language->getLocale() && !‪Locales::setSystemLocaleFromSiteLanguage($this->language)) {
2364  $this->‪getTimeTracker()->‪setTSlogMessage('Locale "' . htmlspecialchars($this->language->getLocale()) . '" not found.', 3);
2365  }
2366  }
2367 
2376  protected function ‪checkTranslatedShortcut(int $languageId, ServerRequestInterface $request)
2377  {
2378  if (!is_null($this->originalShortcutPage)) {
2379  $originalShortcutPageOverlay = $this->sys_page->getPageOverlay($this->originalShortcutPage['uid'], $languageId);
2380  if (!empty($originalShortcutPageOverlay['shortcut']) && $originalShortcutPageOverlay['shortcut'] != $this->id) {
2381  // the translation of the original shortcut page has a different shortcut target!
2382  // set the correct page and id
2383  $shortcut = $this->sys_page->getPageShortcut($originalShortcutPageOverlay['shortcut'], $originalShortcutPageOverlay['shortcut_mode'], $originalShortcutPageOverlay['uid']);
2384  $this->id = ($this->contentPid = $shortcut['uid']);
2385  $this->page = $this->sys_page->getPage($this->id);
2386  // Fix various effects on things like menus f.e.
2387  $this->‪fetch_the_id($request);
2388  $this->tmpl->rootLine = array_reverse($this->rootLine);
2389  }
2390  }
2391  }
2392 
2399  public function ‪calculateLinkVars(array $queryParams)
2400  {
2401  $this->linkVars = '';
2402  $adminCommand = $queryParams['ADMCMD_prev'] ?? '';
2403  if (($adminCommand === 'LIVE' || $adminCommand === 'IGNORE') && $this->‪isBackendUserLoggedIn()) {
2404  $this->config['config']['linkVars'] = ltrim(($this->config['config']['linkVars'] ?? '') . ',ADMCMD_prev', ',');
2405  }
2406  if (empty($this->config['config']['linkVars'])) {
2407  return;
2408  }
2409 
2410  ‪$linkVars = $this->‪splitLinkVarsString((string)$this->config['config']['linkVars']);
2411 
2412  if (empty(‪$linkVars)) {
2413  return;
2414  }
2415  foreach (‪$linkVars as $linkVar) {
2416  $test = $value = '';
2417  if (preg_match('/^(.*)\\((.+)\\)$/', $linkVar, $match)) {
2418  $linkVar = trim($match[1]);
2419  $test = trim($match[2]);
2420  }
2421 
2422  $keys = explode('|', $linkVar);
2423  $numberOfLevels = count($keys);
2424  $rootKey = trim($keys[0]);
2425  if (!isset($queryParams[$rootKey])) {
2426  continue;
2427  }
2428  $value = $queryParams[$rootKey];
2429  for ($i = 1; $i < $numberOfLevels; $i++) {
2430  $currentKey = trim($keys[$i]);
2431  if (isset($value[$currentKey])) {
2432  $value = $value[$currentKey];
2433  } else {
2434  $value = false;
2435  break;
2436  }
2437  }
2438  if ($value !== false) {
2439  $parameterName = $keys[0];
2440  for ($i = 1; $i < $numberOfLevels; $i++) {
2441  $parameterName .= '[' . $keys[$i] . ']';
2442  }
2443  if (!is_array($value)) {
2444  $temp = rawurlencode($value);
2445  if ($test !== '' && !$this->‪isAllowedLinkVarValue($temp, $test)) {
2446  // Error: This value was not allowed for this key
2447  continue;
2448  }
2449  $value = '&' . $parameterName . '=' . $temp;
2450  } else {
2451  if ($test !== '' && $test !== 'array') {
2452  // Error: This key must not be an array!
2453  continue;
2454  }
2455  $value = ‪HttpUtility::buildQueryString([$parameterName => $value], '&');
2456  }
2457  $this->linkVars .= $value;
2458  }
2459  }
2460  }
2461 
2469  protected function ‪splitLinkVarsString(string $string): array
2470  {
2471  $tempCommaReplacementString = '###KASPER###';
2472 
2473  // replace every "," wrapped in "()" by a "unique" string
2474  $string = preg_replace_callback('/\‍((?>[^()]|(?R))*\‍)/', function ($result) use ($tempCommaReplacementString) {
2475  return str_replace(',', $tempCommaReplacementString, $result[0]);
2476  }, $string) ?? '';
2477 
2478  $string = ‪GeneralUtility::trimExplode(',', $string);
2479 
2480  // replace all "unique" strings back to ","
2481  return str_replace($tempCommaReplacementString, ',', $string);
2482  }
2483 
2492  protected function ‪isAllowedLinkVarValue(string $haystack, string $needle): bool
2493  {
2494  $isAllowed = false;
2495  // Integer
2496  if ($needle === 'int' || $needle === 'integer') {
2498  $isAllowed = true;
2499  }
2500  } elseif (preg_match('/^\\/.+\\/[imsxeADSUXu]*$/', $needle)) {
2501  // Regular expression, only "//" is allowed as delimiter
2502  if (@preg_match($needle, $haystack)) {
2503  $isAllowed = true;
2504  }
2505  } elseif (strpos($needle, '-') !== false) {
2506  // Range
2508  $range = explode('-', $needle);
2509  if ($range[0] <= $haystack && $range[1] >= $haystack) {
2510  $isAllowed = true;
2511  }
2512  }
2513  } elseif (strpos($needle, '|') !== false) {
2514  // List
2515  // Trim the input
2516  $haystack = str_replace(' ', '', $haystack);
2517  if (strpos('|' . $needle . '|', '|' . $haystack . '|') !== false) {
2518  $isAllowed = true;
2519  }
2520  } elseif ((string)$needle === (string)$haystack) {
2521  // String comparison
2522  $isAllowed = true;
2523  }
2524  return $isAllowed;
2525  }
2526 
2536  public function ‪getRedirectUriForMountPoint(ServerRequestInterface $request): ?string
2537  {
2538  if (!empty($this->originalMountPointPage) && (int)$this->originalMountPointPage['doktype'] === ‪PageRepository::DOKTYPE_MOUNTPOINT) {
2539  return $this->‪getUriToCurrentPageForRedirect($request);
2540  }
2541 
2542  return null;
2543  }
2544 
2555  public function ‪getRedirectUriForShortcut(ServerRequestInterface $request): ?string
2556  {
2557  if (!empty($this->originalShortcutPage) && $this->originalShortcutPage['doktype'] == ‪PageRepository::DOKTYPE_SHORTCUT) {
2558  return $this->‪getUriToCurrentPageForRedirect($request);
2559  }
2560 
2561  return null;
2562  }
2563 
2570  protected function ‪getUriToCurrentPageForRedirect(ServerRequestInterface $request): string
2571  {
2572  $this->‪calculateLinkVars($request->getQueryParams());
2573  $parameter = $this->page['uid'];
2574  if ($this->type && ‪MathUtility::canBeInterpretedAsInteger($this->type)) {
2575  $parameter .= ',' . ‪$this->type;
2576  }
2577  return GeneralUtility::makeInstance(ContentObjectRenderer::class, $this)->typoLink_URL([
2578  'parameter' => $parameter,
2579  'addQueryString' => true,
2580  'addQueryString.' => ['exclude' => 'id'],
2581  'forceAbsoluteUrl' => true
2582  ]);
2583  }
2585  /********************************************
2586  *
2587  * Page generation; cache handling
2588  *
2589  *******************************************/
2596  public function ‪isGeneratePage()
2597  {
2599  }
2600 
2604  protected function ‪realPageCacheContent()
2605  {
2606  // seconds until a cached page is too old
2607  $cacheTimeout = $this->‪get_cache_timeout();
2608  $timeOutTime = ‪$GLOBALS['EXEC_TIME'] + $cacheTimeout;
2609  $usePageCache = true;
2610  // Hook for deciding whether page cache should be written to the cache backend or not
2611  // NOTE: as hooks are called in a loop, the last hook will have the final word (however each
2612  // hook receives the current status of the $usePageCache flag)
2613  foreach (‪$GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['tslib/class.tslib_fe.php']['usePageCache'] ?? [] as $className) {
2614  $usePageCache = GeneralUtility::makeInstance($className)->usePageCache($this, $usePageCache);
2615  }
2616  // Write the page to cache, if necessary
2617  if ($usePageCache) {
2618  $this->‪setPageCacheContent($this->content, $this->config, $timeOutTime);
2619  }
2620  // Hook for cache post processing (eg. writing static files!)
2621  foreach (‪$GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['tslib/class.tslib_fe.php']['insertPageIncache'] ?? [] as $className) {
2622  GeneralUtility::makeInstance($className)->insertPageIncache($this, $timeOutTime);
2623  }
2624  }
2625 
2634  protected function ‪setPageCacheContent(‪$content, $data, $expirationTstamp)
2635  {
2636  $cacheData = [
2637  'identifier' => ‪$this->newHash,
2638  'page_id' => ‪$this->id,
2639  'content' => ‪$content,
2640  'cache_data' => $data,
2641  'expires' => $expirationTstamp,
2642  'tstamp' => ‪$GLOBALS['EXEC_TIME'],
2643  'pageTitleInfo' => [
2644  'title' => $this->page['title'],
2645  'indexedDocTitle' => ‪$this->indexedDocTitle
2646  ]
2647  ];
2648  $this->cacheExpires = $expirationTstamp;
2649  $this->pageCacheTags[] = 'pageId_' . $cacheData['page_id'];
2650  // Respect the page cache when content of pid is shown
2651  if ($this->id !== $this->contentPid) {
2652  $this->pageCacheTags[] = 'pageId_' . ‪$this->contentPid;
2653  }
2654  if (!empty($this->page['cache_tags'])) {
2655  $tags = ‪GeneralUtility::trimExplode(',', $this->page['cache_tags'], true);
2656  $this->pageCacheTags = array_merge($this->pageCacheTags, $tags);
2657  }
2658  // Add the cache themselves as well, because they are fetched by getPageCacheTags()
2659  $cacheData['cacheTags'] = ‪$this->pageCacheTags;
2660  $this->pageCache->set($this->newHash, $cacheData, $this->pageCacheTags, $expirationTstamp - ‪$GLOBALS['EXEC_TIME']);
2661  }
2662 
2666  public function ‪clearPageCacheContent()
2667  {
2668  $this->pageCache->remove($this->newHash);
2669  }
2670 
2677  protected function ‪setSysLastChanged()
2678  {
2679  // We only update the info if browsing the live workspace
2680  if ($this->page['SYS_LASTCHANGED'] < (int)$this->register['SYS_LASTCHANGED'] && !$this->‪doWorkspacePreview()) {
2681  $connection = GeneralUtility::makeInstance(ConnectionPool::class)
2682  ->getConnectionForTable('pages');
2683  $pageId = $this->page['_PAGES_OVERLAY_UID'] ?? ‪$this->id;
2684  $connection->update(
2685  'pages',
2686  [
2687  'SYS_LASTCHANGED' => (int)$this->register['SYS_LASTCHANGED']
2688  ],
2689  [
2690  'uid' => (int)$pageId
2691  ]
2692  );
2693  }
2694  }
2695 
2703  protected function ‪setRegisterValueForSysLastChanged(array ‪$page): void
2704  {
2705  $this->register['SYS_LASTCHANGED'] = (int)‪$page['tstamp'];
2706  if ($this->register['SYS_LASTCHANGED'] < (int)$page['SYS_LASTCHANGED']) {
2707  $this->register['SYS_LASTCHANGED'] = (int)‪$page['SYS_LASTCHANGED'];
2708  }
2709  }
2710 
2716  public function ‪releaseLocks()
2717  {
2718  $this->‪releaseLock('pagesection');
2719  $this->‪releaseLock('pages');
2720  }
2721 
2728  public function ‪addCacheTags(array $tags)
2729  {
2730  $this->pageCacheTags = array_merge($this->pageCacheTags, $tags);
2731  }
2732 
2736  public function ‪getPageCacheTags(): array
2737  {
2738  return ‪$this->pageCacheTags;
2739  }
2740 
2741  /********************************************
2742  *
2743  * Page generation; rendering and inclusion
2744  *
2745  *******************************************/
2749  public function ‪generatePage_preProcessing()
2750  {
2751  // Same codeline as in getFromCache(). But $this->all has been changed by
2752  // \TYPO3\CMS\Core\TypoScript\TemplateService::start() in the meantime, so this must be called again!
2753  $this->newHash = $this->‪getHash();
2754 
2755  // Used as a safety check in case a PHP script is falsely disabling $this->no_cache during page generation.
2756  $this->no_cacheBeforePageGen = ‪$this->no_cache;
2757  }
2758 
2769  protected function ‪resolveContentPid(ServerRequestInterface $request): int
2770  {
2771  if (!isset($this->page['content_from_pid']) || empty($this->page['content_from_pid'])) {
2772  return (int)‪$this->id;
2773  }
2774  // make REAL copy of TSFE object - not reference!
2775  $temp_copy_TSFE = clone $this;
2776  // Set ->id to the content_from_pid value - we are going to evaluate this pid as was it a given id for a page-display!
2777  $temp_copy_TSFE->id = $this->page['content_from_pid'];
2778  $temp_copy_TSFE->MP = '';
2779  $temp_copy_TSFE->getPageAndRootline($request);
2780  return (int)$temp_copy_TSFE->id;
2781  }
2787  public function ‪preparePageContentGeneration(ServerRequestInterface $request)
2788  {
2789  $this->‪getTimeTracker()->‪push('Prepare page content generation');
2790  $this->contentPid = $this->‪resolveContentPid($request);
2791  // Global vars...
2792  $this->indexedDocTitle = $this->page['title'] ?? null;
2793  // Base url:
2794  if (isset($this->config['config']['baseURL'])) {
2795  $this->baseUrl = $this->config['config']['baseURL'];
2796  }
2797  // Internal and External target defaults
2798  $this->intTarget = (string)($this->config['config']['intTarget'] ?? '');
2799  $this->extTarget = (string)($this->config['config']['extTarget'] ?? '');
2800  $this->fileTarget = (string)($this->config['config']['fileTarget'] ?? '');
2801  $this->spamProtectEmailAddresses = $this->config['config']['spamProtectEmailAddresses'] ?? 0;
2802  if ($this->spamProtectEmailAddresses !== 'ascii') {
2803  $this->spamProtectEmailAddresses = ‪MathUtility::forceIntegerInRange($this->spamProtectEmailAddresses, -10, 10, 0);
2804  }
2805  // calculate the absolute path prefix
2806  if (!empty($this->config['config']['absRefPrefix'])) {
2807  ‪$absRefPrefix = trim($this->config['config']['absRefPrefix']);
2808  if (‪$absRefPrefix === 'auto') {
2809  $this->absRefPrefix = GeneralUtility::getIndpEnv('TYPO3_SITE_PATH');
2810  } else {
2811  $this->absRefPrefix = ‪$absRefPrefix;
2812  }
2813  } else {
2814  $this->absRefPrefix = '';
2815  }
2816  $this->ATagParams = trim($this->config['config']['ATagParams'] ?? '') ? ' ' . trim($this->config['config']['ATagParams']) : '';
2817  $this->‪initializeSearchWordData($request->getParsedBody()['sword_list'] ?? $request->getQueryParams()['sword_list'] ?? null);
2818  // linkVars
2819  $this->‪calculateLinkVars($request->getQueryParams());
2820  // Setting XHTML-doctype from doctype
2821  if (!isset($this->config['config']['xhtmlDoctype']) || !$this->config['config']['xhtmlDoctype']) {
2822  $this->config['config']['xhtmlDoctype'] = $this->config['config']['doctype'] ?? '';
2823  }
2824  if ($this->config['config']['xhtmlDoctype']) {
2825  $this->xhtmlDoctype = $this->config['config']['xhtmlDoctype'];
2826  // Checking XHTML-docytpe
2827  switch ((string)$this->config['config']['xhtmlDoctype']) {
2828  case 'xhtml_trans':
2829  case 'xhtml_strict':
2830  $this->xhtmlVersion = 100;
2831  break;
2832  case 'xhtml_basic':
2833  $this->xhtmlVersion = 105;
2834  break;
2835  case 'xhtml_11':
2836  case 'xhtml+rdfa_10':
2837  $this->xhtmlVersion = 110;
2838  break;
2839  default:
2840  $this->pageRenderer->setRenderXhtml(false);
2841  $this->xhtmlDoctype = '';
2842  $this->xhtmlVersion = 0;
2843  }
2844  } else {
2845  $this->pageRenderer->setRenderXhtml(false);
2846  }
2847 
2848  // Global content object
2849  $this->‪newCObj();
2850  $this->‪getTimeTracker()->‪pull();
2851  }
2852 
2861  protected function ‪initializeSearchWordData($searchWords)
2862  {
2863  $this->sWordRegEx = '';
2864  $this->sWordList = $searchWords ?? '';
2865  if (is_array($this->sWordList)) {
2866  $space = !empty($this->config['config']['sword_standAlone'] ?? null) ? '[[:space:]]' : '';
2867  $regexpParts = [];
2868  foreach ($this->sWordList as $val) {
2869  if (trim($val) !== '') {
2870  $regexpParts[] = $space . preg_quote($val, '/') . $space;
2871  }
2872  }
2873  $this->sWordRegEx = implode('|', $regexpParts);
2874  }
2875  }
2876 
2882  public function ‪generatePage_postProcessing()
2883  {
2884  $this->‪setAbsRefPrefix();
2885  // This is to ensure, that the page is NOT cached if the no_cache parameter was set before the page was generated. This is a safety precaution, as it could have been unset by some script.
2886  if ($this->no_cacheBeforePageGen) {
2887  $this->‪set_no_cache('no_cache has been set before the page was generated - safety check', true);
2888  }
2889  // Hook for post-processing of page content cached/non-cached:
2890  $_params = ['pObj' => &$this];
2891  foreach (‪$GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['tslib/class.tslib_fe.php']['contentPostProc-all'] ?? [] as $_funcRef) {
2892  GeneralUtility::callUserFunction($_funcRef, $_params, $this);
2893  }
2894  // Processing if caching is enabled:
2895  if (!$this->no_cache) {
2896  // Hook for post-processing of page content before being cached:
2897  foreach (‪$GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['tslib/class.tslib_fe.php']['contentPostProc-cached'] ?? [] as $_funcRef) {
2898  GeneralUtility::callUserFunction($_funcRef, $_params, $this);
2899  }
2900  }
2901  // Convert char-set for output: (should be BEFORE indexing of the content (changed 22/4 2005)),
2902  // because otherwise indexed search might convert from the wrong charset!
2903  // One thing is that the charset mentioned in the HTML header would be wrong since the output charset (metaCharset)
2904  // has not been converted to from utf-8. And indexed search will internally convert from metaCharset
2905  // to utf-8 so the content MUST be in metaCharset already!
2906  $this->content = $this->‪convOutputCharset($this->content);
2907  // Hook for indexing pages
2908  if (!empty(‪$GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['tslib/class.tslib_fe.php']['pageIndexing'])) {
2909  trigger_error('The hook $TYPO3_CONF_VARS[SC_OPTIONS][tslib/class.tslib_fe.php][pageIndexing] will be removed in TYPO3 v11.0. Use the contentPostProc-all hook and convert the content if the output charset does not match the internal format.', E_USER_DEPRECATED);
2910  }
2911  foreach (‪$GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['tslib/class.tslib_fe.php']['pageIndexing'] ?? [] as $className) {
2912  GeneralUtility::makeInstance($className)->hook_indexContent($this);
2913  }
2914  // Storing for cache:
2915  if (!$this->no_cache) {
2916  $this->‪realPageCacheContent();
2917  }
2918  // Sets sys-last-change:
2919  $this->‪setSysLastChanged();
2920  }
2921 
2928  public function ‪generatePageTitle(): string
2929  {
2930  $pageTitleSeparator = '';
2931 
2932  // Check for a custom pageTitleSeparator, and perform stdWrap on it
2933  if (isset($this->config['config']['pageTitleSeparator']) && $this->config['config']['pageTitleSeparator'] !== '') {
2934  $pageTitleSeparator = $this->config['config']['pageTitleSeparator'];
2935 
2936  if (isset($this->config['config']['pageTitleSeparator.']) && is_array($this->config['config']['pageTitleSeparator.'])) {
2937  $pageTitleSeparator = $this->cObj->stdWrap($pageTitleSeparator, $this->config['config']['pageTitleSeparator.']);
2938  } else {
2939  $pageTitleSeparator .= ' ';
2940  }
2941  }
2942 
2943  $titleProvider = GeneralUtility::makeInstance(PageTitleProviderManager::class);
2944  if (!empty($this->config['config']['pageTitleCache'])) {
2945  $titleProvider->setPageTitleCache($this->config['config']['pageTitleCache']);
2946  }
2947  $pageTitle = $titleProvider->getTitle();
2948  $this->config['config']['pageTitleCache'] = $titleProvider->getPageTitleCache();
2949 
2950  if ($pageTitle !== '') {
2951  $this->indexedDocTitle = $pageTitle;
2952  }
2953 
2954  $titleTagContent = $this->‪printTitle(
2955  $pageTitle,
2956  (bool)($this->config['config']['noPageTitle'] ?? false),
2957  (bool)($this->config['config']['pageTitleFirst'] ?? false),
2958  $pageTitleSeparator
2959  );
2960  // stdWrap around the title tag
2961  if (isset($this->config['config']['pageTitle.']) && is_array($this->config['config']['pageTitle.'])) {
2962  $titleTagContent = $this->cObj->stdWrap($titleTagContent, $this->config['config']['pageTitle.']);
2963  }
2964 
2965  // config.noPageTitle = 2 - means do not render the page title
2966  if (isset($this->config['config']['noPageTitle']) && (int)$this->config['config']['noPageTitle'] === 2) {
2967  $titleTagContent = '';
2968  }
2969  if ($titleTagContent !== '') {
2970  $this->pageRenderer->setTitle($titleTagContent);
2971  }
2972  return (string)$titleTagContent;
2973  }
2974 
2985  protected function ‪printTitle(string $pageTitle, bool $noTitle = false, bool $showTitleFirst = false, string $pageTitleSeparator = ''): string
2986  {
2987  $websiteTitle = $this->‪getWebsiteTitle();
2988  $pageTitle = $noTitle ? '' : $pageTitle;
2989  if ($showTitleFirst) {
2990  $temp = $websiteTitle;
2991  $websiteTitle = $pageTitle;
2992  $pageTitle = $temp;
2993  }
2994  // only show a separator if there are both site title and page title
2995  if ($pageTitle === '' || $websiteTitle === '') {
2996  $pageTitleSeparator = '';
2997  } elseif (empty($pageTitleSeparator)) {
2998  // use the default separator if non given
2999  $pageTitleSeparator = ': ';
3000  }
3001  return $websiteTitle . $pageTitleSeparator . $pageTitle;
3002  }
3003 
3007  protected function ‪getWebsiteTitle(): string
3008  {
3009  if ($this->language instanceof SiteLanguage
3010  && trim($this->language->getWebsiteTitle()) !== ''
3011  ) {
3012  return trim($this->language->getWebsiteTitle());
3013  }
3014  if ($this->site instanceof SiteInterface
3015  && trim($this->site->getConfiguration()['websiteTitle'] ?? '') !== ''
3016  ) {
3017  return trim($this->site->getConfiguration()['websiteTitle']);
3018  }
3019  if (!empty($this->tmpl->setup['sitetitle'])) {
3020  // @deprecated since TYPO3 v10.2 and will be removed in TYPO3 v11.0
3021  return trim($this->tmpl->setup['sitetitle']);
3022  }
3023 
3024  return '';
3025  }
3026 
3030  public function ‪INTincScript()
3031  {
3032  $this->additionalHeaderData = is_array($this->config['INTincScript_ext']['additionalHeaderData'] ?? false)
3033  ? $this->config['INTincScript_ext']['additionalHeaderData']
3034  : [];
3035  $this->additionalFooterData = is_array($this->config['INTincScript_ext']['additionalFooterData'] ?? false)
3036  ? $this->config['INTincScript_ext']['additionalFooterData']
3037  : [];
3038  $this->additionalJavaScript = $this->config['INTincScript_ext']['additionalJavaScript'] ?? null;
3039  $this->additionalCSS = $this->config['INTincScript_ext']['additionalCSS'] ?? null;
3040  if (empty($this->config['INTincScript_ext']['pageRenderer'])) {
3041  $this->‪initPageRenderer();
3042  } else {
3044  ‪$pageRenderer = unserialize($this->config['INTincScript_ext']['pageRenderer']);
3045  $this->pageRenderer->updateState(‪$pageRenderer->‪getState());
3046  }
3047  if (!empty($this->config['INTincScript_ext']['assetCollector'])) {
3049  $assetCollector = unserialize($this->config['INTincScript_ext']['assetCollector'], ['allowed_classes' => [AssetCollector::class]]);
3050  GeneralUtility::makeInstance(AssetCollector::class)->updateState($assetCollector->getState());
3051  }
3052 
3054  $this->‪getTimeTracker()->‪push('Substitute header section');
3055  $this->‪INTincScript_loadJSCode();
3056  $this->‪generatePageTitle();
3057 
3058  $this->content = str_replace(
3059  [
3060  '<!--HD_' . $this->config['INTincScript_ext']['divKey'] . '-->',
3061  '<!--FD_' . $this->config['INTincScript_ext']['divKey'] . '-->',
3062  ],
3063  [
3064  $this->‪convOutputCharset(implode(LF, $this->additionalHeaderData)),
3065  $this->‪convOutputCharset(implode(LF, $this->additionalFooterData)),
3066  ],
3067  $this->pageRenderer->renderJavaScriptAndCssForProcessingOfUncachedContentObjects($this->content, $this->config['INTincScript_ext']['divKey'])
3068  );
3069  // Replace again, because header and footer data and page renderer replacements may introduce additional placeholders (see #44825)
3071  $this->‪setAbsRefPrefix();
3072  $this->‪getTimeTracker()->‪pull();
3073  }
3074 
3081  {
3082  do {
3083  $nonCacheableData = $this->config['INTincScript'];
3085  // Check if there were new items added to INTincScript during the previous execution:
3086  // array_diff_assoc throws notices if values are arrays but not strings. We suppress this here.
3087  $nonCacheableData = @array_diff_assoc($this->config['INTincScript'], $nonCacheableData);
3088  $reprocess = count($nonCacheableData) > 0;
3089  } while ($reprocess);
3090  }
3091 
3101  protected function ‪processNonCacheableContentPartsAndSubstituteContentMarkers(array $nonCacheableData)
3102  {
3103  $timeTracker = $this->‪getTimeTracker();
3104  $timeTracker->push('Split content');
3105  // Splits content with the key.
3106  $contentSplitByUncacheableMarkers = explode('<!--INT_SCRIPT.', $this->content);
3107  $this->content = '';
3108  $timeTracker->setTSlogMessage('Parts: ' . count($contentSplitByUncacheableMarkers));
3109  $timeTracker->pull();
3110  foreach ($contentSplitByUncacheableMarkers as $counter => $contentPart) {
3111  // If the split had a comment-end after 32 characters it's probably a split-string
3112  if (substr($contentPart, 32, 3) === '-->') {
3113  $nonCacheableKey = 'INT_SCRIPT.' . substr($contentPart, 0, 32);
3114  if (is_array($nonCacheableData[$nonCacheableKey])) {
3115  $label = 'Include ' . $nonCacheableData[$nonCacheableKey]['type'];
3116  $timeTracker->push($label);
3117  $nonCacheableContent = '';
3118  $contentObjectRendererForNonCacheable = unserialize($nonCacheableData[$nonCacheableKey]['cObj']);
3119  /* @var ContentObjectRenderer $contentObjectRendererForNonCacheable */
3120  switch ($nonCacheableData[$nonCacheableKey]['type']) {
3121  case 'COA':
3122  $nonCacheableContent = $contentObjectRendererForNonCacheable->cObjGetSingle('COA', $nonCacheableData[$nonCacheableKey]['conf']);
3123  break;
3124  case 'FUNC':
3125  $nonCacheableContent = $contentObjectRendererForNonCacheable->cObjGetSingle('USER', $nonCacheableData[$nonCacheableKey]['conf']);
3126  break;
3127  case 'POSTUSERFUNC':
3128  $nonCacheableContent = $contentObjectRendererForNonCacheable->callUserFunction($nonCacheableData[$nonCacheableKey]['postUserFunc'], $nonCacheableData[$nonCacheableKey]['conf'], $nonCacheableData[$nonCacheableKey]['content']);
3129  break;
3130  }
3131  $this->content .= $this->‪convOutputCharset($nonCacheableContent);
3132  $this->content .= substr($contentPart, 35);
3133  $timeTracker->pull($nonCacheableContent);
3134  } else {
3135  $this->content .= substr($contentPart, 35);
3136  }
3137  } elseif ($counter) {
3138  // If it's not the first entry (which would be "0" of the array keys), then re-add the INT_SCRIPT part
3139  $this->content .= '<!--INT_SCRIPT.' . $contentPart;
3140  } else {
3141  $this->content .= $contentPart;
3142  }
3143  }
3144  }
3152  public function ‪INTincScript_loadJSCode()
3153  {
3154  // Prepare code and placeholders for additional header and footer files (and make sure that this isn't called twice)
3155  if ($this->‪isINTincScript() && !isset($this->config['INTincScript_ext'])) {
3156  // Storing the JSCode vars...
3157  $this->additionalHeaderData['JSCode'] = ‪$this->JSCode;
3158  $this->config['INTincScript_ext']['divKey'] = $this->‪uniqueHash();
3159  // Storing the header-data array
3160  $this->config['INTincScript_ext']['additionalHeaderData'] = ‪$this->additionalHeaderData;
3161  // Storing the footer-data array
3162  $this->config['INTincScript_ext']['additionalFooterData'] = ‪$this->additionalFooterData;
3163  // Storing the JS-data array
3164  $this->config['INTincScript_ext']['additionalJavaScript'] = ‪$this->additionalJavaScript;
3165  // Storing the Style-data array
3166  $this->config['INTincScript_ext']['additionalCSS'] = ‪$this->additionalCSS;
3167  // Clearing the array
3168  $this->additionalHeaderData = ['<!--HD_' . $this->config['INTincScript_ext']['divKey'] . '-->'];
3169  // Clearing the array
3170  $this->additionalFooterData = ['<!--FD_' . $this->config['INTincScript_ext']['divKey'] . '-->'];
3171  } else {
3172  // Add javascript in a "regular" fashion
3173  $jsCode = trim($this->JSCode);
3174  ‪$additionalJavaScript = is_array($this->additionalJavaScript)
3175  ? implode(LF, $this->additionalJavaScript)
3176  : $this->additionalJavaScript;
3178  if ($jsCode !== '' || ‪$additionalJavaScript !== '') {
3179  $doctype = $this->config['config']['doctype'] ?? 'html5';
3180  $scriptAttribute = $doctype === 'html5' ? '' : ' type="text/javascript"';
3181 
3182  $this->additionalHeaderData['JSCode'] = '
3183 <script' . $scriptAttribute . '>
3184  /*<![CDATA[*/
3185 <!--
3187 ' . $jsCode . '
3188 // -->
3189  /*]]>*/
3190 </script>';
3191  }
3192  // Add CSS
3193  $additionalCss = is_array($this->additionalCSS) ? implode(LF, $this->additionalCSS) : $this->additionalCSS;
3194  $additionalCss = trim($additionalCss);
3195  if ($additionalCss !== '') {
3196  $this->additionalHeaderData['_CSS'] = '
3197 <style type="text/css">
3198 ' . $additionalCss . '
3199 </style>';
3200  }
3201  }
3202  }
3203 
3209  public function ‪isINTincScript()
3210  {
3211  return !empty($this->config['INTincScript']) && is_array($this->config['INTincScript']);
3212  }
3213 
3214  /********************************************
3215  *
3216  * Finished off; outputting, storing session data, statistics...
3217  *
3218  *******************************************/
3227  public function ‪isOutputting(bool $isCoreCall = false)
3228  {
3229  if ($isCoreCall !== true) {
3230  trigger_error('TypoScriptFrontendController->isOutputting will be removed in TYPO3 v11.0, do not depend on this method anymore. Definition of outputting can be configured via PSR-15 middlewares.', E_USER_DEPRECATED);
3231  }
3232  if (!empty(‪$GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['tslib/class.tslib_fe.php']['isOutputting'])) {
3233  trigger_error('The hook $TYPO3_CONF_VARS[SC_OPTIONS][tslib/class.tslib_fe.php][isOutputting] will be removed in TYPO3 v11.0. This hook has various side-effects (as the method is called multiple times during one request) and the configuration if TYPO3 is outputting the content is handled via the Emitter / PSR-15 middlewares.', E_USER_DEPRECATED);
3234  }
3235  // Initialize by status if there is a Redirect URL
3236  $enableOutput = true;
3237  // Call hook for possible disabling of output:
3238  $_params = ['pObj' => &$this, 'enableOutput' => &$enableOutput];
3239  foreach (‪$GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['tslib/class.tslib_fe.php']['isOutputting'] ?? [] as $_funcRef) {
3240  GeneralUtility::callUserFunction($_funcRef, $_params, $this);
3241  }
3242  return $enableOutput;
3243  }
3244 
3254  public function ‪processContentForOutput(bool $isCoreCall = false)
3255  {
3256  if ($isCoreCall !== true) {
3257  trigger_error('TypoScriptFrontendController->processContentForOutput will be removed in TYPO3 v11.0, do not depend on this method anymore. Definition of outputting can be configured via PSR-15 middlewares.', E_USER_DEPRECATED);
3258  }
3259  // Make substitution of eg. username/uid in content only if cache-headers for client/proxy caching is NOT sent!
3260  if (!$this->isClientCachable) {
3261  // Substitute various tokens in content. This should happen only if the content is not cached by proxies or client browsers.
3262  $search = [];
3263  $replace = [];
3264  // Hook for supplying custom search/replace data
3265  if (!empty(‪$GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['tslib/class.tslib_fe.php']['tslib_fe-contentStrReplace'])) {
3266  trigger_error('The hook $TYPO3_CONF_VARS[SC_OPTIONS][tslib/class.tslib_fe.php][tslib_fe-contentStrReplace] will be removed in TYPO3 v11.0. Use a custom PSR-15 middleware instead.', E_USER_DEPRECATED);
3267  }
3268  foreach (‪$GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['tslib/class.tslib_fe.php']['tslib_fe-contentStrReplace'] ?? [] as $_funcRef) {
3269  $_params = [
3270  'search' => &$search,
3271  'replace' => &$replace
3272  ];
3273  GeneralUtility::callUserFunction($_funcRef, $_params, $this);
3274  }
3275  if (!empty($search)) {
3276  $this->content = str_replace($search, $replace, $this->content);
3277  }
3278  }
3279  // Hook for supplying custom search/replace data
3280  if (!empty(‪$GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['tslib/class.tslib_fe.php']['contentPostProc-output'])) {
3281  trigger_error('The hook $TYPO3_CONF_VARS[SC_OPTIONS][tslib/class.tslib_fe.php][contentPostProc-output] will be removed in TYPO3 v11.0. Use a custom PSR-15 middleware instead.', E_USER_DEPRECATED);
3282  }
3283 
3284  // Hook for post-processing of page content before output:
3285  $_params = ['pObj' => &$this];
3286  foreach (‪$GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['tslib/class.tslib_fe.php']['contentPostProc-output'] ?? [] as $_funcRef) {
3287  GeneralUtility::callUserFunction($_funcRef, $_params, $this);
3288  }
3289  }
3290 
3297  public function ‪applyHttpHeadersToResponse(ResponseInterface $response): ResponseInterface
3298  {
3299  // Set header for charset-encoding unless disabled
3300  if (empty($this->config['config']['disableCharsetHeader'])) {
3301  $response = $response->withHeader('Content-Type', $this->contentType . '; charset=' . trim($this->metaCharset));
3302  }
3303  // Set header for content language unless disabled
3304  $contentLanguage = $this->language->getTwoLetterIsoCode();
3305  if (empty($this->config['config']['disableLanguageHeader']) && !empty($contentLanguage)) {
3306  $response = $response->withHeader('Content-Language', trim($contentLanguage));
3307  }
3308  // Set cache related headers to client (used to enable proxy / client caching!)
3309  if (!empty($this->config['config']['sendCacheHeaders'])) {
3310  $headers = $this->‪getCacheHeaders();
3311  foreach ($headers as $header => $value) {
3312  $response = $response->withHeader($header, $value);
3313  }
3314  }
3315  // Set additional headers if any have been configured via TypoScript
3316  $additionalHeaders = $this->‪getAdditionalHeaders();
3317  foreach ($additionalHeaders as $headerConfig) {
3318  [$header, $value] = ‪GeneralUtility::trimExplode(':', $headerConfig['header'], false, 2);
3319  if ($headerConfig['statusCode']) {
3320  $response = $response->withStatus((int)$headerConfig['statusCode']);
3321  }
3322  if ($headerConfig['replace']) {
3323  $response = $response->withHeader($header, $value);
3324  } else {
3325  $response = $response->withAddedHeader($header, $value);
3326  }
3327  }
3328  return $response;
3329  }
3330 
3336  protected function ‪getCacheHeaders(): array
3337  {
3338  // Getting status whether we can send cache control headers for proxy caching:
3339  $doCache = $this->‪isStaticCacheble();
3340  // This variable will be TRUE unless cache headers are configured to be sent ONLY if a branch does not allow logins and logins turns out to be allowed anyway...
3341  $loginsDeniedCfg = empty($this->config['config']['sendCacheHeaders_onlyWhenLoginDeniedInBranch']) || empty($this->loginAllowedInBranch);
3342  // Finally, when backend users are logged in, do not send cache headers at all (Admin Panel might be displayed for instance).
3343  $this->isClientCachable = $doCache && !$this->‪isBackendUserLoggedIn() && !$this->‪doWorkspacePreview() && $loginsDeniedCfg;
3344  if ($this->isClientCachable) {
3345  $headers = [
3346  'Expires' => gmdate('D, d M Y H:i:s T', $this->cacheExpires),
3347  'ETag' => '"' . md5($this->content) . '"',
3348  'Cache-Control' => 'max-age=' . ($this->cacheExpires - ‪$GLOBALS['EXEC_TIME']),
3349  // no-cache
3350  'Pragma' => 'public'
3351  ];
3352  } else {
3353  // "no-store" is used to ensure that the client HAS to ask the server every time, and is not allowed to store anything at all
3354  $headers = [
3355  'Cache-Control' => 'private, no-store'
3356  ];
3357  // Now, if a backend user is logged in, tell him in the Admin Panel log what the caching status would have been:
3358  if ($this->‪isBackendUserLoggedIn()) {
3359  if ($doCache) {
3360  $this->‪getTimeTracker()->‪setTSlogMessage('Cache-headers with max-age "' . ($this->cacheExpires - ‪$GLOBALS['EXEC_TIME']) . '" would have been sent');
3361  } else {
3362  $reasonMsg = [];
3363  if ($this->no_cache) {
3364  $reasonMsg[] = 'Caching disabled (no_cache).';
3365  }
3366  if ($this->‪isINTincScript()) {
3367  $reasonMsg[] = '*_INT object(s) on page.';
3368  }
3369  if (is_array($this->fe_user->user)) {
3370  $reasonMsg[] = 'Frontend user logged in.';
3371  }
3372  $this->‪getTimeTracker()->‪setTSlogMessage('Cache-headers would disable proxy caching! Reason(s): "' . implode(' ', $reasonMsg) . '"', 1);
3373  }
3374  }
3375  }
3376  return $headers;
3377  }
3378 
3389  public function ‪isStaticCacheble()
3390  {
3391  return !$this->no_cache && !$this->‪isINTincScript() && !$this->‪isUserOrGroupSet();
3392  }
3393 
3394  /********************************************
3395  *
3396  * Various internal API functions
3397  *
3398  *******************************************/
3405  public function ‪newCObj()
3406  {
3407  $this->cObj = GeneralUtility::makeInstance(ContentObjectRenderer::class, $this);
3408  $this->cObj->start($this->page, 'pages');
3409  }
3410 
3418  public function ‪setAbsRefPrefix()
3419  {
3420  if (!$this->absRefPrefix) {
3421  return;
3422  }
3423  $encodedAbsRefPrefix = htmlspecialchars($this->absRefPrefix, ENT_QUOTES | ENT_HTML5);
3424  $search = [
3425  '"typo3temp/',
3429  ];
3430  $replace = [
3431  '"' . $encodedAbsRefPrefix . 'typo3temp/',
3432  '"' . $encodedAbsRefPrefix . ‪PathUtility::stripPathSitePrefix(‪Environment::getExtensionsPath()) . '/',
3433  '"' . $encodedAbsRefPrefix . ‪PathUtility::stripPathSitePrefix(‪Environment::getBackendPath()) . '/ext/',
3434  '"' . $encodedAbsRefPrefix . ‪PathUtility::stripPathSitePrefix(‪Environment::getFrameworkBasePath()) . '/',
3435  ];
3437  $storageRepository = GeneralUtility::makeInstance(StorageRepository::class);
3438  $storages = $storageRepository->findAll();
3439  foreach ($storages as $storage) {
3440  if ($storage->getDriverType() === 'Local' && $storage->isPublic() && $storage->isOnline()) {
3441  $folder = $storage->getPublicUrl($storage->getRootLevelFolder(), true);
3442  $search[] = '"' . $folder;
3443  $replace[] = '"' . $encodedAbsRefPrefix . $folder;
3444  }
3445  }
3446  // Process additional directories
3447  $directories = ‪GeneralUtility::trimExplode(',', ‪$GLOBALS['TYPO3_CONF_VARS']['FE']['additionalAbsRefPrefixDirectories'], true);
3448  foreach ($directories as $directory) {
3449  $search[] = '"' . $directory;
3450  $replace[] = '"' . $encodedAbsRefPrefix . $directory;
3451  }
3452  $this->content = str_replace(
3453  $search,
3454  $replace,
3455  $this->content
3456  );
3457  }
3458 
3466  public function ‪baseUrlWrap($url)
3467  {
3468  if ($this->baseUrl) {
3469  $urlParts = parse_url($url);
3470  if (empty($urlParts['scheme']) && $url[0] !== '/') {
3471  $url = $this->baseUrl . $url;
3472  }
3473  }
3474  return $url;
3475  }
3476 
3485  public function ‪logDeprecatedTyposcript($typoScriptProperty, $explanation = '')
3486  {
3487  $explanationText = $explanation !== '' ? ' - ' . $explanation : '';
3488  $this->‪getTimeTracker()->‪setTSlogMessage($typoScriptProperty . ' is deprecated.' . $explanationText, 2);
3489  trigger_error('TypoScript property ' . $typoScriptProperty . ' is deprecated' . $explanationText, E_USER_DEPRECATED);
3490  }
3491 
3492  /********************************************
3493  * PUBLIC ACCESSIBLE WORKSPACES FUNCTIONS
3494  *******************************************/
3495 
3501  public function ‪doWorkspacePreview()
3502  {
3503  return $this->context->getPropertyFromAspect('workspace', 'isOffline', false);
3504  }
3505 
3511  public function ‪whichWorkspace(): int
3512  {
3513  return $this->context->getPropertyFromAspect('workspace', 'id', 0);
3514  }
3515 
3516  /********************************************
3517  *
3518  * Various external API functions - for use in plugins etc.
3519  *
3520  *******************************************/
3521 
3527  public function ‪getPagesTSconfig()
3528  {
3529  if (!is_array($this->pagesTSconfig)) {
3530  $contentHashCache = GeneralUtility::makeInstance(CacheManager::class)->getCache('hash');
3531  $loader = GeneralUtility::makeInstance(PageTsConfigLoader::class);
3532  $tsConfigString = $loader->load(array_reverse($this->rootLine));
3533  ‪$parser = GeneralUtility::makeInstance(
3534  PageTsConfigParser::class,
3535  GeneralUtility::makeInstance(TypoScriptParser::class),
3536  $contentHashCache
3537  );
3538  $this->pagesTSconfig = ‪$parser->parse(
3539  $tsConfigString,
3540  GeneralUtility::makeInstance(ConditionMatcher::class, $this->context, $this->id, $this->rootLine),
3541  $this->site
3542  );
3543  }
3544  return ‪$this->pagesTSconfig;
3545  }
3546 
3555  public function ‪setJS($key, ‪$content = '')
3556  {
3557  if ($key === 'openPic') {
3558  $this->additionalJavaScript[$key] = ' function openPic(url, winName, winParams) {
3559  var theWindow = window.open(url, winName, winParams);
3560  if (theWindow) {theWindow.focus();}
3561  }';
3562  } elseif ($key) {
3563  $this->additionalJavaScript[$key] = ‪$content;
3564  }
3565  }
3566 
3574  public function ‪uniqueHash($str = '')
3575  {
3576  return md5($this->uniqueString . '_' . $str . $this->uniqueCounter++);
3577  }
3578 
3585  public function ‪set_no_cache($reason = '', $internal = false)
3586  {
3587  if ($reason !== '') {
3588  $warning = '$TSFE->set_no_cache() was triggered. Reason: ' . $reason . '.';
3589  } else {
3590  $trace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 1);
3591  // This is a hack to work around ___FILE___ resolving symbolic links
3592  $realWebPath = ‪PathUtility::dirname((string)realpath(‪Environment::getBackendPath())) . '/';
3593  $file = $trace[0]['file'];
3594  if (strpos($file, $realWebPath) === 0) {
3595  $file = str_replace($realWebPath, '', $file);
3596  } else {
3597  $file = str_replace(‪Environment::getPublicPath() . '/', '', $file);
3598  }
3599  $line = $trace[0]['line'];
3600  $trigger = $file . ' on line ' . $line;
3601  $warning = '$GLOBALS[\'TSFE\']->set_no_cache() was triggered by ' . $trigger . '.';
3602  }
3603  if (!$internal && ‪$GLOBALS['TYPO3_CONF_VARS']['FE']['disableNoCacheParameter']) {
3604  $warning .= ' However, $TYPO3_CONF_VARS[\'FE\'][\'disableNoCacheParameter\'] is set, so it will be ignored!';
3605  $this->‪getTimeTracker()->‪setTSlogMessage($warning, 2);
3606  } else {
3607  $warning .= ' Caching is disabled!';
3608  $this->‪disableCache();
3609  }
3610  if ($internal && ($this->‪isBackendUserLoggedIn() || $this->‪isInPreviewMode())) {
3611  $this->logger->notice($warning);
3612  } else {
3613  $this->logger->warning($warning);
3614  }
3615  }
3616 
3622  protected function ‪disableCache()
3623  {
3624  $this->no_cache = true;
3625  }
3626 
3632  public function ‪set_cache_timeout_default($seconds)
3633  {
3634  $seconds = (int)$seconds;
3635  if ($seconds > 0) {
3636  $this->cacheTimeOutDefault = $seconds;
3637  }
3638  }
3639 
3645  public function ‪get_cache_timeout()
3646  {
3648  $runtimeCache = GeneralUtility::makeInstance(CacheManager::class)->getCache('runtime');
3649  $cachedCacheLifetimeIdentifier = 'core-tslib_fe-get_cache_timeout';
3650  $cachedCacheLifetime = $runtimeCache->get($cachedCacheLifetimeIdentifier);
3651  if ($cachedCacheLifetime === false) {
3652  if ($this->page['cache_timeout']) {
3653  // Cache period was set for the page:
3654  $cacheTimeout = $this->page['cache_timeout'];
3655  } else {
3656  // Cache period was set via TypoScript "config.cache_period",
3657  // otherwise it's the default of 24 hours
3658  $cacheTimeout = ‪$this->cacheTimeOutDefault;
3659  }
3660  if (!empty($this->config['config']['cache_clearAtMidnight'])) {
3661  $timeOutTime = ‪$GLOBALS['EXEC_TIME'] + $cacheTimeout;
3662  $midnightTime = mktime(0, 0, 0, (int)date('m', $timeOutTime), (int)date('d', $timeOutTime), (int)date('Y', $timeOutTime));
3663  // If the midnight time of the expire-day is greater than the current time,
3664  // we may set the timeOutTime to the new midnighttime.
3665  if ($midnightTime > ‪$GLOBALS['EXEC_TIME']) {
3666  $cacheTimeout = $midnightTime - ‪$GLOBALS['EXEC_TIME'];
3667  }
3668  }
3669 
3670  // Calculate the timeout time for records on the page and adjust cache timeout if necessary
3671  $cacheTimeout = min($this->‪calculatePageCacheTimeout(), $cacheTimeout);
3672 
3673  foreach (‪$GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['tslib/class.tslib_fe.php']['get_cache_timeout'] ?? [] as $_funcRef) {
3674  $params = ['cacheTimeout' => $cacheTimeout];
3675  $cacheTimeout = GeneralUtility::callUserFunction($_funcRef, $params, $this);
3676  }
3677  $runtimeCache->set($cachedCacheLifetimeIdentifier, $cacheTimeout);
3678  $cachedCacheLifetime = $cacheTimeout;
3679  }
3680  return $cachedCacheLifetime;
3681  }
3682 
3683  /*********************************************
3684  *
3685  * Localization and character set conversion
3686  *
3687  *********************************************/
3694  public function ‪sL($input)
3695  {
3696  return $this->languageService->sL($input);
3697  }
3698 
3703  protected function ‪setOutputLanguage()
3704  {
3705  $this->languageService = ‪LanguageService::createFromSiteLanguage($this->language);
3706  // Always disable debugging for TSFE
3707  $this->languageService->debugKey = false;
3708  }
3709 
3717  public function ‪convOutputCharset(‪$content)
3718  {
3719  if ($this->metaCharset !== 'utf-8') {
3721  $charsetConverter = GeneralUtility::makeInstance(CharsetConverter::class);
3722  try {
3723  ‪$content = $charsetConverter->conv(‪$content, 'utf-8', $this->metaCharset);
3724  } catch (UnknownCharsetException $e) {
3725  throw new \RuntimeException('Invalid config.metaCharset: ' . $e->getMessage(), 1508916185);
3726  }
3727  }
3728  return ‪$content;
3729  }
3730 
3736  protected function ‪calculatePageCacheTimeout()
3737  {
3738  $result = PHP_INT_MAX;
3739  // Get the configuration
3740  $tablesToConsider = $this->‪getCurrentPageCacheConfiguration();
3741  // Get the time, rounded to the minute (do not pollute MySQL cache!)
3742  // It is ok that we do not take seconds into account here because this
3743  // value will be subtracted later. So we never get the time "before"
3744  // the cache change.
3745  $now = ‪$GLOBALS['ACCESS_TIME'];
3746  // Find timeout by checking every table
3747  foreach ($tablesToConsider as $tableDef) {
3748  $result = min($result, $this->‪getFirstTimeValueForRecord($tableDef, $now));
3749  }
3750  // We return + 1 second just to ensure that cache is definitely regenerated
3751  return $result === PHP_INT_MAX ? PHP_INT_MAX : $result - $now + 1;
3752  }
3753 
3771  protected function ‪getCurrentPageCacheConfiguration()
3772  {
3773  $result = ['tt_content:' . ‪$this->id];
3774  if (isset($this->config['config']['cache.'][$this->id])) {
3775  $result = array_merge($result, ‪GeneralUtility::trimExplode(',', str_replace(':current', ':' . $this->id, $this->config['config']['cache.'][$this->id])));
3776  }
3777  if (isset($this->config['config']['cache.']['all'])) {
3778  $result = array_merge($result, ‪GeneralUtility::trimExplode(',', str_replace(':current', ':' . $this->id, $this->config['config']['cache.']['all'])));
3779  }
3780  return array_unique($result);
3781  }
3782 
3792  protected function ‪getFirstTimeValueForRecord($tableDef, $now)
3793  {
3794  $now = (int)$now;
3795  $result = PHP_INT_MAX;
3796  [$tableName, $pid] = ‪GeneralUtility::trimExplode(':', $tableDef);
3797  if (empty($tableName) || empty($pid)) {
3798  throw new \InvalidArgumentException('Unexpected value for parameter $tableDef. Expected <tablename>:<pid>, got \'' . htmlspecialchars($tableDef) . '\'.', 1307190365);
3799  }
3800 
3801  $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)
3802  ->getQueryBuilderForTable($tableName);
3803  $queryBuilder->getRestrictions()
3804  ->removeByType(StartTimeRestriction::class)
3805  ->removeByType(EndTimeRestriction::class);
3806  $timeFields = [];
3807  $timeConditions = $queryBuilder->expr()->orX();
3808  foreach (['starttime', 'endtime'] as $field) {
3809  if (isset($GLOBALS['TCA'][$tableName]['ctrl']['enablecolumns'][$field])) {
3810  $timeFields[$field] = $GLOBALS['TCA'][$tableName]['ctrl']['enablecolumns'][$field];
3811  $queryBuilder->addSelectLiteral(
3812  'MIN('
3813  . 'CASE WHEN '
3814  . $queryBuilder->expr()->lte(
3815  $timeFields[$field],
3816  $queryBuilder->createNamedParameter($now, \PDO::PARAM_INT)
3817  )
3818  . ' THEN NULL ELSE ' . $queryBuilder->quoteIdentifier($timeFields[$field]) . ' END'
3819  . ') AS ' . $queryBuilder->quoteIdentifier($timeFields[$field])
3820  );
3821  $timeConditions->add(
3822  $queryBuilder->expr()->gt(
3823  $timeFields[$field],
3824  $queryBuilder->createNamedParameter($now, \PDO::PARAM_INT)
3825  )
3826  );
3827  }
3828  }
3829 
3830  // if starttime or endtime are defined, evaluate them
3831  if (!empty($timeFields)) {
3832  // find the timestamp, when the current page's content changes the next time
3833  $row = $queryBuilder
3834  ->from($tableName)
3835  ->where(
3836  $queryBuilder->expr()->eq(
3837  'pid',
3838  $queryBuilder->createNamedParameter($pid, \PDO::PARAM_INT)
3839  ),
3840  $timeConditions
3841  )
3842  ->execute()
3843  ->fetch();
3844 
3845  ‪if ($row) {
3846  foreach ($timeFields as $timeField => $_) {
3847  // if a MIN value is found, take it into account for the
3848  // cache lifetime we have to filter out start/endtimes < $now,
3849  // as the SQL query also returns rows with starttime < $now
3850  // and endtime > $now (and using a starttime from the past
3851  // would be wrong)
3852  if ($row[$timeField] !== null && (int)$row[$timeField] > $now) {
3853  $result = min($result, (int)$row[$timeField]);
3854  }
3855  }
3856  }
3857  }
3858 
3859  return $result;
3860  }
3861 
3868  public function ‪getRequestedId()
3869  {
3870  return $this->requestedId ?: ‪$this->id;
3871  }
3872 
3907  protected function ‪acquireLock(‪$type, $key)
3908  {
3909  $lockFactory = GeneralUtility::makeInstance(LockFactory::class);
3910  $this->locks[‪$type]['accessLock'] = $lockFactory->createLocker(‪$type);
3911 
3912  $this->locks[‪$type]['pageLock'] = $lockFactory->createLocker(
3913  $key,
3915  );
3916 
3917  do {
3918  if (!$this->locks[‪$type]['accessLock']->acquire()) {
3919  throw new \RuntimeException('Could not acquire access lock for "' . ‪$type . '"".', 1294586098);
3920  }
3921 
3922  try {
3923  $locked = $this->locks[‪$type]['pageLock']->acquire(
3925  );
3926  } catch (‪LockAcquireWouldBlockException $e) {
3927  // somebody else has the lock, we keep waiting
3928 
3929  // first release the access lock
3930  $this->locks[‪$type]['accessLock']->release();
3931  // now lets make a short break (100ms) until we try again, since
3932  // the page generation by the lock owner will take a while anyways
3933  usleep(100000);
3934  continue;
3935  }
3936  $this->locks[‪$type]['accessLock']->release();
3937  if ($locked) {
3938  break;
3939  }
3940  throw new \RuntimeException('Could not acquire page lock for ' . $key . '.', 1460975877);
3941  } while (true);
3942  }
3943 
3952  protected function ‪releaseLock(‪$type)
3953  {
3954  if ($this->locks[‪$type]['accessLock'] ?? false) {
3955  if (!$this->locks[‪$type]['accessLock']->acquire()) {
3956  throw new \RuntimeException('Could not acquire access lock for "' . ‪$type . '"".', 1460975902);
3957  }
3958 
3959  $this->locks[‪$type]['pageLock']->release();
3960  $this->locks[‪$type]['pageLock']->destroy();
3961  $this->locks[‪$type]['pageLock'] = null;
3962 
3963  $this->locks[‪$type]['accessLock']->release();
3964  $this->locks[‪$type]['accessLock'] = null;
3965  }
3966  }
3967 
3971  protected function ‪getAdditionalHeaders(): array
3972  {
3973  if (!isset($this->config['config']['additionalHeaders.'])) {
3974  return [];
3975  }
3976  $additionalHeaders = [];
3977  ksort($this->config['config']['additionalHeaders.']);
3978  foreach ($this->config['config']['additionalHeaders.'] as $options) {
3979  if (!is_array($options)) {
3980  continue;
3981  }
3982  $header = trim($options['header'] ?? '');
3983  if ($header === '') {
3984  continue;
3985  }
3986  $additionalHeaders[] = [
3987  'header' => $header,
3988  // "replace existing headers" is turned on by default, unless turned off
3989  'replace' => ($options['replace'] ?? '') !== '0',
3990  'statusCode' => (int)($options['httpResponseCode'] ?? 0) ?: null
3991  ];
3992  }
3993  return $additionalHeaders;
3994  }
3995 
3996  protected function ‪isInPreviewMode(): bool
3997  {
3998  return $this->context->getPropertyFromAspect('frontend.preview', 'isPreview', false)
3999  || ‪$GLOBALS['EXEC_TIME'] !== ‪$GLOBALS['SIM_EXEC_TIME']
4000  || $this->context->getPropertyFromAspect('visibility', 'includeHiddenPages', false)
4001  || $this->context->getPropertyFromAspect('visibility', 'includeHiddenContent', false);
4002  }
4003 
4009  protected function ‪getBackendUser()
4010  {
4011  return ‪$GLOBALS['BE_USER'];
4012  }
4013 
4017  protected function ‪getTimeTracker()
4018  {
4019  return GeneralUtility::makeInstance(TimeTracker::class);
4020  }
4021 
4033  public static function ‪getGlobalInstance(): ?self
4034  {
4035  if (‪$GLOBALS['TSFE'] instanceof self) {
4036  return ‪$GLOBALS['TSFE'];
4037  }
4039  if (!(TYPO3_REQUESTTYPE & TYPO3_REQUESTTYPE_FE)) {
4040  // Return null for now (together with shared: false in Services.yaml) as TSFE might not be available in backend context
4041  // That's not an error then
4042  return null;
4043  }
4044 
4045  throw new \LogicException('TypoScriptFrontendController was tried to be injected before initial creation', 1538370377);
4046  }
4047 
4048  public function ‪getLanguage(): SiteLanguage
4049  {
4050  return ‪$this->language;
4051  }
4052 
4053  public function ‪getSite(): Site
4054  {
4055  return ‪$this->site;
4056  }
4057 
4058  public function ‪getContext(): Context
4059  {
4060  return ‪$this->context;
4061  }
4062 
4063  public function ‪getPageArguments(): PageArguments
4064  {
4065  return ‪$this->pageArguments;
4066  }
4067 
4082  public function ‪__isset(string $propertyName)
4083  {
4084  switch ($propertyName) {
4085  case 'domainStartPage':
4086  trigger_error('Property $TSFE->domainStartPage is not in use anymore as this information is now stored within the Site object. Will be removed in TYPO3 v11.0.', E_USER_DEPRECATED);
4087  return true;
4088  case 'cHash':
4089  trigger_error('Property $TSFE->cHash is not in use anymore as this information is now stored within the PageArguments object. Will be removed in TYPO3 v11.0.', E_USER_DEPRECATED);
4090  return isset($this->pageArguments->getArguments()['cHash']);
4091  case 'cHash_array':
4092  trigger_error('Property $TSFE->cHash_array is not in use anymore as this information is now stored within the PageArguments object. Will be removed in TYPO3 v11.0.', E_USER_DEPRECATED);
4093  $value = $this->‪getRelevantParametersForCachingFromPageArguments($this->pageArguments);
4094  return !empty($value);
4095  case 'sys_language_isocode':
4096  trigger_error('Property $TSFE->sys_language_isocode is not in use anymore as this information is now stored within the SiteLanguage object. Will be removed in TYPO3 v11.0.', E_USER_DEPRECATED);
4097  return isset($this->$propertyName);
4098  case 'divSection':
4099  trigger_error('Property $TSFE->divSection is not in use anymore. Will be removed in TYPO3 v11.0.', E_USER_DEPRECATED);
4100  return isset($this->$propertyName);
4101  case 'fePreview':
4102  trigger_error('Property $TSFE->fePreview is not in use anymore as this information is now stored within the FrontendPreview aspect.', E_USER_DEPRECATED);
4103  return $this->context->hasAspect('frontend.preview');
4104  case 'forceTemplateParsing':
4105  trigger_error('Property $TSFE->forceTemplateParsing is not in use anymore as this information is now stored within the TypoScript aspect.', E_USER_DEPRECATED);
4106  return $this->context->hasAspect('typoscript') && $this->context->getPropertyFromAspect('typoscript', 'forcedTemplateParsing');
4107  }
4108  return false;
4109  }
4110 
4120  public function ‪__get(string $propertyName)
4121  {
4122  switch ($propertyName) {
4123  case 'domainStartPage':
4124  trigger_error('Property $TSFE->domainStartPage is not in use anymore as this information is now stored within the Site object. Will be removed in TYPO3 v11.0.', E_USER_DEPRECATED);
4125  return $this->site->getRootPageId();
4126  case 'cHash':
4127  trigger_error('Property $TSFE->cHash is not in use anymore as this information is now stored within the PageArguments object. Will be removed in TYPO3 v11.0.', E_USER_DEPRECATED);
4128  return $this->pageArguments->getArguments()['cHash'] ?? false;
4129  case 'cHash_array':
4130  trigger_error('Property $TSFE->cHash_array is not in use anymore as this information is now stored within the PageArguments object. Will be removed in TYPO3 v11.0.', E_USER_DEPRECATED);
4131  return $this->‪getRelevantParametersForCachingFromPageArguments($this->pageArguments);
4132  case 'sys_language_isocode':
4133  trigger_error('Property $TSFE->sys_language_isocode is not in use anymore as this information is now stored within the SiteLanguage object. Will be removed in TYPO3 v11.0.', E_USER_DEPRECATED);
4134  return $this->sys_language_isocode ?? $this->language->getTwoLetterIsoCode();
4135  case 'divSection':
4136  trigger_error('Property $TSFE->divSection is not in use anymore. Will be removed in TYPO3 v11.0.', E_USER_DEPRECATED);
4137  break;
4138  case 'fePreview':
4139  trigger_error('Property $TSFE->fePreview is not in use anymore as this information is now stored within the FrontendPreview aspect.', E_USER_DEPRECATED);
4140  if ($this->context->hasAspect('frontend.preview')) {
4141  return $this->context->getPropertyFromAspect('frontend.preview', 'isPreview');
4142  }
4143  break;
4144  case 'forceTemplateParsing':
4145  trigger_error('Property $TSFE->forceTemplateParsing is not in use anymore as this information is now stored within the TypoScript aspect.', E_USER_DEPRECATED);
4146  if ($this->context->hasAspect('typoscript')) {
4147  return $this->context->getPropertyFromAspect('typoscript', 'forcedTemplateParsing');
4148  }
4149  break;
4150  }
4151  return $this->$propertyName;
4152  }
4153 
4165  public function ‪__set(string $propertyName, $propertyValue)
4166  {
4167  switch ($propertyName) {
4168  case 'domainStartPage':
4169  trigger_error('Property $TSFE->domainStartPage is not in use anymore as this information is now stored within the Site object. Will be removed in TYPO3 v11.0.', E_USER_DEPRECATED);
4170  break;
4171  case 'cHash':
4172  trigger_error('Property $TSFE->cHash is not in use anymore as this information is now stored within the PageArguments object. Will be removed in TYPO3 v11.0.', E_USER_DEPRECATED);
4173  break;
4174  case 'cHash_array':
4175  trigger_error('Property $TSFE->cHash_array is not in use anymore as this information is now stored within the PageArguments object. Will be removed in TYPO3 v11.0.', E_USER_DEPRECATED);
4176  break;
4177  case 'sys_language_isocode':
4178  trigger_error('Property $TSFE->sys_language_isocode is not in use anymore as this information is now stored within the SiteLanguage object. Will be removed in TYPO3 v11.0.', E_USER_DEPRECATED);
4179  break;
4180  case 'divSection':
4181  trigger_error('Property $TSFE->divSection is not in use anymore. Will be removed in TYPO3 v11.0.', E_USER_DEPRECATED);
4182  break;
4183  case 'fePreview':
4184  trigger_error('Property $TSFE->fePreview is not in use anymore as this information is now stored within the FrontendPreview aspect.', E_USER_DEPRECATED);
4185  $this->context->setAspect('frontend.preview', GeneralUtility::makeInstance(PreviewAspect::class, (bool)$propertyValue));
4186  break;
4187  case 'forceTemplateParsing':
4188  trigger_error('Property $TSFE->forceTemplateParsing is not in use anymore as this information is now stored within the TypoScript aspect.', E_USER_DEPRECATED);
4189  $this->context->setAspect('typoscript', GeneralUtility::makeInstance(TypoScriptAspect::class, (bool)$propertyValue));
4190  break;
4191  }
4192  $this->$propertyName = $propertyValue;
4193  }
4194 
4200  public function ‪__unset(string $propertyName)
4201  {
4202  switch ($propertyName) {
4203  case 'domainStartPage':
4204  trigger_error('Property $TSFE->domainStartPage is not in use anymore as this information is now stored within the Site object. Will be removed in TYPO3 v11.0.', E_USER_DEPRECATED);
4205  break;
4206  case 'cHash':
4207  trigger_error('Property $TSFE->cHash is not in use anymore as this information is now stored within the PageArguments object. Will be removed in TYPO3 v11.0.', E_USER_DEPRECATED);
4208  break;
4209  case 'cHash_array':
4210  trigger_error('Property $TSFE->cHash_array is not in use anymore as this information is now stored within the PageArguments object. Will be removed in TYPO3 v11.0.', E_USER_DEPRECATED);
4211  break;
4212  case 'sys_language_isocode':
4213  trigger_error('Property $TSFE->sys_language_isocode is not in use anymore as this information is now stored within the SiteLanguage object. Will be removed in TYPO3 v11.0.', E_USER_DEPRECATED);
4214  break;
4215  case 'divSection':
4216  trigger_error('Property $TSFE->divSection is not in use anymore. Will be removed in TYPO3 v11.0.', E_USER_DEPRECATED);
4217  break;
4218  case 'fePreview':
4219  trigger_error('Property $TSFE->fePreview is not in use anymore as this information is now stored within the FrontendPreview aspect.', E_USER_DEPRECATED);
4220  $this->context->setAspect('frontend.preview', GeneralUtility::makeInstance(PreviewAspect::class, false));
4221  break;
4222  case 'forceTemplateParsing':
4223  trigger_error('Property $TSFE->forceTemplateParsing is not in use anymore as this information is now stored within the TypoScript aspect.', E_USER_DEPRECATED);
4224  $this->context->setAspect('typoscript', GeneralUtility::makeInstance(TypoScriptAspect::class, false));
4225  break;
4226  }
4227  unset($this->$propertyName);
4228  }
4229 }
‪TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController\$tmpl
‪TemplateService $tmpl
Definition: TypoScriptFrontendController.php:249
‪TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController\$requestedId
‪int $requestedId
Definition: TypoScriptFrontendController.php:599
‪TYPO3\CMS\Frontend\Page\PageAccessFailureReasons\LANGUAGE_AND_FALLBACKS_NOT_AVAILABLE
‪const LANGUAGE_AND_FALLBACKS_NOT_AVAILABLE
Definition: PageAccessFailureReasons.php:43
‪TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController\getCurrentPageCacheConfiguration
‪array getCurrentPageCacheConfiguration()
Definition: TypoScriptFrontendController.php:3689
‪TYPO3\CMS\Core\Routing\PageArguments\getPageType
‪string getPageType()
Definition: PageArguments.php:119
‪TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController\$xhtmlDoctype
‪string $xhtmlDoctype
Definition: TypoScriptFrontendController.php:589
‪TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController\initPageRenderer
‪initPageRenderer()
Definition: TypoScriptFrontendController.php:804
‪TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController\setAbsRefPrefix
‪setAbsRefPrefix()
Definition: TypoScriptFrontendController.php:3336
‪TYPO3\CMS\Core\Site\Entity\SiteInterface
Definition: SiteInterface.php:26
‪TYPO3\CMS\Core\Routing\PageArguments
Definition: PageArguments.php:26
‪TYPO3\CMS\Core\Context\VisibilityAspect
Definition: VisibilityAspect.php:31
‪TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController\convOutputCharset
‪string convOutputCharset($content)
Definition: TypoScriptFrontendController.php:3635
‪TYPO3\CMS\Core\Page\AssetCollector
Definition: AssetCollector.php:44
‪TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController\doWorkspacePreview
‪bool doWorkspacePreview()
Definition: TypoScriptFrontendController.php:3419
‪TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController\$contentType
‪string $contentType
Definition: TypoScriptFrontendController.php:583
‪TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController\$no_cacheBeforePageGen
‪bool $no_cacheBeforePageGen
Definition: TypoScriptFrontendController.php:312
‪TYPO3\CMS\Core\Utility\PathUtility
Definition: PathUtility.php:24
‪TYPO3\CMS\Core\Context\WorkspaceAspect
Definition: WorkspaceAspect.php:31
‪TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController\$uniqueCounter
‪int $uniqueCounter
Definition: TypoScriptFrontendController.php:515
‪TYPO3\CMS\Core\Utility\MathUtility\canBeInterpretedAsInteger
‪static bool canBeInterpretedAsInteger($var)
Definition: MathUtility.php:74
‪TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController\$simUserGroup
‪int $simUserGroup
Definition: TypoScriptFrontendController.php:237
‪TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController\getRedirectUriForMountPoint
‪string null getRedirectUriForMountPoint(ServerRequestInterface $request)
Definition: TypoScriptFrontendController.php:2454
‪TYPO3\CMS\Core\Context\LanguageAspectFactory
Definition: LanguageAspectFactory.php:27
‪TYPO3\CMS\Core\Localization\Locales\setSystemLocaleFromSiteLanguage
‪static bool setSystemLocaleFromSiteLanguage(SiteLanguage $siteLanguage)
Definition: Locales.php:270
‪TYPO3\CMS\Core\Core\Environment\getPublicPath
‪static string getPublicPath()
Definition: Environment.php:180
‪TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController\$additionalCSS
‪array $additionalCSS
Definition: TypoScriptFrontendController.php:365
‪TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController\$currentRecord
‪string $currentRecord
Definition: TypoScriptFrontendController.php:488
‪TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController\checkIfLoginAllowedInBranch
‪bool checkIfLoginAllowedInBranch()
Definition: TypoScriptFrontendController.php:1601
‪TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController\$displayFieldEditIcons
‪string $displayFieldEditIcons
Definition: TypoScriptFrontendController.php:446
‪TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController\$cacheExpires
‪int $cacheExpires
Definition: TypoScriptFrontendController.php:269
‪TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController\getAdditionalHeaders
‪getAdditionalHeaders()
Definition: TypoScriptFrontendController.php:3889
‪TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController\$pagesTSconfig
‪array string $pagesTSconfig
Definition: TypoScriptFrontendController.php:331
‪TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController\splitLinkVarsString
‪array splitLinkVarsString(string $string)
Definition: TypoScriptFrontendController.php:2387
‪TYPO3\CMS\Core\Database\Query\Restriction\EndTimeRestriction
Definition: EndTimeRestriction.php:27
‪TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController\$applicationData
‪array $applicationData
Definition: TypoScriptFrontendController.php:458
‪TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController\newCObj
‪newCObj()
Definition: TypoScriptFrontendController.php:3323
‪TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController\setOutputLanguage
‪setOutputLanguage()
Definition: TypoScriptFrontendController.php:3621
‪TYPO3\CMS\Core\Utility\PathUtility\dirname
‪static string dirname($path)
Definition: PathUtility.php:186
‪TYPO3\CMS\Core\Exception
Definition: Exception.php:22
‪TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController\sL
‪string sL($input)
Definition: TypoScriptFrontendController.php:3612
‪TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController\$linkVars
‪string $linkVars
Definition: TypoScriptFrontendController.php:433
‪TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController\initializeFrontendUserOrUpdateCHashArgument
‪PageArguments initializeFrontendUserOrUpdateCHashArgument($cHashOrFrontendUser, PageArguments $pageArguments)
Definition: TypoScriptFrontendController.php:755
‪TYPO3\CMS\Backend\FrontendBackendUserAuthentication
Definition: FrontendBackendUserAuthentication.php:31
‪TYPO3\CMS\Core\TypoScript\Parser\TypoScriptParser
Definition: TypoScriptParser.php:37
‪TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController\generatePageTitle
‪string generatePageTitle()
Definition: TypoScriptFrontendController.php:2846
‪TYPO3\CMS\Core\Database\Query\Restriction\StartTimeRestriction
Definition: StartTimeRestriction.php:27
‪TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController\applyPreviewSettings
‪string null applyPreviewSettings($backendUser=null)
Definition: TypoScriptFrontendController.php:998
‪TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController\getLockHash
‪string getLockHash()
Definition: TypoScriptFrontendController.php:1952
‪TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController\generatePage_preProcessing
‪generatePage_preProcessing()
Definition: TypoScriptFrontendController.php:2667
‪TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController\checkEnableFields
‪bool checkEnableFields($row, $bypassGroupCheck=false)
Definition: TypoScriptFrontendController.php:1542
‪TYPO3\CMS\Core\Utility\PathUtility\stripPathSitePrefix
‪static string stripPathSitePrefix($path)
Definition: PathUtility.php:372
‪TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController\getPageAccessFailureReasons
‪array getPageAccessFailureReasons(string $failureReasonCode=null)
Definition: TypoScriptFrontendController.php:1631
‪TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController\processContentForOutput
‪processContentForOutput(bool $isCoreCall=false)
Definition: TypoScriptFrontendController.php:3172
‪TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController\getSite
‪getSite()
Definition: TypoScriptFrontendController.php:3971
‪TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController\getPageAndRootlineWithDomain
‪getPageAndRootlineWithDomain($rootPageId, ServerRequestInterface $request)
Definition: TypoScriptFrontendController.php:1668
‪TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController\applyHttpHeadersToResponse
‪ResponseInterface applyHttpHeadersToResponse(ResponseInterface $response)
Definition: TypoScriptFrontendController.php:3215
‪TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController\__set
‪__set(string $propertyName, $propertyValue)
Definition: TypoScriptFrontendController.php:4083
‪TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController\$no_cache
‪bool $no_cache
Definition: TypoScriptFrontendController.php:143
‪TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController\$cacheContentFlag
‪bool $cacheContentFlag
Definition: TypoScriptFrontendController.php:263
‪TYPO3\CMS\Core\Locking\LockingStrategyInterface\LOCK_CAPABILITY_NOBLOCK
‪const LOCK_CAPABILITY_NOBLOCK
Definition: LockingStrategyInterface.php:40
‪TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController\$cHash
‪string $cHash
Definition: TypoScriptFrontendController.php:132
‪TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController\setContentType
‪setContentType($contentType)
Definition: TypoScriptFrontendController.php:822
‪TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController\$MP
‪string $MP
Definition: TypoScriptFrontendController.php:205
‪TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController\$indexedDocTitle
‪string $indexedDocTitle
Definition: TypoScriptFrontendController.php:527
‪TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController\clear_preview
‪clear_preview()
Definition: TypoScriptFrontendController.php:904
‪TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController\disableCache
‪disableCache()
Definition: TypoScriptFrontendController.php:3540
‪TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController\uniqueHash
‪string uniqueHash($str='')
Definition: TypoScriptFrontendController.php:3492
‪if
‪if(PHP_SAPI !=='cli')
Definition: splitAcceptanceTests.php:33
‪TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController\$register
‪array $register
Definition: TypoScriptFrontendController.php:462
‪TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController\set_no_cache
‪set_no_cache($reason='', $internal=false)
Definition: TypoScriptFrontendController.php:3503
‪TYPO3\CMS\Frontend\Resource\FilePathSanitizer
Definition: FilePathSanitizer.php:39
‪TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController\$sys_language_isocode
‪string $sys_language_isocode
Definition: TypoScriptFrontendController.php:452
‪TYPO3\CMS\Core\Utility\MathUtility\forceIntegerInRange
‪static int forceIntegerInRange($theInt, $min, $max=2000000000, $defaultValue=0)
Definition: MathUtility.php:32
‪TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController\populatePageDataFromCache
‪populatePageDataFromCache(array $cachedData)
Definition: TypoScriptFrontendController.php:1867
‪TYPO3\CMS\Core\Domain\Repository\PageRepository\DOKTYPE_SHORTCUT
‪const DOKTYPE_SHORTCUT
Definition: PageRepository.php:105
‪TYPO3\CMS\Core\Configuration\Loader\PageTsConfigLoader
Definition: PageTsConfigLoader.php:39
‪TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController\baseUrlWrap
‪string baseUrlWrap($url)
Definition: TypoScriptFrontendController.php:3384
‪TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController\isInPreviewMode
‪isInPreviewMode()
Definition: TypoScriptFrontendController.php:3914
‪TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController\$pageArguments
‪PageArguments $pageArguments
Definition: TypoScriptFrontendController.php:137
‪TYPO3\CMS\Core\Utility\RootlineUtility
Definition: RootlineUtility.php:39
‪TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController\$additionalFooterData
‪array $additionalFooterData
Definition: TypoScriptFrontendController.php:350
‪TYPO3\CMS\Frontend\Page\PageAccessFailureReasons\CACHEHASH_EMPTY
‪const CACHEHASH_EMPTY
Definition: PageAccessFailureReasons.php:38
‪TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController\$extTarget
‪string $extTarget
Definition: TypoScriptFrontendController.php:391
‪TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController\$metaCharset
‪string $metaCharset
Definition: TypoScriptFrontendController.php:550
‪TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController\$intTarget
‪string $intTarget
Definition: TypoScriptFrontendController.php:386
‪TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController\settingLanguage
‪settingLanguage(ServerRequestInterface $request=null)
Definition: TypoScriptFrontendController.php:2139
‪$parser
‪$parser
Definition: annotationChecker.php:108
‪TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController\getContext
‪getContext()
Definition: TypoScriptFrontendController.php:3976
‪TYPO3\CMS\Core\Locking\LockingStrategyInterface
Definition: LockingStrategyInterface.php:26
‪TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController\createHashBase
‪string createHashBase($createLockHashBase=false)
Definition: TypoScriptFrontendController.php:1968
‪TYPO3\CMS\Core\Localization\Locales
Definition: Locales.php:30
‪TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController\$pageCache
‪TYPO3 CMS Core Cache Frontend FrontendInterface $pageCache
Definition: TypoScriptFrontendController.php:571
‪TYPO3\CMS\Core\Charset\CharsetConverter
Definition: CharsetConverter.php:54
‪TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController\setRegisterValueForSysLastChanged
‪setRegisterValueForSysLastChanged(array $page)
Definition: TypoScriptFrontendController.php:2621
‪TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController\$type
‪int string $type
Definition: TypoScriptFrontendController.php:117
‪TYPO3\CMS\Core\Utility\ArrayUtility\mergeRecursiveWithOverrule
‪static mergeRecursiveWithOverrule(array &$original, array $overrule, $addKeys=true, $includeEmptyValues=true, $enableUnsetFeature=true)
Definition: ArrayUtility.php:654
‪TYPO3\CMS\Core\Context\LanguageAspectFactory\createFromSiteLanguage
‪static LanguageAspect createFromSiteLanguage(SiteLanguage $language)
Definition: LanguageAspectFactory.php:34
‪TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController\$fileTarget
‪string $fileTarget
Definition: TypoScriptFrontendController.php:396
‪TYPO3\CMS\Core\Locking\LockingStrategyInterface\LOCK_CAPABILITY_EXCLUSIVE
‪const LOCK_CAPABILITY_EXCLUSIVE
Definition: LockingStrategyInterface.php:30
‪TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController\$forceTemplateParsing
‪bool $forceTemplateParsing
Definition: TypoScriptFrontendController.php:318
‪TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController\isUserOrGroupSet
‪bool isUserOrGroupSet()
Definition: TypoScriptFrontendController.php:892
‪TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController\initializeSiteLanguageWithCompatibility
‪initializeSiteLanguageWithCompatibility($siteLanguageOrType, ServerRequestInterface $request)
Definition: TypoScriptFrontendController.php:706
‪TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController\$imagesOnPage
‪array $imagesOnPage
Definition: TypoScriptFrontendController.php:501
‪TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController\$pageAccessFailureHistory
‪array $pageAccessFailureHistory
Definition: TypoScriptFrontendController.php:200
‪TYPO3\CMS\Core\Page\PageRenderer\getState
‪array getState()
Definition: PageRenderer.php:329
‪TYPO3\CMS\Frontend\Page\PageAccessFailureReasons\ACCESS_DENIED_INVALID_PAGETYPE
‪const ACCESS_DENIED_INVALID_PAGETYPE
Definition: PageAccessFailureReasons.php:51
‪TYPO3\CMS\Core\Locking\Exception\LockAcquireWouldBlockException
Definition: LockAcquireWouldBlockException.php:22
‪TYPO3\CMS\Core\Context\Context
Definition: Context.php:53
‪TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController\$JSCode
‪string $JSCode
Definition: TypoScriptFrontendController.php:370
‪TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController\getGlobalInstance
‪static TypoScriptFrontendController getGlobalInstance()
Definition: TypoScriptFrontendController.php:3951
‪TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController\$xhtmlVersion
‪int $xhtmlVersion
Definition: TypoScriptFrontendController.php:593
‪TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController\getBackendUser
‪TYPO3 CMS Backend FrontendBackendUserAuthentication getBackendUser()
Definition: TypoScriptFrontendController.php:3927
‪TYPO3\CMS\Core\Type\Bitmask\Permission
Definition: Permission.php:24
‪TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController\isStaticCacheble
‪bool isStaticCacheble()
Definition: TypoScriptFrontendController.php:3307
‪TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController\getHash
‪string getHash()
Definition: TypoScriptFrontendController.php:1939
‪TYPO3\CMS\Core\Core\Environment\getFrameworkBasePath
‪static string getFrameworkBasePath()
Definition: Environment.php:261
‪TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController\$page
‪array $page
Definition: TypoScriptFrontendController.php:153
‪TYPO3\CMS\Core\Context\Context\setAspect
‪setAspect(string $name, AspectInterface $aspect)
Definition: Context.php:162
‪TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController\clearPageCacheContent
‪clearPageCacheContent()
Definition: TypoScriptFrontendController.php:2584
‪TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController\$registerStack
‪array $registerStack
Definition: TypoScriptFrontendController.php:468
‪TYPO3\CMS\Core\Site\Entity\Site
Definition: Site.php:40
‪TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController\getRedirectUriForShortcut
‪string null getRedirectUriForShortcut(ServerRequestInterface $request)
Definition: TypoScriptFrontendController.php:2473
‪TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController\recursivelyReplaceIntPlaceholdersInContent
‪recursivelyReplaceIntPlaceholdersInContent()
Definition: TypoScriptFrontendController.php:2998
‪TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController\$additionalHeaderData
‪array $additionalHeaderData
Definition: TypoScriptFrontendController.php:345
‪TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController\getCacheHeaders
‪array getCacheHeaders()
Definition: TypoScriptFrontendController.php:3254
‪TYPO3\CMS\Core\Site\Entity\SiteLanguage
Definition: SiteLanguage.php:26
‪TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController\settingLocale
‪settingLocale()
Definition: TypoScriptFrontendController.php:2278
‪TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController\realPageCacheContent
‪realPageCacheContent()
Definition: TypoScriptFrontendController.php:2522
‪TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController\$lastImageInfo
‪array $lastImageInfo
Definition: TypoScriptFrontendController.php:508
‪TYPO3\CMS\Core\Domain\Repository\PageRepository\DOKTYPE_MOUNTPOINT
‪const DOKTYPE_MOUNTPOINT
Definition: PageRepository.php:107
‪TYPO3\CMS\Core\TimeTracker\TimeTracker\setTSlogMessage
‪setTSlogMessage($content, $num=0)
Definition: TimeTracker.php:215
‪TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController\getLanguage
‪getLanguage()
Definition: TypoScriptFrontendController.php:3966
‪TYPO3\CMS\Core\Page\PageRenderer
Definition: PageRenderer.php:42
‪TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController\isINTincScript
‪bool isINTincScript()
Definition: TypoScriptFrontendController.php:3127
‪TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController\initUserGroups
‪initUserGroups()
Definition: TypoScriptFrontendController.php:844
‪TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController\__isset
‪bool __isset(string $propertyName)
Definition: TypoScriptFrontendController.php:4000
‪TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController\determineIdIsHiddenPage
‪bool determineIdIsHiddenPage()
Definition: TypoScriptFrontendController.php:1029
‪TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController\reqCHash
‪reqCHash()
Definition: TypoScriptFrontendController.php:1701
‪TYPO3\CMS\Core\Error\Http\PageNotFoundException
Definition: PageNotFoundException.php:24
‪TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController\$locks
‪LockingStrategyInterface[][] $locks
Definition: TypoScriptFrontendController.php:560
‪TYPO3\CMS\Frontend\Page\PageAccessFailureReasons\ACCESS_DENIED_HOST_PAGE_MISMATCH
‪const ACCESS_DENIED_HOST_PAGE_MISMATCH
Definition: PageAccessFailureReasons.php:50
‪TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController\getPageArguments
‪getPageArguments()
Definition: TypoScriptFrontendController.php:3981
‪TYPO3\CMS\Frontend\Page\PageAccessFailureReasons\ACCESS_DENIED_PAGE_NOT_RESOLVED
‪const ACCESS_DENIED_PAGE_NOT_RESOLVED
Definition: PageAccessFailureReasons.php:48
‪TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController\initializeContextWithGlobalFallback
‪initializeContextWithGlobalFallback($context)
Definition: TypoScriptFrontendController.php:661
‪TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController\$accessKey
‪array $accessKey
Definition: TypoScriptFrontendController.php:494
‪TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController\getPageCacheTags
‪array getPageCacheTags()
Definition: TypoScriptFrontendController.php:2654
‪TYPO3\CMS\Core\Context\TypoScriptAspect
Definition: TypoScriptAspect.php:29
‪TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController\$loginAllowedInBranch_mode
‪string $loginAllowedInBranch_mode
Definition: TypoScriptFrontendController.php:222
‪TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController\checkRootlineForIncludeSection
‪bool checkRootlineForIncludeSection()
Definition: TypoScriptFrontendController.php:1474
‪TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController\getFromCache_queryRow
‪array getFromCache_queryRow()
Definition: TypoScriptFrontendController.php:1849
‪TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController\calculateLinkVars
‪calculateLinkVars(array $queryParams)
Definition: TypoScriptFrontendController.php:2317
‪TYPO3\CMS\Frontend\Page\PageAccessFailureReasons\LANGUAGE_DEFAULT_NOT_AVAILABLE
‪const LANGUAGE_DEFAULT_NOT_AVAILABLE
Definition: PageAccessFailureReasons.php:44
‪TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController\getFirstTimeValueForRecord
‪int getFirstTimeValueForRecord($tableDef, $now)
Definition: TypoScriptFrontendController.php:3710
‪TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController\determineId
‪determineId(ServerRequestInterface $request=null)
Definition: TypoScriptFrontendController.php:933
‪TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController\$cHash_array
‪array $cHash_array
Definition: TypoScriptFrontendController.php:325
‪TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController\$pageRenderer
‪PageRenderer $pageRenderer
Definition: TypoScriptFrontendController.php:564
‪TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController\__construct
‪__construct($context=null, $siteOrId=null, $siteLanguageOrType=null, $pageArguments=null, $cHashOrFrontendUser=null, $_2=null, $MP=null)
Definition: TypoScriptFrontendController.php:628
‪TYPO3\CMS\Core\Utility\HttpUtility\buildQueryString
‪static string buildQueryString(array $parameters, string $prependCharacter='', bool $skipEmptyParameters=false)
Definition: HttpUtility.php:163
‪TYPO3\CMS\Core\PageTitle\PageTitleProviderManager
Definition: PageTitleProviderManager.php:31
‪TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController\getWebsiteTitle
‪string getWebsiteTitle()
Definition: TypoScriptFrontendController.php:2925
‪TYPO3\CMS\Core\Resource\StorageRepository
Definition: StorageRepository.php:31
‪TYPO3\CMS\Frontend\Page\PageAccessFailureReasons\LANGUAGE_NOT_AVAILABLE
‪const LANGUAGE_NOT_AVAILABLE
Definition: PageAccessFailureReasons.php:41
‪TYPO3\CMS\Frontend\Page\PageAccessFailureReasons\PAGE_NOT_FOUND
‪const PAGE_NOT_FOUND
Definition: PageAccessFailureReasons.php:28
‪TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController\$pageNotFound
‪int $pageNotFound
Definition: TypoScriptFrontendController.php:188
‪TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController\$ATagParams
‪string $ATagParams
Definition: TypoScriptFrontendController.php:411
‪TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController\isGeneratePage
‪bool isGeneratePage()
Definition: TypoScriptFrontendController.php:2514
‪TYPO3\CMS\Core\Domain\Repository\PageRepository\DOKTYPE_SPACER
‪const DOKTYPE_SPACER
Definition: PageRepository.php:108
‪TYPO3\CMS\Frontend\Page\PageAccessFailureReasons\RENDERING_INSTRUCTIONS_NOT_CONFIGURED
‪const RENDERING_INSTRUCTIONS_NOT_CONFIGURED
Definition: PageAccessFailureReasons.php:33
‪TYPO3\CMS\Core\Localization\LanguageService\createFromSiteLanguage
‪static createFromSiteLanguage(SiteLanguage $language)
Definition: LanguageService.php:443
‪TYPO3\CMS\Core\Http\ServerRequestFactory
Definition: ServerRequestFactory.php:34
‪TYPO3\CMS\Core\TimeTracker\TimeTracker\pull
‪pull($content='')
Definition: TimeTracker.php:195
‪TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController\$loginAllowedInBranch
‪bool $loginAllowedInBranch
Definition: TypoScriptFrontendController.php:216
‪TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController\$contentPid
‪int $contentPid
Definition: TypoScriptFrontendController.php:159
‪TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController\$absRefPrefix
‪string $absRefPrefix
Definition: TypoScriptFrontendController.php:406
‪TYPO3\CMS\Core\Domain\Repository\PageRepository\DOKTYPE_BE_USER_SECTION
‪const DOKTYPE_BE_USER_SECTION
Definition: PageRepository.php:106
‪TYPO3\CMS\Core\Cache\CacheManager
Definition: CacheManager.php:35
‪TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController\$spamProtectEmailAddresses
‪string int $spamProtectEmailAddresses
Definition: TypoScriptFrontendController.php:401
‪TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController\preparePageContentGeneration
‪preparePageContentGeneration(ServerRequestInterface $request)
Definition: TypoScriptFrontendController.php:2705
‪TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController\$site
‪Site $site
Definition: TypoScriptFrontendController.php:121
‪TYPO3\CMS\Frontend\Page\PageAccessFailureReasons\ACCESS_DENIED_SUBSECTION_NOT_RESOLVED
‪const ACCESS_DENIED_SUBSECTION_NOT_RESOLVED
Definition: PageAccessFailureReasons.php:49
‪TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController\$fe_user
‪FrontendUserAuthentication string $fe_user
Definition: TypoScriptFrontendController.php:211
‪TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController\$sWordList
‪string $sWordList
Definition: TypoScriptFrontendController.php:426
‪TYPO3\CMS\Core\Configuration\Parser\PageTsConfigParser
Definition: PageTsConfigParser.php:33
‪TYPO3\CMS\Core\Core\Environment\getBackendPath
‪static string getBackendPath()
Definition: Environment.php:250
‪TYPO3\CMS\Core\Charset\UnknownCharsetException
Definition: UnknownCharsetException.php:24
‪TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController\checkPageGroupAccess
‪bool checkPageGroupAccess($row)
Definition: TypoScriptFrontendController.php:1568
‪TYPO3\CMS\Core\Type\Bitmask\Permission\PAGE_SHOW
‪const PAGE_SHOW
Definition: Permission.php:33
‪TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController\get_cache_timeout
‪int get_cache_timeout()
Definition: TypoScriptFrontendController.php:3563
‪TYPO3\CMS\Core\Domain\Repository\PageRepository\DOKTYPE_SYSFOLDER
‪const DOKTYPE_SYSFOLDER
Definition: PageRepository.php:109
‪TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController\headerNoCache
‪bool headerNoCache(ServerRequestInterface $request=null)
Definition: TypoScriptFrontendController.php:1909
‪TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController\$id
‪string $id
Definition: TypoScriptFrontendController.php:112
‪TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController\$context
‪Context $context
Definition: TypoScriptFrontendController.php:606
‪TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController\getPageAndRootline
‪getPageAndRootline(ServerRequestInterface $request)
Definition: TypoScriptFrontendController.php:1264
‪TYPO3\CMS\Core\Context\LanguageAspect
Definition: LanguageAspect.php:57
‪TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController\$newHash
‪string $newHash
Definition: TypoScriptFrontendController.php:303
‪TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController\$all
‪array $all
Definition: TypoScriptFrontendController.php:283
‪TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController\getConfigArray
‪getConfigArray(ServerRequestInterface $request=null)
Definition: TypoScriptFrontendController.php:2009
‪TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController\printTitle
‪string printTitle(string $pageTitle, bool $noTitle=false, bool $showTitleFirst=false, string $pageTitleSeparator='')
Definition: TypoScriptFrontendController.php:2903
‪TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController\releaseLocks
‪releaseLocks()
Definition: TypoScriptFrontendController.php:2634
‪TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController\$isClientCachable
‪bool $isClientCachable
Definition: TypoScriptFrontendController.php:275
‪TYPO3\CMS\Frontend\Configuration\TypoScript\ConditionMatching\ConditionMatcher
Definition: ConditionMatcher.php:29
‪TYPO3\CMS\Core\Utility\GeneralUtility\trimExplode
‪static string[] trimExplode($delim, $string, $removeEmptyValues=false, $limit=0)
Definition: GeneralUtility.php:1059
‪TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController\getFromCache
‪getFromCache(ServerRequestInterface $request=null)
Definition: TypoScriptFrontendController.php:1763
‪TYPO3\CMS\Frontend\Page\PageAccessFailureReasons\LANGUAGE_NOT_AVAILABLE_STRICT_MODE
‪const LANGUAGE_NOT_AVAILABLE_STRICT_MODE
Definition: PageAccessFailureReasons.php:42
‪$output
‪$output
Definition: annotationChecker.php:119
‪TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController\$deprecatedPublicProperties
‪string[] $deprecatedPublicProperties
Definition: TypoScriptFrontendController.php:104
‪TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController\whichWorkspace
‪int whichWorkspace()
Definition: TypoScriptFrontendController.php:3429
‪TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController\$additionalJavaScript
‪array $additionalJavaScript
Definition: TypoScriptFrontendController.php:358
‪TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController\$inlineJS
‪string $inlineJS
Definition: TypoScriptFrontendController.php:375
‪TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController\setPageCacheContent
‪setPageCacheContent($content, $data, $expirationTstamp)
Definition: TypoScriptFrontendController.php:2552
‪TYPO3\CMS\Core\Database\Connection
Definition: Connection.php:36
‪TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController\logDeprecatedTyposcript
‪logDeprecatedTyposcript($typoScriptProperty, $explanation='')
Definition: TypoScriptFrontendController.php:3403
‪TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController\INTincScript
‪INTincScript()
Definition: TypoScriptFrontendController.php:2948
‪TYPO3\CMS\Core\TypoScript\TemplateService
Definition: TemplateService.php:46
‪TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController\$displayEditIcons
‪string $displayEditIcons
Definition: TypoScriptFrontendController.php:439
‪TYPO3\CMS\Core\Error\Http\ShortcutTargetPageNotFoundException
Definition: ShortcutTargetPageNotFoundException.php:24
‪TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController\isAllowedLinkVarValue
‪bool isAllowedLinkVarValue(string $haystack, string $needle)
Definition: TypoScriptFrontendController.php:2410
‪TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController\addCacheTags
‪addCacheTags(array $tags)
Definition: TypoScriptFrontendController.php:2646
‪TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController
Definition: TypoScriptFrontendController.php:98
‪TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController\$recordRegister
‪array $recordRegister
Definition: TypoScriptFrontendController.php:480
‪TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController\setJS
‪setJS($key, $content='')
Definition: TypoScriptFrontendController.php:3473
‪TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController\initializeSiteWithCompatibility
‪initializeSiteWithCompatibility($siteOrId, ServerRequestInterface $request)
Definition: TypoScriptFrontendController.php:683
‪TYPO3\CMS\Core\Utility\ArrayUtility
Definition: ArrayUtility.php:24
‪TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController\$uniqueString
‪string $uniqueString
Definition: TypoScriptFrontendController.php:520
‪$GLOBALS
‪$GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['adminpanel']['modules']
Definition: ext_localconf.php:5
‪TYPO3\CMS\Core\Database\Query\Restriction\DeletedRestriction
Definition: DeletedRestriction.php:28
‪TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController\processNonCacheableContentPartsAndSubstituteContentMarkers
‪processNonCacheableContentPartsAndSubstituteContentMarkers(array $nonCacheableData)
Definition: TypoScriptFrontendController.php:3019
‪TYPO3\CMS\Core\Error\Http\AbstractServerErrorException
Definition: AbstractServerErrorException.php:22
‪TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController\getUriToCurrentPageForRedirect
‪string getUriToCurrentPageForRedirect(ServerRequestInterface $request)
Definition: TypoScriptFrontendController.php:2488
‪TYPO3\CMS\Core\Core\Environment
Definition: Environment.php:40
‪TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController\fetch_the_id
‪fetch_the_id(ServerRequestInterface $request=null)
Definition: TypoScriptFrontendController.php:1149
‪TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController\initializeSearchWordData
‪initializeSearchWordData($searchWords)
Definition: TypoScriptFrontendController.php:2779
‪TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController\$cacheTimeOutDefault
‪int $cacheTimeOutDefault
Definition: TypoScriptFrontendController.php:256
‪TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController\$sPre
‪string $sPre
Definition: TypoScriptFrontendController.php:289
‪TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController\$fePreview
‪int $fePreview
Definition: TypoScriptFrontendController.php:231
‪TYPO3\CMS\Frontend\Page\CacheHashCalculator
Definition: CacheHashCalculator.php:25
‪TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController\INTincScript_loadJSCode
‪INTincScript_loadJSCode()
Definition: TypoScriptFrontendController.php:3070
‪TYPO3\CMS\Core\Utility\MathUtility
Definition: MathUtility.php:22
‪TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer
Definition: ContentObjectRenderer.php:97
‪TYPO3\CMS\Core\Locking\LockFactory
Definition: LockFactory.php:25
‪TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController\setSysLastChanged
‪setSysLastChanged()
Definition: TypoScriptFrontendController.php:2595
‪TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController\__get
‪mixed __get(string $propertyName)
Definition: TypoScriptFrontendController.php:4038
‪TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController\set_cache_timeout_default
‪set_cache_timeout_default($seconds)
Definition: TypoScriptFrontendController.php:3550
‪TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController\getRequestedId
‪int getRequestedId()
Definition: TypoScriptFrontendController.php:3786
‪TYPO3\CMS\Frontend\Controller
Definition: ErrorController.php:18
‪TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController\getPagesTSconfig
‪array getPagesTSconfig()
Definition: TypoScriptFrontendController.php:3445
‪TYPO3\CMS\Core\Exception\Page\RootLineException
Definition: RootLineException.php:25
‪TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController\initializeLegacyMountPointArgument
‪PageArguments initializeLegacyMountPointArgument(?string $MP, PageArguments $pageArguments)
Definition: TypoScriptFrontendController.php:783
‪TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController\$sWordRegEx
‪string $sWordRegEx
Definition: TypoScriptFrontendController.php:419
‪TYPO3\CMS\Core\Utility\HttpUtility
Definition: HttpUtility.php:24
‪TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController\updateRootLinesWithTranslations
‪updateRootLinesWithTranslations()
Definition: TypoScriptFrontendController.php:2264
‪TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController\$cObj
‪ContentObjectRenderer $cObj
Definition: TypoScriptFrontendController.php:538
‪TYPO3\CMS\Core\Localization\LanguageService
Definition: LanguageService.php:42
‪TYPO3\CMS\Frontend\Authentication\FrontendUserAuthentication
Definition: FrontendUserAuthentication.php:30
‪TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController\$cObjectDepthCounter
‪int $cObjectDepthCounter
Definition: TypoScriptFrontendController.php:474
‪TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController\$domainStartPage
‪int $domainStartPage
Definition: TypoScriptFrontendController.php:195
‪TYPO3\CMS\Core\Compatibility\PublicPropertyDeprecationTrait
Definition: PublicPropertyDeprecationTrait.php:68
‪TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController\$originalShortcutPage
‪array null $originalShortcutPage
Definition: TypoScriptFrontendController.php:176
‪TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController\checkPagerecordForIncludeSection
‪bool checkPagerecordForIncludeSection(array $row)
Definition: TypoScriptFrontendController.php:1591
‪TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController\__unset
‪__unset(string $propertyName)
Definition: TypoScriptFrontendController.php:4118
‪TYPO3\CMS\Core\Domain\Repository\PageRepository
Definition: PageRepository.php:52
‪TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController\$languageService
‪LanguageService $languageService
Definition: TypoScriptFrontendController.php:556
‪TYPO3\CMS\Core\Database\ConnectionPool
Definition: ConnectionPool.php:46
‪TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController\getRelevantParametersForCachingFromPageArguments
‪array getRelevantParametersForCachingFromPageArguments(PageArguments $pageArguments)
Definition: TypoScriptFrontendController.php:1745
‪TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController\calculatePageCacheTimeout
‪int calculatePageCacheTimeout()
Definition: TypoScriptFrontendController.php:3654
‪TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController\generatePage_postProcessing
‪generatePage_postProcessing()
Definition: TypoScriptFrontendController.php:2800
‪TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController\$config
‪array $config
Definition: TypoScriptFrontendController.php:243
‪TYPO3\CMS\Core\Utility\GeneralUtility
Definition: GeneralUtility.php:46
‪TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController\checkTranslatedShortcut
‪checkTranslatedShortcut(int $languageId, ServerRequestInterface $request)
Definition: TypoScriptFrontendController.php:2294
‪TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController\$language
‪SiteLanguage $language
Definition: TypoScriptFrontendController.php:125
‪TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController\setPageArguments
‪setPageArguments(PageArguments $pageArguments)
Definition: TypoScriptFrontendController.php:1726
‪TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController\getTimeTracker
‪TimeTracker getTimeTracker()
Definition: TypoScriptFrontendController.php:3935
‪TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController\$originalMountPointPage
‪array null $originalMountPointPage
Definition: TypoScriptFrontendController.php:167
‪TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController\$content
‪string $content
Definition: TypoScriptFrontendController.php:543
‪TYPO3\CMS\Core\Http\ImmediateResponseException
Definition: ImmediateResponseException.php:30
‪TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController\resolveContentPid
‪int resolveContentPid(ServerRequestInterface $request)
Definition: TypoScriptFrontendController.php:2687
‪TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController\$rootLine
‪array $rootLine
Definition: TypoScriptFrontendController.php:148
‪TYPO3\CMS\Frontend\Aspect\PreviewAspect
Definition: PreviewAspect.php:30
‪TYPO3\CMS\Core\TimeTracker\TimeTracker
Definition: TimeTracker.php:30
‪TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController\isBackendUserLoggedIn
‪bool isBackendUserLoggedIn()
Definition: TypoScriptFrontendController.php:920
‪TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController\releaseLock
‪releaseLock($type)
Definition: TypoScriptFrontendController.php:3870
‪TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController\initCaches
‪initCaches()
Definition: TypoScriptFrontendController.php:835
‪TYPO3\CMS\Core\Resource\Exception
Definition: AbstractFileOperationException.php:16
‪TYPO3\CMS\Core\Routing\PageArguments\getPageId
‪int getPageId()
Definition: PageArguments.php:111
‪TYPO3\CMS\Core\Domain\Repository\PageRepository\DOKTYPE_RECYCLER
‪const DOKTYPE_RECYCLER
Definition: PageRepository.php:110
‪TYPO3\CMS\Core\Context\DateTimeAspect
Definition: DateTimeAspect.php:35
‪TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController\$divSection
‪string $divSection
Definition: TypoScriptFrontendController.php:381
‪TYPO3\CMS\Frontend\Page\PageAccessFailureReasons
Definition: PageAccessFailureReasons.php:25
‪TYPO3\CMS\Frontend\Page\PageAccessFailureReasons\ROOTLINE_BROKEN
‪const ROOTLINE_BROKEN
Definition: PageAccessFailureReasons.php:29
‪TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController\$sys_page
‪PageRepository string $sys_page
Definition: TypoScriptFrontendController.php:182
‪TYPO3\CMS\Core\Context\UserAspect
Definition: UserAspect.php:38
‪TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController\isOutputting
‪bool isOutputting(bool $isCoreCall=false)
Definition: TypoScriptFrontendController.php:3145
‪TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController\buildPageArgumentsWithFallback
‪PageArguments buildPageArgumentsWithFallback($pageArguments, ServerRequestInterface $request)
Definition: TypoScriptFrontendController.php:730
‪TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController\$pageCacheTags
‪array $pageCacheTags
Definition: TypoScriptFrontendController.php:575
‪TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController\resolveTranslatedPageId
‪resolveTranslatedPageId()
Definition: TypoScriptFrontendController.php:1437
‪TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController\$baseUrl
‪string $baseUrl
Definition: TypoScriptFrontendController.php:532
‪TYPO3\CMS\Core\Http\ServerRequestFactory\fromGlobals
‪static ServerRequest fromGlobals()
Definition: ServerRequestFactory.php:59
‪TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController\$pSetup
‪array string $pSetup
Definition: TypoScriptFrontendController.php:296
‪TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController\acquireLock
‪acquireLock($type, $key)
Definition: TypoScriptFrontendController.php:3825
‪TYPO3\CMS\Core\Core\Environment\getExtensionsPath
‪static string getExtensionsPath()
Definition: Environment.php:271
‪TYPO3\CMS\Frontend\Page\PageAccessFailureReasons\RENDERING_INSTRUCTIONS_NOT_FOUND
‪const RENDERING_INSTRUCTIONS_NOT_FOUND
Definition: PageAccessFailureReasons.php:32
‪TYPO3\CMS\Core\TimeTracker\TimeTracker\push
‪push($tslabel, $value='')
Definition: TimeTracker.php:168