isBackend() ) { return; } /** @var DatabaseTreeDataProvider $dataProvider */ $dataProvider = $event->getProvider(); $treeData = $event->getTreeData(); if (!$GLOBALS['BE_USER']->isAdmin() && $dataProvider->getTableName() === $this->categoryTableName) { // Get User permissions related to category $categoryMountPoints = $GLOBALS['BE_USER']->getCategoryMountPoints(); // Backup child nodes to be processed. $treeNodeCollection = $treeData->getChildNodes(); if (!empty($categoryMountPoints) && $treeData->hasChildNodes()) { $shallRepopulateTree = false; // Check the rootline against categoryMountPoints when tree was filtered foreach ($dataProvider->getStartingPoints() as $startingPoint) { if (!in_array($startingPoint, $categoryMountPoints)) { $shallRepopulateTree = true; break; } $uidsInRootline = $this->findUidsInRootline($startingPoint); if (empty(array_intersect($categoryMountPoints, $uidsInRootline))) { $shallRepopulateTree = true; break; } } if ($shallRepopulateTree) { // First, remove all child nodes which must be analyzed to be considered as "secure". // The nodes were backed up in variable $treeNodeCollection beforehand. $treeData->removeChildNodes(); // Create an empty tree node collection to receive the secured nodes. $securedTreeNodeCollection = GeneralUtility::makeInstance(TreeNodeCollection::class); foreach ($categoryMountPoints as $categoryMountPoint) { $treeNode = $this->lookUpCategoryMountPointInTreeNodes((int)$categoryMountPoint, $treeNodeCollection); if ($treeNode !== null) { $securedTreeNodeCollection->append($treeNode); } } // Reset child nodes. $treeData->setChildNodes($securedTreeNodeCollection); } } } } /** * Recursively look up for a category mount point within a tree. */ private function lookUpCategoryMountPointInTreeNodes(int $categoryMountPoint, TreeNodeCollection $treeNodeCollection): ?TreeNode { $result = null; // If any User permission, recursively traverse the tree and set tree part as mount point foreach ($treeNodeCollection as $treeNode) { /** @var TreeNode $treeNode */ if ((int)$treeNode->getId() === $categoryMountPoint) { $result = $treeNode; break; } if ($treeNode->hasChildNodes()) { $node = $this->lookUpCategoryMountPointInTreeNodes($categoryMountPoint, $treeNode->getChildNodes()); if ($node !== null) { $result = $node; break; } } } return $result; } /** * Find parent uids in rootline */ private function findUidsInRootline(int $uid): array { $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class) ->getQueryBuilderForTable($this->categoryTableName); $row = $queryBuilder ->select('parent') ->from($this->categoryTableName) ->where( $queryBuilder->expr()->eq('uid', $queryBuilder->createNamedParameter($uid, Connection::PARAM_INT)) ) ->executeQuery() ->fetchAssociative(); $parentUids = []; if ($row['parent'] > 0) { $parentUids = $this->findUidsInRootline($row['parent']); $parentUids[] = $row['parent']; } return $parentUids; } }