diff --git a/typo3/sysext/core/Classes/Domain/Repository/PageRepository.php b/typo3/sysext/core/Classes/Domain/Repository/PageRepository.php index cc46f1a9a0b9e1040d52e35fccf6eb150fbf9432..ebfed28eb1f8b41269754ca48a45f29670f314c8 100644 --- a/typo3/sysext/core/Classes/Domain/Repository/PageRepository.php +++ b/typo3/sysext/core/Classes/Domain/Repository/PageRepository.php @@ -28,6 +28,7 @@ use TYPO3\CMS\Core\Database\Query\QueryHelper; use TYPO3\CMS\Core\Database\Query\Restriction\DeletedRestriction; use TYPO3\CMS\Core\Database\Query\Restriction\FrontendRestrictionContainer; use TYPO3\CMS\Core\Database\Query\Restriction\FrontendWorkspaceRestriction; +use TYPO3\CMS\Core\Database\Query\Restriction\QueryRestrictionContainerInterface; use TYPO3\CMS\Core\Error\Http\ShortcutTargetPageNotFoundException; use TYPO3\CMS\Core\Utility\GeneralUtility; use TYPO3\CMS\Core\Utility\MathUtility; @@ -1116,6 +1117,40 @@ class PageRepository implements LoggerAwareInterface return $result; } + /** + * Removes Page UID numbers from the input array which are not available due to QueryRestrictions + * This is also very helpful to add a custom RestrictionContainer to add custom Restrictions such as "bad doktypes" e.g. RECYCLER doktypes + * + * @param int[] $pageIds Array of Page UID numbers to check + * @param QueryRestrictionContainerInterface|null $restrictionContainer + * @return int[] Returns the array of remaining page UID numbers + */ + public function filterAccessiblePageIds(array $pageIds, QueryRestrictionContainerInterface $restrictionContainer = null): array + { + if ($pageIds === []) { + return []; + } + $validPageIds = []; + $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable('pages'); + if ($restrictionContainer instanceof QueryRestrictionContainerInterface) { + $queryBuilder->setRestrictions($restrictionContainer); + } else { + $queryBuilder->setRestrictions(GeneralUtility::makeInstance(FrontendRestrictionContainer::class, $this->context)); + } + $statement = $queryBuilder->select('uid') + ->from('pages') + ->where( + $queryBuilder->expr()->in( + 'uid', + $queryBuilder->createNamedParameter($pageIds, Connection::PARAM_INT_ARRAY) + ) + ) + ->execute(); + while ($row = $statement->fetch()) { + $validPageIds[] = (int)$row['uid']; + } + return $validPageIds; + } /******************************** * * Selecting records in general diff --git a/typo3/sysext/frontend/Classes/ContentObject/ContentObjectRenderer.php b/typo3/sysext/frontend/Classes/ContentObject/ContentObjectRenderer.php index 5f482bf38bd697e3a848dba41608d3a2a3ee48f6..8611996dedcb38a5d129e6afb6f7d47458fb631e 100644 --- a/typo3/sysext/frontend/Classes/ContentObject/ContentObjectRenderer.php +++ b/typo3/sysext/frontend/Classes/ContentObject/ContentObjectRenderer.php @@ -25,12 +25,12 @@ use TYPO3\CMS\Core\Cache\CacheManager; use TYPO3\CMS\Core\Context\Context; use TYPO3\CMS\Core\Context\LanguageAspect; use TYPO3\CMS\Core\Core\Environment; -use TYPO3\CMS\Core\Database\Connection; use TYPO3\CMS\Core\Database\ConnectionPool; use TYPO3\CMS\Core\Database\Query\Expression\ExpressionBuilder; use TYPO3\CMS\Core\Database\Query\QueryBuilder; use TYPO3\CMS\Core\Database\Query\QueryHelper; use TYPO3\CMS\Core\Database\Query\Restriction\DeletedRestriction; +use TYPO3\CMS\Core\Database\Query\Restriction\DocumentTypeExclusionRestriction; use TYPO3\CMS\Core\Database\Query\Restriction\FrontendRestrictionContainer; use TYPO3\CMS\Core\Domain\Repository\PageRepository; use TYPO3\CMS\Core\Html\HtmlParser; @@ -350,13 +350,6 @@ class ContentObjectRenderer implements LoggerAwareInterface */ public $parentRecord = []; - /** - * This is used by checkPid, that checks if pages are accessible. The $checkPid_cache['page_uid'] is set TRUE or FALSE upon this check featuring a caching function for the next request. - * - * @var array - */ - public $checkPid_cache = []; - /** * @var string|int */ @@ -6727,81 +6720,21 @@ class ContentObjectRenderer implements LoggerAwareInterface /** * Removes Page UID numbers from the input array which are not available due to enableFields() or the list of bad doktype numbers ($this->checkPid_badDoktypeList) * - * @param array $listArr Array of Page UID numbers for select and for which pages with enablefields and bad doktypes should be removed. + * @param int[] $pageIds Array of Page UID numbers for select and for which pages with enablefields and bad doktypes should be removed. * @return array Returns the array of remaining page UID numbers * @internal - * @see checkPid() */ - public function checkPidArray($listArr) + public function checkPidArray($pageIds) { - if (!is_array($listArr) || empty($listArr)) { + if (!is_array($pageIds) || empty($pageIds)) { return []; } - $outArr = []; - $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable('pages'); - $queryBuilder->setRestrictions(GeneralUtility::makeInstance(FrontendRestrictionContainer::class)); - $queryBuilder->select('uid') - ->from('pages') - ->where( - $queryBuilder->expr()->in( - 'uid', - $queryBuilder->createNamedParameter($listArr, Connection::PARAM_INT_ARRAY) - ), - $queryBuilder->expr()->notIn( - 'doktype', - $queryBuilder->createNamedParameter( - GeneralUtility::intExplode(',', $this->checkPid_badDoktypeList, true), - Connection::PARAM_INT_ARRAY - ) - ) - ); - try { - $result = $queryBuilder->execute(); - while ($row = $result->fetch()) { - $outArr[] = $row['uid']; - } - } catch (DBALException $e) { - $this->getTimeTracker()->setTSlogMessage($e->getMessage() . ': ' . $queryBuilder->getSQL(), 3); - } - - return $outArr; - } - - /** - * Checks if a page UID is available due to enableFields() AND the list of bad doktype numbers ($this->checkPid_badDoktypeList) - * - * @param int $uid Page UID to test - * @return bool TRUE if OK - * @internal - * @see checkPidArray() - */ - public function checkPid($uid) - { - $uid = (int)$uid; - if (!isset($this->checkPid_cache[$uid])) { - $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable('pages'); - $queryBuilder->setRestrictions(GeneralUtility::makeInstance(FrontendRestrictionContainer::class)); - $count = $queryBuilder->count('*') - ->from('pages') - ->where( - $queryBuilder->expr()->eq( - 'uid', - $queryBuilder->createNamedParameter($uid, \PDO::PARAM_INT) - ), - $queryBuilder->expr()->notIn( - 'doktype', - $queryBuilder->createNamedParameter( - GeneralUtility::intExplode(',', $this->checkPid_badDoktypeList, true), - Connection::PARAM_INT_ARRAY - ) - ) - ) - ->execute() - ->fetchColumn(0); - - $this->checkPid_cache[$uid] = (bool)$count; - } - return $this->checkPid_cache[$uid]; + $restrictionContainer = GeneralUtility::makeInstance(FrontendRestrictionContainer::class); + $restrictionContainer->add(GeneralUtility::makeInstance( + DocumentTypeExclusionRestriction::class, + GeneralUtility::intExplode(',', $this->checkPid_badDoktypeList, true) + )); + return $this->getTypoScriptFrontendController()->sys_page->filterAccessiblePageIds($pageIds, $restrictionContainer); } /** diff --git a/typo3/sysext/frontend/Classes/ContentObject/RecordsContentObject.php b/typo3/sysext/frontend/Classes/ContentObject/RecordsContentObject.php index ae03d4882c31e966d43dc2dd2c6b99e22a23321a..999ffabe8a178cab34c736ead1e4d9025f721f42 100644 --- a/typo3/sysext/frontend/Classes/ContentObject/RecordsContentObject.php +++ b/typo3/sysext/frontend/Classes/ContentObject/RecordsContentObject.php @@ -103,7 +103,8 @@ class RecordsContentObject extends AbstractContentObject if (is_array($row)) { $dontCheckPid = isset($conf['dontCheckPid.']) ? $this->cObj->stdWrap($conf['dontCheckPid'], $conf['dontCheckPid.']) : $conf['dontCheckPid']; if (!$dontCheckPid) { - $row = $this->cObj->checkPid($row['pid']) ? $row : ''; + $validPageId = $this->getPageRepository()->filterAccessiblePageIds([$row['pid']]); + $row = !empty($validPageId) ? $row : ''; } if ($row && !$GLOBALS['TSFE']->recordRegister[$val['table'] . ':' . $val['id']]) { $renderObjName = $conf['conf.'][$val['table']] ?: '<' . $val['table'];