[FEATURE] Allow adding additional query restrictions
[Packages/TYPO3.CMS.git] / typo3 / sysext / core / Classes / Database / Query / Restriction / AbstractRestrictionContainer.php
1 <?php
2 declare(strict_types = 1);
3 namespace TYPO3\CMS\Core\Database\Query\Restriction;
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
18 use TYPO3\CMS\Core\Database\Query\Expression\CompositeExpression;
19 use TYPO3\CMS\Core\Database\Query\Expression\ExpressionBuilder;
20 use TYPO3\CMS\Core\Utility\GeneralUtility;
21
22 /**
23 * Base class for query restriction collections
24 */
25 abstract class AbstractRestrictionContainer implements QueryRestrictionContainerInterface
26 {
27 /**
28 * @var QueryRestrictionInterface[]
29 */
30 protected $restrictions = [];
31
32 /**
33 * @var QueryRestrictionInterface[]
34 */
35 protected $enforcedRestrictions = [];
36
37 /**
38 * Main method to build expressions for given tables.
39 * Iterating over all registered expressions and combine them with AND
40 *
41 * @param array $queriedTables Array of tables, where array key is table alias and value is a table name
42 * @param ExpressionBuilder $expressionBuilder Expression builder instance to add restrictions with
43 * @return CompositeExpression The result of query builder expression(s)
44 */
45 public function buildExpression(array $queriedTables, ExpressionBuilder $expressionBuilder): CompositeExpression
46 {
47 $constraints = [];
48 foreach ($this->restrictions as $restriction) {
49 $constraints[] = $restriction->buildExpression($queriedTables, $expressionBuilder);
50 }
51 return $expressionBuilder->andX(...$constraints);
52 }
53
54 /**
55 * Removes all restrictions stored within this container
56 *
57 * @return QueryRestrictionContainerInterface
58 */
59 public function removeAll(): QueryRestrictionContainerInterface
60 {
61 $this->restrictions = $this->enforcedRestrictions;
62 return $this;
63 }
64
65 /**
66 * Remove restriction of a given type
67 *
68 * @param string $restrictionType Class name of the restriction to be removed
69 * @return QueryRestrictionContainerInterface
70 */
71 public function removeByType(string $restrictionType): QueryRestrictionContainerInterface
72 {
73 unset($this->restrictions[$restrictionType], $this->enforcedRestrictions[$restrictionType]);
74 return $this;
75 }
76
77 /**
78 * Add a new restriction instance to this collection
79 *
80 * @param QueryRestrictionInterface $restriction
81 * @return QueryRestrictionContainerInterface
82 */
83 public function add(QueryRestrictionInterface $restriction): QueryRestrictionContainerInterface
84 {
85 $this->restrictions[get_class($restriction)] = $restriction;
86 if ($restriction instanceof EnforceableQueryRestrictionInterface && $restriction->isEnforced()) {
87 $this->enforcedRestrictions[get_class($restriction)] = $restriction;
88 }
89 return $this;
90 }
91
92 /**
93 * Factory method for restrictions.
94 * Currently only instantiates the class.
95 *
96 * @param string $restrictionClass
97 * @return QueryRestrictionInterface
98 */
99 protected function createRestriction($restrictionClass): QueryRestrictionInterface
100 {
101 return GeneralUtility::makeInstance($restrictionClass);
102 }
103 }