‪TYPO3CMS  10.4
FileSearchQuery.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 
30 
37 {
38  private const ‪FILES_TABLE = 'sys_file';
39 
40  private const ‪FILES_META_TABLE = 'sys_file_metadata';
41 
45  private ‪$queryBuilder;
46 
50  private ‪$additionalRestrictions = [];
51 
55  private ‪$result;
56 
57  public function ‪__construct(‪QueryBuilder ‪$queryBuilder = null)
58  {
59  $this->queryBuilder = ‪$queryBuilder ?? GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable(self::FILES_TABLE);
60  }
61 
69  public static function ‪createForSearchDemand(‪FileSearchDemand $searchDemand, ‪QueryBuilder ‪$queryBuilder = null): self
70  {
71  $query = new self(‪$queryBuilder);
72  $query->additionalRestriction(
73  new ‪SearchTermRestriction($searchDemand, $query->queryBuilder)
74  );
75  $folder = $searchDemand->‪getFolder();
76  if ($folder !== null) {
77  $query->additionalRestriction(
78  new ‪FolderRestriction($folder, $searchDemand->‪isRecursive())
79  );
80  } else {
81  $query->additionalRestriction(
82  new FolderMountsRestriction(‪$GLOBALS['BE_USER'])
83  );
84  }
85 
86  $query->queryBuilder->add(
87  'select',
88  [
89  'DISTINCT ' . $query->queryBuilder->quoteIdentifier(self::FILES_TABLE . '.identifier'),
90  $query->queryBuilder->quoteIdentifier(self::FILES_TABLE) . '.*',
91  ]
92  );
93 
94  if ($searchDemand->‪getFirstResult() !== null) {
95  $query->queryBuilder->setFirstResult($searchDemand->‪getFirstResult());
96  }
97  if ($searchDemand->‪getMaxResults() !== null) {
98  $query->queryBuilder->setMaxResults($searchDemand->‪getMaxResults());
99  }
100 
101  if ($searchDemand->‪getOrderings() === null) {
102  $orderBy = ‪$GLOBALS['TCA'][‪self::FILES_TABLE]['ctrl']['sortby'] ?: ‪$GLOBALS['TCA'][‪self::FILES_TABLE]['ctrl']['default_sortby'];
103  foreach (‪QueryHelper::parseOrderBy((string)$orderBy) as [$fieldName, $order]) {
104  $searchDemand = $searchDemand->‪addOrdering(self::FILES_TABLE, $fieldName, $order);
105  }
106  }
107  foreach ($searchDemand->‪getOrderings() as [$tableName, $fieldName, $direction]) {
108  if (!isset(‪$GLOBALS['TCA'][$tableName]['columns'][$fieldName]) || !in_array($direction, ['ASC', 'DESC'], true)) {
109  // This exception is essential to avoid SQL injections based on ordering field names, which could be input controlled by an attacker.
110  throw new \RuntimeException(sprintf('Invalid file search ordering given table: "%s", field: "%s", direction: "%s".', $tableName, $fieldName, $direction), 1555850106);
111  }
112  // Add order by fields to select, to make postgres happy and use random names to make sure to not interfere with file fields
113  $query->queryBuilder->add(
114  'select',
115  $query->queryBuilder->quoteIdentifiersForSelect([
116  $tableName . '.' . $fieldName
117  . ' AS '
118  . preg_replace(
119  '/[^a-z0-9]/',
120  '',
121  ‪StringUtility::getUniqueId($tableName . $fieldName)
122  )
123  ]),
124  true
125  );
126  $query->queryBuilder->addOrderBy($tableName . '.' . $fieldName, $direction);
127  }
128 
129  return $query;
130  }
131 
139  public static function ‪createCountForSearchDemand(FileSearchDemand $searchDemand, QueryBuilder ‪$queryBuilder = null): self
140  {
141  $query = new self(‪$queryBuilder);
142  $query->additionalRestriction(
143  new SearchTermRestriction($searchDemand, $query->queryBuilder)
144  );
145  $folder = $searchDemand->getFolder();
146  if ($folder !== null) {
147  $query->additionalRestriction(
148  new FolderRestriction($folder, $searchDemand->isRecursive())
149  );
150  }
151 
152  $query->queryBuilder->add(
153  'select',
154  'COUNT(DISTINCT ' . $query->queryBuilder->quoteIdentifier(self::FILES_TABLE . '.identifier') . ')'
155  );
156 
157  return $query;
158  }
159 
169  public function ‪additionalRestriction(QueryRestrictionInterface $additionalRestriction): void
170  {
171  $this->‪ensureQueryNotExecuted();
172  $this->additionalRestrictions[get_class($additionalRestriction)] = $additionalRestriction;
173  }
174 
175  public function ‪execute()
176  {
177  if ($this->result === null) {
178  $this->‪initializeQueryBuilder();
179  $this->result = $this->queryBuilder->execute();
180  }
181 
182  return ‪$this->result;
183  }
184 
189  private function ‪initializeQueryBuilder(): void
190  {
191  $this->queryBuilder->from(self::FILES_TABLE);
192  $this->queryBuilder->join(
193  self::FILES_TABLE,
194  self::FILES_META_TABLE,
195  self::FILES_META_TABLE,
196  $this->queryBuilder->expr()->eq(self::FILES_META_TABLE . '.file', $this->queryBuilder->quoteIdentifier(self::FILES_TABLE . '.uid'))
197  );
198 
199  $restrictionContainer = $this->queryBuilder->getRestrictions()
200  ->add(new ConsistencyRestriction($this->queryBuilder));
201  foreach ($this->additionalRestrictions as $additionalRestriction) {
202  $restrictionContainer->add($additionalRestriction);
203  }
204  }
205 
206  private function ‪ensureQueryNotExecuted(): void
207  {
208  if ($this->result) {
209  throw new \RuntimeException('Cannot modify file query once it was executed. Create a new query instead.', 1555944032);
210  }
211  }
212 }
‪TYPO3\CMS\Core\Resource\Search\FileSearchQuery\__construct
‪__construct(QueryBuilder $queryBuilder=null)
Definition: FileSearchQuery.php:54
‪TYPO3\CMS\Core\Resource\Search\FileSearchQuery
Definition: FileSearchQuery.php:37
‪TYPO3\CMS\Core\Database\Query\QueryHelper\parseOrderBy
‪static array array[] parseOrderBy(string $input)
Definition: QueryHelper.php:44
‪TYPO3\CMS\Core\Database\Query\Restriction\QueryRestrictionInterface
Definition: QueryRestrictionInterface.php:27
‪TYPO3\CMS\Core\Resource\Search\FileSearchQuery\createForSearchDemand
‪static FileSearchQuery createForSearchDemand(FileSearchDemand $searchDemand, QueryBuilder $queryBuilder=null)
Definition: FileSearchQuery.php:66
‪TYPO3\CMS\Core\Resource\Search\FileSearchDemand\isRecursive
‪isRecursive()
Definition: FileSearchDemand.php:105
‪TYPO3\CMS\Core\Resource\Search\FileSearchDemand\addOrdering
‪addOrdering(string $tableName, string $fieldName, string $direction='ASC')
Definition: FileSearchDemand.php:157
‪TYPO3\CMS\Core\Resource\Search\FileSearchDemand\getFirstResult
‪getFirstResult()
Definition: FileSearchDemand.php:85
‪TYPO3\CMS\Core\Resource\Search\FileSearchQuery\ensureQueryNotExecuted
‪ensureQueryNotExecuted()
Definition: FileSearchQuery.php:203
‪TYPO3\CMS\Core\Database\Query\QueryBuilder
Definition: QueryBuilder.php:52
‪TYPO3\CMS\Core\Resource\Search\FileSearchQuery\execute
‪execute()
Definition: FileSearchQuery.php:172
‪TYPO3\CMS\Core\Resource\Search\FileSearchQuery\$queryBuilder
‪QueryBuilder $queryBuilder
Definition: FileSearchQuery.php:44
‪TYPO3\CMS\Core\Resource\Search\FileSearchQuery\$additionalRestrictions
‪QueryRestrictionInterface[] $additionalRestrictions
Definition: FileSearchQuery.php:48
‪TYPO3\CMS\Core\Resource\Search\FileSearchQuery\additionalRestriction
‪additionalRestriction(QueryRestrictionInterface $additionalRestriction)
Definition: FileSearchQuery.php:166
‪TYPO3\CMS\Core\Resource\Search\FileSearchQuery\createCountForSearchDemand
‪static FileSearchQuery createCountForSearchDemand(FileSearchDemand $searchDemand, QueryBuilder $queryBuilder=null)
Definition: FileSearchQuery.php:136
‪TYPO3\CMS\Core\Resource\Search\QueryRestrictions\ConsistencyRestriction
Definition: ConsistencyRestriction.php:29
‪TYPO3\CMS\Core\Database\Query\QueryHelper
Definition: QueryHelper.php:32
‪TYPO3\CMS\Core\Resource\Search\FileSearchQuery\initializeQueryBuilder
‪initializeQueryBuilder()
Definition: FileSearchQuery.php:186
‪TYPO3\CMS\Core\Resource\Search\FileSearchDemand
Definition: FileSearchDemand.php:26
‪TYPO3\CMS\Core\Resource\Search\FileSearchQuery\FILES_TABLE
‪const FILES_TABLE
Definition: FileSearchQuery.php:38
‪TYPO3\CMS\Core\Resource\Search\FileSearchQuery\FILES_META_TABLE
‪const FILES_META_TABLE
Definition: FileSearchQuery.php:40
‪TYPO3\CMS\Core\Resource\Search
Definition: FileSearchDemand.php:18
‪TYPO3\CMS\Core\Resource\Search\FileSearchDemand\getFolder
‪getFolder()
Definition: FileSearchDemand.php:80
‪TYPO3\CMS\Core\Utility\StringUtility\getUniqueId
‪static string getUniqueId($prefix='')
Definition: StringUtility.php:92
‪$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:52
‪TYPO3\CMS\Core\Resource\Search\FileSearchDemand\getMaxResults
‪getMaxResults()
Definition: FileSearchDemand.php:90
‪TYPO3\CMS\Core\Resource\Search\FileSearchDemand\getOrderings
‪getOrderings()
Definition: FileSearchDemand.php:100
‪TYPO3\CMS\Core\Resource\Search\QueryRestrictions\FolderMountsRestriction
Definition: FolderMountsRestriction.php:33
‪TYPO3\CMS\Core\Database\ConnectionPool
Definition: ConnectionPool.php:46
‪TYPO3\CMS\Core\Utility\GeneralUtility
Definition: GeneralUtility.php:46
‪TYPO3\CMS\Core\Utility\StringUtility
Definition: StringUtility.php:22
‪TYPO3\CMS\Core\Resource\Search\QueryRestrictions\FolderRestriction
Definition: FolderRestriction.php:30
‪TYPO3\CMS\Core\Resource\Search\QueryRestrictions\SearchTermRestriction
Definition: SearchTermRestriction.php:31