‪TYPO3CMS  10.4
SlugHelper.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 
37 
42 {
46  protected ‪$tableName;
47 
51  protected ‪$fieldName;
52 
56  protected ‪$workspaceId;
57 
61  protected ‪$configuration = [];
62 
66  protected ‪$workspaceEnabled;
67 
75  protected ‪$prependSlashInSlug;
76 
85  public function ‪__construct(string ‪$tableName, string ‪$fieldName, array ‪$configuration, int ‪$workspaceId = 0)
86  {
87  $this->tableName = ‪$tableName;
88  $this->fieldName = ‪$fieldName;
89  $this->configuration = ‪$configuration;
90  $this->workspaceId = ‪$workspaceId;
91 
92  if ($this->tableName === 'pages' && $this->fieldName === 'slug') {
93  $this->prependSlashInSlug = true;
94  } else {
95  $this->prependSlashInSlug = $this->configuration['prependSlash'] ?? false;
96  }
97 
99  }
100 
107  public function ‪sanitize(string $slug): string
108  {
109  // Convert to lowercase + remove tags
110  $slug = mb_strtolower($slug, 'utf-8');
111  $slug = strip_tags($slug);
112 
113  // Convert some special tokens (space, "_" and "-") to the space character
114  $fallbackCharacter = (string)($this->configuration['fallbackCharacter'] ?? '-');
115  $slug = preg_replace('/[ \t\x{00A0}\-+_]+/u', $fallbackCharacter, $slug);
116 
117  if (!\Normalizer::isNormalized((string)$slug)) {
118  $slug = \Normalizer::normalize((string)$slug);
119  }
120 
121  // Convert extended letters to ascii equivalents
122  // The specCharsToASCII() converts "€" to "EUR"
123  $slug = GeneralUtility::makeInstance(CharsetConverter::class)->specCharsToASCII('utf-8', $slug);
124 
125  // Get rid of all invalid characters, but allow slashes
126  $slug = preg_replace('/[^\p{L}\p{M}0-9\/' . preg_quote($fallbackCharacter) . ']/u', '', $slug);
127 
128  // Convert multiple fallback characters to a single one
129  if ($fallbackCharacter !== '') {
130  $slug = preg_replace('/' . preg_quote($fallbackCharacter) . '{2,}/', $fallbackCharacter, $slug);
131  }
132 
133  // Ensure slug is lower cased after all replacement was done
134  $slug = mb_strtolower($slug, 'utf-8');
135  // Extract slug, thus it does not have wrapping fallback and slash characters
136  $extractedSlug = $this->‪extract($slug);
137  // Remove trailing and beginning slashes, except if the trailing slash was added, then we'll re-add it
138  $appendTrailingSlash = $extractedSlug !== '' && substr($slug, -1) === '/';
139  $slug = $extractedSlug . ($appendTrailingSlash ? '/' : '');
140  if ($this->prependSlashInSlug && ($slug[0] ?? '') !== '/') {
141  $slug = '/' . $slug;
142  }
143  return $slug;
144  }
145 
153  public function ‪extract(string $slug): string
154  {
155  // Convert some special tokens (space, "_" and "-") to the space character
156  $fallbackCharacter = $this->configuration['fallbackCharacter'] ?? '-';
157  return trim($slug, $fallbackCharacter . '/');
158  }
159 
167  public function ‪generate(array $recordData, int $pid): string
168  {
169  if ($this->tableName === 'pages' && ($pid === 0 || !empty($recordData['is_siteroot']))) {
170  return '/';
171  }
172  $prefix = '';
173  if ($this->tableName === 'pages' && ($this->configuration['generatorOptions']['prefixParentPageSlug'] ?? false)) {
174  $languageFieldName = ‪$GLOBALS['TCA'][‪$this->tableName]['ctrl']['languageField'] ?? null;
175  $languageId = (int)($recordData[$languageFieldName] ?? 0);
176  $parentPageRecord = $this->‪resolveParentPageRecord($pid, $languageId);
177  if (is_array($parentPageRecord)) {
178  // If the parent page has a slug, use that instead of "re-generating" the slug from the parents' page title
179  if (!empty($parentPageRecord['slug'])) {
180  $rootLineItemSlug = $parentPageRecord['slug'];
181  } else {
182  $rootLineItemSlug = $this->‪generate($parentPageRecord, (int)$parentPageRecord['pid']);
183  }
184  $rootLineItemSlug = trim($rootLineItemSlug, '/');
185  if (!empty($rootLineItemSlug)) {
186  $prefix = $rootLineItemSlug;
187  }
188  }
189  }
190 
191  $fieldSeparator = $this->configuration['generatorOptions']['fieldSeparator'] ?? '/';
192  $slugParts = [];
193 
194  $replaceConfiguration = $this->configuration['generatorOptions']['replacements'] ?? [];
195  foreach ($this->configuration['generatorOptions']['fields'] ?? [] as $fieldNameParts) {
196  if (is_string($fieldNameParts)) {
197  $fieldNameParts = ‪GeneralUtility::trimExplode(',', $fieldNameParts);
198  }
199  foreach ($fieldNameParts as ‪$fieldName) {
200  if (!empty($recordData[‪$fieldName])) {
201  $pieceOfSlug = (string)$recordData[‪$fieldName];
202  $pieceOfSlug = str_replace(
203  array_keys($replaceConfiguration),
204  array_values($replaceConfiguration),
205  $pieceOfSlug
206  );
207  $slugParts[] = $pieceOfSlug;
208  break;
209  }
210  }
211  }
212  $slug = implode($fieldSeparator, $slugParts);
213  $slug = $this->‪sanitize($slug);
214  // No valid data found
215  if ($slug === '' || $slug === '/') {
216  $slug = 'default-' . GeneralUtility::shortMD5(json_encode($recordData));
217  }
218  if ($this->prependSlashInSlug && ($slug[0] ?? '') !== '/') {
219  $slug = '/' . $slug;
220  }
221  if (!empty($prefix)) {
222  $slug = $prefix . $slug;
223  }
224 
225  // Hook for alternative ways of filling/modifying the slug data
226  foreach ($this->configuration['generatorOptions']['postModifiers'] ?? [] as $funcName) {
227  $hookParameters = [
228  'slug' => $slug,
229  'workspaceId' => ‪$this->workspaceId,
230  'configuration' => ‪$this->configuration,
231  'record' => $recordData,
232  'pid' => $pid,
233  'prefix' => $prefix,
234  'tableName' => ‪$this->tableName,
235  'fieldName' => ‪$this->fieldName,
236  ];
237  $slug = GeneralUtility::callUserFunction($funcName, $hookParameters, $this);
238  }
239  return $this->‪sanitize($slug);
240  }
241 
249  public function ‪isUniqueInPid(string $slug, RecordState $state): bool
250  {
251  $pageId = (int)$state->resolveNodeIdentifier();
252  $recordId = $state->getSubject()->getIdentifier();
253  $languageId = $state->getContext()->getLanguageId();
254 
255  $queryBuilder = $this->‪createPreparedQueryBuilder();
256  $this->‪applySlugConstraint($queryBuilder, $slug);
257  $this->‪applyPageIdConstraint($queryBuilder, $pageId);
258  $this->‪applyRecordConstraint($queryBuilder, $recordId);
259  $this->‪applyLanguageConstraint($queryBuilder, $languageId);
260  $this->‪applyWorkspaceConstraint($queryBuilder, $state);
261  $statement = $queryBuilder->execute();
262 
263  $records = $this->‪resolveVersionOverlays(
264  $statement->fetchAll()
265  );
266  return count($records) === 0;
267  }
268 
277  public function ‪isUniqueInSite(string $slug, RecordState $state): bool
278  {
279  $pageId = $state->resolveNodeAggregateIdentifier();
280  $recordId = $state->getSubject()->getIdentifier();
281  $languageId = $state->getContext()->getLanguageId();
282 
284  // If this is a new page, we use the parent page to resolve the site
285  $pageId = $state->getNode()->getIdentifier();
286  }
287  $pageId = (int)$pageId;
288 
289  $queryBuilder = $this->‪createPreparedQueryBuilder();
290  $this->‪applySlugConstraint($queryBuilder, $slug);
291  $this->‪applyRecordConstraint($queryBuilder, $recordId);
292  $this->‪applyLanguageConstraint($queryBuilder, $languageId);
293  $this->‪applyWorkspaceConstraint($queryBuilder, $state);
294  $statement = $queryBuilder->execute();
295 
296  $records = $this->‪resolveVersionOverlays(
297  $statement->fetchAll()
298  );
299  if (count($records) === 0) {
300  return true;
301  }
302 
303  // The installation contains at least ONE other record with the same slug
304  // Now find out if it is the same root page ID
305  $this->‪flushRootLineCaches();
306  $siteFinder = GeneralUtility::makeInstance(SiteFinder::class);
307  try {
308  $siteOfCurrentRecord = $siteFinder->getSiteByPageId($pageId);
309  } catch (SiteNotFoundException $e) {
310  // Not within a site, so nothing to do
311  // TODO: Rather than silently ignoring this misconfiguration,
312  // a warning should be thrown here, or maybe even let the
313  // exception bubble up and catch it in places that uses this API
314  return true;
315  }
316  foreach ($records as $record) {
317  try {
318  $recordState = ‪RecordStateFactory::forName($this->tableName)->fromArray($record);
319  $siteOfExistingRecord = $siteFinder->getSiteByPageId(
320  (int)$recordState->resolveNodeAggregateIdentifier()
321  );
322  } catch (SiteNotFoundException $exception) {
323  // In case not site is found, the record is not
324  // organized in any site
325  continue;
326  }
327  if ($siteOfExistingRecord->getRootPageId() === $siteOfCurrentRecord->getRootPageId()) {
328  return false;
329  }
330  }
331 
332  // Otherwise, everything is still fine
333  return true;
334  }
335 
344  public function ‪isUniqueInTable(string $slug, RecordState $state): bool
345  {
346  $recordId = $state->getSubject()->getIdentifier();
347  $languageId = $state->getContext()->getLanguageId();
348 
349  $queryBuilder = $this->‪createPreparedQueryBuilder();
350  $this->‪applySlugConstraint($queryBuilder, $slug);
351  $this->‪applyRecordConstraint($queryBuilder, $recordId);
352  $this->‪applyLanguageConstraint($queryBuilder, $languageId);
353  $this->‪applyWorkspaceConstraint($queryBuilder, $state);
354  $statement = $queryBuilder->execute();
355 
356  $records = $this->‪resolveVersionOverlays(
357  $statement->fetchAll()
358  );
359 
360  return count($records) === 0;
361  }
362 
367  protected function ‪flushRootLineCaches(): void
368  {
370  GeneralUtility::makeInstance(CacheManager::class)->getCache('rootline')->flush();
371  }
372 
382  protected function ‪buildSlug(string $slug, RecordState $state, callable $isUnique): string
383  {
384  $slug = $this->‪sanitize($slug);
385  $rawValue = $this->‪extract($slug);
386  $newValue = $slug;
387  $counter = 0;
388  while (
389  !call_user_func($isUnique, $newValue, $state)
390  && ++$counter < 100
391  ) {
392  $newValue = $this->‪sanitize($rawValue . '-' . $counter);
393  }
394  if ($counter === 100) {
395  $uniqueId = ‪StringUtility::getUniqueId();
396  $newValue = $this->‪sanitize($rawValue . '-' . GeneralUtility::shortMD5($uniqueId));
397  }
398  return $newValue;
399  }
400 
409  public function ‪buildSlugForUniqueInSite(string $slug, RecordState $state): string
410  {
411  return $this->‪buildSlug($slug, $state, [$this, 'isUniqueInSite']);
412  }
413 
421  public function ‪buildSlugForUniqueInPid(string $slug, RecordState $state): string
422  {
423  return $this->‪buildSlug($slug, $state, [$this, 'isUniqueInPid']);
424  }
425 
434  public function ‪buildSlugForUniqueInTable(string $slug, RecordState $state): string
435  {
436  return $this->‪buildSlug($slug, $state, [$this, 'isUniqueInTable']);
437  }
438 
442  protected function ‪createPreparedQueryBuilder(): ‪QueryBuilder
443  {
444  $fieldNames = ['uid', 'pid', ‪$this->fieldName];
445  if ($this->workspaceEnabled) {
446  $fieldNames[] = 't3ver_state';
447  $fieldNames[] = 't3ver_oid';
448  }
449  $languageFieldName = ‪$GLOBALS['TCA'][‪$this->tableName]['ctrl']['languageField'] ?? null;
450  if (is_string($languageFieldName)) {
451  $fieldNames[] = $languageFieldName;
452  }
453  $languageParentFieldName = ‪$GLOBALS['TCA'][‪$this->tableName]['ctrl']['transOrigPointerField'] ?? null;
454  if (is_string($languageParentFieldName)) {
455  $fieldNames[] = $languageParentFieldName;
456  }
457 
458  $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable($this->tableName);
459  $queryBuilder->getRestrictions()
460  ->removeAll()
461  ->add(GeneralUtility::makeInstance(DeletedRestriction::class));
462  $queryBuilder
463  ->select(...$fieldNames)
464  ->from($this->tableName);
465  return $queryBuilder;
466  }
467 
472  protected function ‪applyWorkspaceConstraint(‪QueryBuilder $queryBuilder, ‪RecordState $state)
473  {
474  if (!$this->workspaceEnabled) {
475  return;
476  }
477 
478  $queryBuilder->‪getRestrictions()->‪add(
479  GeneralUtility::makeInstance(WorkspaceRestriction::class, $this->workspaceId)
480  );
481 
482  // Exclude the online record of a versioned record
483  if ($state->‪getVersionLink()) {
484  $queryBuilder->‪andWhere(
485  $queryBuilder->‪expr()->‪neq('uid', $state->‪getVersionLink()->‪getSubject()->‪getIdentifier())
486  );
487  }
488  }
489 
494  protected function ‪applyLanguageConstraint(‪QueryBuilder $queryBuilder, int $languageId)
495  {
496  $languageFieldName = ‪$GLOBALS['TCA'][‪$this->tableName]['ctrl']['languageField'] ?? null;
497  if (!is_string($languageFieldName)) {
498  return;
499  }
500 
501  // Only check records of the given language
502  $queryBuilder->‪andWhere(
503  $queryBuilder->‪expr()->‪eq(
504  $languageFieldName,
505  $queryBuilder->‪createNamedParameter($languageId, \PDO::PARAM_INT)
506  )
507  );
508  }
509 
514  protected function ‪applySlugConstraint(‪QueryBuilder $queryBuilder, string $slug)
515  {
516  $queryBuilder->‪where(
517  $queryBuilder->‪expr()->‪eq(
518  $this->fieldName,
519  $queryBuilder->‪createNamedParameter($slug)
520  )
521  );
522  }
523 
528  protected function ‪applyPageIdConstraint(‪QueryBuilder $queryBuilder, int $pageId)
529  {
530  if ($pageId < 0) {
531  throw new \RuntimeException(
532  sprintf(
533  'Page id must be positive "%d"',
534  $pageId
535  ),
536  1534962573
537  );
538  }
539 
540  $queryBuilder->‪andWhere(
541  $queryBuilder->‪expr()->‪eq(
542  'pid',
543  $queryBuilder->‪createNamedParameter($pageId, \PDO::PARAM_INT)
544  )
545  );
546  }
547 
552  protected function ‪applyRecordConstraint(‪QueryBuilder $queryBuilder, $recordId)
553  {
554  // Exclude the current record if it is an existing record
556  return;
557  }
558 
559  $queryBuilder->‪andWhere(
560  $queryBuilder->‪expr()->‪neq('uid', $queryBuilder->‪createNamedParameter($recordId, \PDO::PARAM_INT))
561  );
562  if ($this->workspaceId > 0 && $this->workspaceEnabled) {
563  $liveId = ‪BackendUtility::getLiveVersionIdOfRecord($this->tableName, $recordId) ?? $recordId;
564  $queryBuilder->‪andWhere(
565  $queryBuilder->‪expr()->‪neq('uid', $queryBuilder->‪createNamedParameter($liveId, \PDO::PARAM_INT))
566  );
567  }
568  }
569 
574  protected function ‪resolveVersionOverlays(array $records): array
575  {
576  if (!$this->workspaceEnabled) {
577  return $records;
578  }
579 
580  return array_filter(
581  array_map(
582  function (array $record) {
584  $this->tableName,
585  $record,
586  $this->workspaceId,
587  true
588  );
589  if (‪VersionState::cast($record['t3ver_state'] ?? null)
591  return null;
592  }
593  return $record;
594  },
595  $records
596  )
597  );
598  }
599 
606  protected function ‪resolveParentPageRecord(int $pid, int $languageId): ?array
607  {
608  $parentPageRecord = null;
609  $rootLine = ‪BackendUtility::BEgetRootLine($pid, '', true, ['nav_title']);
610  $excludeDokTypes = [
614  ];
615  do {
616  $parentPageRecord = array_shift($rootLine);
617  // exclude spacers, recyclers and folders
618  } while (!empty($rootLine) && in_array((int)$parentPageRecord['doktype'], $excludeDokTypes, true));
619  if ($languageId > 0) {
620  $languageIds = [$languageId];
621  $siteFinder = GeneralUtility::makeInstance(SiteFinder::class);
622 
623  try {
624  $site = $siteFinder->getSiteByPageId($pid);
625  $siteLanguage = $site->getLanguageById($languageId);
626  $languageIds = array_merge($languageIds, $siteLanguage->getFallbackLanguageIds());
627  } catch (SiteNotFoundException | \InvalidArgumentException $e) {
628  // no site or requested language available - move on
629  }
630 
631  foreach ($languageIds as $languageId) {
632  $localizedParentPageRecord = ‪BackendUtility::getRecordLocalization('pages', $parentPageRecord['uid'], $languageId);
633  if (!empty($localizedParentPageRecord)) {
634  $parentPageRecord = reset($localizedParentPageRecord);
635  break;
636  }
637  }
638  }
639  return $parentPageRecord;
640  }
641 }
‪TYPO3\CMS\Core\DataHandling\SlugHelper\applyRecordConstraint
‪applyRecordConstraint(QueryBuilder $queryBuilder, $recordId)
Definition: SlugHelper.php:546
‪TYPO3\CMS\Core\DataHandling\Model\RecordState\resolveNodeAggregateIdentifier
‪string resolveNodeAggregateIdentifier()
Definition: RecordState.php:180
‪TYPO3\CMS\Core\DataHandling\SlugHelper\isUniqueInTable
‪bool isUniqueInTable(string $slug, RecordState $state)
Definition: SlugHelper.php:338
‪TYPO3\CMS\Core\Utility\MathUtility\canBeInterpretedAsInteger
‪static bool canBeInterpretedAsInteger($var)
Definition: MathUtility.php:74
‪TYPO3\CMS\Backend\Utility\BackendUtility\getRecordLocalization
‪static mixed getRecordLocalization($table, $uid, $language, $andWhereClause='')
Definition: BackendUtility.php:285
‪TYPO3\CMS\Core\DataHandling\Model\RecordState\getVersionLink
‪EntityPointerLink getVersionLink()
Definition: RecordState.php:114
‪TYPO3\CMS\Core\DataHandling\Model\RecordState\resolveNodeIdentifier
‪string resolveNodeIdentifier()
Definition: RecordState.php:155
‪TYPO3\CMS\Core\Database\Query\Expression\ExpressionBuilder\eq
‪string eq(string $fieldName, $value)
Definition: ExpressionBuilder.php:109
‪TYPO3\CMS\Core\DataHandling\Model\EntityPointer\getIdentifier
‪string getIdentifier()
‪TYPO3\CMS\Core\DataHandling\SlugHelper\$workspaceEnabled
‪bool $workspaceEnabled
Definition: SlugHelper.php:61
‪TYPO3\CMS\Core\Database\Query\QueryBuilder\createNamedParameter
‪string createNamedParameter($value, int $type=\PDO::PARAM_STR, string $placeHolder=null)
Definition: QueryBuilder.php:941
‪TYPO3\CMS\Core\DataHandling
Definition: DataHandler.php:16
‪TYPO3\CMS\Core\Database\Query\Expression\ExpressionBuilder\neq
‪string neq(string $fieldName, $value)
Definition: ExpressionBuilder.php:128
‪TYPO3\CMS\Core\DataHandling\Model\RecordState\getSubject
‪EntityUidPointer getSubject()
Definition: RecordState.php:84
‪TYPO3\CMS\Core\Utility\RootlineUtility
Definition: RootlineUtility.php:39
‪TYPO3\CMS\Core\Utility\RootlineUtility\purgeCaches
‪static purgeCaches()
Definition: RootlineUtility.php:160
‪TYPO3\CMS\Core\DataHandling\Model\EntityContext\getLanguageId
‪int getLanguageId()
Definition: EntityContext.php:61
‪TYPO3\CMS\Core\DataHandling\SlugHelper\isUniqueInSite
‪bool isUniqueInSite(string $slug, RecordState $state)
Definition: SlugHelper.php:271
‪TYPO3\CMS\Core\DataHandling\SlugHelper\applyLanguageConstraint
‪applyLanguageConstraint(QueryBuilder $queryBuilder, int $languageId)
Definition: SlugHelper.php:488
‪TYPO3\CMS\Core\Exception\SiteNotFoundException
Definition: SiteNotFoundException.php:26
‪TYPO3\CMS\Core\Site\SiteFinder
Definition: SiteFinder.php:31
‪TYPO3\CMS\Core\DataHandling\Model\RecordState\getContext
‪EntityContext getContext()
Definition: RecordState.php:68
‪TYPO3\CMS\Core\DataHandling\SlugHelper\createPreparedQueryBuilder
‪QueryBuilder createPreparedQueryBuilder()
Definition: SlugHelper.php:436
‪TYPO3\CMS\Core\Database\Query\QueryBuilder\getRestrictions
‪QueryRestrictionContainerInterface getRestrictions()
Definition: QueryBuilder.php:104
‪TYPO3\CMS\Core\Charset\CharsetConverter
Definition: CharsetConverter.php:54
‪TYPO3\CMS\Backend\Utility\BackendUtility\getLiveVersionIdOfRecord
‪static int null getLiveVersionIdOfRecord($table, $uid)
Definition: BackendUtility.php:3765
‪TYPO3\CMS\Core\Versioning\VersionState\DELETE_PLACEHOLDER
‪const DELETE_PLACEHOLDER
Definition: VersionState.php:55
‪TYPO3\CMS\Core\DataHandling\SlugHelper\resolveVersionOverlays
‪array resolveVersionOverlays(array $records)
Definition: SlugHelper.php:568
‪TYPO3\CMS\Core\DataHandling\SlugHelper\extract
‪string extract(string $slug)
Definition: SlugHelper.php:147
‪TYPO3\CMS\Backend\Utility\BackendUtility\BEgetRootLine
‪static array BEgetRootLine($uid, $clause='', $workspaceOL=false, array $additionalFields=[])
Definition: BackendUtility.php:343
‪TYPO3\CMS\Core\DataHandling\SlugHelper\$workspaceId
‪int $workspaceId
Definition: SlugHelper.php:53
‪TYPO3\CMS\Core\DataHandling\SlugHelper\resolveParentPageRecord
‪array null resolveParentPageRecord(int $pid, int $languageId)
Definition: SlugHelper.php:600
‪TYPO3\CMS\Core\DataHandling\Model\RecordStateFactory
Definition: RecordStateFactory.php:26
‪TYPO3\CMS\Core\Database\Query\QueryBuilder
Definition: QueryBuilder.php:52
‪TYPO3\CMS\Backend\Utility\BackendUtility\isTableWorkspaceEnabled
‪static bool isTableWorkspaceEnabled($table)
Definition: BackendUtility.php:4021
‪TYPO3\CMS\Core\DataHandling\SlugHelper\buildSlugForUniqueInSite
‪string buildSlugForUniqueInSite(string $slug, RecordState $state)
Definition: SlugHelper.php:403
‪TYPO3\CMS\Core\DataHandling\Model\RecordState\getNode
‪EntityPointer getNode()
Definition: RecordState.php:76
‪TYPO3\CMS\Core\DataHandling\SlugHelper\isUniqueInPid
‪bool isUniqueInPid(string $slug, RecordState $state)
Definition: SlugHelper.php:243
‪TYPO3\CMS\Core\Type\Enumeration\cast
‪static static cast($value)
Definition: Enumeration.php:186
‪TYPO3\CMS\Core\Database\Query\QueryBuilder\andWhere
‪QueryBuilder andWhere(... $where)
Definition: QueryBuilder.php:694
‪TYPO3\CMS\Core\DataHandling\SlugHelper\$fieldName
‪string $fieldName
Definition: SlugHelper.php:49
‪TYPO3\CMS\Core\DataHandling\SlugHelper\applySlugConstraint
‪applySlugConstraint(QueryBuilder $queryBuilder, string $slug)
Definition: SlugHelper.php:508
‪TYPO3\CMS\Core\DataHandling\SlugHelper
Definition: SlugHelper.php:42
‪TYPO3\CMS\Core\Domain\Repository\PageRepository\DOKTYPE_SPACER
‪const DOKTYPE_SPACER
Definition: PageRepository.php:108
‪TYPO3\CMS\Core\Cache\CacheManager
Definition: CacheManager.php:35
‪TYPO3\CMS\Core\DataHandling\SlugHelper\$tableName
‪string $tableName
Definition: SlugHelper.php:45
‪TYPO3\CMS\Core\Domain\Repository\PageRepository\DOKTYPE_SYSFOLDER
‪const DOKTYPE_SYSFOLDER
Definition: PageRepository.php:109
‪TYPO3\CMS\Core\DataHandling\SlugHelper\buildSlug
‪string buildSlug(string $slug, RecordState $state, callable $isUnique)
Definition: SlugHelper.php:376
‪TYPO3\CMS\Backend\Utility\BackendUtility
Definition: BackendUtility.php:75
‪TYPO3\CMS\Core\Versioning\VersionState
Definition: VersionState.php:24
‪TYPO3\CMS\Core\Utility\GeneralUtility\trimExplode
‪static string[] trimExplode($delim, $string, $removeEmptyValues=false, $limit=0)
Definition: GeneralUtility.php:1059
‪TYPO3\CMS\Core\DataHandling\SlugHelper\generate
‪string generate(array $recordData, int $pid)
Definition: SlugHelper.php:161
‪TYPO3\CMS\Core\DataHandling\Model\RecordState
Definition: RecordState.php:32
‪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\Backend\Utility\BackendUtility\workspaceOL
‪static workspaceOL($table, &$row, $wsid=-99, $unsetMovePointers=false)
Definition: BackendUtility.php:3586
‪TYPO3\CMS\Core\DataHandling\SlugHelper\$prependSlashInSlug
‪bool $prependSlashInSlug
Definition: SlugHelper.php:69
‪TYPO3\CMS\Core\Database\Query\Restriction\DeletedRestriction
Definition: DeletedRestriction.php:28
‪TYPO3\CMS\Core\DataHandling\Model\EntityUidPointer\getIdentifier
‪string getIdentifier()
Definition: EntityUidPointer.php:54
‪TYPO3\CMS\Core\Utility\MathUtility
Definition: MathUtility.php:22
‪TYPO3\CMS\Core\DataHandling\SlugHelper\$configuration
‪array $configuration
Definition: SlugHelper.php:57
‪TYPO3\CMS\Core\DataHandling\SlugHelper\buildSlugForUniqueInTable
‪string buildSlugForUniqueInTable(string $slug, RecordState $state)
Definition: SlugHelper.php:428
‪TYPO3\CMS\Core\DataHandling\SlugHelper\sanitize
‪string sanitize(string $slug)
Definition: SlugHelper.php:101
‪TYPO3\CMS\Core\DataHandling\SlugHelper\applyWorkspaceConstraint
‪applyWorkspaceConstraint(QueryBuilder $queryBuilder, RecordState $state)
Definition: SlugHelper.php:466
‪TYPO3\CMS\Core\Domain\Repository\PageRepository
Definition: PageRepository.php:52
‪TYPO3\CMS\Core\Database\ConnectionPool
Definition: ConnectionPool.php:46
‪TYPO3\CMS\Core\Database\Query\Restriction\QueryRestrictionContainerInterface\add
‪QueryRestrictionContainerInterface add(QueryRestrictionInterface $restriction)
‪TYPO3\CMS\Core\Utility\GeneralUtility
Definition: GeneralUtility.php:46
‪TYPO3\CMS\Core\Utility\StringUtility
Definition: StringUtility.php:22
‪TYPO3\CMS\Core\DataHandling\SlugHelper\__construct
‪__construct(string $tableName, string $fieldName, array $configuration, int $workspaceId=0)
Definition: SlugHelper.php:79
‪TYPO3\CMS\Core\Domain\Repository\PageRepository\DOKTYPE_RECYCLER
‪const DOKTYPE_RECYCLER
Definition: PageRepository.php:110
‪TYPO3\CMS\Core\Database\Query\QueryBuilder\where
‪QueryBuilder where(... $predicates)
Definition: QueryBuilder.php:677
‪TYPO3\CMS\Core\Database\Query\QueryBuilder\expr
‪ExpressionBuilder expr()
Definition: QueryBuilder.php:151
‪TYPO3\CMS\Core\DataHandling\SlugHelper\applyPageIdConstraint
‪applyPageIdConstraint(QueryBuilder $queryBuilder, int $pageId)
Definition: SlugHelper.php:522
‪TYPO3\CMS\Core\DataHandling\SlugHelper\buildSlugForUniqueInPid
‪string buildSlugForUniqueInPid(string $slug, RecordState $state)
Definition: SlugHelper.php:415
‪TYPO3\CMS\Core\DataHandling\Model\RecordStateFactory\forName
‪static static forName(string $name)
Definition: RecordStateFactory.php:35
‪TYPO3\CMS\Core\DataHandling\SlugHelper\flushRootLineCaches
‪flushRootLineCaches()
Definition: SlugHelper.php:361
‪TYPO3\CMS\Core\Database\Query\Restriction\WorkspaceRestriction
Definition: WorkspaceRestriction.php:39