From 6e2eb2933bae36dbf76360ca46aa93263f226c54 Mon Sep 17 00:00:00 2001 From: Benni Mack <benni@typo3.org> Date: Fri, 13 Jul 2018 20:53:44 +0200 Subject: [PATCH] [TASK] Use RootlineUtility directly Instead of calling PageRepository to fetch the rootline, RootlineUtility can do that now directly. However, all exceptions are more specific and caught specifically, for each use-case. Additionally, PageRepository->getRootline() is deprecated now. For this reason, the deprecation for the argument $ignoreMPerrors is removed again, as it does not make sense anymore. Resolves: #85557 Releases: master Change-Id: I5a9192311c5616f5a58e89a39c3869b593e97968 Reviewed-on: https://review.typo3.org/57590 Tested-by: TYPO3com <no-reply@typo3.com> Reviewed-by: Andreas Fernandez <a.fernandez@scripting-base.de> Tested-by: Andreas Fernandez <a.fernandez@scripting-base.de> Reviewed-by: Anja Leichsenring <aleichsenring@ab-softlab.de> Tested-by: Anja Leichsenring <aleichsenring@ab-softlab.de> Reviewed-by: Benni Mack <benni@typo3.org> Tested-by: Benni Mack <benni@typo3.org> --- .../Controller/Page/TreeController.php | 10 ++- .../Page/BrokenRootLineException.php | 24 ++++++ .../Page/CircularRootLineException.php | 24 ++++++ .../Exception/Page/MountPointException.php | 24 ++++++ .../Page/MountPointsDisabledException.php | 25 ++++++ .../Exception/Page/PageNotFoundException.php | 24 ++++++ .../PagePropertyRelationNotFoundException.php | 24 ++++++ .../Exception/Page/RootLineException.php | 25 ++++++ .../core/Classes/Utility/RootlineUtility.php | 27 ++++--- ...odArgumentInPageRepository-getRootLine.rst | 37 --------- ...ation-85557-PageRepository-getRootLine.rst | 34 ++++++++ .../TypoScriptFrontendController.php | 68 ++++++++++------ .../frontend/Classes/Page/PageRepository.php | 7 +- .../Classes/Typolink/PageLinkBuilder.php | 6 +- .../ContentObjectRendererTest.php | 22 +++--- .../Classes/Controller/SearchController.php | 78 ++++++++++--------- .../Classes/Hook/CrawlerHook.php | 27 ++++--- .../Php/MethodArgumentDroppedMatcher.php | 6 -- .../Php/MethodCallMatcher.php | 7 ++ .../IRRE/CSV/Modify/ActionTest.php | 2 +- .../IRRE/ForeignField/Modify/ActionTest.php | 2 +- .../Regular/Modify/ActionTest.php | 4 +- 22 files changed, 358 insertions(+), 149 deletions(-) create mode 100644 typo3/sysext/core/Classes/Exception/Page/BrokenRootLineException.php create mode 100644 typo3/sysext/core/Classes/Exception/Page/CircularRootLineException.php create mode 100644 typo3/sysext/core/Classes/Exception/Page/MountPointException.php create mode 100644 typo3/sysext/core/Classes/Exception/Page/MountPointsDisabledException.php create mode 100644 typo3/sysext/core/Classes/Exception/Page/PageNotFoundException.php create mode 100644 typo3/sysext/core/Classes/Exception/Page/PagePropertyRelationNotFoundException.php create mode 100644 typo3/sysext/core/Classes/Exception/Page/RootLineException.php delete mode 100644 typo3/sysext/core/Documentation/Changelog/9.3/Deprecation-85105-3rdMethodArgumentInPageRepository-getRootLine.rst create mode 100644 typo3/sysext/core/Documentation/Changelog/master/Deprecation-85557-PageRepository-getRootLine.rst diff --git a/typo3/sysext/backend/Classes/Controller/Page/TreeController.php b/typo3/sysext/backend/Classes/Controller/Page/TreeController.php index 7ddda5d99049..0892c64c4096 100644 --- a/typo3/sysext/backend/Classes/Controller/Page/TreeController.php +++ b/typo3/sysext/backend/Classes/Controller/Page/TreeController.php @@ -22,6 +22,7 @@ use TYPO3\CMS\Backend\Tree\Repository\PageTreeRepository; use TYPO3\CMS\Backend\Utility\BackendUtility; use TYPO3\CMS\Core\Authentication\BackendUserAuthentication; use TYPO3\CMS\Core\Database\ConnectionPool; +use TYPO3\CMS\Core\Exception\Page\RootLineException; use TYPO3\CMS\Core\Http\JsonResponse; use TYPO3\CMS\Core\Imaging\Icon; use TYPO3\CMS\Core\Imaging\IconFactory; @@ -29,7 +30,7 @@ use TYPO3\CMS\Core\Type\Bitmask\JsConfirmation; use TYPO3\CMS\Core\Type\Bitmask\Permission; use TYPO3\CMS\Core\Utility\ExtensionManagementUtility; use TYPO3\CMS\Core\Utility\GeneralUtility; -use TYPO3\CMS\Frontend\Page\PageRepository; +use TYPO3\CMS\Core\Utility\RootlineUtility; use TYPO3\CMS\Workspaces\Service\WorkspaceService; /** @@ -327,7 +328,6 @@ class TreeController { $backendUser = $this->getBackendUser(); $repository = GeneralUtility::makeInstance(PageTreeRepository::class, (int)$backendUser->workspace); - $pageRepository = GeneralUtility::makeInstance(PageRepository::class); $entryPoints = (int)($backendUser->uc['pageTree_temporaryMountPoint'] ?? 0); if ($entryPoints > 0) { @@ -353,7 +353,11 @@ class TreeController } if (!empty($this->backgroundColors) && is_array($this->backgroundColors)) { - $entryPointRootLine = $pageRepository->getRootLine($entryPoint); + try { + $entryPointRootLine = GeneralUtility::makeInstance(RootlineUtility::class, $entryPoint)->get(); + } catch (RootLineException $e) { + $entryPointRootLine = []; + } foreach ($entryPointRootLine as $rootLineEntry) { $parentUid = $rootLineEntry['uid']; if (!empty($this->backgroundColors[$parentUid]) && empty($this->backgroundColors[$entryPoint])) { diff --git a/typo3/sysext/core/Classes/Exception/Page/BrokenRootLineException.php b/typo3/sysext/core/Classes/Exception/Page/BrokenRootLineException.php new file mode 100644 index 000000000000..260a3cea7d06 --- /dev/null +++ b/typo3/sysext/core/Classes/Exception/Page/BrokenRootLineException.php @@ -0,0 +1,24 @@ +<?php +declare(strict_types = 1); + +namespace TYPO3\CMS\Core\Exception\Page; + +/* + * This file is part of the TYPO3 CMS project. + * + * It is free software; you can redistribute it and/or modify it under + * the terms of the GNU General Public License, either version 2 + * of the License, or any later version. + * + * For the full copyright and license information, please read the + * LICENSE.txt file that was distributed with this source code. + * + * The TYPO3 project - inspiring people to share! + */ + +/** + * Exception for root line traversal when a page within the root line traversal is missing / can not be resolved + */ +class BrokenRootLineException extends RootLineException +{ +} diff --git a/typo3/sysext/core/Classes/Exception/Page/CircularRootLineException.php b/typo3/sysext/core/Classes/Exception/Page/CircularRootLineException.php new file mode 100644 index 000000000000..afdc546236c4 --- /dev/null +++ b/typo3/sysext/core/Classes/Exception/Page/CircularRootLineException.php @@ -0,0 +1,24 @@ +<?php +declare(strict_types = 1); + +namespace TYPO3\CMS\Core\Exception\Page; + +/* + * This file is part of the TYPO3 CMS project. + * + * It is free software; you can redistribute it and/or modify it under + * the terms of the GNU General Public License, either version 2 + * of the License, or any later version. + * + * For the full copyright and license information, please read the + * LICENSE.txt file that was distributed with this source code. + * + * The TYPO3 project - inspiring people to share! + */ + +/** + * Exception for root line traversal when a loop is detected + */ +class CircularRootLineException extends RootLineException +{ +} diff --git a/typo3/sysext/core/Classes/Exception/Page/MountPointException.php b/typo3/sysext/core/Classes/Exception/Page/MountPointException.php new file mode 100644 index 000000000000..7913d99dce08 --- /dev/null +++ b/typo3/sysext/core/Classes/Exception/Page/MountPointException.php @@ -0,0 +1,24 @@ +<?php +declare(strict_types = 1); + +namespace TYPO3\CMS\Core\Exception\Page; + +/* + * This file is part of the TYPO3 CMS project. + * + * It is free software; you can redistribute it and/or modify it under + * the terms of the GNU General Public License, either version 2 + * of the License, or any later version. + * + * For the full copyright and license information, please read the + * LICENSE.txt file that was distributed with this source code. + * + * The TYPO3 project - inspiring people to share! + */ + +/** + * Exception thrown if a mount point is used + */ +class MountPointException extends RootLineException +{ +} diff --git a/typo3/sysext/core/Classes/Exception/Page/MountPointsDisabledException.php b/typo3/sysext/core/Classes/Exception/Page/MountPointsDisabledException.php new file mode 100644 index 000000000000..3faad95721e2 --- /dev/null +++ b/typo3/sysext/core/Classes/Exception/Page/MountPointsDisabledException.php @@ -0,0 +1,25 @@ +<?php +declare(strict_types = 1); + +namespace TYPO3\CMS\Core\Exception\Page; + +/* + * This file is part of the TYPO3 CMS project. + * + * It is free software; you can redistribute it and/or modify it under + * the terms of the GNU General Public License, either version 2 + * of the License, or any later version. + * + * For the full copyright and license information, please read the + * LICENSE.txt file that was distributed with this source code. + * + * The TYPO3 project - inspiring people to share! + */ + +/** + * Exception thrown if a mount point is used but disabled via + * "$GLOBALS['TYPO3_CONF_VARS']['FE']['enable_mount_pids']" + */ +class MountPointsDisabledException extends MountPointException +{ +} diff --git a/typo3/sysext/core/Classes/Exception/Page/PageNotFoundException.php b/typo3/sysext/core/Classes/Exception/Page/PageNotFoundException.php new file mode 100644 index 000000000000..92194311ec41 --- /dev/null +++ b/typo3/sysext/core/Classes/Exception/Page/PageNotFoundException.php @@ -0,0 +1,24 @@ +<?php +declare(strict_types = 1); + +namespace TYPO3\CMS\Core\Exception\Page; + +/* + * This file is part of the TYPO3 CMS project. + * + * It is free software; you can redistribute it and/or modify it under + * the terms of the GNU General Public License, either version 2 + * of the License, or any later version. + * + * For the full copyright and license information, please read the + * LICENSE.txt file that was distributed with this source code. + * + * The TYPO3 project - inspiring people to share! + */ + +/** + * Exception thrown if a page can not be fetched from the DB + */ +class PageNotFoundException extends RootLineException +{ +} diff --git a/typo3/sysext/core/Classes/Exception/Page/PagePropertyRelationNotFoundException.php b/typo3/sysext/core/Classes/Exception/Page/PagePropertyRelationNotFoundException.php new file mode 100644 index 000000000000..53578a06e8be --- /dev/null +++ b/typo3/sysext/core/Classes/Exception/Page/PagePropertyRelationNotFoundException.php @@ -0,0 +1,24 @@ +<?php +declare(strict_types = 1); + +namespace TYPO3\CMS\Core\Exception\Page; + +/* + * This file is part of the TYPO3 CMS project. + * + * It is free software; you can redistribute it and/or modify it under + * the terms of the GNU General Public License, either version 2 + * of the License, or any later version. + * + * For the full copyright and license information, please read the + * LICENSE.txt file that was distributed with this source code. + * + * The TYPO3 project - inspiring people to share! + */ + +/** + * Exception thrown if a page property relation can not be fetched from the DB + */ +class PagePropertyRelationNotFoundException extends \RuntimeException +{ +} diff --git a/typo3/sysext/core/Classes/Exception/Page/RootLineException.php b/typo3/sysext/core/Classes/Exception/Page/RootLineException.php new file mode 100644 index 000000000000..512b36b6d605 --- /dev/null +++ b/typo3/sysext/core/Classes/Exception/Page/RootLineException.php @@ -0,0 +1,25 @@ +<?php +declare(strict_types = 1); + +namespace TYPO3\CMS\Core\Exception\Page; + +/* + * This file is part of the TYPO3 CMS project. + * + * It is free software; you can redistribute it and/or modify it under + * the terms of the GNU General Public License, either version 2 + * of the License, or any later version. + * + * For the full copyright and license information, please read the + * LICENSE.txt file that was distributed with this source code. + * + * The TYPO3 project - inspiring people to share! + */ + +/** + * Base exception for root line traversal. This extends from RuntimeException for historical reasons + * and bw compatibility + */ +class RootLineException extends \RuntimeException +{ +} diff --git a/typo3/sysext/core/Classes/Utility/RootlineUtility.php b/typo3/sysext/core/Classes/Utility/RootlineUtility.php index bf5d704d9768..b941273fe076 100644 --- a/typo3/sysext/core/Classes/Utility/RootlineUtility.php +++ b/typo3/sysext/core/Classes/Utility/RootlineUtility.php @@ -19,6 +19,11 @@ use TYPO3\CMS\Core\Context\Context; use TYPO3\CMS\Core\Database\ConnectionPool; use TYPO3\CMS\Core\Database\Query\Restriction\DeletedRestriction; use TYPO3\CMS\Core\Database\Query\Restriction\HiddenRestriction; +use TYPO3\CMS\Core\Exception\Page\BrokenRootLineException; +use TYPO3\CMS\Core\Exception\Page\CircularRootLineException; +use TYPO3\CMS\Core\Exception\Page\MountPointsDisabledException; +use TYPO3\CMS\Core\Exception\Page\PageNotFoundException; +use TYPO3\CMS\Core\Exception\Page\PagePropertyRelationNotFoundException; use TYPO3\CMS\Frontend\Page\PageRepository; /** @@ -120,7 +125,7 @@ class RootlineUtility * @param int $uid * @param string $mountPointParameter * @param PageRepository|Context $context - @deprecated PageRepository is used until TYPO3 v9.4, but now the third parameter should be a Context object - * @throws \RuntimeException + * @throws MountPointsDisabledException */ public function __construct($uid, $mountPointParameter = '', $context = null) { @@ -142,7 +147,7 @@ class RootlineUtility $this->workspaceUid = $this->context->getPropertyFromAspect('workspace', 'id', 0); if ($this->mountPointParameter !== '') { if (!$GLOBALS['TYPO3_CONF_VARS']['FE']['enable_mount_pids']) { - throw new \RuntimeException('Mount-Point Pages are disabled for this installation. Cannot resolve a Rootline for a page with Mount-Points', 1343462896); + throw new MountPointsDisabledException('Mount-Point Pages are disabled for this installation. Cannot resolve a Rootline for a page with Mount-Points', 1343462896); } $this->parseMountPointParameter(); } @@ -225,7 +230,7 @@ class RootlineUtility * Queries the database for the page record and returns it. * * @param int $uid Page id - * @throws \RuntimeException + * @throws PageNotFoundException * @return array */ protected function getRecordArray($uid) @@ -246,7 +251,7 @@ class RootlineUtility ->execute() ->fetch(); if (empty($row)) { - throw new \RuntimeException('Could not fetch page data for uid ' . $uid . '.', 1343589451); + throw new PageNotFoundException('Could not fetch page data for uid ' . $uid . '.', 1343589451); } $this->pageContext->versionOL('pages', $row, false, true); $this->pageContext->fixVersioningPid('pages', $row); @@ -259,7 +264,7 @@ class RootlineUtility } } if (!is_array(self::$pageRecordCache[$currentCacheIdentifier])) { - throw new \RuntimeException('Broken rootline. Could not resolve page with uid ' . $uid . '.', 1343464101); + throw new PageNotFoundException('Broken rootline. Could not resolve page with uid ' . $uid . '.', 1343464101); } return self::$pageRecordCache[$currentCacheIdentifier]; } @@ -269,7 +274,7 @@ class RootlineUtility * * @param int $uid page ID * @param array $pageRecord Page record (possibly overlaid) to be extended with relations - * @throws \RuntimeException + * @throws PagePropertyRelationNotFoundException * @return array $pageRecord with additional relations */ protected function enrichWithRelationFields($uid, array $pageRecord) @@ -341,7 +346,7 @@ class RootlineUtility try { $statement = $queryBuilder->execute(); } catch (DBALException $e) { - throw new \RuntimeException('Could to resolve related records for page ' . $uid . ' and foreign_table ' . htmlspecialchars($table), 1343589452); + throw new PagePropertyRelationNotFoundException('Could to resolve related records for page ' . $uid . ' and foreign_table ' . htmlspecialchars($table), 1343589452); } $relatedUids = []; while ($row = $statement->fetch()) { @@ -376,7 +381,7 @@ class RootlineUtility /** * Actual function to generate the rootline and cache it * - * @throws \RuntimeException + * @throws CircularRootLineException */ protected function generateRootlineCache() { @@ -400,7 +405,7 @@ class RootlineUtility foreach ($rootline as $entry) { $cacheTags[] = 'pageId_' . $entry['uid']; if ($entry['uid'] == $this->pageUid) { - throw new \RuntimeException('Circular connection in rootline for page with uid ' . $this->pageUid . ' found. Check your mountpoint configuration.', 1343464103); + throw new CircularRootLineException('Circular connection in rootline for page with uid ' . $this->pageUid . ' found. Check your mountpoint configuration.', 1343464103); } } } else { @@ -428,7 +433,7 @@ class RootlineUtility * * @param array $mountedPageData page record array of mounted page * @param array $mountPointPageData page record array of mount point page - * @throws \RuntimeException + * @throws BrokenRootLineException * @return array */ protected function processMountedPage(array $mountedPageData, array $mountPointPageData) @@ -436,7 +441,7 @@ class RootlineUtility $mountPid = $mountPointPageData['mount_pid'] ?? null; $uid = $mountedPageData['uid'] ?? null; if ($mountPid != $uid) { - throw new \RuntimeException('Broken rootline. Mountpoint parameter does not match the actual rootline. mount_pid (' . $mountPid . ') does not match page uid (' . $uid . ').', 1343464100); + throw new BrokenRootLineException('Broken rootline. Mountpoint parameter does not match the actual rootline. mount_pid (' . $mountPid . ') does not match page uid (' . $uid . ').', 1343464100); } // Current page replaces the original mount-page $mountUid = $mountPointPageData['uid'] ?? null; diff --git a/typo3/sysext/core/Documentation/Changelog/9.3/Deprecation-85105-3rdMethodArgumentInPageRepository-getRootLine.rst b/typo3/sysext/core/Documentation/Changelog/9.3/Deprecation-85105-3rdMethodArgumentInPageRepository-getRootLine.rst deleted file mode 100644 index 4945035de438..000000000000 --- a/typo3/sysext/core/Documentation/Changelog/9.3/Deprecation-85105-3rdMethodArgumentInPageRepository-getRootLine.rst +++ /dev/null @@ -1,37 +0,0 @@ -.. include:: ../../Includes.txt - -========================================================================== -Deprecation: #85105 - 3rd method argument in PageRepository->getRootLine() -========================================================================== - -See :issue:`85105` - -Description -=========== - -The third argument of :php:`TYPO3\CMS\Frontend\Page\PageRepository->getRootLine()` has been marked -as deprecated. - -That argument was mainly used to catch exceptions when a faulty rootline is found. The PageRepository -currently handles the exceptions in a special way with some special magic. However, it is more -feasible to always throw an exception and have the caller handle possible exceptions. - - -Impact -====== - -Calling the method with three arguments will trigger a PHP :php:`E_USER_DEPRECATED` error. - - -Affected Installations -====================== - -TYPO3 installations with extensions calling the method directly with the 3rd argument. - - -Migration -========= - -Remove the third argument from code in PHP and wrap a try/catch block around the method call. - -.. index:: Frontend, PHP-API, FullyScanned \ No newline at end of file diff --git a/typo3/sysext/core/Documentation/Changelog/master/Deprecation-85557-PageRepository-getRootLine.rst b/typo3/sysext/core/Documentation/Changelog/master/Deprecation-85557-PageRepository-getRootLine.rst new file mode 100644 index 000000000000..2495143c60ad --- /dev/null +++ b/typo3/sysext/core/Documentation/Changelog/master/Deprecation-85557-PageRepository-getRootLine.rst @@ -0,0 +1,34 @@ +.. include:: ../../Includes.txt + +================================================= +Deprecation: #85557 - PageRepository->getRootLine +================================================= + +See :issue:`85557` + +Description +=========== + +The public method :php:`TYPO3\CMS\Frontend\Page\PageRepository->getRootLine` has been marked as +deprecated. + + +Impact +====== + +Calling the method directly will trigger a deprecation message. + + +Affected Installations +====================== + +TYPO3 installations with custom extensions calling this method directly. + + +Migration +========= + +As `getRootLine()` acts as a simple wrapper around `RootlineUtility`, it is recommended to instantiate +the RootLineUtility directly and catch any specific exceptions directly. + +.. index:: Frontend, PHP-API, FullyScanned, ext:frontend \ No newline at end of file diff --git a/typo3/sysext/frontend/Classes/Controller/TypoScriptFrontendController.php b/typo3/sysext/frontend/Classes/Controller/TypoScriptFrontendController.php index 30340ca9569a..0bb14d099126 100644 --- a/typo3/sysext/frontend/Classes/Controller/TypoScriptFrontendController.php +++ b/typo3/sysext/frontend/Classes/Controller/TypoScriptFrontendController.php @@ -41,6 +41,7 @@ use TYPO3\CMS\Core\Database\Query\Restriction\StartTimeRestriction; use TYPO3\CMS\Core\Error\Http\PageNotFoundException; use TYPO3\CMS\Core\Error\Http\ServiceUnavailableException; use TYPO3\CMS\Core\Error\Http\ShortcutTargetPageNotFoundException; +use TYPO3\CMS\Core\Exception\Page\RootLineException; use TYPO3\CMS\Core\Localization\LanguageService; use TYPO3\CMS\Core\Locking\Exception\LockAcquireWouldBlockException; use TYPO3\CMS\Core\Locking\LockFactory; @@ -60,6 +61,7 @@ use TYPO3\CMS\Core\Utility\GeneralUtility; use TYPO3\CMS\Core\Utility\HttpUtility; use TYPO3\CMS\Core\Utility\MathUtility; use TYPO3\CMS\Core\Utility\PathUtility; +use TYPO3\CMS\Core\Utility\RootlineUtility; use TYPO3\CMS\Frontend\Authentication\FrontendUserAuthentication; use TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer; use TYPO3\CMS\Frontend\Http\UrlHandlerInterface; @@ -1479,20 +1481,24 @@ class TypoScriptFrontendController implements LoggerAwareInterface // If no page, we try to find the page before in the rootLine. // Page is 'not found' in case the id itself was not an accessible page. code 1 $this->pageNotFound = 1; - $this->rootLine = $this->sys_page->getRootLine($this->id, $this->MP); - if (!empty($this->rootLine)) { - $c = count($this->rootLine) - 1; - while ($c > 0) { - // Add to page access failure history: - $this->pageAccessFailureHistory['direct_access'][] = $this->rootLine[$c]; - // Decrease to next page in rootline and check the access to that, if OK, set as page record and ID value. - $c--; - $this->id = $this->rootLine[$c]['uid']; - $this->page = $this->sys_page->getPage($this->id); - if (!empty($this->page)) { - break; + try { + $this->rootLine = GeneralUtility::makeInstance(RootlineUtility::class, $this->id, $this->MP, $this->context)->get(); + if (!empty($this->rootLine)) { + $c = count($this->rootLine) - 1; + while ($c > 0) { + // Add to page access failure history: + $this->pageAccessFailureHistory['direct_access'][] = $this->rootLine[$c]; + // Decrease to next page in rootline and check the access to that, if OK, set as page record and ID value. + $c--; + $this->id = $this->rootLine[$c]['uid']; + $this->page = $this->sys_page->getPage($this->id); + if (!empty($this->page)) { + break; + } } } + } catch (RootLineException $e) { + $this->rootLine = []; } // If still no page... if (empty($this->page)) { @@ -1552,7 +1558,11 @@ class TypoScriptFrontendController implements LoggerAwareInterface $this->id = $this->page['uid']; } // Gets the rootLine - $this->rootLine = $this->sys_page->getRootLine($this->id, $this->MP); + try { + $this->rootLine = GeneralUtility::makeInstance(RootlineUtility::class, $this->id, $this->MP, $this->context)->get(); + } catch (RootLineException $e) { + $this->rootLine = []; + } // If not rootline we're off... if (empty($this->rootLine)) { $message = 'The requested page didn\'t have a proper connection to the tree-root!'; @@ -1587,7 +1597,11 @@ class TypoScriptFrontendController implements LoggerAwareInterface $el = reset($this->rootLine); $this->id = $el['uid']; $this->page = $this->sys_page->getPage($this->id); - $this->rootLine = $this->sys_page->getRootLine($this->id, $this->MP); + try { + $this->rootLine = GeneralUtility::makeInstance(RootlineUtility::class, $this->id, $this->MP, $this->context)->get(); + } catch (RootLineException $e) { + $this->rootLine = []; + } } } } @@ -2754,7 +2768,11 @@ class TypoScriptFrontendController implements LoggerAwareInterface */ protected function updateRootLinesWithTranslations() { - $this->rootLine = $this->sys_page->getRootLine($this->id, $this->MP); + try { + $this->rootLine = GeneralUtility::makeInstance(RootlineUtility::class, $this->id, $this->MP, $this->context)->get(); + } catch (RootLineException $e) { + $this->rootLine = []; + } $this->tmpl->updateRootlineData($this->rootLine); } @@ -4692,15 +4710,19 @@ class TypoScriptFrontendController implements LoggerAwareInterface if (!array_key_exists($targetPid, $this->domainDataCache)) { $result = null; $sysDomainData = $this->getSysDomainCache(); - $rootline = $this->sys_page->getRootLine($targetPid); - // walk the rootline downwards from the target page - // to the root page, until a domain record is found - foreach ($rootline as $pageInRootline) { - $pidInRootline = $pageInRootline['uid']; - if (isset($sysDomainData[$pidInRootline])) { - $result = $sysDomainData[$pidInRootline]; - break; + try { + $rootLine = GeneralUtility::makeInstance(RootlineUtility::class, $targetPid, null, $this->context)->get(); + // walk the rootline downwards from the target page + // to the root page, until a domain record is found + foreach ($rootLine as $pageInRootline) { + $pidInRootline = $pageInRootline['uid']; + if (isset($sysDomainData[$pidInRootline])) { + $result = $sysDomainData[$pidInRootline]; + break; + } } + } catch (RootLineException $e) { + // Do nothing } $this->domainDataCache[$targetPid] = $result; } diff --git a/typo3/sysext/frontend/Classes/Page/PageRepository.php b/typo3/sysext/frontend/Classes/Page/PageRepository.php index c6671427db17..e52740112875 100644 --- a/typo3/sysext/frontend/Classes/Page/PageRepository.php +++ b/typo3/sysext/frontend/Classes/Page/PageRepository.php @@ -1114,14 +1114,11 @@ class PageRepository implements LoggerAwareInterface * @throws \RuntimeException * @return array Array with page records from the root line as values. The array is ordered with the outer records first and root record in the bottom. The keys are numeric but in reverse order. So if you traverse/sort the array by the numeric keys order you will get the order from root and out. If an error is found (like eternal looping or invalid mountpoint) it will return an empty array. * @see \TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController::getPageAndRootline() + * @deprecated since TYPO3 v10.0. */ public function getRootLine($uid, $MP = '', $ignoreMPerrors = null) { - if ($ignoreMPerrors !== null) { - trigger_error('The third argument in PageRepository::getRootline() will be removed in TYPO3 v10.0. Use a try/catch block around this method to catch any mount point errors, if necessary', E_USER_DEPRECATED); - } else { - $ignoreMPerrors = false; - } + trigger_error('Calling PageRepository->getRootLine() will be removed in TYPO3 v10.0. Use RootlineUtility directly.', E_USER_DEPRECATED); $rootline = GeneralUtility::makeInstance(RootlineUtility::class, $uid, $MP, $this->context); try { return $rootline->get(); diff --git a/typo3/sysext/frontend/Classes/Typolink/PageLinkBuilder.php b/typo3/sysext/frontend/Classes/Typolink/PageLinkBuilder.php index 85a713dcf798..13990190f4c5 100644 --- a/typo3/sysext/frontend/Classes/Typolink/PageLinkBuilder.php +++ b/typo3/sysext/frontend/Classes/Typolink/PageLinkBuilder.php @@ -20,9 +20,11 @@ use TYPO3\CMS\Backend\Routing\PageUriBuilder; use TYPO3\CMS\Core\Cache\CacheManager; use TYPO3\CMS\Core\Database\ConnectionPool; use TYPO3\CMS\Core\Database\Query\Restriction\DeletedRestriction; +use TYPO3\CMS\Core\Exception\Page\RootLineException; use TYPO3\CMS\Core\Site\Entity\SiteLanguage; use TYPO3\CMS\Core\Utility\GeneralUtility; use TYPO3\CMS\Core\Utility\MathUtility; +use TYPO3\CMS\Core\Utility\RootlineUtility; use TYPO3\CMS\Frontend\ContentObject\TypolinkModifyLinkConfigForPageLinksHookInterface; use TYPO3\CMS\Frontend\Page\CacheHashCalculator; use TYPO3\CMS\Frontend\Page\PageRepository; @@ -294,8 +296,8 @@ class PageLinkBuilder extends AbstractTypolinkBuilder // Find closest mount point // Gets rootline of linked-to page try { - $tCR_rootline = $tsfe->sys_page->getRootLine($pageId); - } catch (\RuntimeException $e) { + $tCR_rootline = GeneralUtility::makeInstance(RootlineUtility::class, $pageId)->get(); + } catch (RootLineException $e) { $tCR_rootline = []; } $inverseTmplRootline = array_reverse($tsfe->tmpl->rootLine); diff --git a/typo3/sysext/frontend/Tests/Functional/ContentObject/ContentObjectRendererTest.php b/typo3/sysext/frontend/Tests/Functional/ContentObject/ContentObjectRendererTest.php index 6fb0cc81e3a3..e6a9f1939606 100644 --- a/typo3/sysext/frontend/Tests/Functional/ContentObject/ContentObjectRendererTest.php +++ b/typo3/sysext/frontend/Tests/Functional/ContentObject/ContentObjectRendererTest.php @@ -412,12 +412,11 @@ class ContentObjectRendererTest extends \TYPO3\TestingFramework\Core\Functional\ ->getMock(); $pageRepositoryMockObject->expects($this->any())->method('getPage')->willReturn($pageArray); - $typoScriptFrontendController = GeneralUtility::makeInstance( - TypoScriptFrontendController::class, - null, - 1, - 0 - ); + $typoScriptFrontendController = $this->getMockBuilder(TypoScriptFrontendController::class) + ->setConstructorArgs([null, 1, 0]) + ->setMethods(['getDomainDataForPid']) + ->getMock(); + $typoScriptFrontendController->expects($this->any())->method('getDomainDataForPid')->willReturn(null); $typoScriptFrontendController->config = [ 'config' => [], ]; @@ -472,12 +471,11 @@ class ContentObjectRendererTest extends \TYPO3\TestingFramework\Core\Functional\ ]); GeneralUtility::addInstance(PageLinkBuilder::class, $pageLinkBuilder); - $typoScriptFrontendController = GeneralUtility::makeInstance( - TypoScriptFrontendController::class, - null, - 1, - 0 - ); + $typoScriptFrontendController = $this->getMockBuilder(TypoScriptFrontendController::class) + ->setConstructorArgs([null, 1, 0]) + ->setMethods(['getDomainDataForPid']) + ->getMock(); + $typoScriptFrontendController->expects($this->any())->method('getDomainDataForPid')->willReturn(null); $typoScriptFrontendController->config = [ 'config' => [], ]; diff --git a/typo3/sysext/indexed_search/Classes/Controller/SearchController.php b/typo3/sysext/indexed_search/Classes/Controller/SearchController.php index 9afbacd0bb04..b22a4c5a5470 100644 --- a/typo3/sysext/indexed_search/Classes/Controller/SearchController.php +++ b/typo3/sysext/indexed_search/Classes/Controller/SearchController.php @@ -19,6 +19,7 @@ use TYPO3\CMS\Core\Context\Context; use TYPO3\CMS\Core\Database\Connection; use TYPO3\CMS\Core\Database\ConnectionPool; use TYPO3\CMS\Core\Database\Query\Restriction\FrontendRestrictionContainer; +use TYPO3\CMS\Core\Exception\Page\RootLineException; use TYPO3\CMS\Core\Html\HtmlParser; use TYPO3\CMS\Core\Type\File\ImageInfo; use TYPO3\CMS\Core\TypoScript\TypoScriptService; @@ -26,6 +27,7 @@ use TYPO3\CMS\Core\Utility\GeneralUtility; use TYPO3\CMS\Core\Utility\IpAnonymizationUtility; use TYPO3\CMS\Core\Utility\MathUtility; use TYPO3\CMS\Core\Utility\PathUtility; +use TYPO3\CMS\Core\Utility\RootlineUtility; use TYPO3\CMS\Extbase\Utility\LocalizationUtility; /** @@ -577,9 +579,9 @@ class SearchController extends \TYPO3\CMS\Extbase\Mvc\Controller\ActionControlle { $pathId = $row['data_page_id'] ?: $row['page_id']; $pathMP = $row['data_page_id'] ? $row['data_page_mp'] : ''; - $rl = $GLOBALS['TSFE']->sys_page->getRootLine($pathId, $pathMP); $specConf = $this->settings['specialConfiguration']['0']; - if (is_array($rl)) { + try { + $rl = GeneralUtility::makeInstance(RootlineUtility::class, $pathId, $pathMP)->get(); foreach ($rl as $dat) { if (is_array($this->settings['specialConfiguration'][$dat['uid']])) { $specConf = $this->settings['specialConfiguration'][$dat['uid']]; @@ -587,6 +589,8 @@ class SearchController extends \TYPO3\CMS\Extbase\Mvc\Controller\ActionControlle break; } } + } catch (RootLineException $e) { + // do nothing } return $specConf; } @@ -1389,43 +1393,47 @@ class SearchController extends \TYPO3\CMS\Extbase\Mvc\Controller\ActionControlle if (!isset($this->pathCache[$identStr])) { $this->requiredFrontendUsergroups[$id] = []; $this->domainRecords[$id] = []; - $rl = $GLOBALS['TSFE']->sys_page->getRootLine($id, $pathMP); - $path = ''; - $pageCount = count($rl); - if (is_array($rl) && !empty($rl)) { - $excludeDoktypesFromPath = GeneralUtility::trimExplode( - ',', - $this->settings['results']['pathExcludeDoktypes'] ?? '', - true - ); - $breadcrumbWrap = $this->settings['breadcrumbWrap'] ?? '/'; - $breadcrumbWraps = GeneralUtility::makeInstance(TypoScriptService::class) - ->explodeConfigurationForOptionSplit(['wrap' => $breadcrumbWrap], $pageCount); - foreach ($rl as $k => $v) { - if (in_array($v['doktype'], $excludeDoktypesFromPath, false)) { - continue; - } - // Check fe_user - if ($v['fe_group'] && ($v['uid'] == $id || $v['extendToSubpages'])) { - $this->requiredFrontendUsergroups[$id][] = $v['fe_group']; - } - // Check sys_domain - if ($this->settings['detectDomainRecords']) { - $domainName = $this->getFirstSysDomainRecordForPage($v['uid']); - if ($domainName) { - $this->domainRecords[$id][] = $domainName; - // Set path accordingly - $path = $domainName . $path; + try { + $rl = GeneralUtility::makeInstance(RootlineUtility::class, $id, $pathMP)->get(); + $path = ''; + $pageCount = count($rl); + if (!empty($rl)) { + $excludeDoktypesFromPath = GeneralUtility::trimExplode( + ',', + $this->settings['results']['pathExcludeDoktypes'] ?? '', + true + ); + $breadcrumbWrap = $this->settings['breadcrumbWrap'] ?? '/'; + $breadcrumbWraps = GeneralUtility::makeInstance(TypoScriptService::class) + ->explodeConfigurationForOptionSplit(['wrap' => $breadcrumbWrap], $pageCount); + foreach ($rl as $k => $v) { + if (in_array($v['doktype'], $excludeDoktypesFromPath, false)) { + continue; + } + // Check fe_user + if ($v['fe_group'] && ($v['uid'] == $id || $v['extendToSubpages'])) { + $this->requiredFrontendUsergroups[$id][] = $v['fe_group']; + } + // Check sys_domain + if ($this->settings['detectDomainRecords']) { + $domainName = $this->getFirstSysDomainRecordForPage($v['uid']); + if ($domainName) { + $this->domainRecords[$id][] = $domainName; + // Set path accordingly + $path = $domainName . $path; + break; + } + } + // Stop, if we find that the current id is the current root page. + if ($v['uid'] == $GLOBALS['TSFE']->config['rootLine'][0]['uid']) { + array_pop($breadcrumbWraps); break; } + $path = $GLOBALS['TSFE']->cObj->wrap(htmlspecialchars($v['title']), array_pop($breadcrumbWraps)['wrap']) . $path; } - // Stop, if we find that the current id is the current root page. - if ($v['uid'] == $GLOBALS['TSFE']->config['rootLine'][0]['uid']) { - array_pop($breadcrumbWraps); - break; - } - $path = $GLOBALS['TSFE']->cObj->wrap(htmlspecialchars($v['title']), array_pop($breadcrumbWraps)['wrap']) . $path; } + } catch (RootLineException $e) { + $path = ''; } $this->pathCache[$identStr] = $path; } diff --git a/typo3/sysext/indexed_search/Classes/Hook/CrawlerHook.php b/typo3/sysext/indexed_search/Classes/Hook/CrawlerHook.php index d254f7a60983..0d2527aed9e7 100644 --- a/typo3/sysext/indexed_search/Classes/Hook/CrawlerHook.php +++ b/typo3/sysext/indexed_search/Classes/Hook/CrawlerHook.php @@ -20,8 +20,10 @@ use TYPO3\CMS\Core\Database\Connection; use TYPO3\CMS\Core\Database\ConnectionPool; use TYPO3\CMS\Core\Database\Query\Restriction\DeletedRestriction; use TYPO3\CMS\Core\DataHandling\DataHandler; +use TYPO3\CMS\Core\Exception\Page\RootLineException; use TYPO3\CMS\Core\Utility\GeneralUtility; use TYPO3\CMS\Core\Utility\MathUtility; +use TYPO3\CMS\Core\Utility\RootlineUtility; /** * Crawler hook for indexed search. Works with the "crawler" extension @@ -688,18 +690,21 @@ class CrawlerHook */ public function getUidRootLineForClosestTemplate($id) { - $tmpl = GeneralUtility::makeInstance(\TYPO3\CMS\Core\TypoScript\ExtendedTemplateService::class); - // Gets the rootLine - $sys_page = GeneralUtility::makeInstance(\TYPO3\CMS\Frontend\Page\PageRepository::class); - $rootLine = $sys_page->getRootLine($id); - // This generates the constants/config + hierarchy info for the template. - $tmpl->runThroughTemplates($rootLine, 0); - // Root line uids - $rootline_uids = []; - foreach ($tmpl->rootLine as $rlkey => $rldat) { - $rootline_uids[$rlkey] = $rldat['uid']; + $rootLineUids = []; + try { + // Gets the rootLine + $rootLine = GeneralUtility::makeInstance(RootlineUtility::class, $id)->get(); + // This generates the constants/config + hierarchy info for the template. + $tmpl = GeneralUtility::makeInstance(\TYPO3\CMS\Core\TypoScript\ExtendedTemplateService::class); + $tmpl->runThroughTemplates($rootLine); + // Root line uids + foreach ($tmpl->rootLine as $rlkey => $rldat) { + $rootLineUids[$rlkey] = $rldat['uid']; + } + } catch (RootLineException $e) { + // do nothing } - return $rootline_uids; + return $rootLineUids; } /** diff --git a/typo3/sysext/install/Configuration/ExtensionScanner/Php/MethodArgumentDroppedMatcher.php b/typo3/sysext/install/Configuration/ExtensionScanner/Php/MethodArgumentDroppedMatcher.php index e2472dfdfa69..f88110880e40 100644 --- a/typo3/sysext/install/Configuration/ExtensionScanner/Php/MethodArgumentDroppedMatcher.php +++ b/typo3/sysext/install/Configuration/ExtensionScanner/Php/MethodArgumentDroppedMatcher.php @@ -177,10 +177,4 @@ return [ 'Breaking-84877-MethodsOfLocalizationRepositoryChanged.rst', ], ], - 'TYPO3\CMS\Frontend\Page\PageRepository->getRootLine' => [ - 'maximumNumberOfArguments' => 2, - 'restFiles' => [ - 'Deprecation-85105-3rdMethodArgumentInPageRepository-getRootLine.rst', - ], - ], ]; diff --git a/typo3/sysext/install/Configuration/ExtensionScanner/Php/MethodCallMatcher.php b/typo3/sysext/install/Configuration/ExtensionScanner/Php/MethodCallMatcher.php index 783d651a354a..7f014b77ccba 100644 --- a/typo3/sysext/install/Configuration/ExtensionScanner/Php/MethodCallMatcher.php +++ b/typo3/sysext/install/Configuration/ExtensionScanner/Php/MethodCallMatcher.php @@ -2424,6 +2424,13 @@ return [ 'Deprecation-85445-TemplateService-getFileName.rst' ], ], + 'TYPO3\CMS\Frontend\Page\PageRepository->getRootLine' => [ + 'numberOfMandatoryArguments' => 1, + 'maximumNumberOfArguments' => 3, + 'restFiles' => [ + 'Deprecation-85557-PageRepository-getRootLine.rst' + ], + ], 'TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer->calcIntExplode' => [ 'numberOfMandatoryArguments' => 2, 'maximumNumberOfArguments' => 2, diff --git a/typo3/sysext/workspaces/Tests/Functional/DataHandling/IRRE/CSV/Modify/ActionTest.php b/typo3/sysext/workspaces/Tests/Functional/DataHandling/IRRE/CSV/Modify/ActionTest.php index 1b82e46ecf18..59ff6e2e5dfd 100644 --- a/typo3/sysext/workspaces/Tests/Functional/DataHandling/IRRE/CSV/Modify/ActionTest.php +++ b/typo3/sysext/workspaces/Tests/Functional/DataHandling/IRRE/CSV/Modify/ActionTest.php @@ -218,7 +218,7 @@ class ActionTest extends \TYPO3\CMS\Workspaces\Tests\Functional\DataHandling\IRR $this->assertAssertionDataSet('deletePage'); $response = $this->getFrontendResponse(self::VALUE_PageId, 0, self::VALUE_BackendUserId, self::VALUE_WorkspaceId, false); - $this->assertContains('RuntimeException', $response->getError()); + $this->assertContains('PageNotFoundException', $response->getError()); } /** diff --git a/typo3/sysext/workspaces/Tests/Functional/DataHandling/IRRE/ForeignField/Modify/ActionTest.php b/typo3/sysext/workspaces/Tests/Functional/DataHandling/IRRE/ForeignField/Modify/ActionTest.php index f55f15c52b94..da4199b4ec8f 100644 --- a/typo3/sysext/workspaces/Tests/Functional/DataHandling/IRRE/ForeignField/Modify/ActionTest.php +++ b/typo3/sysext/workspaces/Tests/Functional/DataHandling/IRRE/ForeignField/Modify/ActionTest.php @@ -218,7 +218,7 @@ class ActionTest extends \TYPO3\CMS\Workspaces\Tests\Functional\DataHandling\IRR $this->assertAssertionDataSet('deletePage'); $response = $this->getFrontendResponse(self::VALUE_PageId, 0, self::VALUE_BackendUserId, self::VALUE_WorkspaceId, false); - $this->assertContains('RuntimeException', $response->getError()); + $this->assertContains('PageNotFoundException', $response->getError()); } /** diff --git a/typo3/sysext/workspaces/Tests/Functional/DataHandling/Regular/Modify/ActionTest.php b/typo3/sysext/workspaces/Tests/Functional/DataHandling/Regular/Modify/ActionTest.php index a282f5af7ff0..5481c6598aba 100644 --- a/typo3/sysext/workspaces/Tests/Functional/DataHandling/Regular/Modify/ActionTest.php +++ b/typo3/sysext/workspaces/Tests/Functional/DataHandling/Regular/Modify/ActionTest.php @@ -312,7 +312,7 @@ class ActionTest extends \TYPO3\CMS\Workspaces\Tests\Functional\DataHandling\Reg $this->assertAssertionDataSet('deletePage'); $response = $this->getFrontendResponse(self::VALUE_PageId, 0, self::VALUE_BackendUserId, self::VALUE_WorkspaceId, false); - $this->assertContains('RuntimeException', $response->getError()); + $this->assertContains('PageNotFoundException', $response->getError()); } /** @@ -325,7 +325,7 @@ class ActionTest extends \TYPO3\CMS\Workspaces\Tests\Functional\DataHandling\Reg $this->assertAssertionDataSet('deleteContentAndPage'); $response = $this->getFrontendResponse(self::VALUE_PageId, 0, self::VALUE_BackendUserId, self::VALUE_WorkspaceId, false); - $this->assertContains('RuntimeException', $response->getError()); + $this->assertContains('PageNotFoundException', $response->getError()); } /** -- GitLab