‪TYPO3CMS  ‪main
DatabaseRecordProvider.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 
20 use Doctrine\DBAL\ArrayParameterType;
21 use Psr\EventDispatcher\EventDispatcherInterface;
29 use TYPO3\CMS\Backend\Utility\BackendUtility;
34 use TYPO3\CMS\Core\Database\Query\QueryBuilder;
40 use TYPO3\CMS\Core\Imaging\IconSize;
46 
53 {
54  private const ‪RECURSIVE_PAGE_LEVEL = 99;
55 
57  protected string ‪$userPermissions;
58  protected array ‪$pageIdList = [];
59 
60  public function ‪__construct(
61  protected readonly EventDispatcherInterface $eventDispatcher,
62  protected readonly ‪IconFactory $iconFactory,
63  protected readonly ‪LanguageServiceFactory $languageServiceFactory,
64  protected readonly ‪UriBuilder $uriBuilder,
65  protected readonly ‪QueryParser $queryParser,
66  ) {
67  $this->languageService = $this->languageServiceFactory->createFromUserPreferences($this->‪getBackendUser());
68  $this->userPermissions = $this->‪getBackendUser()->getPagePermsClause(‪Permission::PAGE_SHOW);
69  }
70 
71  public function ‪getFilterLabel(): string
72  {
73  return $this->languageService->sL('LLL:EXT:backend/Resources/Private/Language/locallang.xlf:liveSearch.databaseRecordProvider.filterLabel');
74  }
75 
76  public function ‪count(‪SearchDemand $searchDemand): int
77  {
78  $count = 0;
79  $event = $this->eventDispatcher->dispatch(
81  );
82  $this->pageIdList = $event->getSearchPageIds();
83  $searchDemand = $event->getSearchDemand();
84 
85  $accessibleTables = $this->‪getAccessibleTables($event);
86 
87  $parsedCommand = $this->‪parseCommand($searchDemand);
88  $searchDemand = $parsedCommand['searchDemand'];
89  if ($parsedCommand['table'] !== null && in_array($parsedCommand['table'], $accessibleTables)) {
90  $accessibleTables = [$parsedCommand['table']];
91  }
92 
93  foreach ($accessibleTables as $tableName) {
94  $count += $this->‪countByTable($searchDemand, $tableName);
95  }
96 
97  return $count;
98  }
99 
103  public function ‪find(‪SearchDemand $searchDemand): array
104  {
105  $result = [];
106  $remainingItems = $searchDemand->‪getLimit();
107  $offset = $searchDemand->‪getOffset();
108  if ($remainingItems < 1) {
109  return [];
110  }
111 
112  $event = $this->eventDispatcher->dispatch(
114  );
115  $this->pageIdList = $event->getSearchPageIds();
116  $searchDemand = $event->getSearchDemand();
117  $accessibleTables = $this->‪getAccessibleTables($event);
118 
119  $parsedCommand = $this->‪parseCommand($searchDemand);
120  $searchDemand = $parsedCommand['searchDemand'];
121  if ($parsedCommand['table'] !== null && in_array($parsedCommand['table'], $accessibleTables)) {
122  $accessibleTables = [$parsedCommand['table']];
123  }
124 
125  foreach ($accessibleTables as $tableName) {
126  if ($remainingItems < 1) {
127  break;
128  }
129 
130  // To have a reliable offset calculation across several database tables, we have to count the amount of
131  // records and subtract the amount from the offset to be used, IF the amount is smaller than the requested
132  // offset. At any point, the offset will be smaller than the amount of records, which will then be used in
133  // ->findByTable().
134  // If any subsequent ->findByTable() call returns a result, the offset becomes irrelevant and is then zeroed.
135  if ($offset > 0) {
136  $tableCount = $this->‪countByTable($searchDemand, $tableName);
137  if ($tableCount <= $offset) {
138  $offset = max(0, $offset - $tableCount);
139  continue;
140  }
141  }
142 
143  $tableResult = $this->‪findByTable($searchDemand, $tableName, $remainingItems, $offset);
144  if ($tableResult !== []) {
145  $remainingItems -= ‪count($tableResult);
146  $offset = 0;
147  $result[] = $tableResult;
148  }
149  }
150 
151  return array_merge([], ...$result);
152  }
153 
154  protected function ‪parseCommand(‪SearchDemand $searchDemand): array
155  {
156  $tableName = null;
157  $commandQuery = null;
158  $query = $searchDemand->‪getQuery();
159 
160  if ($this->queryParser->isValidCommand($query)) {
161  $commandQuery = $query;
162  } elseif ($this->queryParser->isValidPageJump($query)) {
163  $commandQuery = $this->queryParser->getCommandForPageJump($query);
164  }
165 
166  if ($commandQuery !== null) {
167  $tableName = $this->queryParser->getTableNameFromCommand($query);
168  $extractedQueryString = $this->queryParser->getSearchQueryValue($commandQuery);
169  $searchDemand = new ‪SearchDemand([
170  new ‪DemandProperty(DemandPropertyName::query, $extractedQueryString),
171  ...array_filter(
172  $searchDemand->‪getProperties(),
173  static fn(‪DemandProperty $demandProperty): bool => $demandProperty->‪getName() !== DemandPropertyName::query
174  ),
175  ]);
176  }
177 
178  return [
179  'searchDemand' => $searchDemand,
180  'table' => $tableName,
181  ];
182  }
183 
184  protected function ‪getQueryBuilderForTable(‪SearchDemand $searchDemand, string $tableName): ?QueryBuilder
185  {
186  $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)
187  ->getQueryBuilderForTable($tableName);
188  $queryBuilder->getRestrictions()
189  ->removeByType(HiddenRestriction::class)
190  ->removeByType(StartTimeRestriction::class)
191  ->removeByType(EndTimeRestriction::class);
192 
193  $constraints = $this->‪buildConstraintsForTable($searchDemand->‪getQuery(), $queryBuilder, $tableName);
194  if ($constraints === []) {
195  return null;
196  }
197 
198  $queryBuilder
199  ->from($tableName)
200  ->where(
201  $queryBuilder->expr()->or(...$constraints)
202  );
203 
204  if ($this->pageIdList !== []) {
205  $queryBuilder->andWhere(
206  $queryBuilder->expr()->in(
207  'pid',
208  $queryBuilder->createNamedParameter($this->pageIdList, ArrayParameterType::INTEGER)
209  )
210  );
211  }
212 
214  $event = $this->eventDispatcher->dispatch(new ‪ModifyQueryForLiveSearchEvent($queryBuilder, $tableName));
215 
216  return $event->getQueryBuilder();
217  }
218 
219  protected function ‪countByTable(‪SearchDemand $searchDemand, string $tableName): int
220  {
221  $queryBuilder = $this->‪getQueryBuilderForTable($searchDemand, $tableName);
222  return (int)$queryBuilder?->count('*')->executeQuery()->fetchOne();
223  }
224 
228  protected function ‪findByTable(‪SearchDemand $searchDemand, string $tableName, int $limit, int $offset): array
229  {
230  $queryBuilder = $this->‪getQueryBuilderForTable($searchDemand, $tableName);
231  if ($queryBuilder === null) {
232  return [];
233  }
234 
235  $queryBuilder
236  ->select('*')
237  ->setFirstResult($offset)
238  ->setMaxResults($limit);
239 
240  $queryBuilder->addOrderBy('uid', 'DESC');
241 
242  $items = [];
243  $result = $queryBuilder->executeQuery();
244  while ($row = $result->fetchAssociative()) {
245  BackendUtility::workspaceOL($tableName, $row);
246  if (!is_array($row)) {
247  continue;
248  }
249 
250  $actions = [];
251  $showLink = $this->‪getShowLink($row);
252  if ($showLink !== '') {
253  $actions[] = (new ‪ResultItemAction('open_page_details'))
254  ->setLabel($this->languageService->sL('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:labels.showList'))
255  ->setIcon($this->iconFactory->getIcon('actions-list', IconSize::SMALL))
256  ->setUrl($showLink);
257  }
258 
259  $editLink = $this->‪getEditLink($tableName, $row);
260  if ($editLink !== '') {
261  $actions[] = (new ‪ResultItemAction('edit_record'))
262  ->setLabel($this->languageService->sL('LLL:EXT:core/Resources/Private/Language/locallang_common.xlf:edit'))
263  ->setIcon($this->iconFactory->getIcon('actions-open', IconSize::SMALL))
264  ->setUrl($editLink);
265  }
266 
267  $extraData = [
268  'table' => $tableName,
269  'uid' => $row['uid'],
270  ];
271  if (!(‪$GLOBALS['TCA'][$tableName]['ctrl']['rootLevel'] ?? false)) {
272  $extraData['breadcrumb'] = BackendUtility::getRecordPath($row['pid'], 'AND ' . $this->userPermissions, 0);
273  }
274 
275  $icon = $this->iconFactory->getIconForRecord($tableName, $row, IconSize::SMALL);
276  $items[] = (new ‪ResultItem(self::class))
277  ->setItemTitle(BackendUtility::getRecordTitle($tableName, $row))
278  ->setTypeLabel($this->languageService->sL(‪$GLOBALS['TCA'][$tableName]['ctrl']['title']))
279  ->setIcon($icon)
280  ->setActions(...$actions)
281  ->setExtraData($extraData)
282  ->setInternalData([
283  'row' => $row,
284  ])
285  ;
286  }
287 
288  return $items;
289  }
290 
291  protected function ‪canAccessTable(string $tableName): bool
292  {
293  if ((‪$GLOBALS['TCA'][$tableName]['ctrl']['hideTable'] ?? false)
294  || (
295  !$this->‪getBackendUser()->check('tables_select', $tableName)
296  && !$this->‪getBackendUser()->check('tables_modify', $tableName)
297  )
298  ) {
299  return false;
300  }
301 
302  return true;
303  }
304 
306  {
307  return array_filter(array_keys(‪$GLOBALS['TCA']), function (string $tableName) use ($event): bool {
308  return $this->‪canAccessTable($tableName) && !$event->‪isTableIgnored($tableName);
309  });
310  }
311 
317  protected function ‪getPageIdList(): array
318  {
319  if ($this->‪getBackendUser()->isAdmin()) {
320  return [];
321  }
322  $mounts = $this->‪getBackendUser()->returnWebmounts();
323  $pageList = $mounts;
324  $repository = GeneralUtility::makeInstance(PageTreeRepository::class);
325  $repository->setAdditionalWhereClause($this->userPermissions);
326  $pages = $repository->getFlattenedPages($mounts, self::RECURSIVE_PAGE_LEVEL);
327  foreach ($pages as $page) {
328  $pageList[] = (int)$page['uid'];
329  }
330  return $pageList;
331  }
332 
338  protected function ‪extractSearchableFieldsFromTable(string $tableName): array
339  {
340  // Get the list of fields to search in from the TCA, if any
341  if (isset(‪$GLOBALS['TCA'][$tableName]['ctrl']['searchFields'])) {
342  $fieldListArray = ‪GeneralUtility::trimExplode(',', ‪$GLOBALS['TCA'][$tableName]['ctrl']['searchFields'], true);
343  } else {
344  $fieldListArray = [];
345  }
346  // Add special fields
347  if ($this->‪getBackendUser()->isAdmin()) {
348  $fieldListArray[] = 'uid';
349  $fieldListArray[] = 'pid';
350  }
351  return $fieldListArray;
352  }
353 
357  protected function ‪buildConstraintsForTable(string $queryString, QueryBuilder $queryBuilder, string $tableName): array
358  {
359  $fieldsToSearchWithin = $this->‪extractSearchableFieldsFromTable($tableName);
360  if ($fieldsToSearchWithin === []) {
361  return [];
362  }
363 
364  $constraints = [];
365 
366  // If the search string is a simple integer, assemble an equality comparison
367  if (‪MathUtility::canBeInterpretedAsInteger($queryString)) {
368  foreach ($fieldsToSearchWithin as $fieldName) {
369  if ($fieldName !== 'uid'
370  && $fieldName !== 'pid'
371  && !isset(‪$GLOBALS['TCA'][$tableName]['columns'][$fieldName])
372  ) {
373  continue;
374  }
375  $fieldConfig = ‪$GLOBALS['TCA'][$tableName]['columns'][$fieldName]['config'] ?? [];
376  $fieldType = $fieldConfig['type'] ?? '';
377 
378  // Assemble the search condition only if the field is an integer, or is uid or pid
379  if ($fieldName === 'uid'
380  || $fieldName === 'pid'
381  || ($fieldType === 'number' && ($fieldConfig['format'] ?? 'integer') === 'integer')
382  || ($fieldType === 'datetime' && !in_array($fieldConfig['dbType'] ?? '', ‪QueryHelper::getDateTimeTypes(), true))
383  ) {
384  $constraints[] = $queryBuilder->expr()->eq(
385  $fieldName,
386  $queryBuilder->createNamedParameter($queryString, ‪Connection::PARAM_INT)
387  );
388  } elseif ($this->‪fieldTypeIsSearchable($fieldType)) {
389  // Otherwise and if the field makes sense to be searched, assemble a like condition
390  $constraints[] = $queryBuilder->expr()->like(
391  $fieldName,
392  $queryBuilder->createNamedParameter(
393  '%' . $queryBuilder->escapeLikeWildcards($queryString) . '%'
394  )
395  );
396  }
397  }
398  } else {
399  $like = '%' . $queryBuilder->escapeLikeWildcards($queryString) . '%';
400  foreach ($fieldsToSearchWithin as $fieldName) {
401  if (!isset(‪$GLOBALS['TCA'][$tableName]['columns'][$fieldName])) {
402  continue;
403  }
404  $fieldConfig = ‪$GLOBALS['TCA'][$tableName]['columns'][$fieldName]['config'] ?? [];
405  $fieldType = $fieldConfig['type'] ?? '';
406 
407  // Check whether search should be case-sensitive or not
408  $searchConstraint = $queryBuilder->expr()->and(
409  $queryBuilder->expr()->comparison(
410  'LOWER(' . $queryBuilder->quoteIdentifier($fieldName) . ')',
411  'LIKE',
412  $queryBuilder->createNamedParameter(mb_strtolower($like))
413  )
414  );
415 
416  if (is_array($fieldConfig['search'] ?? false)) {
417  if (in_array('case', $fieldConfig['search'], true)) {
418  // Replace case insensitive default constraint
419  $searchConstraint = $queryBuilder->expr()->and(
420  $queryBuilder->expr()->like(
421  $fieldName,
422  $queryBuilder->createNamedParameter($like)
423  )
424  );
425  }
426  // Apply additional condition, if any
427  if ($fieldConfig['search']['andWhere'] ?? false) {
428  $searchConstraint = $searchConstraint->with(
429  ‪QueryHelper::stripLogicalOperatorPrefix(‪QueryHelper::quoteDatabaseIdentifiers($queryBuilder->getConnection(), $fieldConfig['search']['andWhere']))
430  );
431  }
432  }
433  // Assemble the search condition only if the field makes sense to be searched
434  if ($this->‪fieldTypeIsSearchable($fieldType) && $searchConstraint->count() !== 0) {
435  $constraints[] = $searchConstraint;
436  }
437  }
438  }
439 
440  return $constraints;
441  }
442 
443  protected function ‪fieldTypeIsSearchable(string $fieldType): bool
444  {
445  $searchableFieldTypes = [
446  'input',
447  'text',
448  'json',
449  'flex',
450  'email',
451  'link',
452  'color',
453  'slug',
454  'uuid',
455  ];
456 
457  return in_array($fieldType, $searchableFieldTypes, true);
458  }
459 
466  protected function ‪getShowLink(array $row): string
467  {
468  $backendUser = $this->‪getBackendUser();
469  $showLink = '';
470  $permissionSet = new ‪Permission($this->‪getBackendUser()->calcPerms(BackendUtility::getRecord('pages', $row['pid']) ?? []));
471  // "View" link - Only with proper permissions
472  if ($backendUser->isAdmin()
473  || (
474  $permissionSet->showPagePermissionIsGranted()
475  && !(‪$GLOBALS['TCA']['pages']['ctrl']['adminOnly'] ?? false)
476  && $backendUser->check('tables_select', 'pages')
477  )
478  ) {
479  $showLink = (string)$this->uriBuilder->buildUriFromRoute('web_list', ['id' => $row['pid']]);
480  }
481  return $showLink;
482  }
483 
492  protected function ‪getEditLink(string $tableName, array $row): string
493  {
494  $backendUser = $this->‪getBackendUser();
495  $editLink = '';
496  $permissionSet = new ‪Permission($backendUser->calcPerms(BackendUtility::readPageAccess($row['pid'], $this->userPermissions) ?: []));
497  // "Edit" link - Only with proper edit permissions
498  if (!(‪$GLOBALS['TCA'][$tableName]['ctrl']['readOnly'] ?? false)
499  && (
500  $backendUser->isAdmin()
501  || (
502  $permissionSet->editContentPermissionIsGranted()
503  && !(‪$GLOBALS['TCA'][$tableName]['ctrl']['adminOnly'] ?? false)
504  && $backendUser->check('tables_modify', $tableName)
505  && $backendUser->recordEditAccessInternals($tableName, $row)
506  )
507  )
508  ) {
509  $returnUrl = (string)$this->uriBuilder->buildUriFromRoute('web_list', ['id' => $row['pid']]);
510  $editLink = (string)$this->uriBuilder->buildUriFromRoute('record_edit', [
511  'edit[' . $tableName . '][' . $row['uid'] . ']' => 'edit',
512  'returnUrl' => $returnUrl,
513  ]);
514  }
515  return $editLink;
516  }
517 
519  {
520  return ‪$GLOBALS['BE_USER'];
521  }
522 }
‪TYPO3\CMS\Backend\Search\LiveSearch\DatabaseRecordProvider\RECURSIVE_PAGE_LEVEL
‪const RECURSIVE_PAGE_LEVEL
Definition: DatabaseRecordProvider.php:54
‪TYPO3\CMS\Core\Localization\LanguageServiceFactory
Definition: LanguageServiceFactory.php:25
‪TYPO3\CMS\Backend\Search\LiveSearch\DatabaseRecordProvider\$pageIdList
‪array $pageIdList
Definition: DatabaseRecordProvider.php:58
‪TYPO3\CMS\Core\Database\Query\Restriction\HiddenRestriction
Definition: HiddenRestriction.php:27
‪TYPO3\CMS\Backend\Search\LiveSearch\DatabaseRecordProvider\parseCommand
‪parseCommand(SearchDemand $searchDemand)
Definition: DatabaseRecordProvider.php:154
‪TYPO3\CMS\Core\Database\Connection\PARAM_INT
‪const PARAM_INT
Definition: Connection.php:52
‪TYPO3\CMS\Backend\Search\LiveSearch\DatabaseRecordProvider\canAccessTable
‪canAccessTable(string $tableName)
Definition: DatabaseRecordProvider.php:291
‪TYPO3\CMS\Core\Database\Query\QueryHelper\quoteDatabaseIdentifiers
‪static quoteDatabaseIdentifiers(Connection $connection, string $sql)
Definition: QueryHelper.php:224
‪TYPO3\CMS\Core\Database\Query\Restriction\EndTimeRestriction
Definition: EndTimeRestriction.php:27
‪TYPO3\CMS\Backend\Search\Event\BeforeSearchInDatabaseRecordProviderEvent
Definition: BeforeSearchInDatabaseRecordProviderEvent.php:28
‪TYPO3\CMS\Core\Database\Query\Restriction\StartTimeRestriction
Definition: StartTimeRestriction.php:27
‪TYPO3\CMS\Backend\Search\LiveSearch\QueryParser
Definition: QueryParser.php:27
‪TYPO3\CMS\Backend\Search\LiveSearch\SearchDemand\SearchDemand\getProperties
‪DemandProperty[] getProperties()
Definition: SearchDemand.php:56
‪TYPO3\CMS\Backend\Search\LiveSearch\DatabaseRecordProvider\$languageService
‪LanguageService $languageService
Definition: DatabaseRecordProvider.php:56
‪TYPO3\CMS\Core\Imaging\IconFactory
Definition: IconFactory.php:34
‪TYPO3\CMS\Backend\Search\Event\ModifyQueryForLiveSearchEvent
Definition: ModifyQueryForLiveSearchEvent.php:26
‪TYPO3\CMS\Backend\Search\LiveSearch\SearchDemand\DemandPropertyName
‪DemandPropertyName
Definition: DemandPropertyName.php:21
‪TYPO3\CMS\Backend\Search\LiveSearch\DatabaseRecordProvider\$userPermissions
‪string $userPermissions
Definition: DatabaseRecordProvider.php:57
‪TYPO3\CMS\Core\Type\Bitmask\Permission
Definition: Permission.php:26
‪TYPO3\CMS\Backend\Search\LiveSearch\SearchDemand\DemandProperty
Definition: DemandProperty.php:21
‪TYPO3\CMS\Core\Utility\MathUtility\canBeInterpretedAsInteger
‪static bool canBeInterpretedAsInteger(mixed $var)
Definition: MathUtility.php:69
‪TYPO3\CMS\Core\Database\Query\Expression\CompositeExpression
Definition: CompositeExpression.php:27
‪TYPO3\CMS\Backend\Search\LiveSearch\DatabaseRecordProvider\fieldTypeIsSearchable
‪fieldTypeIsSearchable(string $fieldType)
Definition: DatabaseRecordProvider.php:443
‪TYPO3\CMS\Core\Database\Query\QueryHelper
Definition: QueryHelper.php:32
‪TYPO3\CMS\Backend\Search\LiveSearch\SearchDemand\SearchDemand
Definition: SearchDemand.php:29
‪TYPO3\CMS\Backend\Search\LiveSearch
Definition: DatabaseRecordProvider.php:18
‪TYPO3\CMS\Backend\Search\LiveSearch\SearchDemand\SearchDemand\getQuery
‪getQuery()
Definition: SearchDemand.php:66
‪TYPO3\CMS\Backend\Search\LiveSearch\DatabaseRecordProvider\getFilterLabel
‪getFilterLabel()
Definition: DatabaseRecordProvider.php:71
‪TYPO3\CMS\Backend\Search\LiveSearch\DatabaseRecordProvider\buildConstraintsForTable
‪CompositeExpression[] buildConstraintsForTable(string $queryString, QueryBuilder $queryBuilder, string $tableName)
Definition: DatabaseRecordProvider.php:357
‪TYPO3\CMS\Core\Database\Query\QueryHelper\getDateTimeTypes
‪static array getDateTimeTypes()
Definition: QueryHelper.php:211
‪TYPO3\CMS\Backend\Routing\UriBuilder
Definition: UriBuilder.php:44
‪TYPO3\CMS\Backend\Search\LiveSearch\SearchDemand\SearchDemand\getOffset
‪getOffset()
Definition: SearchDemand.php:76
‪TYPO3\CMS\Backend\Search\LiveSearch\DatabaseRecordProvider
Definition: DatabaseRecordProvider.php:53
‪TYPO3\CMS\Core\Authentication\BackendUserAuthentication
Definition: BackendUserAuthentication.php:62
‪TYPO3\CMS\Core\Type\Bitmask\Permission\PAGE_SHOW
‪const PAGE_SHOW
Definition: Permission.php:35
‪TYPO3\CMS\Backend\Search\LiveSearch\DatabaseRecordProvider\getEditLink
‪string getEditLink(string $tableName, array $row)
Definition: DatabaseRecordProvider.php:492
‪TYPO3\CMS\Backend\Search\Event\BeforeSearchInDatabaseRecordProviderEvent\isTableIgnored
‪isTableIgnored(string $table)
Definition: BeforeSearchInDatabaseRecordProviderEvent.php:66
‪TYPO3\CMS\Backend\Search\LiveSearch\SearchDemand\DemandProperty\getName
‪getName()
Definition: DemandProperty.php:27
‪TYPO3\CMS\Core\Database\Connection
Definition: Connection.php:41
‪TYPO3\CMS\Backend\Search\LiveSearch\DatabaseRecordProvider\__construct
‪__construct(protected readonly EventDispatcherInterface $eventDispatcher, protected readonly IconFactory $iconFactory, protected readonly LanguageServiceFactory $languageServiceFactory, protected readonly UriBuilder $uriBuilder, protected readonly QueryParser $queryParser,)
Definition: DatabaseRecordProvider.php:60
‪TYPO3\CMS\Backend\Search\LiveSearch\SearchDemand\SearchDemand\getLimit
‪getLimit()
Definition: SearchDemand.php:71
‪TYPO3\CMS\Core\Database\Query\QueryHelper\stripLogicalOperatorPrefix
‪static string stripLogicalOperatorPrefix(string $constraint)
Definition: QueryHelper.php:171
‪$GLOBALS
‪$GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['adminpanel']['modules']
Definition: ext_localconf.php:25
‪TYPO3\CMS\Backend\Tree\Repository\PageTreeRepository
Definition: PageTreeRepository.php:41
‪TYPO3\CMS\Backend\Search\LiveSearch\DatabaseRecordProvider\getBackendUser
‪getBackendUser()
Definition: DatabaseRecordProvider.php:518
‪TYPO3\CMS\Backend\Search\LiveSearch\DatabaseRecordProvider\getAccessibleTables
‪getAccessibleTables(BeforeSearchInDatabaseRecordProviderEvent $event)
Definition: DatabaseRecordProvider.php:305
‪TYPO3\CMS\Core\Utility\MathUtility
Definition: MathUtility.php:24
‪TYPO3\CMS\Core\Localization\LanguageService
Definition: LanguageService.php:46
‪TYPO3\CMS\Backend\Search\LiveSearch\ResultItem
Definition: ResultItem.php:28
‪TYPO3\CMS\Core\Database\ConnectionPool
Definition: ConnectionPool.php:46
‪TYPO3\CMS\Core\Utility\GeneralUtility
Definition: GeneralUtility.php:52
‪TYPO3\CMS\Backend\Search\LiveSearch\DatabaseRecordProvider\getQueryBuilderForTable
‪getQueryBuilderForTable(SearchDemand $searchDemand, string $tableName)
Definition: DatabaseRecordProvider.php:184
‪TYPO3\CMS\Backend\Search\LiveSearch\DatabaseRecordProvider\extractSearchableFieldsFromTable
‪string[] extractSearchableFieldsFromTable(string $tableName)
Definition: DatabaseRecordProvider.php:338
‪TYPO3\CMS\Backend\Search\LiveSearch\DatabaseRecordProvider\find
‪ResultItem[] find(SearchDemand $searchDemand)
Definition: DatabaseRecordProvider.php:103
‪TYPO3\CMS\Backend\Search\LiveSearch\DatabaseRecordProvider\findByTable
‪ResultItem[] findByTable(SearchDemand $searchDemand, string $tableName, int $limit, int $offset)
Definition: DatabaseRecordProvider.php:228
‪TYPO3\CMS\Core\Utility\GeneralUtility\trimExplode
‪static list< string > trimExplode(string $delim, string $string, bool $removeEmptyValues=false, int $limit=0)
Definition: GeneralUtility.php:822
‪TYPO3\CMS\Backend\Search\LiveSearch\DatabaseRecordProvider\count
‪count(SearchDemand $searchDemand)
Definition: DatabaseRecordProvider.php:76
‪TYPO3\CMS\Backend\Search\LiveSearch\DatabaseRecordProvider\getShowLink
‪string getShowLink(array $row)
Definition: DatabaseRecordProvider.php:466
‪TYPO3\CMS\Backend\Search\LiveSearch\DatabaseRecordProvider\getPageIdList
‪int[] getPageIdList()
Definition: DatabaseRecordProvider.php:317
‪TYPO3\CMS\Backend\Search\LiveSearch\ResultItemAction
Definition: ResultItemAction.php:28
‪TYPO3\CMS\Backend\Search\LiveSearch\DatabaseRecordProvider\countByTable
‪countByTable(SearchDemand $searchDemand, string $tableName)
Definition: DatabaseRecordProvider.php:219
‪TYPO3\CMS\Backend\Search\LiveSearch\SearchProviderInterface
Definition: SearchProviderInterface.php:28