‪TYPO3CMS  ‪main
CategoryPermissionsAspect.php
Go to the documentation of this file.
1 <?php
2 
3 declare(strict_types=1);
4 
5 /*
6  * This file is part of the TYPO3 CMS project.
7  *
8  * It is free software; you can redistribute it and/or modify it under
9  * the terms of the GNU General Public License, either version 2
10  * of the License, or any later version.
11  *
12  * For the full copyright and license information, please read the
13  * LICENSE.txt file that was distributed with this source code.
14  *
15  * The TYPO3 project - inspiring people to share!
16  */
17 
19 
20 use Psr\Http\Message\ServerRequestInterface;
29 
39 {
43  private ‪$categoryTableName = 'sys_category';
44 
48  #[AsEventListener('backend-user-permissions')]
50  {
51  // Only evaluate this in the backend
52  if (!(‪$GLOBALS['TYPO3_REQUEST'] ?? null) instanceof ServerRequestInterface
53  || !‪ApplicationType::fromRequest(‪$GLOBALS['TYPO3_REQUEST'])->isBackend()
54  ) {
55  return;
56  }
57 
58  $dataProvider = $event->‪getProvider();
59  $treeData = $event->‪getTreeData();
60 
61  if (!‪$GLOBALS['BE_USER']->isAdmin() && $dataProvider->getTableName() === $this->categoryTableName) {
62  // Get User permissions related to category
63  $categoryMountPoints = ‪$GLOBALS['BE_USER']->getCategoryMountPoints();
64 
65  // Backup child nodes to be processed.
66  $treeNodeCollection = $treeData->getChildNodes();
67 
68  if (!empty($categoryMountPoints) && !empty($treeNodeCollection)) {
69  $shallRepopulateTree = false;
70 
71  // Check the rootline against categoryMountPoints when tree was filtered
72  foreach ($dataProvider->getStartingPoints() as $startingPoint) {
73  if (!in_array($startingPoint, $categoryMountPoints)) {
74  $shallRepopulateTree = true;
75  break;
76  }
77  $uidsInRootline = $this->‪findUidsInRootline($startingPoint);
78  if (empty(array_intersect($categoryMountPoints, $uidsInRootline))) {
79  $shallRepopulateTree = true;
80  break;
81  }
82  }
83 
84  if ($shallRepopulateTree) {
85  // First, remove all child nodes which must be analyzed to be considered as "secure".
86  // The nodes were backed up in variable $treeNodeCollection beforehand.
87  $treeData->removeChildNodes();
88 
89  // Create an empty tree node collection to receive the secured nodes.
90  $securedTreeNodeCollection = GeneralUtility::makeInstance(TreeNodeCollection::class);
91 
92  foreach ($categoryMountPoints as $categoryMountPoint) {
93  $treeNode = $this->‪lookUpCategoryMountPointInTreeNodes((int)$categoryMountPoint, $treeNodeCollection);
94  if ($treeNode !== null) {
95  $securedTreeNodeCollection->append($treeNode);
96  }
97  }
98 
99  // Reset child nodes.
100  $treeData->setChildNodes($securedTreeNodeCollection);
101  }
102  }
103  }
104  }
105 
111  private function ‪lookUpCategoryMountPointInTreeNodes(int $categoryMountPoint, ‪TreeNodeCollection $treeNodeCollection)
112  {
113  $result = null;
114 
115  // If any User permission, recursively traverse the tree and set tree part as mount point
116  foreach ($treeNodeCollection as $treeNode) {
118  if ((int)$treeNode->getId() === $categoryMountPoint) {
119  $result = $treeNode;
120  break;
121  }
122 
123  if ($treeNode->hasChildNodes()) {
125  $node = $this->‪lookUpCategoryMountPointInTreeNodes($categoryMountPoint, $treeNode->getChildNodes());
126  if ($node !== null) {
127  $result = $node;
128  break;
129  }
130  }
131  }
132  return $result;
133  }
134 
140  private function ‪findUidsInRootline(int ‪$uid)
141  {
142  $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)
143  ->getQueryBuilderForTable($this->categoryTableName);
144  $row = $queryBuilder
145  ->select('parent')
146  ->from($this->categoryTableName)
147  ->where(
148  $queryBuilder->expr()->eq('uid', $queryBuilder->createNamedParameter(‪$uid, ‪Connection::PARAM_INT))
149  )
150  ->executeQuery()
151  ->fetchAssociative();
152 
153  $parentUids = [];
154  if ($row['parent'] > 0) {
155  $parentUids = $this->‪findUidsInRootline($row['parent']);
156  $parentUids[] = $row['parent'];
157  }
158  return $parentUids;
159  }
160 }
‪TYPO3\CMS\Backend\Security\CategoryPermissionsAspect\$categoryTableName
‪string $categoryTableName
Definition: CategoryPermissionsAspect.php:42
‪TYPO3\CMS\Core\Database\Connection\PARAM_INT
‪const PARAM_INT
Definition: Connection.php:52
‪TYPO3\CMS\Backend\Security\CategoryPermissionsAspect\findUidsInRootline
‪array findUidsInRootline(int $uid)
Definition: CategoryPermissionsAspect.php:139
‪TYPO3\CMS\Core\Tree\Event\ModifyTreeDataEvent\getTreeData
‪getTreeData()
Definition: ModifyTreeDataEvent.php:33
‪TYPO3\CMS\Core\Attribute\AsEventListener
Definition: AsEventListener.php:25
‪TYPO3\CMS\Backend\Security\CategoryPermissionsAspect\lookUpCategoryMountPointInTreeNodes
‪TreeNode null lookUpCategoryMountPointInTreeNodes(int $categoryMountPoint, TreeNodeCollection $treeNodeCollection)
Definition: CategoryPermissionsAspect.php:110
‪TYPO3\CMS\Core\Tree\Event\ModifyTreeDataEvent
Definition: ModifyTreeDataEvent.php:27
‪TYPO3\CMS\Backend\Security\CategoryPermissionsAspect\addUserPermissionsToCategoryTreeData
‪addUserPermissionsToCategoryTreeData(ModifyTreeDataEvent $event)
Definition: CategoryPermissionsAspect.php:48
‪TYPO3\CMS\Backend\Tree\TreeNodeCollection
Definition: TreeNodeCollection.php:25
‪TYPO3\CMS\Backend\Tree\TreeNode
Definition: TreeNode.php:25
‪TYPO3\CMS\Backend\Security
Definition: CategoryPermissionsAspect.php:18
‪TYPO3\CMS\Backend\Security\CategoryPermissionsAspect
Definition: CategoryPermissionsAspect.php:39
‪TYPO3\CMS\Core\Database\Connection
Definition: Connection.php:41
‪TYPO3\CMS\Core\Tree\Event\ModifyTreeDataEvent\getProvider
‪getProvider()
Definition: ModifyTreeDataEvent.php:43
‪TYPO3\CMS\Webhooks\Message\$uid
‪identifier readonly int $uid
Definition: PageModificationMessage.php:35
‪$GLOBALS
‪$GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['adminpanel']['modules']
Definition: ext_localconf.php:25
‪TYPO3\CMS\Core\Http\fromRequest
‪@ fromRequest
Definition: ApplicationType.php:67
‪TYPO3\CMS\Core\Database\ConnectionPool
Definition: ConnectionPool.php:46
‪TYPO3\CMS\Core\Utility\GeneralUtility
Definition: GeneralUtility.php:52
‪TYPO3\CMS\Core\Http\ApplicationType
‪ApplicationType
Definition: ApplicationType.php:56