‪TYPO3CMS  ‪main
PagePositionMap.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 
20 use Psr\Http\Message\ServerRequestInterface;
22 use TYPO3\CMS\Backend\Utility\BackendUtility;
25 use TYPO3\CMS\Core\Imaging\IconSize;
29 
39 {
40  // EXTERNAL, static:
44  public ‪$moveOrCopy = 'move';
45 
50 
51  // How deep the position page tree will go.
55  public ‪$depth = 2;
56 
57  // INTERNAL, dynamic:
58  // Request uri
62  public ‪$R_URI = '';
63 
64  // tt_content element uid to move.
68  public ‪$moveUid;
69 
73  public ‪$checkNewPageCache = [];
74 
80  protected ‪$pageTreeClassName = PageTreeView::class;
81 
85  protected ‪$iconFactory;
86 
92  public function ‪__construct(string ‪$pageTreeClassName = null)
93  {
94  if (‪$pageTreeClassName !== null) {
95  $this->pageTreeClassName = ‪$pageTreeClassName;
96  }
97  $this->iconFactory = GeneralUtility::makeInstance(IconFactory::class);
98  }
99 
100  /*************************************
101  *
102  * Page position map:
103  *
104  **************************************/
114  public function ‪positionTree($id, $pageinfo, $perms_clause, ‪$R_URI, ServerRequestInterface $request)
115  {
116  // Make page tree object
117  if ($this->pageTreeClassName === NewRecordPageTreeView::class) {
118  $pageTree = GeneralUtility::makeInstance($this->pageTreeClassName, (int)$id);
119  } else {
120  $pageTree = GeneralUtility::makeInstance($this->pageTreeClassName);
121  }
123  $pageTree->init(' AND ' . $perms_clause);
124  $pageTree->addField('pid');
125  // Initialize variables:
126  $this->R_URI = ‪$R_URI;
127  // Create page tree, in $this->depth levels.
128  $pageTree->getTree($pageinfo['pid'] ?? 0, $this->depth);
129  // Initialize variables:
130  $saveLatestUid = [];
131  $latestInvDepth = ‪$this->depth;
132  // Traverse the tree:
133  $lines = [];
134  foreach ($pageTree->tree as $cc => $dat) {
135  if ($latestInvDepth > $dat['invertedDepth']) {
136  $margin = 'style="margin-left: ' . ($dat['invertedDepth'] * 16 + 9) . 'px;"';
137  $lines[] = '<ul class="treelist" ' . $margin . '>';
138  }
139  // Make link + parameters.
140  $latestInvDepth = $dat['invertedDepth'];
141  $saveLatestUid[$latestInvDepth] = $dat;
142  if (isset($pageTree->tree[$cc - 1])) {
143  $prev_dat = $pageTree->tree[$cc - 1];
144  // If current page, subpage?
145  if ($prev_dat['row']['uid'] == $id) {
146  // 1) It must be allowed to create a new page and 2) If there are subpages there is no need to render a subpage icon here - it'll be done over the subpages...
147  if (!$this->dontPrintPageInsertIcons && $this->‪checkNewPageInPid($id) && !($prev_dat['invertedDepth'] > $pageTree->tree[$cc]['invertedDepth'])) {
148  end($lines);
149  $margin = 'style="margin-left: ' . (($dat['invertedDepth'] - 1) * 16 + 9) . 'px;"';
150  $lines[] = '<ul class="treelist" ' . $margin . '><li><span class="text-nowrap"><a href="' . htmlspecialchars($this->‪getActionLink($id, $id)) . '" title="' . $this->‪insertlabel() . '">' . $this->iconFactory->getIcon('actions-arrow-left-alt', IconSize::SMALL)->render() . '</a></span></li></ul>';
151  }
152  }
153  // If going down
154  if ($prev_dat['invertedDepth'] > $pageTree->tree[$cc]['invertedDepth']) {
155  $prevPid = $pageTree->tree[$cc]['row']['pid'];
156  } elseif ($prev_dat['invertedDepth'] < $pageTree->tree[$cc]['invertedDepth']) {
157  // If going up
158  // First of all the previous level should have an icon:
159  if (!$this->dontPrintPageInsertIcons && $this->‪checkNewPageInPid($prev_dat['row']['pid'])) {
160  $prevPid = -$prev_dat['row']['uid'];
161  end($lines);
162  $lines[] = '<li><span class="text-nowrap"><a href="' . htmlspecialchars($this->‪getActionLink((int)$prevPid, $prev_dat['row']['pid'])) . '" title="' . $this->‪insertlabel() . '">' . $this->iconFactory->getIcon('actions-arrow-left-alt', IconSize::SMALL)->render() . '</a></span></li>';
163  }
164  // Then set the current prevPid
165  $prevPid = -$prev_dat['row']['pid'];
166  if ($prevPid !== $dat['row']['pid']) {
167  $lines[] = '</ul>';
168  }
169  } else {
170  // In on the same level
171  $prevPid = -$prev_dat['row']['uid'];
172  }
173  } else {
174  // First in the tree
175  $prevPid = $dat['row']['pid'];
176  }
177  // print arrow on the same level
178  if (!$this->dontPrintPageInsertIcons && $this->‪checkNewPageInPid($dat['row']['pid'])) {
179  $lines[] = '<span class="text-nowrap"><a href="' . htmlspecialchars($this->‪getActionLink($prevPid, $dat['row']['pid'])) . '" title="' . $this->‪insertlabel() . '">' . $this->iconFactory->getIcon('actions-arrow-left-alt', IconSize::SMALL)->render() . '</a></span>';
180  }
181  // The line with the icon and title:
182  $icon = $this->iconFactory
183  ->getIconForRecord('pages', $dat['row'], IconSize::SMALL)
184  ->setTitle(BackendUtility::getRecordIconAltText($dat['row'], 'pages', false))
185  ->render();
186 
187  $lines[] = '<span class="text-nowrap">' . $icon . ' ' .
188  $this->‪linkPageTitle(
189  $this->‪boldTitle(
190  htmlspecialchars(‪GeneralUtility::fixed_lgd_cs($dat['row']['title'], (int)$this->‪getBackendUser()->uc['titleLen'])),
191  $dat,
192  $id
193  ),
194  $dat['row'],
195  $request
196  ) . '</span>';
197  }
198  // If the current page was the last in the tree:
199  $prev_dat = end($pageTree->tree);
200  if ($prev_dat['row']['uid'] == $id) {
201  if (!$this->dontPrintPageInsertIcons && $this->‪checkNewPageInPid($id)) {
202  $lines[] = '<ul class="treelist" style="margin-left: 25px"><li><span class="text-nowrap"><a href="' . htmlspecialchars($this->‪getActionLink($id, $id)) . '" title="' . $this->‪insertlabel() . '">' . $this->iconFactory->getIcon('actions-arrow-left-alt', IconSize::SMALL)->render() . '</a></span></li></ul>';
203  }
204  }
205  for ($a = $latestInvDepth; $a <= ‪$this->depth; $a++) {
206  $dat = $saveLatestUid[$a];
207  $prevPid = -$dat['row']['uid'];
208  if (!$this->dontPrintPageInsertIcons && $this->‪checkNewPageInPid($dat['row']['pid'])) {
209  if ($latestInvDepth < $dat['invertedDepth']) {
210  $lines[] = '</ul>';
211  }
212  $lines[] = '<span class="text-nowrap"><a href="' . htmlspecialchars($this->‪getActionLink((int)$prevPid, $dat['row']['pid'])) . '" title="' . $this->‪insertlabel() . '">' . $this->iconFactory->getIcon('actions-arrow-left-alt', IconSize::SMALL)->render() . '</a></span>';
213  }
214  }
215 
216  $code = '<ul class="treelist">';
217 
218  foreach ($lines as $line) {
219  if (str_starts_with($line, '<ul') || str_starts_with($line, '</ul')) {
220  $code .= $line;
221  } else {
222  $code .= '<li>' . $line . '</li>';
223  }
224  }
225 
226  $code .= '</ul>';
227  return $code;
228  }
229 
238  public function ‪boldTitle($t_code, $dat, $id)
239  {
240  if ($dat['row']['uid'] == $id) {
241  $t_code = '<strong>' . $t_code . '</strong>';
242  }
243  return $t_code;
244  }
245 
256  public function ‪getActionLink($pid, $newPagePID): string
257  {
258  $uriBuilder = GeneralUtility::makeInstance(UriBuilder::class);
259  $TSconfig = BackendUtility::getPagesTSconfig($newPagePID)['mod.']['newPageWizard.'] ?? [];
260  if (isset($TSconfig['override']) && !empty($TSconfig['override'])) {
261  ‪$url = $uriBuilder->buildUriFromRoute(
262  $TSconfig['override'],
263  [
264  'positionPid' => $pid,
265  'newPageId' => $newPagePID,
266  'cmd' => 'crPage',
267  'returnUrl' => $this->R_URI,
268  ]
269  );
270  return (string)‪$url;
271  }
272 
273  return (string)$uriBuilder->buildUriFromRoute('record_edit', [
274  'edit' => [
275  'pages' => [
276  $pid => 'new',
277  ],
278  ],
279  'returnNewPageId' => '1',
280  'returnUrl' => $this->R_URI,
281  ]);
282  }
283 
289  protected function ‪insertlabel()
290  {
291  return htmlspecialchars($this->‪getLanguageService()->sL('LLL:EXT:core/Resources/Private/Language/locallang_misc.xlf:insertNewPageHere'));
292  }
293 
301  public function ‪linkPageTitle($str, $rec, ServerRequestInterface $request)
302  {
303  return $str;
304  }
305 
313  public function ‪checkNewPageInPid($pid)
314  {
315  if (!isset($this->checkNewPageCache[$pid])) {
316  $pidInfo = BackendUtility::getRecord('pages', $pid);
317  $this->checkNewPageCache[$pid] = $this->‪getBackendUser()->isAdmin() || $this->‪getBackendUser()->doesUserHaveAccess($pidInfo, ‪Permission::PAGE_NEW);
318  }
319  return $this->checkNewPageCache[$pid];
320  }
321 
322  protected function ‪getBackendUser(): ‪BackendUserAuthentication
323  {
324  return ‪$GLOBALS['BE_USER'];
325  }
326 
327  protected function ‪getLanguageService(): LanguageService
328  {
329  return ‪$GLOBALS['LANG'];
330  }
331 }
‪TYPO3\CMS\Backend\Tree\View\PagePositionMap\__construct
‪__construct(string $pageTreeClassName=null)
Definition: PagePositionMap.php:84
‪TYPO3\CMS\Core\Utility\GeneralUtility\fixed_lgd_cs
‪static string fixed_lgd_cs(string $string, int $chars, string $appendString='...')
Definition: GeneralUtility.php:92
‪TYPO3\CMS\Backend\Tree\View\PagePositionMap\$moveUid
‪int $moveUid
Definition: PagePositionMap.php:63
‪TYPO3\CMS\Backend\Tree\View\PagePositionMap\getLanguageService
‪getLanguageService()
Definition: PagePositionMap.php:319
‪TYPO3\CMS\Core\Type\Bitmask\Permission\PAGE_NEW
‪const PAGE_NEW
Definition: Permission.php:50
‪TYPO3\CMS\Backend\Tree\View\PagePositionMap\$pageTreeClassName
‪string $pageTreeClassName
Definition: PagePositionMap.php:73
‪TYPO3\CMS\Backend\Tree\View\PagePositionMap\$R_URI
‪string $R_URI
Definition: PagePositionMap.php:58
‪TYPO3\CMS\Backend\Tree\View\PagePositionMap\getBackendUser
‪getBackendUser()
Definition: PagePositionMap.php:314
‪TYPO3\CMS\Core\Imaging\IconFactory
Definition: IconFactory.php:34
‪TYPO3\CMS\Core\Type\Bitmask\Permission
Definition: Permission.php:26
‪TYPO3\CMS\Backend\Tree\View\PagePositionMap\$checkNewPageCache
‪array $checkNewPageCache
Definition: PagePositionMap.php:67
‪TYPO3\CMS\Backend\Tree\View\PagePositionMap\insertlabel
‪string insertlabel()
Definition: PagePositionMap.php:281
‪TYPO3\CMS\Backend\Tree\View\PagePositionMap\getActionLink
‪string getActionLink($pid, $newPagePID)
Definition: PagePositionMap.php:248
‪TYPO3\CMS\Backend\Tree\View\PagePositionMap\checkNewPageInPid
‪bool checkNewPageInPid($pid)
Definition: PagePositionMap.php:305
‪TYPO3\CMS\Backend\Routing\UriBuilder
Definition: UriBuilder.php:44
‪TYPO3\CMS\Backend\Tree\View\PagePositionMap
Definition: PagePositionMap.php:39
‪TYPO3\CMS\Backend\Tree\View\PagePositionMap\boldTitle
‪string boldTitle($t_code, $dat, $id)
Definition: PagePositionMap.php:230
‪TYPO3\CMS\Core\Authentication\BackendUserAuthentication
Definition: BackendUserAuthentication.php:62
‪TYPO3\CMS\Backend\Tree\View\PagePositionMap\$iconFactory
‪IconFactory $iconFactory
Definition: PagePositionMap.php:77
‪TYPO3\CMS\Backend\Tree\View
Definition: AbstractContentPagePositionMap.php:18
‪TYPO3\CMS\Backend\Tree\View\PagePositionMap\$depth
‪int $depth
Definition: PagePositionMap.php:52
‪TYPO3\CMS\Webhooks\Message\$url
‪identifier readonly UriInterface $url
Definition: LoginErrorOccurredMessage.php:36
‪TYPO3\CMS\Backend\Tree\View\PagePositionMap\$dontPrintPageInsertIcons
‪int $dontPrintPageInsertIcons
Definition: PagePositionMap.php:47
‪TYPO3\CMS\Backend\Tree\View\PagePositionMap\$moveOrCopy
‪string $moveOrCopy
Definition: PagePositionMap.php:43
‪$GLOBALS
‪$GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['adminpanel']['modules']
Definition: ext_localconf.php:25
‪TYPO3\CMS\Backend\Tree\View\PagePositionMap\linkPageTitle
‪string linkPageTitle($str, $rec, ServerRequestInterface $request)
Definition: PagePositionMap.php:293
‪TYPO3\CMS\Core\Localization\LanguageService
Definition: LanguageService.php:46
‪TYPO3\CMS\Core\Utility\GeneralUtility
Definition: GeneralUtility.php:52
‪TYPO3\CMS\Backend\Tree\View\PagePositionMap\positionTree
‪string positionTree($id, $pageinfo, $perms_clause, $R_URI, ServerRequestInterface $request)
Definition: PagePositionMap.php:106