‪TYPO3CMS  9.5
PageTreeRepository.php
Go to the documentation of this file.
1 <?php
2 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 
18 use Doctrine\DBAL\Connection;
29 
39 {
45  protected ‪$fields = [
46  'uid',
47  'pid',
48  'sorting',
49  'starttime',
50  'endtime',
51  'hidden',
52  'fe_group',
53  'title',
54  'nav_title',
55  'nav_hide',
56  'alias',
57  'php_tree_stop',
58  'doktype',
59  'is_siteroot',
60  'module',
61  'extendToSubpages',
62  'content_from_pid',
63  't3ver_oid',
64  't3ver_id',
65  't3ver_wsid',
66  't3ver_label',
67  't3ver_state',
68  't3ver_stage',
69  't3ver_tstamp',
70  't3ver_move_id',
71  'perms_userid',
72  'perms_user',
73  'perms_groupid',
74  'perms_group',
75  'perms_everybody',
76  'mount_pid',
77  'shortcut',
78  'shortcut_mode',
79  'mount_pid_ol',
80  'url',
81  'sys_language_uid',
82  'l10n_parent',
83  ];
84 
90  protected ‪$currentWorkspace = 0;
91 
97  protected ‪$fullPageTree = [];
98 
102  protected ‪$additionalQueryRestrictions = [];
103 
109  public function ‪__construct(int $workspaceId = 0, array $additionalFieldsToQuery = [], array ‪$additionalQueryRestrictions = [])
110  {
111  $this->currentWorkspace = $workspaceId;
112  if (!empty($additionalFieldsToQuery)) {
113  $this->fields = array_merge($this->fields, $additionalFieldsToQuery);
114  }
115 
116  if (!empty(‪$additionalQueryRestrictions)) {
117  $this->additionalQueryRestrictions = ‪$additionalQueryRestrictions;
118  }
119  }
120 
131  public function ‪getTree(
132  int $entryPoint,
133  callable $callback = null,
134  array $dbMounts = [],
135  $resolveUserPermissions = false
136  ): array {
137  $this->‪fetchAllPages($dbMounts, $resolveUserPermissions);
138  if ($entryPoint === 0) {
139  $tree = ‪$this->fullPageTree;
140  } else {
141  $tree = $this->‪findInPageTree($entryPoint, $this->fullPageTree);
142  }
143  if (!empty($tree) && $callback !== null) {
144  $this->‪applyCallbackToChildren($tree, $callback);
145  }
146  return $tree;
147  }
148 
155  protected function ‪applyCallbackToChildren(array &$tree, callable $callback)
156  {
157  if (!isset($tree['_children'])) {
158  return;
159  }
160  foreach ($tree['_children'] as $k => &$childPage) {
161  if (!call_user_func_array($callback, [$childPage])) {
162  unset($tree['_children'][$k]);
163  continue;
164  }
165  $this->‪applyCallbackToChildren($childPage, $callback);
166  }
167  }
168 
176  public function ‪getTreeLevels(array $pageTree, int $depth): array
177  {
178  $parentPageIds = [$pageTree['uid']];
179  $groupedAndSortedPagesByPid = [];
180  for ($i = 0; $i < $depth; $i++) {
181  if (empty($parentPageIds)) {
182  break;
183  }
184  $pageRecords = $this->‪getChildPageRecords($parentPageIds);
185 
186  $groupedAndSortedPagesByPid = $this->‪groupAndSortPages($pageRecords, $groupedAndSortedPagesByPid);
187 
188  $parentPageIds = array_column($pageRecords, 'uid');
189  }
190  $this->‪addChildrenToPage($pageTree, $groupedAndSortedPagesByPid);
191  return $pageTree;
192  }
193 
200  protected function ‪getChildPageRecords(array $parentPageIds): array
201  {
202  $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)
203  ->getQueryBuilderForTable('pages');
204  $queryBuilder->getRestrictions()
205  ->removeAll()
206  ->add(GeneralUtility::makeInstance(DeletedRestriction::class))
207  ->add(GeneralUtility::makeInstance(WorkspaceRestriction::class, $this->currentWorkspace));
208 
209  if (!empty($this->additionalQueryRestrictions)) {
210  foreach ($this->additionalQueryRestrictions as $additionalQueryRestriction) {
211  $queryBuilder->getRestrictions()->add($additionalQueryRestriction);
212  }
213  }
214 
215  $pageRecords = $queryBuilder
216  ->select(...$this->fields)
217  ->from('pages')
218  ->where(
219  $queryBuilder->expr()->eq('sys_language_uid', $queryBuilder->createNamedParameter(0, \PDO::PARAM_INT)),
220  $queryBuilder->expr()->in('pid', $queryBuilder->createNamedParameter($parentPageIds, Connection::PARAM_INT_ARRAY))
221  )
222  ->andWhere(
224  )
225  ->execute()
226  ->fetchAll();
227 
228  // This is necessary to resolve all IDs in a workspace
229  if ($this->currentWorkspace !== 0 && !empty($pageRecords)) {
230  $livePagePids = [];
231  $livePageIds = [];
232  $movePlaceholderData = [];
233  foreach ($pageRecords as $pageRecord) {
234  $livePageIds[] = (int)$pageRecord['uid'];
235  $livePagePids[(int)$pageRecord['uid']] = (int)$pageRecord['pid'];
236  if ((int)$pageRecord['t3ver_state'] === ‪VersionState::MOVE_PLACEHOLDER) {
237  $movePlaceholderData[$pageRecord['t3ver_move_id']] = [
238  'pid' => (int)$pageRecord['pid'],
239  'sorting' => (int)$pageRecord['sorting']
240  ];
241  }
242  }
243 
244  // Resolve placeholders of workspace versions
245  $resolver = GeneralUtility::makeInstance(
246  PlainDataResolver::class,
247  'pages',
248  $livePageIds
249  );
250  $resolver->setWorkspaceId($this->currentWorkspace);
251  $resolver->setKeepDeletePlaceholder(false);
252  $resolver->setKeepMovePlaceholder(false);
253  $resolver->setKeepLiveIds(false);
254  $recordIds = $resolver->get();
255 
256  if (!empty($recordIds)) {
257  $queryBuilder->getRestrictions()->removeAll();
258  $pageRecords = $queryBuilder
259  ->select(...$this->fields)
260  ->from('pages')
261  ->where(
262  $queryBuilder->expr()->in('uid', $queryBuilder->createNamedParameter($recordIds, Connection::PARAM_INT_ARRAY))
263  )
264  ->execute()
265  ->fetchAll();
266 
267  foreach ($pageRecords as &$pageRecord) {
268  if ((int)$pageRecord['t3ver_state'] === ‪VersionState::MOVE_PLACEHOLDER) {
269  $liveRecord = ‪BackendUtility::getRecord('pages', $pageRecord['t3ver_move_id']);
270  $pageRecord['uid'] = (int)$liveRecord['uid'];
271  $pageRecord['t3ver_oid'] = (int)$pageRecord['t3ver_move_id'];
272  $pageRecord['title'] = $liveRecord['title'];
273  } elseif ((int)$pageRecord['t3ver_state'] === ‪VersionState::MOVE_POINTER && !empty($movePlaceholderData[$pageRecord['t3ver_oid']])) {
274  $pageRecord['uid'] = $pageRecord['t3ver_oid'];
275  $pageRecord['sorting'] = (int)$movePlaceholderData[$pageRecord['t3ver_oid']]['sorting'];
276  $pageRecord['t3ver_state'] = ‪VersionState::MOVE_PLACEHOLDER;
277  $pageRecord['pid'] = (int)$movePlaceholderData[$pageRecord['t3ver_oid']]['pid'];
278  } elseif ((int)$pageRecord['t3ver_oid'] > 0) {
279  $liveRecord = ‪BackendUtility::getRecord('pages', $pageRecord['t3ver_oid']);
280  $pageRecord['sorting'] = (int)$liveRecord['sorting'];
281  $pageRecord['uid'] = (int)$liveRecord['uid'];
282  $pageRecord['pid'] = (int)$liveRecord['pid'];
283  }
284  }
285  } else {
286  $pageRecords = [];
287  }
288  }
289  foreach ($pageRecords as &$pageRecord) {
290  $pageRecord['uid'] = (int)$pageRecord['uid'];
291  }
292 
293  return $pageRecords;
294  }
295 
296  public function ‪hasChildren(int $pid): bool
297  {
298  $pageRecords = $this->‪getChildPageRecords([$pid]);
299  return !empty($pageRecords);
300  }
301 
309  protected function ‪fetchAllPages(array $dbMounts, bool $resolveUserPermissions = false): array
310  {
311  if (!empty($this->fullPageTree)) {
312  return ‪$this->fullPageTree;
313  }
314  $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)
315  ->getQueryBuilderForTable('pages');
316  $queryBuilder->getRestrictions()
317  ->removeAll()
318  ->add(GeneralUtility::makeInstance(DeletedRestriction::class))
319  ->add(GeneralUtility::makeInstance(WorkspaceRestriction::class, $this->currentWorkspace));
320 
321  if (!empty($this->additionalQueryRestrictions)) {
322  foreach ($this->additionalQueryRestrictions as $additionalQueryRestriction) {
323  $queryBuilder->getRestrictions()->add($additionalQueryRestriction);
324  }
325  }
326 
327  $query = $queryBuilder
328  ->select(...$this->fields)
329  ->from('pages')
330  ->where(
331  // Only show records in default language
332  $queryBuilder->expr()->eq('sys_language_uid', $queryBuilder->createNamedParameter(0, \PDO::PARAM_INT))
333  );
334 
335  if ($resolveUserPermissions) {
336  $query->andWhere(
338  );
339  }
340 
341  $pageRecords = $query->execute()->fetchAll();
342 
343  $ids = array_column($pageRecords, 'uid');
344  foreach ($dbMounts as $mount) {
345  $entryPointRootLine = ‪BackendUtility::BEgetRootLine($mount, '', false, $this->fields);
346  foreach ($entryPointRootLine as $page) {
347  $pageId = (int)$page['uid'];
348  if (in_array($pageId, $ids) || $pageId === 0) {
349  continue;
350  }
351  $pageRecords[] = $page;
352  $ids[] = $pageId;
353  }
354  }
355 
356  $livePagePids = [];
357  $movePlaceholderData = [];
358  // This is necessary to resolve all IDs in a workspace
359  if ($this->currentWorkspace !== 0 && !empty($pageRecords)) {
360  $livePageIds = [];
361  foreach ($pageRecords as $pageRecord) {
362  $livePageIds[] = (int)$pageRecord['uid'];
363  $livePagePids[(int)$pageRecord['uid']] = (int)$pageRecord['pid'];
364  if ((int)$pageRecord['t3ver_state'] === ‪VersionState::MOVE_PLACEHOLDER) {
365  $movePlaceholderData[$pageRecord['t3ver_move_id']] = [
366  'pid' => (int)$pageRecord['pid'],
367  'sorting' => (int)$pageRecord['sorting']
368  ];
369  }
370  }
371  // Resolve placeholders of workspace versions
372  $resolver = GeneralUtility::makeInstance(
373  PlainDataResolver::class,
374  'pages',
375  $livePageIds
376  );
377  $resolver->setWorkspaceId($this->currentWorkspace);
378  $resolver->setKeepDeletePlaceholder(false);
379  $resolver->setKeepMovePlaceholder(false);
380  $resolver->setKeepLiveIds(false);
381  $recordIds = $resolver->get();
382 
383  $queryBuilder->getRestrictions()->removeAll();
384  $pageRecords = $queryBuilder
385  ->select(...$this->fields)
386  ->from('pages')
387  ->where(
388  $queryBuilder->expr()->in('uid', $recordIds)
389  )
390  ->execute()
391  ->fetchAll();
392  }
393 
394  // Now set up sorting, nesting (tree-structure) for all pages based on pid+sorting fields
395  $groupedAndSortedPagesByPid = [];
396  foreach ($pageRecords as $pageRecord) {
397  $parentPageId = (int)$pageRecord['pid'];
398  // In case this is a record from a workspace
399  // The uid+pid of the live-version record is fetched
400  // This is done in order to avoid fetching records again (e.g. via BackendUtility::workspaceOL()
401  if ($parentPageId === -1) {
402  // When a move pointer is found, the pid+sorting of the MOVE_PLACEHOLDER should be used (this is the
403  // workspace record holding this information), also the t3ver_state is set to the MOVE_PLACEHOLDER
404  // because the record is then added
405  if ((int)$pageRecord['t3ver_state'] === ‪VersionState::MOVE_POINTER && !empty($movePlaceholderData[$pageRecord['t3ver_oid']])) {
406  $parentPageId = (int)$movePlaceholderData[$pageRecord['t3ver_oid']]['pid'];
407  $pageRecord['sorting'] = (int)$movePlaceholderData[$pageRecord['t3ver_oid']]['sorting'];
408  $pageRecord['t3ver_state'] = ‪VersionState::MOVE_PLACEHOLDER;
409  } else {
410  // Just a record in a workspace (not moved etc)
411  $parentPageId = (int)$livePagePids[$pageRecord['t3ver_oid']];
412  }
413  // this is necessary so the links to the modules are still pointing to the live IDs
414  $pageRecord['uid'] = (int)$pageRecord['t3ver_oid'];
415  $pageRecord['pid'] = $parentPageId;
416  }
417 
418  $sorting = (int)$pageRecord['sorting'];
419  while (isset($groupedAndSortedPagesByPid[$parentPageId][$sorting])) {
420  $sorting++;
421  }
422  $groupedAndSortedPagesByPid[$parentPageId][$sorting] = $pageRecord;
423  }
424 
425  $this->fullPageTree = [
426  'uid' => 0,
427  'title' => ‪$GLOBALS['TYPO3_CONF_VARS']['SYS']['sitename'] ?: 'TYPO3'
428  ];
429  $this->‪addChildrenToPage($this->fullPageTree, $groupedAndSortedPagesByPid);
430  return ‪$this->fullPageTree;
431  }
432 
439  protected function ‪addChildrenToPage(array &$page, array &$groupedAndSortedPagesByPid)
440  {
441  $page['_children'] = $groupedAndSortedPagesByPid[(int)$page['uid']] ?? [];
442  ksort($page['_children']);
443  foreach ($page['_children'] as &$child) {
444  $this->‪addChildrenToPage($child, $groupedAndSortedPagesByPid);
445  }
446  }
447 
455  protected function ‪findInPageTree(int $pageId, array $pages): array
456  {
457  foreach ($pages['_children'] as $childPage) {
458  if ((int)$childPage['uid'] === $pageId) {
459  return $childPage;
460  }
461  $result = $this->‪findInPageTree($pageId, $childPage);
462  if (!empty($result)) {
463  return $result;
464  }
465  }
466  return [];
467  }
468 
477  public function ‪fetchFilteredTree(string $searchFilter, array $allowedMountPointPageIds, string $additionalWhereClause): array
478  {
479  $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)
480  ->getQueryBuilderForTable('pages');
481  $queryBuilder->getRestrictions()
482  ->removeAll()
483  ->add(GeneralUtility::makeInstance(DeletedRestriction::class));
484 
485  if (!empty($this->additionalQueryRestrictions)) {
486  foreach ($this->additionalQueryRestrictions as $additionalQueryRestriction) {
487  $queryBuilder->getRestrictions()->add($additionalQueryRestriction);
488  }
489  }
490 
491  $expressionBuilder = $queryBuilder->expr();
492 
493  if ($this->currentWorkspace === 0) {
494  // Only include ws_id=0
495  $workspaceIdExpression = $expressionBuilder->eq('t3ver_wsid', 0);
496  } else {
497  // Include live records PLUS records from the given workspace
498  $workspaceIdExpression = $expressionBuilder->in(
499  't3ver_wsid',
500  [0, $this->currentWorkspace]
501  );
502  }
503 
504  $queryBuilder = $queryBuilder
505  ->select(...$this->fields)
506  ->from('pages')
507  ->where(
508  // Only show records in default language
509  $expressionBuilder->eq('sys_language_uid', $queryBuilder->createNamedParameter(0, \PDO::PARAM_INT)),
510  $workspaceIdExpression,
511  ‪QueryHelper::stripLogicalOperatorPrefix($additionalWhereClause)
512  );
513 
514  $searchParts = $expressionBuilder->orX();
515  if (is_numeric($searchFilter) && $searchFilter > 0) {
516  $searchParts->add(
517  $expressionBuilder->eq('uid', $queryBuilder->createNamedParameter($searchFilter, \PDO::PARAM_INT))
518  );
519  }
520  $searchFilter = '%' . $queryBuilder->escapeLikeWildcards($searchFilter) . '%';
521 
522  $searchWhereAlias = $expressionBuilder->orX(
523  $expressionBuilder->like(
524  'nav_title',
525  $queryBuilder->createNamedParameter($searchFilter, \PDO::PARAM_STR)
526  ),
527  $expressionBuilder->like(
528  'title',
529  $queryBuilder->createNamedParameter($searchFilter, \PDO::PARAM_STR)
530  )
531  );
532  $searchParts->add($searchWhereAlias);
533 
534  $queryBuilder->andWhere($searchParts);
535  $pageRecords = $queryBuilder
536  ->execute()
537  ->fetchAll();
538 
539  $livePagePids = [];
540  if ($this->currentWorkspace !== 0 && !empty($pageRecords)) {
541  $livePageIds = [];
542  foreach ($pageRecords as $pageRecord) {
543  $livePageIds[] = (int)$pageRecord['uid'];
544  $livePagePids[(int)$pageRecord['uid']] = (int)$pageRecord['pid'];
545  if ((int)$pageRecord['t3ver_state'] === ‪VersionState::MOVE_POINTER) {
546  $movePlaceholder = ‪BackendUtility::getMovePlaceholder('pages', $pageRecord['t3ver_oid'], '*', $this->currentWorkspace);
547  $movePlaceholderData[$pageRecord['t3ver_oid']] = [
548  'pid' => (int)$movePlaceholder['pid'],
549  'sorting' => (int)$movePlaceholder['sorting']
550  ];
551  }
552  if ((int)$pageRecord['t3ver_state'] === ‪VersionState::MOVE_PLACEHOLDER) {
553  $movePlaceholderData[$pageRecord['t3ver_move_id']] = [
554  'pid' => (int)$pageRecord['pid'],
555  'sorting' => (int)$pageRecord['sorting']
556  ];
557  }
558  }
559  // Resolve placeholders of workspace versions
560  $resolver = GeneralUtility::makeInstance(
561  PlainDataResolver::class,
562  'pages',
563  $livePageIds
564  );
565  $resolver->setWorkspaceId($this->currentWorkspace);
566  $resolver->setKeepDeletePlaceholder(false);
567  $resolver->setKeepMovePlaceholder(false);
568  $resolver->setKeepLiveIds(false);
569  $recordIds = $resolver->get();
570 
571  $pageRecords = [];
572  if (!empty($recordIds)) {
573  $queryBuilder->getRestrictions()->removeAll();
574  $queryBuilder
575  ->select(...$this->fields)
576  ->from('pages')
577  ->where(
578  $queryBuilder->expr()->in('uid', $queryBuilder->createNamedParameter($recordIds, Connection::PARAM_INT_ARRAY))
579  );
580  $queryBuilder->andWhere($searchParts);
581  $pageRecords = $queryBuilder
582  ->execute()
583  ->fetchAll();
584  }
585  }
586 
587  $pages = [];
588  foreach ($pageRecords as $pageRecord) {
589  $parentPageId = (int)$pageRecord['pid'];
590  // In case this is a record from a workspace
591  // The uid+pid of the live-version record is fetched
592  // This is done in order to avoid fetching records again (e.g. via BackendUtility::workspaceOL()
593  if ($parentPageId === -1) {
594  // This probably should also remove the live version
595  if ((int)$pageRecord['t3ver_state'] === ‪VersionState::DELETE_PLACEHOLDER) {
596  continue;
597  }
598  // When a move pointer is found, the pid+sorting of the MOVE_PLACEHOLDER should be used (this is the
599  // workspace record holding this information), also the t3ver_state is set to the MOVE_PLACEHOLDER
600  // because the record is then added
601  if ((int)$pageRecord['t3ver_state'] === ‪VersionState::MOVE_POINTER && !empty($movePlaceholderData[$pageRecord['t3ver_oid']])) {
602  $parentPageId = (int)$movePlaceholderData[$pageRecord['t3ver_oid']]['pid'];
603  $pageRecord['sorting'] = (int)$movePlaceholderData[$pageRecord['t3ver_oid']]['sorting'];
604  $pageRecord['t3ver_state'] = ‪VersionState::MOVE_PLACEHOLDER;
605  } else {
606  // Just a record in a workspace (not moved etc)
607  if (isset($livePagePids[$pageRecord['t3ver_oid']])) {
608  $parentPageId = (int)$livePagePids[$pageRecord['t3ver_oid']];
609  } else {
610  $liveRecord = ‪BackendUtility::getRecord('pages', $pageRecord['t3ver_oid'], 'uid,pid');
611  $parentPageId = (int)$liveRecord['pid'];
612  }
613  }
614  // this is necessary so the links to the modules are still pointing to the live IDs
615  $pageRecord['uid'] = (int)$pageRecord['t3ver_oid'];
616  $pageRecord['pid'] = $parentPageId;
617  }
618  $pages[(int)$pageRecord['uid']] = $pageRecord;
619  }
620  unset($pageRecords);
621 
622  $pages = $this->‪filterPagesOnMountPoints($pages, $allowedMountPointPageIds);
623 
624  $groupedAndSortedPagesByPid = $this->‪groupAndSortPages($pages);
625 
626  $this->fullPageTree = [
627  'uid' => 0,
628  'title' => ‪$GLOBALS['TYPO3_CONF_VARS']['SYS']['sitename'] ?: 'TYPO3'
629  ];
630  $this->‪addChildrenToPage($this->fullPageTree, $groupedAndSortedPagesByPid);
631 
632  return ‪$this->fullPageTree;
633  }
634 
642  protected function ‪filterPagesOnMountPoints(array $pages, array $mountPoints): array
643  {
644  foreach ($pages as $key => $pageRecord) {
646  $pageRecord['uid'],
647  '',
648  $this->currentWorkspace !== 0,
649  $this->fields
650  );
651  $rootline = array_reverse($rootline);
652  if (!in_array(0, $mountPoints, true)) {
653  $isInsideMountPoints = false;
654  foreach ($rootline as $rootlineElement) {
655  if (in_array((int)$rootlineElement['uid'], $mountPoints, true)) {
656  $isInsideMountPoints = true;
657  break;
658  }
659  }
660  if (!$isInsideMountPoints) {
661  unset($pages[$key]);
662  //skip records outside of the allowed mount points
663  continue;
664  }
665  }
666 
667  $inFilteredRootline = false;
668  $amountOfRootlineElements = count($rootline);
669  for ($i = 0; $i < $amountOfRootlineElements; ++$i) {
670  $rootlineElement = $rootline[$i];
671  $rootlineElement['uid'] = (int)$rootlineElement['uid'];
672  $isInWebMount = false;
673  if ($rootlineElement['uid'] > 0) {
674  $isInWebMount = (int)$this->‪getBackendUser()->‪isInWebMount($rootlineElement);
675  }
676 
677  if (!$isInWebMount
678  || ($rootlineElement['uid'] === (int)$mountPoints[0]
679  && $rootlineElement['uid'] !== $isInWebMount)
680  ) {
681  continue;
682  }
683  if ($this->‪getBackendUser()->‪isAdmin() || ($rootlineElement['uid'] === $isInWebMount && in_array($rootlineElement['uid'], $mountPoints, true))) {
684  $inFilteredRootline = true;
685  }
686  if (!$inFilteredRootline) {
687  continue;
688  }
689 
690  if (!isset($pages[$rootlineElement['uid']])) {
691  $pages[$rootlineElement['uid']] = $rootlineElement;
692  }
693  }
694  }
695  // Make sure the mountpoints show up in page tree even when parent pages are not accessible pages
696  foreach ($mountPoints as $mountPoint) {
697  if ($mountPoint !== 0) {
698  if (!array_key_exists($mountPoint, $pages)) {
699  $pages[$mountPoint] = ‪BackendUtility::getRecord('pages', $mountPoint);
700  $pages[$mountPoint]['uid'] = (int)$pages[$mountPoint]['uid'];
701  }
702  $pages[$mountPoint]['pid'] = 0;
703  }
704  }
705 
706  return $pages;
707  }
708 
716  protected function ‪groupAndSortPages(array $pages, $groupedAndSortedPagesByPid = []): array
717  {
718  foreach ($pages as $key => $pageRecord) {
719  $parentPageId = (int)$pageRecord['pid'];
720  $sorting = (int)$pageRecord['sorting'];
721  while (isset($groupedAndSortedPagesByPid[$parentPageId][$sorting])) {
722  $sorting++;
723  }
724  $groupedAndSortedPagesByPid[$parentPageId][$sorting] = $pageRecord;
725  }
726 
727  return $groupedAndSortedPagesByPid;
728  }
729 
733  protected function ‪getBackendUser(): ‪BackendUserAuthentication
734  {
735  return ‪$GLOBALS['BE_USER'];
736  }
737 }
‪TYPO3\CMS\Backend\Tree\Repository\PageTreeRepository\$fullPageTree
‪array $fullPageTree
Definition: PageTreeRepository.php:94
‪TYPO3\CMS\Core\DataHandling\PlainDataResolver
Definition: PlainDataResolver.php:32
‪TYPO3\CMS\Backend\Tree\Repository\PageTreeRepository\filterPagesOnMountPoints
‪array filterPagesOnMountPoints(array $pages, array $mountPoints)
Definition: PageTreeRepository.php:638
‪TYPO3\CMS\Backend\Tree\Repository\PageTreeRepository\hasChildren
‪hasChildren(int $pid)
Definition: PageTreeRepository.php:292
‪TYPO3\CMS\Backend\Tree\Repository\PageTreeRepository\$fields
‪string[] $fields
Definition: PageTreeRepository.php:44
‪TYPO3\CMS\Backend\Tree\Repository\PageTreeRepository\fetchAllPages
‪array fetchAllPages(array $dbMounts, bool $resolveUserPermissions=false)
Definition: PageTreeRepository.php:305
‪TYPO3\CMS\Backend\Tree\Repository\PageTreeRepository\$additionalQueryRestrictions
‪array $additionalQueryRestrictions
Definition: PageTreeRepository.php:98
‪TYPO3\CMS\Backend\Tree\Repository\PageTreeRepository\$currentWorkspace
‪int $currentWorkspace
Definition: PageTreeRepository.php:88
‪TYPO3\CMS\Core\Authentication\BackendUserAuthentication\isAdmin
‪bool isAdmin()
Definition: BackendUserAuthentication.php:294
‪TYPO3\CMS\Backend\Tree\Repository\PageTreeRepository\fetchFilteredTree
‪array fetchFilteredTree(string $searchFilter, array $allowedMountPointPageIds, string $additionalWhereClause)
Definition: PageTreeRepository.php:473
‪TYPO3\CMS\Core\Versioning\VersionState\DELETE_PLACEHOLDER
‪const DELETE_PLACEHOLDER
Definition: VersionState.php:54
‪TYPO3\CMS\Backend\Tree\Repository\PageTreeRepository\getChildPageRecords
‪array getChildPageRecords(array $parentPageIds)
Definition: PageTreeRepository.php:196
‪TYPO3\CMS\Backend\Utility\BackendUtility\BEgetRootLine
‪static array BEgetRootLine($uid, $clause='', $workspaceOL=false, array $additionalFields=[])
Definition: BackendUtility.php:374
‪TYPO3\CMS\Core\Versioning\VersionState\MOVE_POINTER
‪const MOVE_POINTER
Definition: VersionState.php:72
‪TYPO3\CMS\Core\Type\Bitmask\Permission
Definition: Permission.php:23
‪TYPO3\CMS\Backend\Tree\Repository
Definition: PageTreeRepository.php:3
‪TYPO3\CMS\Backend\Tree\Repository\PageTreeRepository\findInPageTree
‪array findInPageTree(int $pageId, array $pages)
Definition: PageTreeRepository.php:451
‪TYPO3\CMS\Core\Database\Query\QueryHelper
Definition: QueryHelper.php:30
‪TYPO3\CMS\Backend\Tree\Repository\PageTreeRepository\groupAndSortPages
‪array groupAndSortPages(array $pages, $groupedAndSortedPagesByPid=[])
Definition: PageTreeRepository.php:712
‪TYPO3\CMS\Backend\Tree\Repository\PageTreeRepository\getTreeLevels
‪array getTreeLevels(array $pageTree, int $depth)
Definition: PageTreeRepository.php:172
‪TYPO3\CMS\Backend\Tree\Repository\PageTreeRepository\addChildrenToPage
‪addChildrenToPage(array &$page, array &$groupedAndSortedPagesByPid)
Definition: PageTreeRepository.php:435
‪TYPO3\CMS\Backend\Utility\BackendUtility\getMovePlaceholder
‪static array bool getMovePlaceholder($table, $uid, $fields=' *', $workspace=null)
Definition: BackendUtility.php:4311
‪TYPO3\CMS\Core\Authentication\BackendUserAuthentication
Definition: BackendUserAuthentication.php:45
‪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\Tree\Repository\PageTreeRepository\getBackendUser
‪BackendUserAuthentication getBackendUser()
Definition: PageTreeRepository.php:729
‪TYPO3\CMS\Backend\Utility\BackendUtility\getRecord
‪static array null getRecord($table, $uid, $fields=' *', $where='', $useDeleteClause=true)
Definition: BackendUtility.php:130
‪TYPO3\CMS\Core\Versioning\VersionState
Definition: VersionState.php:23
‪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\Core\Database\Query\Restriction\DeletedRestriction
Definition: DeletedRestriction.php:26
‪TYPO3\CMS\Backend\Tree\Repository\PageTreeRepository
Definition: PageTreeRepository.php:39
‪TYPO3\CMS\Backend\Tree\Repository\PageTreeRepository\getTree
‪array getTree(int $entryPoint, callable $callback=null, array $dbMounts=[], $resolveUserPermissions=false)
Definition: PageTreeRepository.php:127
‪TYPO3\CMS\Core\Database\ConnectionPool
Definition: ConnectionPool.php:44
‪TYPO3\CMS\Backend\Tree\Repository\PageTreeRepository\__construct
‪__construct(int $workspaceId=0, array $additionalFieldsToQuery=[], array $additionalQueryRestrictions=[])
Definition: PageTreeRepository.php:105
‪TYPO3\CMS\Core\Utility\GeneralUtility
Definition: GeneralUtility.php:45
‪TYPO3\CMS\Backend\Tree\Repository\PageTreeRepository\applyCallbackToChildren
‪applyCallbackToChildren(array &$tree, callable $callback)
Definition: PageTreeRepository.php:151
‪TYPO3\CMS\Core\Authentication\BackendUserAuthentication\isInWebMount
‪int null isInWebMount($idOrRow, $readPerms='', $exitOnError=0)
Definition: BackendUserAuthentication.php:353
‪TYPO3\CMS\Core\Versioning\VersionState\MOVE_PLACEHOLDER
‪const MOVE_PLACEHOLDER
Definition: VersionState.php:71
‪TYPO3\CMS\Core\Database\Query\Restriction\WorkspaceRestriction
Definition: WorkspaceRestriction.php:37