‪TYPO3CMS  9.5
SuggestWizardDefaultReceiver.php
Go to the documentation of this file.
1 <?php
3 
4 /*
5  * This file is part of the TYPO3 CMS project.
6  *
7  * It is free software; you can redistribute it and/or modify it under
8  * the terms of the GNU General Public License, either version 2
9  * of the License, or any later version.
10  *
11  * For the full copyright and license information, please read the
12  * LICENSE.txt file that was distributed with this source code.
13  *
14  * The TYPO3 project - inspiring people to share!
15  */
16 
30 
38 {
44  protected ‪$table = '';
45 
52  protected ‪$mmForeignTable = '';
53 
59  protected ‪$config = [];
60 
66  protected ‪$allowedPages = [];
67 
73  protected ‪$maxItems = 10;
74 
78  protected ‪$params = [];
79 
83  protected ‪$iconFactory;
84 
88  protected ‪$queryBuilder;
89 
96  public function ‪__construct(‪$table, ‪$config)
97  {
98  $this->iconFactory = GeneralUtility::makeInstance(IconFactory::class);
99  $this->queryBuilder = $this->‪getQueryBuilderForTable(‪$table);
100  $this->queryBuilder->getRestrictions()
101  ->removeAll()
102  ->add(GeneralUtility::makeInstance(DeletedRestriction::class))
103  // if table is versionized, only get the records from the Live Workspace
104  // the overlay itself of WS-records is done below
105  ->add(GeneralUtility::makeInstance(BackendWorkspaceRestriction::class, 0));
106  $this->table = ‪$table;
107  $this->config = ‪$config;
108  // get a list of all the pages that should be looked on
109  if (isset(‪$config['pidList'])) {
110  $pageIds = GeneralUtility::intExplode(',', ‪$config['pidList'], true);
111  $depth = (int)(‪$config['pidDepth'] ?? 0);
112  $availablePageIds = [];
113  foreach ($pageIds as $pageId) {
114  $availablePageIds[] = $this->‪getAvailablePageIds($pageId, $depth);
115  }
116  $this->allowedPages = array_unique(array_merge($this->allowedPages, ...$availablePageIds));
117  }
118  if (isset(‪$config['maxItemsInResultList'])) {
119  $this->maxItems = ‪$config['maxItemsInResultList'];
120  }
121  ‪$GLOBALS['BE_USER']->initializeWebmountsForElementBrowser();
122  if ($this->table === 'pages') {
123  $this->queryBuilder->andWhere(
125  $this->queryBuilder->expr()->eq('sys_language_uid', 0)
126  );
127  }
128  if (isset(‪$config['addWhere'])) {
129  $this->queryBuilder->andWhere(
131  );
132  }
133  }
134 
147  public function ‪queryTable(&‪$params, $recursionCounter = 0)
148  {
149  $maxQueryResults = 50;
150  $rows = [];
151  $this->params = &‪$params;
152  $start = $recursionCounter * $maxQueryResults;
153  $this->‪prepareSelectStatement();
155  $result = $this->queryBuilder->select('*')
156  ->from($this->table)
157  ->setFirstResult($start)
158  ->setMaxResults($maxQueryResults)
159  ->execute();
160  $allRowsCount = $this->queryBuilder
161  ->count('uid')
162  ->resetQueryPart('orderBy')
163  ->execute()
164  ->fetchColumn(0);
165  if ($allRowsCount) {
166  while ($row = $result->fetch()) {
167  // check if we already have collected the maximum number of records
168  if (count($rows) > $this->maxItems) {
169  break;
170  }
171  $this->‪manipulateRecord($row);
172  $this->‪makeWorkspaceOverlay($row);
173  // check if the user has access to the record
174  if (!$this->‪checkRecordAccess($row, $row['uid'])) {
175  continue;
176  }
177  $spriteIcon = $this->iconFactory->getIconForRecord($this->table, $row, ‪Icon::SIZE_SMALL)->render();
178  $uid = $row['t3ver_oid'] > 0 ? $row['t3ver_oid'] : $row['uid'];
179  $path = $this->‪getRecordPath($row, $uid);
180  if (mb_strlen($path, 'utf-8') > 30) {
181  $croppedPath = '<abbr title="' . htmlspecialchars($path) . '">' .
182  htmlspecialchars(
183  mb_substr($path, 0, 10, 'utf-8')
184  . '...'
185  . mb_substr($path, -20, null, 'utf-8')
186  ) .
187  '</abbr>';
188  } else {
189  $croppedPath = htmlspecialchars($path);
190  }
191  $label = $this->‪getLabel($row);
192  $entry = [
193  'text' => '<span class="suggest-label">' . $label . '</span><span class="suggest-uid">[' . $uid . ']</span><br />
194  <span class="suggest-path">' . $croppedPath . '</span>',
195  'table' => $this->mmForeignTable ? $this->mmForeignTable : ‪$this->table,
196  'label' => strip_tags($label),
197  'path' => $path,
198  'uid' => $uid,
199  'style' => '',
200  'class' => $this->config['cssClass'] ?? '',
201  'sprite' => $spriteIcon
202  ];
203  $rows[$this->table . '_' . $uid] = $this->‪renderRecord($row, $entry);
204  }
205 
206  // if there are less records than we need, call this function again to get more records
207  if (count($rows) < $this->maxItems && $allRowsCount >= $maxQueryResults && $recursionCounter < $this->maxItems) {
208  $tmp = ‪self::queryTable(‪$params, ++$recursionCounter);
209  $rows = array_merge($tmp, $rows);
210  }
211  }
212  return $rows;
213  }
214 
219  protected function ‪prepareSelectStatement()
220  {
221  $expressionBuilder = $this->queryBuilder->expr();
222  $searchString = $this->params['value'];
223  if ($searchString !== '') {
224  $splitStrings = $this->‪splitSearchString($searchString);
225  $constraints = [];
226  foreach ($splitStrings as $splitString) {
227  $constraints[] = $this->‪buildConstraintBlock($splitString);
228  }
229  foreach ($constraints as $constraint) {
230  $this->queryBuilder->andWhere($expressionBuilder->andX($constraint));
231  }
232  }
233  if (!empty($this->allowedPages)) {
234  $pidList = array_map('intval', $this->allowedPages);
235  if (!empty($pidList)) {
236  $this->queryBuilder->andWhere(
237  $expressionBuilder->in('pid', $pidList)
238  );
239  }
240  }
241  // add an additional search condition comment
242  if (isset($this->config['searchCondition']) && $this->config['searchCondition'] !== '') {
243  $this->queryBuilder->andWhere(‪QueryHelper::stripLogicalOperatorPrefix($this->config['searchCondition']));
244  }
245  }
246 
253  protected function ‪buildConstraintBlock(string $searchString)
254  {
255  $expressionBuilder = $this->queryBuilder->expr();
256  $selectParts = $expressionBuilder->orX();
257  if (‪MathUtility::canBeInterpretedAsInteger($searchString) && (int)$searchString > 0) {
258  $selectParts->add($expressionBuilder->eq('uid', (int)$searchString));
259  }
260  $searchWholePhrase = !isset($this->config['searchWholePhrase']) || $this->config['searchWholePhrase'];
261  $likeCondition = ($searchWholePhrase ? '%' : '') . $this->queryBuilder->escapeLikeWildcards($searchString) . '%';
262  // Search in all fields given by label or label_alt
263  $selectFieldsList = (‪$GLOBALS['TCA'][‪$this->table]['ctrl']['label'] ?? '') . ',' . (‪$GLOBALS['TCA'][$this->table]['ctrl']['label_alt'] ?? '') . ',' . $this->config['additionalSearchFields'];
264  $selectFields = GeneralUtility::trimExplode(',', $selectFieldsList, true);
265  $selectFields = array_unique($selectFields);
266  foreach ($selectFields as $field) {
267  $selectParts->add($expressionBuilder->like($field, $this->queryBuilder->createPositionalParameter($likeCondition)));
268  }
269 
270  return $selectParts;
271  }
272 
281  protected function ‪splitSearchString(string $searchString): array
282  {
283  return str_getcsv($searchString, ' ');
284  }
285 
293  protected function ‪getAvailablePageIds(int $id, int $depth = 0): array
294  {
295  if ($depth === 0) {
296  return [$id];
297  }
298  $tree = GeneralUtility::makeInstance(PageTreeView::class);
299  $tree->init();
300  $tree->getTree($id, $depth);
301  $tree->makeHTML = 0;
302  $tree->fieldArray = ['uid'];
303  $tree->ids[] = $id;
304  return $tree->ids;
305  }
306 
311  protected function ‪prepareOrderByStatement()
312  {
313  if (empty($this->config['orderBy'])) {
314  $this->queryBuilder->addOrderBy(‪$GLOBALS['TCA'][$this->table]['ctrl']['label']);
315  } else {
316  foreach (‪QueryHelper::parseOrderBy($this->config['orderBy']) as $orderPair) {
317  list($fieldName, $order) = $orderPair;
318  $this->queryBuilder->addOrderBy($fieldName, $order);
319  }
320  }
321  }
322 
328  protected function ‪manipulateRecord(&$row)
329  {
330  }
331 
339  protected function ‪checkRecordAccess($row, $uid)
340  {
341  $retValue = true;
342  ‪$table = $this->mmForeignTable ?: ‪$this->table;
343  if (‪$table === 'pages') {
344  if (!‪BackendUtility::readPageAccess($uid, ‪$GLOBALS['BE_USER']->getPagePermsClause(‪Permission::PAGE_SHOW))) {
345  $retValue = false;
346  }
347  } elseif (isset(‪$GLOBALS['TCA'][‪$table]['ctrl']['is_static']) && (bool)‪$GLOBALS['TCA'][‪$table]['ctrl']['is_static']) {
348  $retValue = true;
349  } else {
350  if (!is_array(‪BackendUtility::readPageAccess($row['pid'], ‪$GLOBALS['BE_USER']->getPagePermsClause(‪Permission::PAGE_SHOW)))) {
351  $retValue = false;
352  }
353  }
354  return $retValue;
355  }
356 
362  protected function ‪makeWorkspaceOverlay(&$row)
363  {
364  // Check for workspace-versions
365  if (‪$GLOBALS['BE_USER']->workspace != 0 && ‪$GLOBALS['TCA'][$this->table]['ctrl']['versioningWS'] == true) {
366  ‪BackendUtility::workspaceOL($this->mmForeignTable ? $this->mmForeignTable : $this->table, $row);
367  }
368  }
369 
380  protected function ‪getRecordPath(&$row, $uid)
381  {
382  $titleLimit = max($this->config['maxPathTitleLength'], 0);
383  if (($this->mmForeignTable ? $this->mmForeignTable : $this->table) === 'pages') {
384  $path = ‪BackendUtility::getRecordPath($uid, '', $titleLimit);
385  // For pages we only want the first (n-1) parts of the path,
386  // because the n-th part is the page itself
387  $path = substr($path, 0, strrpos($path, '/', -2)) . '/';
388  } else {
389  $path = ‪BackendUtility::getRecordPath($row['pid'], '', $titleLimit);
390  }
391  return $path;
392  }
393 
400  protected function ‪getLabel($row)
401  {
402  return ‪BackendUtility::getRecordTitle($this->mmForeignTable ? $this->mmForeignTable : $this->table, $row, true);
403  }
404 
414  protected function ‪renderRecord($row, $entry)
415  {
416  // Call renderlet if available (normal pages etc. usually don't have one)
417  if ($this->config['renderFunc'] != '') {
418  ‪$params = [
419  'table' => ‪$this->table,
420  'uid' => $row['uid'],
421  'row' => $row,
422  'entry' => &$entry
423  ];
424  GeneralUtility::callUserFunction($this->config['renderFunc'], ‪$params, $this);
425  }
426  return $entry;
427  }
428 
432  protected function ‪getLanguageService()
433  {
434  return ‪$GLOBALS['LANG'];
435  }
436 
441  protected function ‪getQueryBuilderForTable(‪$table)
442  {
443  return GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable(‪$table);
444  }
445 }
‪TYPO3\CMS\Core\Imaging\Icon\SIZE_SMALL
‪const SIZE_SMALL
Definition: Icon.php:29
‪TYPO3\CMS\Core\Database\Query\QueryHelper\parseOrderBy
‪static array array[] parseOrderBy(string $input)
Definition: QueryHelper.php:42
‪TYPO3\CMS\Backend\Form\Wizard\SuggestWizardDefaultReceiver\$config
‪array $config
Definition: SuggestWizardDefaultReceiver.php:56
‪TYPO3\CMS\Backend\Form\Wizard\SuggestWizardDefaultReceiver\getRecordPath
‪string getRecordPath(&$row, $uid)
Definition: SuggestWizardDefaultReceiver.php:372
‪TYPO3\CMS\Core\Utility\MathUtility\canBeInterpretedAsInteger
‪static bool canBeInterpretedAsInteger($var)
Definition: MathUtility.php:73
‪TYPO3\CMS\Core\Imaging\Icon
Definition: Icon.php:25
‪TYPO3\CMS\Backend\Form\Wizard\SuggestWizardDefaultReceiver\renderRecord
‪array renderRecord($row, $entry)
Definition: SuggestWizardDefaultReceiver.php:406
‪TYPO3\CMS\Backend\Form\Wizard
Definition: SuggestWizardDefaultReceiver.php:2
‪TYPO3\CMS\Core\Database\Query\Restriction\BackendWorkspaceRestriction
Definition: BackendWorkspaceRestriction.php:28
‪TYPO3\CMS\Backend\Form\Wizard\SuggestWizardDefaultReceiver\splitSearchString
‪array splitSearchString(string $searchString)
Definition: SuggestWizardDefaultReceiver.php:273
‪TYPO3\CMS\Core\Imaging\IconFactory
Definition: IconFactory.php:31
‪TYPO3\CMS\Backend\Form\Wizard\SuggestWizardDefaultReceiver\makeWorkspaceOverlay
‪makeWorkspaceOverlay(&$row)
Definition: SuggestWizardDefaultReceiver.php:354
‪TYPO3\CMS\Backend\Tree\View\PageTreeView
Definition: PageTreeView.php:23
‪TYPO3\CMS\Core\Type\Bitmask\Permission
Definition: Permission.php:23
‪TYPO3\CMS\Backend\Form\Wizard\SuggestWizardDefaultReceiver\$iconFactory
‪IconFactory $iconFactory
Definition: SuggestWizardDefaultReceiver.php:76
‪TYPO3\CMS\Core\Database\Query\QueryBuilder
Definition: QueryBuilder.php:47
‪TYPO3\CMS\Backend\Form\Wizard\SuggestWizardDefaultReceiver\getLanguageService
‪LanguageService getLanguageService()
Definition: SuggestWizardDefaultReceiver.php:424
‪TYPO3\CMS\Backend\Form\Wizard\SuggestWizardDefaultReceiver\queryTable
‪array queryTable(&$params, $recursionCounter=0)
Definition: SuggestWizardDefaultReceiver.php:139
‪TYPO3\CMS\Backend\Form\Wizard\SuggestWizardDefaultReceiver\getAvailablePageIds
‪array getAvailablePageIds(int $id, int $depth=0)
Definition: SuggestWizardDefaultReceiver.php:285
‪TYPO3\CMS\Backend\Form\Wizard\SuggestWizardDefaultReceiver\getQueryBuilderForTable
‪QueryBuilder getQueryBuilderForTable($table)
Definition: SuggestWizardDefaultReceiver.php:433
‪TYPO3\CMS\Backend\Form\Wizard\SuggestWizardDefaultReceiver\$mmForeignTable
‪string $mmForeignTable
Definition: SuggestWizardDefaultReceiver.php:50
‪TYPO3\CMS\Core\Database\Query\Expression\CompositeExpression
Definition: CompositeExpression.php:23
‪TYPO3\CMS\Backend\Form\Wizard\SuggestWizardDefaultReceiver\$params
‪array $params
Definition: SuggestWizardDefaultReceiver.php:72
‪TYPO3\CMS\Core\Database\Query\QueryHelper
Definition: QueryHelper.php:30
‪TYPO3\CMS\Backend\Form\Wizard\SuggestWizardDefaultReceiver\$queryBuilder
‪QueryBuilder $queryBuilder
Definition: SuggestWizardDefaultReceiver.php:80
‪TYPO3\CMS\Backend\Utility\BackendUtility\getRecordTitle
‪static string getRecordTitle($table, $row, $prep=false, $forceResult=true)
Definition: BackendUtility.php:1811
‪TYPO3\CMS\Backend\Form\Wizard\SuggestWizardDefaultReceiver\prepareOrderByStatement
‪prepareOrderByStatement()
Definition: SuggestWizardDefaultReceiver.php:303
‪TYPO3\CMS\Backend\Form\Wizard\SuggestWizardDefaultReceiver\getLabel
‪string getLabel($row)
Definition: SuggestWizardDefaultReceiver.php:392
‪TYPO3\CMS\Core\Type\Bitmask\Permission\PAGE_SHOW
‪const PAGE_SHOW
Definition: Permission.php:32
‪TYPO3\CMS\Backend\Utility\BackendUtility
Definition: BackendUtility.php:72
‪TYPO3\CMS\Backend\Form\Wizard\SuggestWizardDefaultReceiver\checkRecordAccess
‪bool checkRecordAccess($row, $uid)
Definition: SuggestWizardDefaultReceiver.php:331
‪TYPO3\CMS\Backend\Form\Wizard\SuggestWizardDefaultReceiver\$allowedPages
‪array $allowedPages
Definition: SuggestWizardDefaultReceiver.php:62
‪TYPO3\CMS\Backend\Form\Wizard\SuggestWizardDefaultReceiver\$table
‪string $table
Definition: SuggestWizardDefaultReceiver.php:43
‪TYPO3\CMS\Core\Database\Query\QueryHelper\stripLogicalOperatorPrefix
‪static string stripLogicalOperatorPrefix(string $constraint)
Definition: QueryHelper.php:163
‪$GLOBALS
‪$GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['adminpanel']['modules']
Definition: ext_localconf.php:5
‪TYPO3\CMS\Backend\Utility\BackendUtility\workspaceOL
‪static workspaceOL($table, &$row, $wsid=-99, $unsetMovePointers=false)
Definition: BackendUtility.php:4048
‪TYPO3\CMS\Core\Database\Query\Restriction\DeletedRestriction
Definition: DeletedRestriction.php:26
‪TYPO3\CMS\Backend\Form\Wizard\SuggestWizardDefaultReceiver\prepareSelectStatement
‪prepareSelectStatement()
Definition: SuggestWizardDefaultReceiver.php:211
‪TYPO3\CMS\Core\Utility\MathUtility
Definition: MathUtility.php:21
‪TYPO3\CMS\Backend\Form\Wizard\SuggestWizardDefaultReceiver\$maxItems
‪int $maxItems
Definition: SuggestWizardDefaultReceiver.php:68
‪TYPO3\CMS\Core\Localization\LanguageService
Definition: LanguageService.php:29
‪TYPO3\CMS\Core\Database\ConnectionPool
Definition: ConnectionPool.php:44
‪TYPO3\CMS\Core\Utility\GeneralUtility
Definition: GeneralUtility.php:45
‪TYPO3\CMS\Backend\Utility\BackendUtility\getRecordPath
‪static mixed getRecordPath($uid, $clause, $titleLimit, $fullTitleLimit=0)
Definition: BackendUtility.php:572
‪TYPO3\CMS\Backend\Form\Wizard\SuggestWizardDefaultReceiver\manipulateRecord
‪manipulateRecord(&$row)
Definition: SuggestWizardDefaultReceiver.php:320
‪TYPO3\CMS\Backend\Form\Wizard\SuggestWizardDefaultReceiver
Definition: SuggestWizardDefaultReceiver.php:38
‪TYPO3\CMS\Backend\Form\Wizard\SuggestWizardDefaultReceiver\buildConstraintBlock
‪string TYPO3 CMS Core Database Query Expression CompositeExpression buildConstraintBlock(string $searchString)
Definition: SuggestWizardDefaultReceiver.php:245
‪TYPO3\CMS\Backend\Utility\BackendUtility\readPageAccess
‪static array bool readPageAccess($id, $perms_clause)
Definition: BackendUtility.php:635
‪TYPO3\CMS\Backend\Form\Wizard\SuggestWizardDefaultReceiver\__construct
‪__construct($table, $config)
Definition: SuggestWizardDefaultReceiver.php:88