From 75c5d46236762c608eba9bf71aa5536913cbe742 Mon Sep 17 00:00:00 2001 From: Alexander Kellner Date: Mon, 4 Mar 2024 16:11:37 +0100 Subject: [PATCH] [FEATURE] Filter available categories by permission in Filter and in new/edit views --- .../Domain/Repository/CategoryRepository.php | 10 ++- Classes/Domain/Service/PermissionTrait.php | 83 ++++++++++++++++++- 2 files changed, 89 insertions(+), 4 deletions(-) diff --git a/Classes/Domain/Repository/CategoryRepository.php b/Classes/Domain/Repository/CategoryRepository.php index 1e6d97e..4b68676 100644 --- a/Classes/Domain/Repository/CategoryRepository.php +++ b/Classes/Domain/Repository/CategoryRepository.php @@ -3,16 +3,20 @@ declare(strict_types=1); namespace In2code\Luxletter\Domain\Repository; +use In2code\Luxletter\Domain\Model\Category; +use In2code\Luxletter\Domain\Service\PermissionTrait; use TYPO3\CMS\Extbase\Persistence\QueryInterface; -use TYPO3\CMS\Extbase\Persistence\QueryResultInterface; class CategoryRepository extends AbstractRepository { - public function findAllLuxletterCategories(): QueryResultInterface + use PermissionTrait; + + public function findAllLuxletterCategories(): array { $query = $this->createQuery(); $query->matching($query->equals('luxletter_newsletter_category', true)); $query->setOrderings(['title' => QueryInterface::ORDER_ASCENDING]); - return $query->execute(); + $records = $query->execute()->toArray(); + return $this->filterRecords($records, Category::TABLE_NAME); } } diff --git a/Classes/Domain/Service/PermissionTrait.php b/Classes/Domain/Service/PermissionTrait.php index d99a985..3d55afa 100644 --- a/Classes/Domain/Service/PermissionTrait.php +++ b/Classes/Domain/Service/PermissionTrait.php @@ -3,12 +3,54 @@ declare(strict_types=1); namespace In2code\Luxletter\Domain\Service; +use Doctrine\DBAL\Exception as ExceptionDbal; use In2code\Luxletter\Utility\BackendUserUtility; +use In2code\Luxletter\Utility\DatabaseUtility; +use TYPO3\CMS\Core\Database\Connection; use TYPO3\CMS\Core\Type\Bitmask\Permission; trait PermissionTrait { - private function isAuthenticated(array $pageRecord): bool + /** + * Remove unauthorized records from array + * + * @param array $rows + * @param string $table + * @return array + * @throws ExceptionDbal + */ + private function filterRecords(array $rows, string $table): array + { + if (BackendUserUtility::isAdministrator()) { + return $rows; + } + + foreach ($rows as $key => $row) { + $identifier = is_array($row) ? $row['uid'] : $row->getUid(); + if ($this->isAuthenticatedForRecord($identifier, $table) === false) { + unset($rows[$key]); + } + } + return $rows; + } + + /** + * @param int $identifier + * @param string $table + * @return bool + * @throws ExceptionDbal + */ + private function isAuthenticatedForRecord(int $identifier, string $table): bool + { + if (BackendUserUtility::isAdministrator()) { + return true; + } + + $pageIdentifier = $this->getPageIdentifierFromRecord($identifier, $table); + return $this->isAuthenticatedForPageRow($this->getPageRowFromPageIdentifier($pageIdentifier)); + } + + private function isAuthenticatedForPageRow(array $pageRecord): bool { if (BackendUserUtility::isAdministrator()) { return true; @@ -18,4 +60,43 @@ private function isAuthenticated(array $pageRecord): bool return $beuserAuthentication !== null && $beuserAuthentication->doesUserHaveAccess($pageRecord, Permission::PAGE_SHOW); } + + /** + * @param int $identifier + * @param string $table + * @return int + * @throws ExceptionDbal + */ + protected function getPageIdentifierFromRecord(int $identifier, string $table): int + { + $queryBuilder = DatabaseUtility::getQueryBuilderForTable($table); + return (int)$queryBuilder + ->select('pid') + ->from($table) + ->where( + $queryBuilder->expr()->eq('uid', $queryBuilder->createNamedParameter($identifier, Connection::PARAM_INT)) + ) + ->setMaxResults(1) + ->executeQuery() + ->fetchOne(); + } + + /** + * @param int $identifier + * @return array|int + * @throws ExceptionDbal + */ + protected function getPageRowFromPageIdentifier(int $identifier): array + { + $queryBuilder = DatabaseUtility::getQueryBuilderForTable('pages'); + return (array)$queryBuilder + ->select('*') + ->from('pages') + ->where( + $queryBuilder->expr()->eq('uid', $queryBuilder->createNamedParameter($identifier, Connection::PARAM_INT)) + ) + ->setMaxResults(1) + ->executeQuery() + ->fetchAssociative(); + } }