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