‪TYPO3CMS  ‪main
SearchTermRestriction.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 
22 use TYPO3\CMS\Core\Database\Query\QueryBuilder;
26 
31 {
35  private ‪$searchDemand;
36 
41 
43  {
44  $this->searchDemand = ‪$searchDemand;
45  $this->queryBuilder = ‪$queryBuilder;
46  }
47 
48  public function ‪buildExpression(array $queriedTables, ‪ExpressionBuilder $expressionBuilder): ‪CompositeExpression
49  {
50  $constraints = [];
51  foreach ($queriedTables as $tableAlias => $tableName) {
52  if (!in_array($tableName, ['sys_file', 'sys_file_metadata'])) {
53  continue;
54  }
55  $constraints[] = $this->‪makeQuerySearchByTable($tableName, $tableAlias);
56  }
57 
58  return $expressionBuilder->‪or(...$constraints);
59  }
60 
66  private function ‪makeQuerySearchByTable(string $tableName, string $tableAlias): CompositeExpression
67  {
68  $fieldsToSearchWithin = $this->‪extractSearchableFieldsFromTable($tableName);
69  $searchTerm = (string)$this->searchDemand->getSearchTerm();
70  $constraints = [];
71 
72  $searchTermParts = str_getcsv($searchTerm, ' ');
73  foreach ($searchTermParts as $searchTermPart) {
74  $searchTermPart = trim($searchTermPart);
75  if ($searchTermPart === '') {
76  continue;
77  }
78  $constraintsForParts = [];
79  $like = '%' . $this->queryBuilder->escapeLikeWildcards($searchTermPart) . '%';
80  foreach ($fieldsToSearchWithin as $fieldName) {
81  if (!isset(‪$GLOBALS['TCA'][$tableName]['columns'][$fieldName])) {
82  continue;
83  }
84  $fieldConfig = ‪$GLOBALS['TCA'][$tableName]['columns'][$fieldName]['config'];
85  $fieldType = $fieldConfig['type'];
86  $evalRules = $fieldConfig['eval'] ?? '';
87 
88  // Check whether search should be case-sensitive or not
89  if (in_array('case', (array)($fieldConfig['search'] ?? []), true)) {
90  // case sensitive
91  $searchConstraint = $this->queryBuilder->expr()->and(
92  $this->queryBuilder->expr()->like(
93  $tableAlias . '.' . $fieldName,
94  $this->queryBuilder->createNamedParameter($like)
95  )
96  );
97  } else {
98  $searchConstraint = $this->queryBuilder->expr()->and(
99  // case insensitive
100  $this->queryBuilder->expr()->comparison(
101  'LOWER(' . $this->queryBuilder->quoteIdentifier($tableAlias . '.' . $fieldName) . ')',
102  'LIKE',
103  $this->queryBuilder->createNamedParameter(mb_strtolower($like))
104  )
105  );
106  }
107 
108  // Assemble the search condition only if the field makes sense to be searched
109  if ($fieldType === 'text'
110  || $fieldType === 'flex'
111  || $fieldType === 'json'
112  || $fieldType === 'email'
113  || $fieldType === 'link'
114  || $fieldType === 'color'
115  || $fieldType === 'input'
116  || $fieldType === 'uuid'
117  ) {
118  $constraintsForParts[] = $searchConstraint;
119  }
120  }
121  $constraints[] = $this->queryBuilder->expr()->or(...$constraintsForParts);
122  }
123 
124  return $this->queryBuilder->expr()->and(...$constraints);
125  }
126 
132  private function ‪extractSearchableFieldsFromTable(string $tableName): array
133  {
134  if ($searchFields = $this->searchDemand->getSearchFields()) {
135  if (empty($searchFields[$tableName])) {
136  return [];
137  }
138  foreach ($searchFields[$tableName] as $searchField) {
139  if (!isset(‪$GLOBALS['TCA'][$tableName]['columns'][$searchField])) {
140  throw new \RuntimeException(sprintf('Cannot use search field "%s" because it is not defined in TCA.', $searchField), 1556367071);
141  }
142  }
143 
144  return $searchFields;
145  }
146  $fieldListArray = [];
147  // Get the list of fields to search in from the TCA, if any
148  if (isset(‪$GLOBALS['TCA'][$tableName]['ctrl']['searchFields'])) {
149  $fieldListArray = ‪GeneralUtility::trimExplode(',', ‪$GLOBALS['TCA'][$tableName]['ctrl']['searchFields'], true);
150  }
151 
152  return $fieldListArray;
153  }
154 }
‪TYPO3\CMS\Core\Database\Query\Expression\ExpressionBuilder
Definition: ExpressionBuilder.php:40
‪TYPO3\CMS\Core\Resource\Search\QueryRestrictions\SearchTermRestriction\buildExpression
‪buildExpression(array $queriedTables, ExpressionBuilder $expressionBuilder)
Definition: SearchTermRestriction.php:46
‪TYPO3\CMS\Core\Database\Query\Restriction\QueryRestrictionInterface
Definition: QueryRestrictionInterface.php:27
‪TYPO3\CMS\Core\Database\Query\Expression\ExpressionBuilder\or
‪or(CompositeExpression|\Doctrine\DBAL\Query\Expression\CompositeExpression|string|null ... $expressions)
Definition: ExpressionBuilder.php:59
‪TYPO3\CMS\Core\Resource\Search\QueryRestrictions\SearchTermRestriction\extractSearchableFieldsFromTable
‪extractSearchableFieldsFromTable(string $tableName)
Definition: SearchTermRestriction.php:130
‪TYPO3\CMS\Core\Resource\Search\QueryRestrictions\SearchTermRestriction\$queryBuilder
‪QueryBuilder $queryBuilder
Definition: SearchTermRestriction.php:38
‪TYPO3\CMS\Core\Resource\Search\QueryRestrictions\SearchTermRestriction\makeQuerySearchByTable
‪makeQuerySearchByTable(string $tableName, string $tableAlias)
Definition: SearchTermRestriction.php:64
‪TYPO3\CMS\Core\Resource\Search\QueryRestrictions\SearchTermRestriction\$searchDemand
‪FileSearchDemand $searchDemand
Definition: SearchTermRestriction.php:34
‪TYPO3\CMS\Core\Database\Query\Expression\CompositeExpression
Definition: CompositeExpression.php:27
‪TYPO3\CMS\Core\Resource\Search\FileSearchDemand
Definition: FileSearchDemand.php:26
‪TYPO3\CMS\Core\Resource\Search\QueryRestrictions
Definition: ConsistencyRestriction.php:18
‪$GLOBALS
‪$GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['adminpanel']['modules']
Definition: ext_localconf.php:25
‪TYPO3\CMS\Core\Resource\Search\QueryRestrictions\SearchTermRestriction\__construct
‪__construct(FileSearchDemand $searchDemand, QueryBuilder $queryBuilder)
Definition: SearchTermRestriction.php:40
‪TYPO3\CMS\Core\Utility\GeneralUtility
Definition: GeneralUtility.php:52
‪TYPO3\CMS\Core\Resource\Search\QueryRestrictions\SearchTermRestriction
Definition: SearchTermRestriction.php:31
‪TYPO3\CMS\Core\Utility\GeneralUtility\trimExplode
‪static list< string > trimExplode(string $delim, string $string, bool $removeEmptyValues=false, int $limit=0)
Definition: GeneralUtility.php:822