‪TYPO3CMS  ‪main
RootlineUtility.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 
25 use TYPO3\CMS\Core\Database\Query\QueryBuilder;
35 
40 {
42  public const ‪RUNTIME_CACHE_TAG = 'rootline-utility';
43 
44  protected int ‪$pageUid;
45 
46  protected string ‪$mountPointParameter;
47 
49  protected array ‪$parsedMountPointParameters = [];
50 
51  protected int ‪$languageUid = 0;
52 
53  protected int ‪$workspaceUid = 0;
54 
57 
65  protected array ‪$rootlineFields = [
66  'pid',
67  'uid',
68  't3ver_oid',
69  't3ver_wsid',
70  't3ver_state',
71  'title',
72  'nav_title',
73  'media',
74  'layout',
75  'hidden',
76  'starttime',
77  'endtime',
78  'fe_group',
79  'extendToSubpages',
80  'doktype',
81  'TSconfig',
82  'tsconfig_includes',
83  'is_siteroot',
84  'mount_pid',
85  'mount_pid_ol',
86  'backend_layout_next_level',
87  ];
88 
93 
98 
99  protected string ‪$cacheIdentifier;
100 
104  public function ‪__construct(int ‪$uid, string ‪$mountPointParameter = '', ?‪Context ‪$context = null)
105  {
106  $this->mountPointParameter = $this->‪sanitizeMountPointParameter($mountPointParameter);
107  $this->context = ‪$context ?? GeneralUtility::makeInstance(Context::class);
108  $this->pageRepository = GeneralUtility::makeInstance(PageRepository::class, $this->context);
109  $this->languageUid = $this->context->getPropertyFromAspect('language', 'id', 0);
110  $this->workspaceUid = (int)$this->context->getPropertyFromAspect('workspace', 'id', 0);
111  if ($this->mountPointParameter !== '') {
112  if (!(‪$GLOBALS['TYPO3_CONF_VARS']['FE']['enable_mount_pids'] ?? false)) {
113  throw new ‪MountPointsDisabledException('Mount-Point Pages are disabled for this installation. Cannot resolve a Rootline for a page with Mount-Points', 1343462896);
114  }
116  }
117  $this->pageUid = $this->‪resolvePageId($uid);
118  $this->cache = GeneralUtility::makeInstance(CacheManager::class)->getCache('rootline');
119  $this->runtimeCache = GeneralUtility::makeInstance(CacheManager::class)->getCache('runtime');
120  $this->cacheIdentifier = $this->‪getCacheIdentifier();
121  }
122 
126  public function get(): array
127  {
128  if ($this->pageUid === 0) {
129  // pageUid 0 has no root line, return empty array right away
130  return [];
131  }
132  if (!$this->runtimeCache->has('rootline-localcache-' . $this->cacheIdentifier)) {
133  $entry = $this->cache->get($this->cacheIdentifier);
134  if (!$entry) {
135  $this->‪generateRootlineCache();
136  } else {
137  $this->runtimeCache->set('rootline-localcache-' . $this->cacheIdentifier, $entry, [self::RUNTIME_CACHE_TAG]);
138  $depth = count($entry);
139  // Populate the root-lines for parent pages as well
140  // since they are part of the current root-line
141  while ($depth > 1) {
142  --$depth;
143  $parentCacheIdentifier = $this->‪getCacheIdentifier($entry[$depth - 1]['uid']);
144  // Abort if the root-line of the parent page is
145  // already in the local cache data
146  if ($this->runtimeCache->has('rootline-localcache-' . $parentCacheIdentifier)) {
147  break;
148  }
149  // Behaves similar to array_shift(), but preserves
150  // the array keys - which contain the page ids here
151  $entry = array_slice($entry, 1, null, true);
152  $this->runtimeCache->set('rootline-localcache-' . $parentCacheIdentifier, $entry, [self::RUNTIME_CACHE_TAG]);
153  }
154  }
155  }
156  return $this->runtimeCache->get('rootline-localcache-' . $this->cacheIdentifier);
157  }
158 
159  protected function ‪getCacheIdentifier(int $otherUid = null): string
160  {
162  if (‪$mountPointParameter !== '' && str_contains(‪$mountPointParameter, ',')) {
163  ‪$mountPointParameter = str_replace(',', '__', ‪$mountPointParameter);
164  }
165  return implode('_', [
166  $otherUid ?? $this->pageUid,
168  $this->languageUid,
169  $this->workspaceUid,
170  $this->context->getAspect('visibility')->includeHiddenContent() ? '1' : '0',
171  $this->context->getAspect('visibility')->includeHiddenPages() ? '1' : '0',
172  ]);
173  }
174 
183  protected function getRecordArray(int ‪$uid): array
184  {
185  ‪$rootlineFields = array_merge($this->rootlineFields, ‪GeneralUtility::trimExplode(',', ‪$GLOBALS['TYPO3_CONF_VARS']['FE']['addRootLineFields'], true));
186  ‪$rootlineFields = array_unique(‪$rootlineFields);
187  $currentCacheIdentifier = $this->‪getCacheIdentifier($uid);
188  if (!$this->runtimeCache->has('rootline-recordcache-' . $currentCacheIdentifier)) {
189  $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable('pages');
190  $queryBuilder->getRestrictions()->removeAll()->add(GeneralUtility::makeInstance(DeletedRestriction::class));
191  $row = $queryBuilder->select(...‪$rootlineFields)
192  ->from('pages')
193  ->where(
194  $queryBuilder->expr()->eq('uid', $queryBuilder->createNamedParameter(‪$uid, ‪Connection::PARAM_INT)),
195  $queryBuilder->expr()->in('t3ver_wsid', $queryBuilder->createNamedParameter([0, $this->workspaceUid], ‪Connection::PARAM_INT_ARRAY))
196  )
197  ->executeQuery()
198  ->fetchAssociative();
199  if (empty($row)) {
200  throw new ‪PageNotFoundException('Could not fetch page data for uid ' . ‪$uid . '.', 1343589451);
201  }
202  $this->pageRepository->versionOL('pages', $row, false, true);
203  if (is_array($row)) {
204  $row = $this->pageRepository->getLanguageOverlay('pages', $row, $this->context->getAspect('language'));
205  $row = $this->enrichWithRelationFields($row['_LOCALIZED_UID'] ?? ‪$uid, $row);
206  $this->runtimeCache->set('rootline-recordcache-' . $currentCacheIdentifier, $row, [self::RUNTIME_CACHE_TAG]);
207  }
208  }
209  if (!is_array($this->runtimeCache->get('rootline-recordcache-' . $currentCacheIdentifier) ?? false)) {
210  throw new PageNotFoundException('Broken rootline. Could not resolve page with uid ' . ‪$uid . '.', 1343464101);
211  }
212  return $this->runtimeCache->get('rootline-recordcache-' . $currentCacheIdentifier);
213  }
214 
223  protected function enrichWithRelationFields(int ‪$uid, array ‪$pageRecord): array
224  {
225  if (!is_array(‪$GLOBALS['TCA']['pages']['columns'] ?? false)) {
226  throw new \LogicException(
227  'Main ext:core configuration $GLOBALS[\'TCA\'][\'pages\'][\'columns\'] not found.',
228  1712572738
229  );
230  }
231 
232  foreach (‪$GLOBALS['TCA']['pages']['columns'] as $column => $configuration) {
233  // Ensure that only fields defined in $rootlineFields (and "addRootLineFields") are actually evaluated
234  if (array_key_exists($column, ‪$pageRecord) && $this->‪columnHasRelationToResolve($configuration)) {
235  $fieldConfig = $configuration['config'];
236  ‪$relatedUids = [];
237  if (($fieldConfig['MM'] ?? false) || (!empty($fieldConfig['foreign_table'] ?? $fieldConfig['allowed'] ?? ''))) {
238  $relationHandler = GeneralUtility::makeInstance(RelationHandler::class);
239  // do not include hidden relational fields
240  $relationalTable = $fieldConfig['foreign_table'] ?? $fieldConfig['allowed'];
241  $hiddenFieldName = ‪$GLOBALS['TCA'][$relationalTable]['ctrl']['enablecolumns']['disabled'] ?? null;
242  if (!$this->context->getAspect('visibility')->includeHiddenContent() && $hiddenFieldName) {
243  $fieldConfig['foreign_match_fields'][$hiddenFieldName] = 0;
244  }
245  $relationHandler->setWorkspaceId($this->workspaceUid);
246  $relationHandler->start(
247  ‪$pageRecord[$column],
248  $fieldConfig['foreign_table'] ?? $fieldConfig['allowed'],
249  $fieldConfig['MM'] ?? '',
250  ‪$uid,
251  'pages',
252  $fieldConfig
253  );
254  $relationHandler->processDeletePlaceholder();
255  ‪$relatedUids = $relationHandler->getValueArray();
256  }
257  ‪$pageRecord[$column] = implode(',', ‪$relatedUids);
258  }
259  }
261  }
262 
270  protected function ‪columnHasRelationToResolve(array $configuration): bool
271  {
272  $configuration = $configuration['config'] ?? [];
273  if (!empty($configuration['MM']) && !empty($configuration['type']) && in_array($configuration['type'], ['select', 'inline', 'group'])) {
274  return true;
275  }
276  if (!empty($configuration['foreign_field']) && !empty($configuration['type']) && in_array($configuration['type'], ['inline', 'file'])) {
277  return true;
278  }
279  if (($configuration['type'] ?? '') === 'category' && ($configuration['relationship'] ?? '') === 'manyToMany') {
280  return true;
281  }
282  return false;
283  }
284 
290  protected function ‪generateRootlineCache(): void
291  {
292  $page = $this->getRecordArray($this->pageUid);
293  // If the current page is a mounted (according to the MP parameter) handle the mount-point
294  if ($this->‪isMountedPage()) {
295  $mountPoint = $this->getRecordArray($this->parsedMountPointParameters[$this->pageUid]);
296  $page = $this->processMountedPage($page, $mountPoint);
297  $parentUid = $mountPoint['pid'];
298  // Anyhow after reaching the mount-point, we have to go up that rootline
299  unset($this->parsedMountPointParameters[$this->pageUid]);
300  } else {
301  $parentUid = $page['pid'];
302  }
303  $cacheTags = ['pageId_' . $page['uid']];
304  if ($parentUid > 0) {
305  // Get rootline of (and including) parent page
306  ‪$mountPointParameter = !empty($this->parsedMountPointParameters) ? $this->mountPointParameter : '';
307  $rootlineUtility = GeneralUtility::makeInstance(self::class, $parentUid, ‪$mountPointParameter, $this->context);
308  $rootline = $rootlineUtility->get();
309  // retrieve cache tags of parent rootline
310  foreach ($rootline as $entry) {
311  $cacheTags[] = 'pageId_' . $entry['uid'];
312  if ($entry['uid'] == $this->pageUid) {
313  // @todo: Bug. This detection is broken since it happens *after* the child ->get() call, and thus
314  // triggers infinite recursion already. To fix this, the child needs to know the list of
315  // resolved children to except on duplicate *before* going up itself. Cover this case with
316  // a functional test when fixing.
318  'Circular connection in rootline for page with uid ' . $this->pageUid . ' found. Check your mountpoint configuration.',
319  1343464103
320  );
321  }
322  }
323  } else {
324  $rootline = [];
325  }
326  $rootline[] = $page;
327  krsort($rootline);
328  $this->cache->set($this->cacheIdentifier, $rootline, $cacheTags);
329  $this->runtimeCache->set('rootline-localcache-' . $this->cacheIdentifier, $rootline, [self::RUNTIME_CACHE_TAG]);
330  }
331 
336  protected function ‪isMountedPage(): bool
337  {
338  return array_key_exists($this->pageUid, $this->parsedMountPointParameters);
339  }
340 
349  protected function processMountedPage(array ‪$mountedPageData, array $mountPointPageData): array
350  {
351  $mountPid = $mountPointPageData['mount_pid'] ?? null;
352  ‪$uid = ‪$mountedPageData['uid'] ?? null;
353  if ((int)$mountPid !== (int)‪$uid) {
354  throw new ‪BrokenRootLineException('Broken rootline. Mountpoint parameter does not match the actual rootline. mount_pid (' . $mountPid . ') does not match page uid (' . ‪$uid . ').', 1343464100);
355  }
356  // Current page replaces the original mount-page
357  ‪$mountUid = $mountPointPageData['uid'] ?? null;
358  if (!empty($mountPointPageData['mount_pid_ol'])) {
359  ‪$mountedPageData['_MOUNT_OL'] = true;
360  ‪$mountedPageData['_MOUNT_PAGE'] = [
361  'uid' => ‪$mountUid,
362  'pid' => $mountPointPageData['pid'] ?? null,
363  'title' => $mountPointPageData['title'] ?? null,
364  ];
365  } else {
366  // The mount-page is not replaced, the mount-page itself has to be used
367  ‪$mountedPageData = $mountPointPageData;
368  }
370  ‪$mountedPageData['_MP_PARAM'] = $this->pageUid . '-' . ‪$mountUid;
372  }
373 
379  protected function ‪sanitizeMountPointParameter(string ‪$mountPointParameter): string
380  {
382  if (‪$mountPointParameter === '') {
383  return '';
384  }
386  foreach ($mountPoints as $key => $mP) {
387  // If MP has incorrect format, discard it
388  if (!preg_match('/^\d+-\d+$/', $mP)) {
389  unset($mountPoints[$key]);
390  }
391  }
392  return implode(',', $mountPoints);
393  }
394 
400  protected function ‪parseMountPointParameter(): void
401  {
402  $mountPoints = ‪GeneralUtility::trimExplode(',', $this->mountPointParameter);
403  foreach ($mountPoints as $mP) {
404  [$mountedPageUid, $mountPageUid] = ‪GeneralUtility::intExplode('-', $mP);
405  $this->parsedMountPointParameters[$mountedPageUid] = $mountPageUid;
406  }
407  }
408 
415  protected function ‪resolvePageId(int $pageId): int
416  {
417  if ($pageId === 0 || $this->workspaceUid === 0) {
418  return $pageId;
419  }
420 
421  $page = $this->‪resolvePageRecord($pageId);
422  if (!isset($page['t3ver_state']) || VersionState::tryFrom($page['t3ver_state']) !== VersionState::MOVE_POINTER) {
423  return $pageId;
424  }
425 
426  $movePointerId = $this->‪resolveMovePointerId((int)$page['t3ver_oid']);
427  return $movePointerId ?: $pageId;
428  }
429 
430  protected function ‪resolvePageRecord(int $pageId): ?array
431  {
432  $queryBuilder = $this->‪createQueryBuilder('pages');
433  $queryBuilder->getRestrictions()->removeAll()
434  ->add(GeneralUtility::makeInstance(DeletedRestriction::class));
435 
436  $statement = $queryBuilder
437  ->from('pages')
438  ->select('uid', 't3ver_oid', 't3ver_state')
439  ->where(
440  $queryBuilder->expr()->eq(
441  'uid',
442  $queryBuilder->createNamedParameter($pageId, ‪Connection::PARAM_INT)
443  )
444  )
445  ->setMaxResults(1)
446  ->executeQuery();
447 
448  ‪$record = $statement->fetchAssociative();
449  return ‪$record ?: null;
450  }
451 
455  protected function ‪resolveMovePointerId(int $liveId): ?int
456  {
457  $queryBuilder = $this->‪createQueryBuilder('pages');
458  $queryBuilder->getRestrictions()->removeAll()
459  ->add(GeneralUtility::makeInstance(DeletedRestriction::class));
460 
461  $statement = $queryBuilder
462  ->from('pages')
463  ->select('uid')
464  ->setMaxResults(1)
465  ->where(
466  $queryBuilder->expr()->eq(
467  't3ver_wsid',
468  $queryBuilder->createNamedParameter($this->workspaceUid, ‪Connection::PARAM_INT)
469  ),
470  $queryBuilder->expr()->eq(
471  't3ver_state',
472  $queryBuilder->createNamedParameter(VersionState::MOVE_POINTER->value, ‪Connection::PARAM_INT)
473  ),
474  $queryBuilder->expr()->eq(
475  't3ver_oid',
476  $queryBuilder->createNamedParameter($liveId, ‪Connection::PARAM_INT)
477  )
478  )
479  ->executeQuery();
480 
481  $movePointerId = $statement->fetchOne();
482  return $movePointerId ? (int)$movePointerId : null;
483  }
484 
485  protected function ‪createQueryBuilder(string $tableName): QueryBuilder
486  {
487  return GeneralUtility::makeInstance(ConnectionPool::class)
488  ->getQueryBuilderForTable($tableName);
489  }
490 }
‪TYPO3\CMS\Core\Utility\RootlineUtility\$workspaceUid
‪int $workspaceUid
Definition: RootlineUtility.php:53
‪TYPO3\CMS\Core\Utility\RootlineUtility\getCacheIdentifier
‪getCacheIdentifier(int $otherUid=null)
Definition: RootlineUtility.php:159
‪TYPO3\CMS\Core\Utility\RootlineUtility\$languageUid
‪int $languageUid
Definition: RootlineUtility.php:51
‪TYPO3\CMS\Core\Utility\RootlineUtility\$pageUid
‪int $pageUid
Definition: RootlineUtility.php:44
‪TYPO3\CMS\Core\Database\Connection\PARAM_INT
‪const PARAM_INT
Definition: Connection.php:52
‪TYPO3\CMS\Core\Utility\RootlineUtility\RUNTIME_CACHE_TAG
‪const RUNTIME_CACHE_TAG
Definition: RootlineUtility.php:42
‪TYPO3\CMS\Core\Utility\RootlineUtility\$relatedUids
‪$relatedUids
Definition: RootlineUtility.php:255
‪TYPO3\CMS\Core\Utility\RootlineUtility\createQueryBuilder
‪createQueryBuilder(string $tableName)
Definition: RootlineUtility.php:485
‪TYPO3\CMS\Core\Utility\RootlineUtility\$mountedPageData
‪return $mountedPageData
Definition: RootlineUtility.php:371
‪TYPO3\CMS\Core\Database\RelationHandler
Definition: RelationHandler.php:36
‪TYPO3\CMS\Core\Utility\RootlineUtility\parseMountPointParameter
‪parseMountPointParameter()
Definition: RootlineUtility.php:400
‪TYPO3\CMS\Core\Versioning\VersionState
‪VersionState
Definition: VersionState.php:22
‪TYPO3\CMS\Core\Utility\RootlineUtility\$mountUid
‪array< string, function processMountedPage(array $mountedPageData, array $mountPointPageData):array { $mountPid=$mountPointPageData[ 'mount_pid'] ?? null;$uid=$mountedPageData[ 'uid'] ?? null;if((int) $mountPid !==(int) $uid) { throw new BrokenRootLineException( 'Broken rootline. Mountpoint parameter does not match the actual rootline. mount_pid(' . $mountPid . ') does not match page uid(' . $uid . ').', 1343464100);} $mountUid=$mountPointPageData[ 'uid'] ?? null;if(!empty( $mountPointPageData[ 'mount_pid_ol'])) { $mountedPageData[ '_MOUNT_OL']=true;$mountedPageData[ '_MOUNT_PAGE']=['uid'=> $mountUid
Definition: RootlineUtility.php:361
‪TYPO3\CMS\Core\Utility\RootlineUtility\$pageRecord
‪return $pageRecord
Definition: RootlineUtility.php:260
‪TYPO3\CMS\Core\Utility\RootlineUtility\resolvePageId
‪resolvePageId(int $pageId)
Definition: RootlineUtility.php:415
‪TYPO3\CMS\Core\Utility\RootlineUtility
Definition: RootlineUtility.php:40
‪TYPO3\CMS\Core\Utility\RootlineUtility\$runtimeCache
‪FrontendInterface $runtimeCache
Definition: RootlineUtility.php:56
‪TYPO3\CMS\Core\Utility
Definition: ArrayUtility.php:18
‪TYPO3\CMS\Core\Utility\RootlineUtility\$mountedPageData
‪$mountedPageData['_MOUNTED_FROM']
Definition: RootlineUtility.php:369
‪TYPO3\CMS\Core\Utility\RootlineUtility\sanitizeMountPointParameter
‪sanitizeMountPointParameter(string $mountPointParameter)
Definition: RootlineUtility.php:379
‪TYPO3\CMS\Core\Utility\RootlineUtility\$pageRecord
‪$pageRecord[$column]
Definition: RootlineUtility.php:257
‪TYPO3\CMS\Core\Utility\RootlineUtility\isMountedPage
‪isMountedPage()
Definition: RootlineUtility.php:336
‪TYPO3\CMS\Core\Context\Context
Definition: Context.php:54
‪TYPO3\CMS\Core\Utility\RootlineUtility\columnHasRelationToResolve
‪bool columnHasRelationToResolve(array $configuration)
Definition: RootlineUtility.php:270
‪TYPO3\CMS\Core\Utility\RootlineUtility\generateRootlineCache
‪generateRootlineCache()
Definition: RootlineUtility.php:290
‪TYPO3\CMS\Core\Utility\RootlineUtility\$cacheIdentifier
‪string $cacheIdentifier
Definition: RootlineUtility.php:99
‪TYPO3\CMS\Core\Utility\RootlineUtility\$pageRepository
‪PageRepository $pageRepository
Definition: RootlineUtility.php:92
‪TYPO3\CMS\Core\Utility\RootlineUtility\$cache
‪FrontendInterface $cache
Definition: RootlineUtility.php:55
‪TYPO3\CMS\Core\Utility\RootlineUtility\$mountPointParameter
‪string $mountPointParameter
Definition: RootlineUtility.php:46
‪TYPO3\CMS\Webhooks\Message\$record
‪identifier readonly int readonly array $record
Definition: PageModificationMessage.php:36
‪TYPO3\CMS\Core\Exception\Page\CircularRootLineException
Definition: CircularRootLineException.php:23
‪TYPO3\CMS\Core\Cache\CacheManager
Definition: CacheManager.php:36
‪TYPO3\CMS\Core\Utility\RootlineUtility\$parsedMountPointParameters
‪array $parsedMountPointParameters
Definition: RootlineUtility.php:49
‪TYPO3\CMS\Core\Utility\RootlineUtility\__construct
‪__construct(int $uid, string $mountPointParameter='', ?Context $context=null)
Definition: RootlineUtility.php:104
‪TYPO3\CMS\Core\Database\Connection
Definition: Connection.php:41
‪TYPO3\CMS\Core\Cache\Frontend\FrontendInterface
Definition: FrontendInterface.php:22
‪TYPO3\CMS\Webhooks\Message\$uid
‪identifier readonly int $uid
Definition: PageModificationMessage.php:35
‪$GLOBALS
‪$GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['adminpanel']['modules']
Definition: ext_localconf.php:25
‪TYPO3\CMS\Core\Database\Query\Restriction\DeletedRestriction
Definition: DeletedRestriction.php:28
‪TYPO3\CMS\Core\Utility\RootlineUtility\resolveMovePointerId
‪resolveMovePointerId(int $liveId)
Definition: RootlineUtility.php:455
‪TYPO3\CMS\Core\Utility\RootlineUtility\$context
‪Context $context
Definition: RootlineUtility.php:97
‪TYPO3\CMS\Core\Exception\Page\BrokenRootLineException
Definition: BrokenRootLineException.php:23
‪TYPO3\CMS\Core\Exception\Page\MountPointsDisabledException
Definition: MountPointsDisabledException.php:24
‪TYPO3\CMS\Core\Domain\Repository\PageRepository
Definition: PageRepository.php:69
‪TYPO3\CMS\Core\Database\ConnectionPool
Definition: ConnectionPool.php:46
‪TYPO3\CMS\Core\Exception\Page\PageNotFoundException
Definition: PageNotFoundException.php:23
‪TYPO3\CMS\Core\Utility\RootlineUtility\$rootlineFields
‪array $rootlineFields
Definition: RootlineUtility.php:65
‪TYPO3\CMS\Core\Utility\RootlineUtility\resolvePageRecord
‪resolvePageRecord(int $pageId)
Definition: RootlineUtility.php:430
‪TYPO3\CMS\Core\Utility\GeneralUtility\intExplode
‪static list< int > intExplode(string $delimiter, string $string, bool $removeEmptyValues=false)
Definition: GeneralUtility.php:756
‪TYPO3\CMS\Core\Database\Connection\PARAM_INT_ARRAY
‪const PARAM_INT_ARRAY
Definition: Connection.php:72
‪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\Core\Exception\Page\PagePropertyRelationNotFoundException
Definition: PagePropertyRelationNotFoundException.php:23
‪TYPO3\CMS\Core\Utility\RootlineUtility\getCacheIdentifier
‪array< string, getRecordArray(int $uid):array { $rootlineFields=array_merge( $this->rootlineFields, GeneralUtility::trimExplode(',', $GLOBALS[ 'TYPO3_CONF_VARS'][ 'FE'][ 'addRootLineFields'], true));$rootlineFields=array_unique( $rootlineFields);$currentCacheIdentifier=$this-> getCacheIdentifier($uid)