17 use Psr\Log\LoggerAwareInterface;
18 use Psr\Log\LoggerAwareTrait;
63 'versioningPreview' =>
'Using $versioningPreview of class PageRepository is discouraged, just use versioningWorkspaceId to determine if a workspace should be previewed.',
64 'workspaceCache' =>
'Using $workspaceCache of class PageRepository from the outside is discouraged, as this only reflects a local runtime cache.',
65 'error_getRootLine' =>
'Using $error_getRootLine of class PageRepository from the outside is deprecated as this property only exists for legacy reasons.',
66 'error_getRootLine_failPid' =>
'Using $error_getRootLine_failPid of class PageRepository from the outside is deprecated as this property only exists for legacy reasons.',
67 'sys_language_uid' =>
'Using $sys_language_uid of class PageRepository from the outside is deprecated as this information is now stored within the Context Language Aspect given by the constructor.',
68 'versioningWorkspaceId' =>
'Using $versioningWorkspaceId of class PageRepository from the outside is deprecated as this information is now stored within the Context Workspace Aspect given by the constructor.',
76 'init' =>
'init() is now called implicitly on object creation, and is not necessary anymore to be called explicitly. Calling init() will throw an error in TYPO3 v10.0.',
77 'movePlhOL' =>
'Using movePlhOL is deprecated and will not be possible anymore in TYPO3 v10.0.',
78 'getMovePlaceholder' =>
'Using getMovePlaceholder is deprecated and will not be possible anymore in TYPO3 v10.0.'
175 '_PAGES_OVERLAY_UID',
176 '_PAGES_OVERLAY_LANGUAGE',
177 '_PAGES_OVERLAY_REQUESTEDLANGUAGE',
213 $this->context =
$context ?? GeneralUtility::makeInstance(Context::class);
214 $this->versioningWorkspaceId = $this->context->getPropertyFromAspect(
'workspace',
'id');
218 $this->
init($this->context->getPropertyFromAspect(
'visibility',
'includeHiddenPages'));
220 $this->sys_language_uid = (int)$this->context->getPropertyFromAspect(
'language',
'id', 0);
233 protected function init($show_hidden)
235 $this->where_groupAccess =
'';
242 $userAspect = $this->context->getAspect(
'frontend.user');
243 $frontendUserIdentifier =
'user_' . (int)$userAspect->get(
'id') .
'_groups_' . md5(implode(
',', $userAspect->getGroupIds()));
246 $dateTimeIdentifier = $this->context->getAspect(
'date')->get(
'timestamp');
249 $cacheIdentifier =
'PageRepository_hidDelWhere' . ($show_hidden ?
'ShowHidden' :
'') .
'_' . (
int)$this->versioningWorkspaceId .
'_' . $frontendUserIdentifier .
'_' . $dateTimeIdentifier;
250 $cacheEntry = $cache->get($cacheIdentifier);
252 $this->where_hid_del = $cacheEntry;
254 $expressionBuilder = GeneralUtility::makeInstance(ConnectionPool::class)
255 ->getQueryBuilderForTable(
'pages')
257 if ($this->versioningWorkspaceId > 0) {
262 $this->where_hid_del =
' AND ' . $expressionBuilder->andX(
263 $expressionBuilder->eq(
'pages.deleted', 0),
264 $expressionBuilder->orX(
265 $expressionBuilder->eq(
'pages.t3ver_wsid', 0),
266 $expressionBuilder->eq(
'pages.t3ver_wsid', (
int)$this->versioningWorkspaceId)
268 $expressionBuilder->lt(
'pages.doktype', 200)
274 $this->where_hid_del =
' AND ' . (string)$expressionBuilder->andX(
276 $this->enableFields(
'pages', $show_hidden, [
'fe_group' =>
true],
true)
278 $expressionBuilder->lt(
'pages.doktype', 200)
281 $cache->set($cacheIdentifier, $this->where_hid_del);
283 if (is_array(
$GLOBALS[
'TYPO3_CONF_VARS'][
'SC_OPTIONS'][self::class][
'init'] ??
false)) {
284 foreach (
$GLOBALS[
'TYPO3_CONF_VARS'][
'SC_OPTIONS'][self::class][
'init'] as $classRef) {
285 $hookObject = GeneralUtility::makeInstance($classRef);
286 if (!$hookObject instanceof PageRepositoryInitHookInterface) {
287 throw new \UnexpectedValueException($classRef .
' must implement interface ' . PageRepositoryInitHookInterface::class, 1379579812);
289 $hookObject->init_postProcess($this);
328 public function getPage($uid, $disableGroupAccessCheck =
false)
331 foreach (
$GLOBALS[
'TYPO3_CONF_VARS'][
'SC_OPTIONS'][
't3lib/class.t3lib_page.php'][
'getPage'] ?? [] as $className) {
332 $hookObject = GeneralUtility::makeInstance($className);
333 if (!$hookObject instanceof PageRepositoryGetPageHookInterface) {
334 throw new \UnexpectedValueException($className .
' must implement interface ' . PageRepositoryGetPageHookInterface::class, 1251476766);
336 $hookObject->getPage_preProcess($uid, $disableGroupAccessCheck, $this);
338 $cacheIdentifier =
'PageRepository_getPage_' . md5(
343 $disableGroupAccessCheck ?
'' : $this->where_groupAccess,
344 $this->where_hid_del,
345 $this->sys_language_uid
350 $cacheEntry = $cache->get($cacheIdentifier);
351 if (is_array($cacheEntry)) {
355 $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable(
'pages');
356 $queryBuilder->getRestrictions()->removeAll();
357 $queryBuilder->select(
'*')
360 $queryBuilder->expr()->eq(
'uid', (
int)$uid),
364 $originalWhereGroupAccess =
'';
365 if (!$disableGroupAccessCheck) {
369 $this->where_groupAccess =
'';
372 $row = $queryBuilder->execute()->fetch();
375 if (is_array($row)) {
380 if ($disableGroupAccessCheck) {
381 $this->where_groupAccess = $originalWhereGroupAccess;
384 $cache->set($cacheIdentifier, $result);
400 $cacheEntry = $cache->get($cacheIdentifier);
401 if ($cacheEntry !==
false) {
405 $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable(
'pages');
406 $queryBuilder->getRestrictions()
408 ->add(GeneralUtility::makeInstance(DeletedRestriction::class));
409 $row = $queryBuilder->select(
'*')
411 ->where($queryBuilder->expr()->eq(
'uid', (
int)$uid))
418 if (is_array($row)) {
422 $cache->set($cacheIdentifier, $result);
436 trigger_error(
'PageRepository->getFirstWebPage() will be removed in TYPO3 v10.0. Use "getMenu()" instead.', E_USER_DEPRECATED);
438 $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable(
'pages');
439 $queryBuilder->getRestrictions()->removeAll();
440 $row = $queryBuilder->select(
'*')
443 $queryBuilder->expr()->eq(
'pid', $queryBuilder->createNamedParameter($uid, \PDO::PARAM_INT)),
454 if (is_array($row)) {
470 $alias = strtolower($alias);
471 $cacheIdentifier =
'PageRepository_getPageIdFromAlias_' . md5($alias);
473 $cacheEntry = $cache->get($cacheIdentifier);
474 if ($cacheEntry !==
false) {
477 $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable(
'pages');
478 $queryBuilder->getRestrictions()
480 ->add(GeneralUtility::makeInstance(DeletedRestriction::class));
482 $row = $queryBuilder->select(
'uid')
485 $queryBuilder->expr()->eq(
'alias', $queryBuilder->createNamedParameter($alias, \PDO::PARAM_STR)),
487 $queryBuilder->expr()->gte(
'pid', $queryBuilder->createNamedParameter(0, \PDO::PARAM_INT))
494 $cache->set($cacheIdentifier, $row[
'uid']);
497 $cache->set($cacheIdentifier, 0);
514 if (!isset(
$GLOBALS[
'TCA'][$table][
'ctrl'][
'languageField'])) {
519 $languageAspect = $this->context->getAspect(
'language');
520 if ($languageAspect->doOverlays()) {
521 if ($table ===
'pages') {
527 $languageAspect->getContentId(),
528 $languageAspect->getOverlayType() === $languageAspect::OVERLAYS_MIXED ?
'1' :
'hideNonTranslated'
531 }
catch (AspectNotFoundException $e) {
547 if ($languageUid === -1) {
548 trigger_error(
'Calling getPageOverlay() with "-1" as languageId is discouraged and will be unsupported in TYPO3 v10.0. Omit the parameter or use "null" instead.', E_USER_DEPRECATED);
553 return $rows[0] ?? [];
569 if (empty($pagesInput)) {
572 if ($languageUid ===
null) {
574 } elseif ($languageUid < 0) {
575 trigger_error(
'Calling getPagesOverlay() with "-1" as languageId is discouraged and will be unsupported in TYPO3 v10.0. Omit the parameter or use "null" instead.', E_USER_DEPRECATED);
578 foreach ($pagesInput as &$origPage) {
579 foreach (
$GLOBALS[
'TYPO3_CONF_VARS'][
'SC_OPTIONS'][
't3lib/class.t3lib_page.php'][
'getPageOverlay'] ?? [] as $className) {
580 $hookObject = GeneralUtility::makeInstance($className);
581 if (!$hookObject instanceof PageRepositoryGetPageOverlayHookInterface) {
582 throw new \UnexpectedValueException($className .
' must implement interface ' . PageRepositoryGetPageOverlayHookInterface::class, 1269878881);
584 $hookObject->getPageOverlay_preProcess($origPage, $languageUid, $this);
595 foreach ($pagesInput as $origPage) {
596 if (is_array($origPage)) {
598 $pageIds[] = (int)$origPage[
'uid'];
601 $pageIds[] = (int)$origPage;
609 foreach ($pagesInput as $key => $origPage) {
610 if (is_array($origPage)) {
611 $pagesOutput[$key] = $origPage;
612 if (isset($overlays[$origPage[
'uid']])) {
614 foreach ($overlays[$origPage[
'uid']] as $fieldName => $fieldValue) {
615 if ($fieldName !==
'uid' && $fieldName !==
'pid') {
616 $pagesOutput[$key][$fieldName] = $fieldValue;
621 if (isset($overlays[$origPage])) {
622 $pagesOutput[$key] = $overlays[$origPage];
639 $languageUid = $languageAspect->getId();
642 if (GeneralUtility::hideIfDefaultLanguage($page[
'l18n_cfg']) && (!$languageUid || $languageUid && !$page[
'_PAGES_OVERLAY'])) {
645 if ($languageUid > 0 && GeneralUtility::hideIfNotTranslated($page[
'l18n_cfg'])) {
646 if (!$page[
'_PAGES_OVERLAY'] || (
int)$page[
'_PAGES_OVERLAY_LANGUAGE'] !== $languageUid) {
649 } elseif ($languageUid > 0) {
651 return in_array((
int)$page[
'sys_language_uid'], $languageUids,
true);
664 $languageAspect = $languageAspect ?? $this->context->getAspect(
'language');
665 return array_filter($languageAspect->getFallbackChain(), function ($item) {
686 $languageUids = array_filter($languageUids);
687 $languageField =
$GLOBALS[
'TCA'][
'pages'][
'ctrl'][
'languageField'];
690 foreach ($pageUids as $pageId) {
693 $orderedListByLanguages = array_flip($languageUids);
695 $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable(
'pages');
696 $queryBuilder->setRestrictions(GeneralUtility::makeInstance(FrontendRestrictionContainer::class, $this->context));
698 $queryBuilder->getRestrictions()->removeByType(FrontendGroupRestriction::class);
699 $result = $queryBuilder->select(
'*')
702 $queryBuilder->expr()->eq(
703 $GLOBALS[
'TCA'][
'pages'][
'ctrl'][
'transOrigPointerField'],
704 $queryBuilder->createNamedParameter($pageId, \PDO::PARAM_INT)
706 $queryBuilder->expr()->in(
707 $GLOBALS[
'TCA'][
'pages'][
'ctrl'][
'languageField'],
708 $queryBuilder->createNamedParameter($languageUids, Connection::PARAM_INT_ARRAY)
714 while ($row = $result->fetch()) {
715 $orderedListByLanguages[$row[$languageField]] = $row;
718 foreach ($orderedListByLanguages as $languageUid => $row) {
719 if (!is_array($row)) {
725 if (is_array($row)) {
726 $row[
'_PAGES_OVERLAY'] =
true;
727 $row[
'_PAGES_OVERLAY_UID'] = $row[
'uid'];
728 $row[
'_PAGES_OVERLAY_LANGUAGE'] = $languageUid;
729 $row[
'_PAGES_OVERLAY_REQUESTEDLANGUAGE'] = $languageUids[0];
731 unset($row[
'uid'], $row[
'pid'], $row[
'alias']);
732 $overlays[$pageId] = $row;
754 public function getRecordOverlay($table, $row, $sys_language_content, $OLmode =
'')
756 foreach (
$GLOBALS[
'TYPO3_CONF_VARS'][
'SC_OPTIONS'][
't3lib/class.t3lib_page.php'][
'getRecordOverlay'] ?? [] as $className) {
757 $hookObject = GeneralUtility::makeInstance($className);
758 if (!$hookObject instanceof PageRepositoryGetRecordOverlayHookInterface) {
759 throw new \UnexpectedValueException($className .
' must implement interface ' . PageRepositoryGetRecordOverlayHookInterface::class, 1269881658);
761 $hookObject->getRecordOverlay_preProcess($table, $row, $sys_language_content, $OLmode, $this);
764 $tableControl =
$GLOBALS[
'TCA'][$table][
'ctrl'] ?? [];
766 if (!empty($tableControl[
'languageField'])
769 && (
int)$row[$tableControl[
'languageField']] !== -1
770 && !empty($tableControl[
'transOrigPointerField'])
772 && ($row[
'pid'] > 0 || in_array($tableControl[
'rootLevel'] ??
false, [
true, 1, -1],
true))) {
774 if ($sys_language_content > 0) {
776 if ((
int)$row[$tableControl[
'languageField']] === 0) {
778 $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)
779 ->getQueryBuilderForTable($table);
780 $queryBuilder->setRestrictions(
781 GeneralUtility::makeInstance(FrontendRestrictionContainer::class, $this->context)
783 $olrow = $queryBuilder->select(
'*')
786 $queryBuilder->expr()->eq(
788 $queryBuilder->createNamedParameter($row[
'pid'], \PDO::PARAM_INT)
790 $queryBuilder->expr()->eq(
791 $tableControl[
'languageField'],
792 $queryBuilder->createNamedParameter($sys_language_content, \PDO::PARAM_INT)
794 $queryBuilder->expr()->eq(
795 $tableControl[
'transOrigPointerField'],
796 $queryBuilder->createNamedParameter($row[
'uid'], \PDO::PARAM_INT)
805 if (is_array($olrow)) {
806 if (isset($olrow[
'_ORIG_uid'])) {
807 $row[
'_ORIG_uid'] = $olrow[
'_ORIG_uid'];
809 if (isset($olrow[
'_ORIG_pid'])) {
810 $row[
'_ORIG_pid'] = $olrow[
'_ORIG_pid'];
812 foreach ($row as $fN => $fV) {
813 if ($fN !==
'uid' && $fN !==
'pid' && isset($olrow[$fN])) {
814 $row[$fN] = $olrow[$fN];
815 } elseif ($fN ===
'uid') {
816 $row[
'_LOCALIZED_UID'] = $olrow[
'uid'];
819 } elseif ($OLmode ===
'hideNonTranslated' && (
int)$row[$tableControl[
'languageField']] === 0) {
824 } elseif ($sys_language_content != $row[$tableControl[
'languageField']]) {
830 if ($row[$tableControl[
'languageField']] > 0) {
836 foreach (
$GLOBALS[
'TYPO3_CONF_VARS'][
'SC_OPTIONS'][
't3lib/class.t3lib_page.php'][
'getRecordOverlay'] ?? [] as $className) {
837 $hookObject = GeneralUtility::makeInstance($className);
838 if (!$hookObject instanceof PageRepositoryGetRecordOverlayHookInterface) {
839 throw new \UnexpectedValueException($className .
' must implement interface ' . PageRepositoryGetRecordOverlayHookInterface::class, 1269881659);
841 $hookObject->getRecordOverlay_postProcess($table, $row, $sys_language_content, $OLmode, $this);
868 public function getMenu($pageId,
$fields =
'*', $sortField =
'sorting', $additionalWhereClause =
'', $checkShortcuts =
true)
886 public function getMenuForPages(array $pageIds,
$fields =
'*', $sortField =
'sorting', $additionalWhereClause =
'', $checkShortcuts =
true)
929 string $sortField =
'sorting',
930 string $additionalWhereClause =
'',
931 bool $checkShortcuts =
true,
932 bool $parentPages =
true
934 $relationField = $parentPages ?
'pid' :
'uid';
935 $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable(
'pages');
936 $queryBuilder->getRestrictions()->removeAll();
938 $res = $queryBuilder->select(...GeneralUtility::trimExplode(
',',
$fields,
true))
941 $queryBuilder->expr()->in(
943 $queryBuilder->createNamedParameter($pageIds, Connection::PARAM_INT_ARRAY)
945 $queryBuilder->expr()->eq(
946 $GLOBALS[
'TCA'][
'pages'][
'ctrl'][
'languageField'],
947 $queryBuilder->createNamedParameter(0, \PDO::PARAM_INT)
954 if (!empty($sortField)) {
956 foreach ($orderBy as $order) {
957 $res->addOrderBy($order[0], $order[1] ??
'ASC');
960 $result = $res->execute();
963 while ($page = $result->fetch()) {
964 $originalUid = $page[
'uid'];
978 if ($checkShortcuts) {
984 $pages[$originalUid] = $page;
1017 if (is_array($mountPointInfo) && $mountPointInfo[
'overlay']) {
1021 $mountPointPage = $this->
getPage($mountPointInfo[
'mount_pid']);
1023 if (!empty($mountPointPage)) {
1024 $page = $mountPointPage;
1025 $page[
'_MP_PARAM'] = $mountPointInfo[
'MPvar'];
1046 $dokType = (int)$page[
'doktype'];
1047 $shortcutMode = (int)$page[
'shortcut_mode'];
1049 if ($dokType === self::DOKTYPE_SHORTCUT && ($page[
'shortcut'] || $shortcutMode)) {
1050 if ($shortcutMode === self::SHORTCUT_MODE_NONE) {
1052 $searchField =
'uid';
1053 $searchUid = (int)$page[
'shortcut'];
1054 } elseif ($shortcutMode === self::SHORTCUT_MODE_FIRST_SUBPAGE || $shortcutMode === self::SHORTCUT_MODE_RANDOM_SUBPAGE) {
1056 $searchField =
'pid';
1059 $searchUid = (int)$page[
'shortcut'] ?: $page[
'uid'];
1060 } elseif ($shortcutMode === self::SHORTCUT_MODE_PARENT_PAGE) {
1062 $searchField =
'uid';
1063 $searchUid = $page[
'pid'];
1069 $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable(
'pages');
1070 $queryBuilder->getRestrictions()->removeAll();
1071 $count = $queryBuilder->count(
'uid')
1074 $queryBuilder->expr()->eq(
1076 $queryBuilder->createNamedParameter($searchUid, \PDO::PARAM_INT)
1088 } elseif ($dokType === self::DOKTYPE_SHORTCUT) {
1111 public function getPageShortcut($shortcutFieldValue, $shortcutMode, $thisUid, $iteration = 20, $pageLog = [], $disableGroupCheck =
false)
1113 $idArray = GeneralUtility::intExplode(
',', $shortcutFieldValue);
1115 switch ($shortcutMode) {
1118 $pageArray = $this->
getMenu($idArray[0] ?: $thisUid,
'*',
'sorting',
'AND pages.doktype<199 AND pages.doktype!=' . self::DOKTYPE_BE_USER_SECTION);
1120 if ($shortcutMode == self::SHORTCUT_MODE_RANDOM_SUBPAGE && !empty($pageArray)) {
1121 $pO = (int)rand(0, count($pageArray) - 1);
1125 foreach ($pageArray as $pV) {
1133 $message =
'This page (ID ' . $thisUid .
') is of type "Shortcut" and configured to redirect to a subpage. However, this page has no accessible subpages.';
1134 throw new ShortcutTargetPageNotFoundException($message, 1301648328);
1138 $parent = $this->
getPage($idArray[0] ?: $thisUid, $disableGroupCheck);
1139 $page = $this->
getPage($parent[
'pid'], $disableGroupCheck);
1141 $message =
'This page (ID ' . $thisUid .
') is of type "Shortcut" and configured to redirect to its parent page. However, the parent page is not accessible.';
1142 throw new ShortcutTargetPageNotFoundException($message, 1301648358);
1146 $page = $this->
getPage($idArray[0], $disableGroupCheck);
1148 $message =
'This page (ID ' . $thisUid .
') is of type "Shortcut" and configured to redirect to a page, which is not accessible (ID ' . $idArray[0] .
').';
1149 throw new ShortcutTargetPageNotFoundException($message, 1301648404);
1153 if ($page[
'doktype'] == self::DOKTYPE_SHORTCUT) {
1154 if (!in_array($page[
'uid'], $pageLog) && $iteration > 0) {
1155 $pageLog[] = $page[
'uid'];
1156 $page = $this->
getPageShortcut($page[
'shortcut'], $page[
'shortcut_mode'], $page[
'uid'], $iteration - 1, $pageLog, $disableGroupCheck);
1158 $pageLog[] = $page[
'uid'];
1159 $message =
'Page shortcuts were looping in uids ' . implode(
',', $pageLog) .
'...!';
1160 $this->logger->error($message);
1161 throw new \RuntimeException($message, 1294587212);
1180 trigger_error(
'This method will be removed in TYPO3 v10.0. As the SiteResolver middleware resolves the domain start page.', E_USER_DEPRECATED);
1181 $domain = explode(
':', $domain);
1182 $domain = strtolower(preg_replace(
'/\\.$/',
'', $domain[0]));
1184 $path = trim(preg_replace(
'/\\/[^\\/]*$/',
'', $path));
1187 $domain = preg_replace(
'/\\/*$/',
'', $domain);
1188 $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable(
'pages');
1189 $queryBuilder->getRestrictions()->removeAll();
1190 $row = $queryBuilder
1195 ->from(
'sys_domain')
1197 $queryBuilder->expr()->eq(
'pages.uid', $queryBuilder->quoteIdentifier(
'sys_domain.pid')),
1198 $queryBuilder->expr()->eq(
1199 'sys_domain.hidden',
1200 $queryBuilder->createNamedParameter(0, \PDO::PARAM_INT)
1202 $queryBuilder->expr()->orX(
1203 $queryBuilder->expr()->eq(
1204 'sys_domain.domainName',
1205 $queryBuilder->createNamedParameter($domain, \PDO::PARAM_STR)
1207 $queryBuilder->expr()->eq(
1208 'sys_domain.domainName',
1209 $queryBuilder->createNamedParameter($domain .
'/', \PDO::PARAM_STR)
1246 public function getRootLine($uid, $MP =
'', $ignoreMPerrors =
null)
1248 trigger_error(
'Calling PageRepository->getRootLine() will be removed in TYPO3 v10.0. Use RootlineUtility directly.', E_USER_DEPRECATED);
1249 $rootline = GeneralUtility::makeInstance(RootlineUtility::class, $uid, $MP, $this->context);
1251 return $rootline->get();
1252 }
catch (\RuntimeException $ex) {
1253 if ($ignoreMPerrors) {
1254 $this->error_getRootLine = $ex->getMessage();
1255 if (substr($this->error_getRootLine, -7) ===
'uid -1.') {
1256 $this->error_getRootLine_failPid = -1;
1260 if ($ex->getCode() === 1343589451) {
1277 if ((
int)$pagerow[
'doktype'] === self::DOKTYPE_LINK) {
1278 $redirectTo = $pagerow[
'url'];
1279 $uI = parse_url($redirectTo);
1282 if (!($uI[
'scheme'] ??
false)) {
1283 if (GeneralUtility::validEmail($redirectTo)) {
1284 $redirectTo =
'mailto:' . $redirectTo;
1285 } elseif ($redirectTo[0] !==
'/') {
1286 $redirectTo = GeneralUtility::getIndpEnv(
'TYPO3_SITE_URL') . $redirectTo;
1326 public function getMountPointInfo($pageId, $pageRec =
false, $prevMountPids = [], $firstPageUid = 0)
1328 if (!
$GLOBALS[
'TYPO3_CONF_VARS'][
'FE'][
'enable_mount_pids']) {
1331 $cacheIdentifier =
'PageRepository_getMountPointInfo_' . $pageId;
1333 if ($cache->has($cacheIdentifier)) {
1334 return $cache->get($cacheIdentifier);
1338 if (!is_array($pageRec)) {
1339 $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable(
'pages');
1340 $queryBuilder->getRestrictions()
1342 ->add(GeneralUtility::makeInstance(DeletedRestriction::class));
1344 $pageRec = $queryBuilder->select(
'uid',
'pid',
'doktype',
'mount_pid',
'mount_pid_ol',
't3ver_state')
1347 $queryBuilder->expr()->eq(
1349 $queryBuilder->createNamedParameter($pageId, \PDO::PARAM_INT)
1351 $queryBuilder->expr()->neq(
1353 $queryBuilder->createNamedParameter(255, \PDO::PARAM_INT)
1364 if (!$firstPageUid) {
1365 $firstPageUid = $pageRec[
'uid'];
1368 $mount_pid = (int)$pageRec[
'mount_pid'];
1369 if (is_array($pageRec) && (int)$pageRec[
'doktype'] === self::DOKTYPE_MOUNTPOINT && $mount_pid > 0 && !in_array($mount_pid, $prevMountPids,
true)) {
1371 $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable(
'pages');
1372 $queryBuilder->getRestrictions()
1374 ->add(GeneralUtility::makeInstance(DeletedRestriction::class));
1376 $mountRec = $queryBuilder->select(
'uid',
'pid',
'doktype',
'mount_pid',
'mount_pid_ol',
't3ver_state')
1379 $queryBuilder->expr()->eq(
1381 $queryBuilder->createNamedParameter($mount_pid, \PDO::PARAM_INT)
1383 $queryBuilder->expr()->neq(
1385 $queryBuilder->createNamedParameter(255, \PDO::PARAM_INT)
1392 if (is_array($mountRec)) {
1394 $prevMountPids[] = $mount_pid;
1395 $recursiveMountPid = $this->
getMountPointInfo($mount_pid, $mountRec, $prevMountPids, $firstPageUid);
1397 $result = $recursiveMountPid ?: [
1398 'mount_pid' => $mount_pid,
1399 'overlay' => $pageRec[
'mount_pid_ol'],
1400 'MPvar' => $mount_pid .
'-' . $firstPageUid,
1401 'mount_point_rec' => $pageRec,
1402 'mount_pid_rec' => $mountRec
1409 $cache->set($cacheIdentifier, $result);
1428 public function checkRecord($table, $uid, $checkPage = 0)
1431 if (is_array(
$GLOBALS[
'TCA'][$table]) && $uid > 0) {
1432 $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable($table);
1433 $queryBuilder->setRestrictions(GeneralUtility::makeInstance(FrontendRestrictionContainer::class, $this->context));
1434 $row = $queryBuilder->select(
'*')
1436 ->where($queryBuilder->expr()->eq(
'uid', $queryBuilder->createNamedParameter($uid, \PDO::PARAM_INT)))
1442 if (is_array($row)) {
1444 $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)
1445 ->getQueryBuilderForTable(
'pages');
1446 $queryBuilder->setRestrictions(GeneralUtility::makeInstance(FrontendRestrictionContainer::class, $this->context));
1447 $numRows = (int)$queryBuilder->count(
'*')
1450 $queryBuilder->expr()->eq(
1452 $queryBuilder->createNamedParameter($row[
'pid'], \PDO::PARAM_INT)
1482 if (isset(
$GLOBALS[
'TCA'][$table]) && is_array(
$GLOBALS[
'TCA'][$table]) && $uid > 0) {
1483 $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable($table);
1484 $queryBuilder->getRestrictions()
1486 ->add(GeneralUtility::makeInstance(DeletedRestriction::class));
1487 $row = $queryBuilder->select(...GeneralUtility::trimExplode(
',',
$fields,
true))
1489 ->where($queryBuilder->expr()->eq(
'uid', $queryBuilder->createNamedParameter($uid, \PDO::PARAM_INT)))
1494 if ($noWSOL !==
null) {
1495 trigger_error(
'The fourth parameter of PageRepository->getRawRecord() will be removed in TYPO3 v10.0. Use a SQL statement directly.', E_USER_DEPRECATED);
1501 if (is_array($row)) {
1522 public function getRecordsByField($theTable, $theField, $theValue, $whereClause =
'', $groupBy =
'', $orderBy =
'', $limit =
'')
1524 trigger_error(
'PageRepository->getRecordsByField() should not be used any longer, this method will be removed in TYPO3 v10.0.', E_USER_DEPRECATED);
1525 if (is_array(
$GLOBALS[
'TCA'][$theTable])) {
1526 $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable($theTable);
1527 $queryBuilder->getRestrictions()
1529 ->add(GeneralUtility::makeInstance(DeletedRestriction::class));
1531 $queryBuilder->select(
'*')
1533 ->where($queryBuilder->expr()->eq($theField, $queryBuilder->createNamedParameter($theValue)));
1535 if ($whereClause !==
'') {
1539 if ($groupBy !==
'') {
1543 if ($orderBy !==
'') {
1545 [$fieldName, $order] = $orderPair;
1546 $queryBuilder->addOrderBy($fieldName, $order);
1550 if ($limit !==
'') {
1551 if (strpos($limit,
',')) {
1552 $limitOffsetAndMax = GeneralUtility::intExplode(
',', $limit);
1553 $queryBuilder->setFirstResult((
int)$limitOffsetAndMax[0]);
1554 $queryBuilder->setMaxResults((
int)$limitOffsetAndMax[1]);
1556 $queryBuilder->setMaxResults((
int)$limit);
1560 $rows = $queryBuilder->execute()->fetchAll();
1562 if (!empty($rows)) {
1586 trigger_error(
'PageRepository->deleteClause() will be removed in TYPO3 v10.0. The delete clause can be applied via the DeletedRestrictions via QueryBuilder.', E_USER_DEPRECATED);
1587 return $GLOBALS[
'TCA'][$table][
'ctrl'][
'delete'] ?
' AND ' . $table .
'.' .
$GLOBALS[
'TCA'][$table][
'ctrl'][
'delete'] .
'=0' :
'';
1607 public function enableFields($table, $show_hidden = -1, $ignore_array = [], $noVersionPreview =
false)
1609 if ($show_hidden === -1) {
1611 $show_hidden = (int)$this->context->getPropertyFromAspect(
'visibility', $table ===
'pages' ?
'includeHiddenPages' :
'includeHiddenContent',
false);
1614 $ctrl =
$GLOBALS[
'TCA'][$table][
'ctrl'] ??
null;
1615 $expressionBuilder = GeneralUtility::makeInstance(ConnectionPool::class)
1616 ->getQueryBuilderForTable($table)
1619 if (is_array($ctrl)) {
1621 if ($ctrl[
'delete']) {
1622 $constraints[] = $expressionBuilder->eq($table .
'.' . $ctrl[
'delete'], 0);
1624 if ($ctrl[
'versioningWS'] ??
false) {
1625 if (!$this->versioningWorkspaceId > 0) {
1628 $constraints[] = $expressionBuilder->lte(
1629 $table .
'.t3ver_state',
1632 } elseif ($table !==
'pages') {
1635 $constraints[] = $expressionBuilder->orX(
1636 $expressionBuilder->eq($table .
'.t3ver_wsid', 0),
1637 $expressionBuilder->eq($table .
'.t3ver_wsid', (
int)$this->versioningWorkspaceId)
1642 if (!$noVersionPreview && empty($ignore_array[
'pid'])) {
1643 $constraints[] = $expressionBuilder->neq($table .
'.pid', -1);
1648 if (is_array($ctrl[
'enablecolumns'])) {
1651 if ($this->versioningWorkspaceId <= 0 || !$ctrl[
'versioningWS'] || $noVersionPreview) {
1652 if (($ctrl[
'enablecolumns'][
'disabled'] ??
false) && !$show_hidden && !($ignore_array[
'disabled'] ??
false)) {
1653 $field = $table .
'.' . $ctrl[
'enablecolumns'][
'disabled'];
1654 $constraints[] = $expressionBuilder->eq($field, 0);
1656 if (($ctrl[
'enablecolumns'][
'starttime'] ??
false) && !($ignore_array[
'starttime'] ??
false)) {
1657 $field = $table .
'.' . $ctrl[
'enablecolumns'][
'starttime'];
1658 $constraints[] = $expressionBuilder->lte(
1660 $this->context->getPropertyFromAspect(
'date',
'accessTime', 0)
1663 if (($ctrl[
'enablecolumns'][
'endtime'] ??
false) && !($ignore_array[
'endtime'] ??
false)) {
1664 $field = $table .
'.' . $ctrl[
'enablecolumns'][
'endtime'];
1665 $constraints[] = $expressionBuilder->orX(
1666 $expressionBuilder->eq($field, 0),
1667 $expressionBuilder->gt(
1669 $this->context->getPropertyFromAspect(
'date',
'accessTime', 0)
1673 if (($ctrl[
'enablecolumns'][
'fe_group'] ??
false) && !($ignore_array[
'fe_group'] ??
false)) {
1674 $field = $table .
'.' . $ctrl[
'enablecolumns'][
'fe_group'];
1684 'show_hidden' => $show_hidden,
1685 'ignore_array' => $ignore_array,
1688 foreach (
$GLOBALS[
'TYPO3_CONF_VARS'][
'SC_OPTIONS'][
't3lib/class.t3lib_page.php'][
'addEnableColumns'] ?? [] as $_funcRef) {
1690 GeneralUtility::callUserFunction($_funcRef, $_params, $this)
1696 throw new \InvalidArgumentException(
'There is no entry in the $TCA array for the table "' . $table .
'". This means that the function enableFields() is ' .
'called with an invalid table name as argument.', 1283790586);
1699 return empty($constraints) ?
'' :
' AND ' . $expressionBuilder->andX(...$constraints);
1713 if (!$this->context->hasAspect(
'frontend.user')) {
1717 $userAspect = $this->context->getAspect(
'frontend.user');
1718 $memberGroups = $userAspect->getGroupIds();
1720 $cacheIdentifier =
'PageRepository_groupAccessWhere_' . md5($field .
'_' . $table .
'_' . implode(
'_', $memberGroups));
1721 $cacheEntry = $cache->get($cacheIdentifier);
1725 $expressionBuilder = GeneralUtility::makeInstance(ConnectionPool::class)
1726 ->getQueryBuilderForTable($table)
1730 $orChecks[] = $expressionBuilder->eq($field, $expressionBuilder->literal(
''));
1732 $orChecks[] = $expressionBuilder->isNull($field);
1734 $orChecks[] = $expressionBuilder->eq($field, $expressionBuilder->literal(
'0'));
1735 foreach ($memberGroups as $value) {
1736 $orChecks[] = $expressionBuilder->inSet($field, $expressionBuilder->literal($value));
1739 $accessGroupWhere =
' AND (' . $expressionBuilder->orX(...$orChecks) .
')';
1740 $cache->set($cacheIdentifier, $accessGroupWhere);
1741 return $accessGroupWhere;
1770 if ($this->versioningWorkspaceId > 0 && is_array($rr) && (
int)$rr[
'pid'] === -1 &&
$GLOBALS[
'TCA'][$table][
'ctrl'][
'versioningWS']) {
1774 if (isset($rr[
't3ver_oid']) && isset($rr[
't3ver_wsid'])) {
1776 $oid = $rr[
't3ver_oid'];
1777 $wsid = $rr[
't3ver_wsid'];
1781 $uid = (int)$rr[
'uid'];
1783 $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable($table);
1784 $queryBuilder->getRestrictions()
1786 ->add(GeneralUtility::makeInstance(DeletedRestriction::class));
1787 $newPidRec = $queryBuilder->select(
't3ver_oid',
't3ver_wsid')
1789 ->where($queryBuilder->expr()->eq(
'uid', $queryBuilder->createNamedParameter($uid, \PDO::PARAM_INT)))
1793 if (is_array($newPidRec)) {
1794 $oid = $newPidRec[
't3ver_oid'];
1795 $wsid = $newPidRec[
't3ver_wsid'];
1801 if ($oid && (
int)$wsid === (
int)$this->versioningWorkspaceId) {
1802 $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable($table);
1803 $queryBuilder->getRestrictions()
1805 ->add(GeneralUtility::makeInstance(DeletedRestriction::class));
1806 $oidRec = $queryBuilder->select(
'pid')
1808 ->where($queryBuilder->expr()->eq(
'uid', $queryBuilder->createNamedParameter($oid, \PDO::PARAM_INT)))
1812 if (is_array($oidRec)) {
1818 $rr[
'_ORIG_pid'] = $rr[
'pid'];
1819 $rr[
'pid'] = $oidRec[
'pid'];
1825 $rr[
'pid'] = $movePlhRec[
'pid'];
1848 public function versionOL($table, &$row, $unsetMovePointers =
false, $bypassEnableFieldsCheck =
false)
1850 if ($this->versioningWorkspaceId > 0 && is_array($row)) {
1853 $movePldSwap = $this->
movePlhOL($table, $row);
1858 if ($wsAlt = $this->
getWorkspaceVersionOfRecord($this->versioningWorkspaceId, $table, $row[
'uid'], $fieldNames, $bypassEnableFieldsCheck)) {
1859 if (is_array($wsAlt)) {
1863 $wsAlt[
'_ORIG_pid'] = $wsAlt[
'pid'];
1865 $wsAlt[
'pid'] = $row[
'pid'];
1869 $wsAlt[
'_ORIG_uid'] = $wsAlt[
'uid'];
1870 $wsAlt[
'uid'] = $row[
'uid'];
1872 if ($table ===
'pages') {
1873 $wsAlt[
'alias'] = $row[
'alias'];
1894 ) && $unsetMovePointers
1907 if ($wsAlt <= -1 || $versionState->indicatesPlaceholder()) {
1928 if (!empty(
$GLOBALS[
'TCA'][$table][
'ctrl'][
'versioningWS'])
1933 if (!isset($row[
't3ver_move_id'])) {
1934 if ((
int)$row[
'uid'] > 0) {
1935 $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable($table);
1936 $queryBuilder->getRestrictions()
1938 ->add(GeneralUtility::makeInstance(DeletedRestriction::class));
1939 $moveIDRec = $queryBuilder->select(
't3ver_move_id')
1941 ->where($queryBuilder->expr()->eq(
'uid', $queryBuilder->createNamedParameter($row[
'uid'], \PDO::PARAM_INT)))
1945 if (is_array($moveIDRec)) {
1946 $moveID = $moveIDRec[
't3ver_move_id'];
1950 $moveID = $row[
't3ver_move_id'];
1954 $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable($table);
1955 $queryBuilder->setRestrictions(GeneralUtility::makeInstance(FrontendRestrictionContainer::class, $this->context));
1956 $queryBuilder->getRestrictions()->removeByType(HiddenRestriction::class);
1960 $queryBuilder->expr()->eq(
1962 $queryBuilder->createNamedParameter($moveID, \PDO::PARAM_INT)
1989 $workspace = (int)$this->versioningWorkspaceId;
1990 if (!empty(
$GLOBALS[
'TCA'][$table][
'ctrl'][
'versioningWS']) && $workspace > 0) {
1992 $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable($table);
1993 $queryBuilder->getRestrictions()
1995 ->add(GeneralUtility::makeInstance(DeletedRestriction::class));
1997 $row = $queryBuilder->select(...GeneralUtility::trimExplode(
',',
$fields,
true))
2000 $queryBuilder->expr()->neq(
'pid', $queryBuilder->createNamedParameter(-1, \PDO::PARAM_INT)),
2001 $queryBuilder->expr()->eq(
2003 $queryBuilder->createNamedParameter(
2008 $queryBuilder->expr()->eq(
2010 $queryBuilder->createNamedParameter($uid, \PDO::PARAM_INT)
2012 $queryBuilder->expr()->eq(
2014 $queryBuilder->createNamedParameter($workspace, \PDO::PARAM_INT)
2021 if (is_array($row)) {
2041 if ($workspace !== 0 && !empty(
$GLOBALS[
'TCA'][$table][
'ctrl'][
'versioningWS'])) {
2042 $workspace = (int)$workspace;
2045 $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable($table);
2046 $queryBuilder->getRestrictions()
2048 ->add(GeneralUtility::makeInstance(DeletedRestriction::class));
2050 $newrow = $queryBuilder->select(...GeneralUtility::trimExplode(
',',
$fields,
true))
2053 $queryBuilder->expr()->eq(
'pid', $queryBuilder->createNamedParameter(-1, \PDO::PARAM_INT)),
2054 $queryBuilder->expr()->eq(
2056 $queryBuilder->createNamedParameter($uid, \PDO::PARAM_INT)
2058 $queryBuilder->expr()->eq(
2060 $queryBuilder->createNamedParameter($workspace, \PDO::PARAM_INT)
2069 $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable($table);
2070 $queryBuilder->setRestrictions(GeneralUtility::makeInstance(FrontendRestrictionContainer::class, $this->context));
2072 $queryBuilder->getRestrictions()->removeByType(FrontendWorkspaceRestriction::class);
2073 $queryBuilder->select(
'uid')
2077 if (is_array($newrow)) {
2078 $queryBuilder->where(
2079 $queryBuilder->expr()->eq(
'pid', $queryBuilder->createNamedParameter(-1, \PDO::PARAM_INT)),
2080 $queryBuilder->expr()->eq(
2082 $queryBuilder->createNamedParameter($uid, \PDO::PARAM_INT)
2084 $queryBuilder->expr()->eq(
2086 $queryBuilder->createNamedParameter($workspace, \PDO::PARAM_INT)
2089 if ($bypassEnableFieldsCheck || $queryBuilder->execute()->fetchColumn()) {
2098 $queryBuilder->where(
2099 $queryBuilder->expr()->eq(
'uid', $queryBuilder->createNamedParameter($uid, \PDO::PARAM_INT))
2101 if ($bypassEnableFieldsCheck || $queryBuilder->execute()->fetchColumn()) {
2122 trigger_error(
'PageRepository->checkWorkspaceAccess() will be removed in TYPO3 v10.0.', E_USER_DEPRECATED);
2126 if (!isset($this->workspaceCache[$wsid])) {
2127 $this->workspaceCache[$wsid] = $this->
getBackendUser()->checkWorkspace($wsid);
2129 return (
string)$this->workspaceCache[$wsid][
'_ACCESS'] !==
'';
2143 trigger_error(
'PageRepository->getFileReferences() should not be used any longer, this method will be removed in TYPO3 v10.0.', E_USER_DEPRECATED);
2145 $fileRepository = GeneralUtility::makeInstance(FileRepository::class);
2146 $currentId = !empty($element[
'uid']) ? $element[
'uid'] : 0;
2150 $references = $fileRepository->findByRelation($tableName, $fieldName, $currentId);
2151 }
catch (FileDoesNotExistException $e) {
2157 }
catch (\InvalidArgumentException $e) {
2162 $logMessage = $e->getMessage() .
' (table: "' . $tableName .
'", fieldName: "' . $fieldName .
'", currentId: ' . $currentId .
')';
2163 $this->logger->error($logMessage, [
'exception' => $e]);
2167 $localizedId =
null;
2168 if (isset($element[
'_LOCALIZED_UID'])) {
2169 $localizedId = $element[
'_LOCALIZED_UID'];
2170 } elseif (isset($element[
'_PAGES_OVERLAY_UID'])) {
2171 $localizedId = $element[
'_PAGES_OVERLAY_UID'];
2174 $isTableLocalizable = (
2175 !empty(
$GLOBALS[
'TCA'][$tableName][
'ctrl'][
'languageField'])
2176 && !empty(
$GLOBALS[
'TCA'][$tableName][
'ctrl'][
'transOrigPointerField'])
2178 if ($isTableLocalizable && $localizedId !==
null) {
2179 $localizedReferences = $fileRepository->findByRelation($tableName, $fieldName, $localizedId);
2180 $references = $localizedReferences;
2195 foreach ($this->computedPropertyNames as $computedPropertyName) {
2196 if (array_key_exists($computedPropertyName, $row)) {
2197 unset($row[$computedPropertyName]);
2219 return GeneralUtility::makeInstance(CacheManager::class)->getCache(
'cache_runtime');