‪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, ‪$context);
109 
110  $this->languageUid = $this->context->getPropertyFromAspect('language', 'id', 0);
111  $this->workspaceUid = (int)$this->context->getPropertyFromAspect('workspace', 'id', 0);
112  if ($this->mountPointParameter !== '') {
113  if (!(‪$GLOBALS['TYPO3_CONF_VARS']['FE']['enable_mount_pids'] ?? false)) {
114  throw new ‪MountPointsDisabledException('Mount-Point Pages are disabled for this installation. Cannot resolve a Rootline for a page with Mount-Points', 1343462896);
115  }
117  }
118 
119  $this->pageUid = $this->‪resolvePageId($uid);
120  $this->cache ??= GeneralUtility::makeInstance(CacheManager::class)->getCache('rootline');
121  $this->runtimeCache ??= GeneralUtility::makeInstance(CacheManager::class)->getCache('runtime');
122 
123  $this->cacheIdentifier = $this->‪getCacheIdentifier();
124  }
125 
129  public function ‪getCacheIdentifier(int $otherUid = null): string
130  {
131  ‪$mountPointParameter = (string)$this->mountPointParameter;
132  if (‪$mountPointParameter !== '' && str_contains(‪$mountPointParameter, ',')) {
133  ‪$mountPointParameter = str_replace(',', '__', ‪$mountPointParameter);
134  }
135 
136  return implode('_', [
137  $otherUid ?? $this->pageUid,
139  $this->languageUid,
140  $this->workspaceUid,
141  $this->context->getAspect('visibility')->includeHiddenContent() ? '1' : '0',
142  $this->context->getAspect('visibility')->includeHiddenPages() ? '1' : '0',
143  ]);
144  }
145 
149  public function get(): array
150  {
151  if ($this->pageUid === 0) {
152  // pageUid 0 has no root line, return empty array right away
153  return [];
154  }
155  if (!$this->runtimeCache->has('rootline-localcache-' . $this->cacheIdentifier)) {
156  $entry = $this->cache->get($this->cacheIdentifier);
157  if (!$entry) {
158  $this->‪generateRootlineCache();
159  } else {
160  $this->runtimeCache->set('rootline-localcache-' . $this->cacheIdentifier, $entry, [self::RUNTIME_CACHE_TAG]);
161  $depth = count($entry);
162  // Populate the root-lines for parent pages as well
163  // since they are part of the current root-line
164  while ($depth > 1) {
165  --$depth;
166  $parentCacheIdentifier = $this->‪getCacheIdentifier($entry[$depth - 1]['uid']);
167  // Abort if the root-line of the parent page is
168  // already in the local cache data
169  if ($this->runtimeCache->has('rootline-localcache-' . $parentCacheIdentifier)) {
170  break;
171  }
172  // Behaves similar to array_shift(), but preserves
173  // the array keys - which contain the page ids here
174  $entry = array_slice($entry, 1, null, true);
175  $this->runtimeCache->set('rootline-localcache-' . $parentCacheIdentifier, $entry, [self::RUNTIME_CACHE_TAG]);
176  }
177  }
178  }
179  return $this->runtimeCache->get('rootline-localcache-' . $this->cacheIdentifier);
180  }
181 
190  protected function getRecordArray(int ‪$uid): array
191  {
192  ‪$rootlineFields = array_merge($this->rootlineFields, GeneralUtility::trimExplode(',', ‪$GLOBALS['TYPO3_CONF_VARS']['FE']['addRootLineFields'], true));
193  ‪$rootlineFields = array_unique(‪$rootlineFields);
194  $currentCacheIdentifier = $this->‪getCacheIdentifier($uid);
195  if (!$this->runtimeCache->has('rootline-recordcache-' . $currentCacheIdentifier)) {
196  $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable('pages');
197  $queryBuilder->getRestrictions()->removeAll()->add(GeneralUtility::makeInstance(DeletedRestriction::class));
198  $row = $queryBuilder->select(...‪$rootlineFields)
199  ->from('pages')
200  ->where(
201  $queryBuilder->expr()->eq('uid', $queryBuilder->createNamedParameter(‪$uid, ‪Connection::PARAM_INT)),
202  $queryBuilder->expr()->in('t3ver_wsid', $queryBuilder->createNamedParameter([0, $this->workspaceUid], Connection::PARAM_INT_ARRAY))
203  )
204  ->executeQuery()
205  ->fetchAssociative();
206  if (empty($row)) {
207  throw new ‪PageNotFoundException('Could not fetch page data for uid ' . ‪$uid . '.', 1343589451);
208  }
209  $this->pageRepository->versionOL('pages', $row, false, true);
210  if (is_array($row)) {
211  $row = $this->pageRepository->getLanguageOverlay('pages', $row, $this->context->getAspect('language'));
212  $row = $this->enrichWithRelationFields($row['_PAGES_OVERLAY_UID'] ?? ‪$uid, $row);
213  $this->runtimeCache->set('rootline-recordcache-' . $currentCacheIdentifier, $row, [self::RUNTIME_CACHE_TAG]);
214  }
215  }
216  if (!is_array($this->runtimeCache->get('rootline-recordcache-' . $currentCacheIdentifier) ?? false)) {
217  throw new PageNotFoundException('Broken rootline. Could not resolve page with uid ' . ‪$uid . '.', 1343464101);
218  }
219  return $this->runtimeCache->get('rootline-recordcache-' . $currentCacheIdentifier);
220  }
221 
230  protected function enrichWithRelationFields(int ‪$uid, array ‪$pageRecord): array
231  {
232  if (!isset(‪$GLOBALS['TCA']['pages']['columns']) || !is_array(‪$GLOBALS['TCA']['pages']['columns'])) {
233  return ‪$pageRecord;
234  }
235 
236  foreach (‪$GLOBALS['TCA']['pages']['columns'] as $column => $configuration) {
237  // Ensure that only fields defined in $rootlineFields (and "addRootLineFields") are actually evaluated
238  if (array_key_exists($column, ‪$pageRecord) && $this->‪columnHasRelationToResolve($configuration)) {
239  $fieldConfig = $configuration['config'];
240  ‪$relatedUids = [];
241  if (($fieldConfig['MM'] ?? false) || (!empty($fieldConfig['foreign_table'] ?? $fieldConfig['allowed'] ?? ''))) {
242  $relationHandler = GeneralUtility::makeInstance(RelationHandler::class);
243  // do not include hidden relational fields
244  $relationalTable = $fieldConfig['foreign_table'] ?? $fieldConfig['allowed'];
245  $hiddenFieldName = ‪$GLOBALS['TCA'][$relationalTable]['ctrl']['enablecolumns']['disabled'] ?? null;
246  if (!$this->context->getAspect('visibility')->includeHiddenContent() && $hiddenFieldName) {
247  $fieldConfig['foreign_match_fields'][$hiddenFieldName] = 0;
248  }
249  $relationHandler->setWorkspaceId($this->workspaceUid);
250  $relationHandler->start(
251  ‪$pageRecord[$column],
252  $fieldConfig['foreign_table'] ?? $fieldConfig['allowed'],
253  $fieldConfig['MM'] ?? '',
254  ‪$uid,
255  'pages',
256  $fieldConfig
257  );
258  ‪$relatedUids = $relationHandler->getValueArray();
259  }
260  ‪$pageRecord[$column] = implode(',', ‪$relatedUids);
261  }
262  }
264  }
265 
273  protected function ‪columnHasRelationToResolve(array $configuration): bool
274  {
275  $configuration = $configuration['config'] ?? [];
276  if (!empty($configuration['MM']) && !empty($configuration['type']) && in_array($configuration['type'], ['select', 'inline', 'group'])) {
277  return true;
278  }
279  if (!empty($configuration['foreign_field']) && !empty($configuration['type']) && in_array($configuration['type'], ['select', 'inline', 'file'])) {
280  return true;
281  }
282  if (($configuration['type'] ?? '') === 'category' && ($configuration['relationship'] ?? '') === 'manyToMany') {
283  return true;
284  }
285  return false;
286  }
287 
293  protected function ‪generateRootlineCache(): void
294  {
295  $page = $this->getRecordArray($this->pageUid);
296  // If the current page is a mounted (according to the MP parameter) handle the mount-point
297  if ($this->‪isMountedPage()) {
298  $mountPoint = $this->getRecordArray($this->parsedMountPointParameters[$this->pageUid]);
299  $page = $this->processMountedPage($page, $mountPoint);
300  $parentUid = $mountPoint['pid'];
301  // Anyhow after reaching the mount-point, we have to go up that rootline
302  unset($this->parsedMountPointParameters[$this->pageUid]);
303  } else {
304  $parentUid = $page['pid'];
305  }
306  $cacheTags = ['pageId_' . $page['uid']];
307  if ($parentUid > 0) {
308  // Get rootline of (and including) parent page
309  ‪$mountPointParameter = !empty($this->parsedMountPointParameters) ? $this->mountPointParameter : '';
310  $rootlineUtility = GeneralUtility::makeInstance(self::class, $parentUid, ‪$mountPointParameter, $this->context);
311  $rootline = $rootlineUtility->get();
312  // retrieve cache tags of parent rootline
313  foreach ($rootline as $entry) {
314  $cacheTags[] = 'pageId_' . $entry['uid'];
315  if ($entry['uid'] == $this->pageUid) {
316  throw new ‪CircularRootLineException('Circular connection in rootline for page with uid ' . $this->pageUid . ' found. Check your mountpoint configuration.', 1343464103);
317  }
318  }
319  } else {
320  $rootline = [];
321  }
322  $rootline[] = $page;
323  krsort($rootline);
324  $this->cache->set($this->cacheIdentifier, $rootline, $cacheTags);
325  $this->runtimeCache->set('rootline-localcache-' . $this->cacheIdentifier, $rootline, [self::RUNTIME_CACHE_TAG]);
326  }
327 
332  public function ‪isMountedPage(): bool
333  {
334  return array_key_exists($this->pageUid, $this->parsedMountPointParameters);
335  }
336 
345  protected function processMountedPage(array ‪$mountedPageData, array $mountPointPageData): array
346  {
347  $mountPid = $mountPointPageData['mount_pid'] ?? null;
348  ‪$uid = ‪$mountedPageData['uid'] ?? null;
349  if ((int)$mountPid !== (int)‪$uid) {
350  throw new ‪BrokenRootLineException('Broken rootline. Mountpoint parameter does not match the actual rootline. mount_pid (' . $mountPid . ') does not match page uid (' . ‪$uid . ').', 1343464100);
351  }
352  // Current page replaces the original mount-page
353  ‪$mountUid = $mountPointPageData['uid'] ?? null;
354  if (!empty($mountPointPageData['mount_pid_ol'])) {
355  ‪$mountedPageData['_MOUNT_OL'] = true;
356  ‪$mountedPageData['_MOUNT_PAGE'] = [
357  'uid' => ‪$mountUid,
358  'pid' => $mountPointPageData['pid'] ?? null,
359  'title' => $mountPointPageData['title'] ?? null,
360  ];
361  } else {
362  // The mount-page is not replaced, the mount-page itself has to be used
363  ‪$mountedPageData = $mountPointPageData;
364  }
366  ‪$mountedPageData['_MP_PARAM'] = $this->pageUid . '-' . ‪$mountUid;
368  }
369 
375  protected function ‪sanitizeMountPointParameter(string ‪$mountPointParameter): string
376  {
378  if (‪$mountPointParameter === '') {
379  return '';
380  }
381  $mountPoints = GeneralUtility::trimExplode(',', ‪$mountPointParameter);
382  foreach ($mountPoints as $key => $mP) {
383  // If MP has incorrect format, discard it
384  if (!preg_match('/^\d+-\d+$/', $mP)) {
385  unset($mountPoints[$key]);
386  }
387  }
388  return implode(',', $mountPoints);
389  }
390 
396  protected function ‪parseMountPointParameter(): void
397  {
398  $mountPoints = GeneralUtility::trimExplode(',', $this->mountPointParameter);
399  foreach ($mountPoints as $mP) {
400  [$mountedPageUid, $mountPageUid] = GeneralUtility::intExplode('-', $mP);
401  $this->parsedMountPointParameters[$mountedPageUid] = $mountPageUid;
402  }
403  }
404 
411  protected function ‪resolvePageId(int $pageId): int
412  {
413  if ($pageId === 0 || $this->workspaceUid === 0) {
414  return $pageId;
415  }
416 
417  $page = $this->‪resolvePageRecord($pageId);
418  if (!isset($page['t3ver_state']) || VersionState::tryFrom($page['t3ver_state']) !== VersionState::MOVE_POINTER) {
419  return $pageId;
420  }
421 
422  $movePointerId = $this->‪resolveMovePointerId((int)$page['t3ver_oid']);
423  return $movePointerId ?: $pageId;
424  }
425 
426  protected function ‪resolvePageRecord(int $pageId): ?array
427  {
428  $queryBuilder = $this->‪createQueryBuilder('pages');
429  $queryBuilder->getRestrictions()->removeAll()
430  ->add(GeneralUtility::makeInstance(DeletedRestriction::class));
431 
432  $statement = $queryBuilder
433  ->from('pages')
434  ->select('uid', 't3ver_oid', 't3ver_state')
435  ->where(
436  $queryBuilder->expr()->eq(
437  'uid',
438  $queryBuilder->createNamedParameter($pageId, ‪Connection::PARAM_INT)
439  )
440  )
441  ->setMaxResults(1)
442  ->executeQuery();
443 
444  ‪$record = $statement->fetchAssociative();
445  return ‪$record ?: null;
446  }
447 
451  protected function ‪resolveMovePointerId(int $liveId): ?int
452  {
453  $queryBuilder = $this->‪createQueryBuilder('pages');
454  $queryBuilder->getRestrictions()->removeAll()
455  ->add(GeneralUtility::makeInstance(DeletedRestriction::class));
456 
457  $statement = $queryBuilder
458  ->from('pages')
459  ->select('uid')
460  ->setMaxResults(1)
461  ->where(
462  $queryBuilder->expr()->eq(
463  't3ver_wsid',
464  $queryBuilder->createNamedParameter($this->workspaceUid, ‪Connection::PARAM_INT)
465  ),
466  $queryBuilder->expr()->eq(
467  't3ver_state',
468  $queryBuilder->createNamedParameter(VersionState::MOVE_POINTER->value, ‪Connection::PARAM_INT)
469  ),
470  $queryBuilder->expr()->eq(
471  't3ver_oid',
472  $queryBuilder->createNamedParameter($liveId, ‪Connection::PARAM_INT)
473  )
474  )
475  ->executeQuery();
476 
477  $movePointerId = $statement->fetchOne();
478  return $movePointerId ? (int)$movePointerId : null;
479  }
480 
481  protected function ‪createQueryBuilder(string $tableName): QueryBuilder
482  {
483  return GeneralUtility::makeInstance(ConnectionPool::class)
484  ->getQueryBuilderForTable($tableName);
485  }
486 }
‪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:129
‪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:50
‪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:258
‪TYPO3\CMS\Core\Utility\RootlineUtility\createQueryBuilder
‪createQueryBuilder(string $tableName)
Definition: RootlineUtility.php:481
‪TYPO3\CMS\Core\Utility\RootlineUtility\$mountedPageData
‪return $mountedPageData
Definition: RootlineUtility.php:367
‪TYPO3\CMS\Core\Database\RelationHandler
Definition: RelationHandler.php:36
‪TYPO3\CMS\Core\Utility\RootlineUtility\parseMountPointParameter
‪parseMountPointParameter()
Definition: RootlineUtility.php:396
‪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:357
‪TYPO3\CMS\Core\Utility\RootlineUtility\$pageRecord
‪return $pageRecord
Definition: RootlineUtility.php:263
‪TYPO3\CMS\Core\Utility\RootlineUtility\resolvePageId
‪resolvePageId(int $pageId)
Definition: RootlineUtility.php:411
‪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:365
‪TYPO3\CMS\Core\Utility\RootlineUtility\sanitizeMountPointParameter
‪sanitizeMountPointParameter(string $mountPointParameter)
Definition: RootlineUtility.php:375
‪TYPO3\CMS\Core\Utility\RootlineUtility\$pageRecord
‪$pageRecord[$column]
Definition: RootlineUtility.php:260
‪TYPO3\CMS\Core\Utility\RootlineUtility\isMountedPage
‪isMountedPage()
Definition: RootlineUtility.php:332
‪TYPO3\CMS\Core\Context\Context
Definition: Context.php:55
‪TYPO3\CMS\Core\Utility\RootlineUtility\columnHasRelationToResolve
‪bool columnHasRelationToResolve(array $configuration)
Definition: RootlineUtility.php:273
‪TYPO3\CMS\Core\Utility\RootlineUtility\generateRootlineCache
‪generateRootlineCache()
Definition: RootlineUtility.php:293
‪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:39
‪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:451
‪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:61
‪TYPO3\CMS\Core\Database\ConnectionPool
Definition: ConnectionPool.php:48
‪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:426
‪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)