‪TYPO3CMS  9.5
FileSearchQuery.php
Go to the documentation of this file.
1 <?php
2 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 
27 
34 {
35  private const ‪FILES_TABLE = 'sys_file';
36 
37  private const ‪FILES_META_TABLE = 'sys_file_metadata';
38 
42  private ‪$queryBuilder;
43 
47  private ‪$additionalRestrictions = [];
48 
52  private ‪$result;
53 
54  public function ‪__construct(‪QueryBuilder ‪$queryBuilder = null)
55  {
56  $this->queryBuilder = ‪$queryBuilder ?? GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable(self::FILES_TABLE);
57  }
58 
66  public static function ‪createForSearchDemand(‪FileSearchDemand $searchDemand, ‪QueryBuilder ‪$queryBuilder = null): self
67  {
68  $query = new self(‪$queryBuilder);
69  $query->additionalRestriction(
70  new ‪SearchTermRestriction($searchDemand, $query->queryBuilder)
71  );
72  if ($searchDemand->‪getFolder()) {
73  $query->additionalRestriction(
74  new ‪FolderRestriction($searchDemand->‪getFolder(), $searchDemand->‪isRecursive())
75  );
76  } else {
77  $query->additionalRestriction(
78  new FolderMountsRestriction(‪$GLOBALS['BE_USER'])
79  );
80  }
81 
82  $query->queryBuilder->add(
83  'select',
84  [
85  'DISTINCT ' . $query->queryBuilder->quoteIdentifier(self::FILES_TABLE . '.identifier'),
86  $query->queryBuilder->quoteIdentifier(self::FILES_TABLE) . '.*',
87  ]
88  );
89 
90  if ($searchDemand->‪getFirstResult() !== null) {
91  $query->queryBuilder->setFirstResult($searchDemand->‪getFirstResult());
92  }
93  if ($searchDemand->‪getMaxResults() !== null) {
94  $query->queryBuilder->setMaxResults($searchDemand->‪getMaxResults());
95  }
96 
97  if ($searchDemand->‪getOrderings() === null) {
98  $orderBy = ‪$GLOBALS['TCA'][‪self::FILES_TABLE]['ctrl']['sortby'] ?: ‪$GLOBALS['TCA'][‪self::FILES_TABLE]['ctrl']['default_sortby'];
99  foreach (‪QueryHelper::parseOrderBy((string)$orderBy) as [$fieldName, $order]) {
100  $searchDemand = $searchDemand->‪addOrdering(self::FILES_TABLE, $fieldName, $order);
101  }
102  }
103  foreach ($searchDemand->‪getOrderings() as [$tableName, $fieldName, $direction]) {
104  if (!isset(‪$GLOBALS['TCA'][$tableName]['columns'][$fieldName]) || !in_array($direction, ['ASC', 'DESC'], true)) {
105  // This exception is essential to avoid SQL injections based on ordering field names, which could be input controlled by an attacker.
106  throw new \RuntimeException(sprintf('Invalid file search ordering given table: "%s", field: "%s", direction: "%s".', $tableName, $fieldName, $direction), 1555850106);
107  }
108  // Add order by fields to select, to make postgres happy and use random names to make sure to not interfere with file fields
109  $query->queryBuilder->add(
110  'select',
111  $query->queryBuilder->quoteIdentifiersForSelect([
112  $tableName . '.' . $fieldName
113  . ' AS '
114  . preg_replace(
115  '/[^a-z0-9]/',
116  '',
117  uniqid($tableName . $fieldName, true)
118  )
119  ]),
120  true
121  );
122  $query->queryBuilder->addOrderBy($tableName . '.' . $fieldName, $direction);
123  }
124 
125  return $query;
126  }
127 
135  public static function ‪createCountForSearchDemand(FileSearchDemand $searchDemand, QueryBuilder ‪$queryBuilder = null): self
136  {
137  $query = new self(‪$queryBuilder);
138  $query->additionalRestriction(
139  new SearchTermRestriction($searchDemand, $query->queryBuilder)
140  );
141  if ($searchDemand->getFolder()) {
142  $query->additionalRestriction(
143  new FolderRestriction($searchDemand->getFolder(), $searchDemand->isRecursive())
144  );
145  }
146 
147  $query->queryBuilder->add(
148  'select',
149  'COUNT(DISTINCT ' . $query->queryBuilder->quoteIdentifier(self::FILES_TABLE . '.identifier') . ')'
150  );
151 
152  return $query;
153  }
154 
164  public function ‪additionalRestriction(QueryRestrictionInterface $additionalRestriction): void
165  {
166  $this->‪ensureQueryNotExecuted();
167  $this->additionalRestrictions[get_class($additionalRestriction)] = $additionalRestriction;
168  }
169 
170  public function ‪execute()
171  {
172  if ($this->result === null) {
173  $this->‪initializeQueryBuilder();
174  $this->result = $this->queryBuilder->execute();
175  }
176 
177  return ‪$this->result;
178  }
179 
184  private function ‪initializeQueryBuilder(): void
185  {
186  $this->queryBuilder->from(self::FILES_TABLE);
187  $this->queryBuilder->join(
188  self::FILES_TABLE,
189  self::FILES_META_TABLE,
190  self::FILES_META_TABLE,
191  $this->queryBuilder->expr()->eq(self::FILES_META_TABLE . '.file', $this->queryBuilder->quoteIdentifier(self::FILES_TABLE . '.uid'))
192  );
193 
194  $restrictionContainer = $this->queryBuilder->getRestrictions()
195  ->add(new ConsistencyRestriction($this->queryBuilder));
196  foreach ($this->additionalRestrictions as $additionalRestriction) {
197  $restrictionContainer->add($additionalRestriction);
198  }
199  }
200 
201  private function ‪ensureQueryNotExecuted(): void
202  {
203  if ($this->result) {
204  throw new \RuntimeException('Cannot modify file query once it was executed. Create a new query instead.', 1555944032);
205  }
206  }
207 }
‪TYPO3\CMS\Core\Resource\Search\FileSearchQuery\__construct
‪__construct(QueryBuilder $queryBuilder=null)
Definition: FileSearchQuery.php:51
‪TYPO3\CMS\Core\Resource\Search\FileSearchQuery
Definition: FileSearchQuery.php:34
‪TYPO3\CMS\Core\Database\Query\QueryHelper\parseOrderBy
‪static array array[] parseOrderBy(string $input)
Definition: QueryHelper.php:42
‪TYPO3\CMS\Core\Database\Query\Restriction\QueryRestrictionInterface
Definition: QueryRestrictionInterface.php:25
‪TYPO3\CMS\Core\Resource\Search\FileSearchQuery\createForSearchDemand
‪static FileSearchQuery createForSearchDemand(FileSearchDemand $searchDemand, QueryBuilder $queryBuilder=null)
Definition: FileSearchQuery.php:63
‪TYPO3\CMS\Core\Resource\Search\FileSearchDemand\isRecursive
‪isRecursive()
Definition: FileSearchDemand.php:103
‪TYPO3\CMS\Core\Resource\Search\FileSearchDemand\addOrdering
‪addOrdering(string $tableName, string $fieldName, string $direction='ASC')
Definition: FileSearchDemand.php:155
‪TYPO3\CMS\Core\Resource\Search\FileSearchDemand\getFirstResult
‪getFirstResult()
Definition: FileSearchDemand.php:83
‪TYPO3\CMS\Core\Resource\Search\FileSearchQuery\ensureQueryNotExecuted
‪ensureQueryNotExecuted()
Definition: FileSearchQuery.php:198
‪TYPO3\CMS\Core\Database\Query\QueryBuilder
Definition: QueryBuilder.php:47
‪TYPO3\CMS\Core\Resource\Search\FileSearchQuery\execute
‪execute()
Definition: FileSearchQuery.php:167
‪TYPO3\CMS\Core\Resource\Search\FileSearchQuery\$queryBuilder
‪QueryBuilder $queryBuilder
Definition: FileSearchQuery.php:41
‪TYPO3\CMS\Core\Resource\Search\FileSearchQuery\$additionalRestrictions
‪QueryRestrictionInterface[] $additionalRestrictions
Definition: FileSearchQuery.php:45
‪TYPO3\CMS\Core\Resource\Search\FileSearchQuery\additionalRestriction
‪additionalRestriction(QueryRestrictionInterface $additionalRestriction)
Definition: FileSearchQuery.php:161
‪TYPO3\CMS\Core\Resource\Search\FileSearchQuery\createCountForSearchDemand
‪static FileSearchQuery createCountForSearchDemand(FileSearchDemand $searchDemand, QueryBuilder $queryBuilder=null)
Definition: FileSearchQuery.php:132
‪TYPO3\CMS\Core\Resource\Search\QueryRestrictions\ConsistencyRestriction
Definition: ConsistencyRestriction.php:27
‪TYPO3\CMS\Core\Database\Query\QueryHelper
Definition: QueryHelper.php:30
‪TYPO3\CMS\Core\Resource\Search\FileSearchQuery\initializeQueryBuilder
‪initializeQueryBuilder()
Definition: FileSearchQuery.php:181
‪TYPO3\CMS\Core\Resource\Search\FileSearchDemand
Definition: FileSearchDemand.php:24
‪TYPO3\CMS\Core\Resource\Search\FileSearchQuery\FILES_TABLE
‪const FILES_TABLE
Definition: FileSearchQuery.php:35
‪TYPO3\CMS\Core\Resource\Search\FileSearchQuery\FILES_META_TABLE
‪const FILES_META_TABLE
Definition: FileSearchQuery.php:37
‪TYPO3\CMS\Core\Resource\Search
Definition: FileSearchDemand.php:3
‪TYPO3\CMS\Core\Resource\Search\FileSearchDemand\getFolder
‪getFolder()
Definition: FileSearchDemand.php:78
‪$GLOBALS
‪$GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['adminpanel']['modules']
Definition: ext_localconf.php:5
‪TYPO3\CMS\Core\Resource\Search\FileSearchQuery\$result
‪Doctrine DBAL Driver Statement int $result
Definition: FileSearchQuery.php:49
‪TYPO3\CMS\Core\Resource\Search\FileSearchDemand\getMaxResults
‪getMaxResults()
Definition: FileSearchDemand.php:88
‪TYPO3\CMS\Core\Resource\Search\FileSearchDemand\getOrderings
‪getOrderings()
Definition: FileSearchDemand.php:98
‪TYPO3\CMS\Core\Resource\Search\QueryRestrictions\FolderMountsRestriction
Definition: FolderMountsRestriction.php:30
‪TYPO3\CMS\Core\Database\ConnectionPool
Definition: ConnectionPool.php:44
‪TYPO3\CMS\Core\Utility\GeneralUtility
Definition: GeneralUtility.php:45
‪TYPO3\CMS\Core\Resource\Search\QueryRestrictions\FolderRestriction
Definition: FolderRestriction.php:28
‪TYPO3\CMS\Core\Resource\Search\QueryRestrictions\SearchTermRestriction
Definition: SearchTermRestriction.php:29