‪TYPO3CMS  ‪main
MovePageController.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\ResponseInterface;
21 use Psr\Http\Message\ServerRequestInterface;
25 use TYPO3\CMS\Backend\Utility\BackendUtility;
39 
45 #[AsController]
46 final readonly class ‪MovePageController
47 {
49 
50  public function ‪__construct(
51  private ‪PageRenderer $pageRenderer,
52  private ‪BackendViewFactory $backendViewFactory,
53  private ‪UriBuilder $uriBuilder,
54  private ‪LanguageServiceFactory $languageServiceFactory,
55  private ‪ExtensionConfiguration $extensionConfiguration
56  ) {}
57 
58  public function ‪mainAction(ServerRequestInterface $request): ResponseInterface
59  {
61  $this->pageRenderer,
62  $this->extensionConfiguration,
63  $request,
64  $this->languageServiceFactory->createFromUserPreferences($this->getBackendUser())
65  );
66  $view = $this->backendViewFactory->create($request);
67  $queryParams = $request->getQueryParams();
68  $contentOnly = $queryParams['contentOnly'] ?? false;
69  $this->pageRenderer->loadJavaScriptModule('@typo3/backend/tree/page-browser.js');
70  $this->pageRenderer->loadJavaScriptModule('@typo3/backend/viewport/resizable-navigation.js');
71  $this->pageRenderer->getJavaScriptRenderer()->addJavaScriptModuleInstruction(
72  ‪JavaScriptModuleInstruction::create('@typo3/backend/wizard/move-page.js', 'MovePage')->instance()
73  );
74  $this->pageRenderer->addInlineLanguageLabelFile('EXT:core/Resources/Private/Language/locallang_core.xlf');
75  $this->pageRenderer->addInlineLanguageLabelFile('EXT:core/Resources/Private/Language/locallang_misc.xlf');
76  $this->pageRenderer->addInlineLanguageLabelFile('EXT:backend/Resources/Private/Language/Wizards/move_page.xlf');
77 
78  $targetPid = (int)($queryParams['expandPage'] ?? 0);
79  $pageIdToMove = (int)($queryParams['uid'] ?? 0);
80  $makeCopy = (bool)($queryParams['makeCopy'] ?? 0);
81 
82  if ($targetPid) {
83  $view->assignMultiple($this->‪getContentVariables($pageIdToMove, $targetPid));
84  }
85  $view->assignMultiple([
86  'activePage' => $targetPid,
87  'contentOnly' => $contentOnly,
88  // Make-copy checkbox (clicking this will reload the page with the GET var makeCopy set differently):
89  'makeCopyChecked' => $makeCopy,
90  'makeCopyUrl' => $this->uriBuilder->buildUriFromRoute(
91  'move_page',
92  [
93  'uid' => $pageIdToMove,
94  'makeCopy' => !$makeCopy,
95  ]
96  ),
97  ]);
98 
99  $content = $view->render('Page/MovePage');
100  if ($contentOnly) {
101  return new ‪HtmlResponse($content);
102  }
103  $this->pageRenderer->setBodyContent('<body>' . $content);
104  return new ‪HtmlResponse($this->pageRenderer->render());
105  }
106 
107  private function ‪getContentVariables(int $pageIdToMove, int $targetPid): array
108  {
109  $elementRow = BackendUtility::getRecordWSOL('pages', $pageIdToMove);
110  $targetRow = BackendUtility::getRecordWSOL('pages', $targetPid);
111  if (!$this->‪getBackendUser()->doesUserHaveAccess($targetRow, ‪Permission::PAGE_EDIT)) {
112  return [];
113  }
114  return [
115  'targetHasSubpages' => $this->‪pageHasSubpages($targetPid),
116  'element' => [
117  'record' => $elementRow,
118  'recordTooltip' => BackendUtility::getRecordIconAltText($elementRow, 'pages', false),
119  'recordTitle' => BackendUtility::getRecordTitle('pages', $elementRow),
120  'recordPath' => BackendUtility::getRecordPath($pageIdToMove, $this->‪getBackendUser()->getPagePermsClause(‪Permission::PAGE_SHOW), 0),
121  ],
122  'target' => [
123  'record' => $targetRow,
124  'recordTooltip' => BackendUtility::getRecordIconAltText($targetRow, 'pages', false),
125  'recordTitle' => BackendUtility::getRecordTitle('pages', $targetRow),
126  'recordPath' => BackendUtility::getRecordPath($targetPid, $this->‪getBackendUser()->getPagePermsClause(‪Permission::PAGE_SHOW), 0),
127  ],
128  'positions' => [
129  'above' => $this->‪getTargetForAboveInsert($targetRow),
130  'inside' => $targetRow['uid'],
131  'below' => $targetRow['uid'] * -1,
132  ],
133  'hasEditPermissions' => $this->‪getBackendUser()->doesUserHaveAccess($elementRow, ‪Permission::PAGE_EDIT),
134  'isDifferentPage' => $pageIdToMove !== $targetRow['uid'],
135  ];
136  }
137 
138  protected function ‪getTargetForAboveInsert(array $targetRow): int
139  {
140  $targetPageId = (int)$targetRow['uid'];
141  $subpages = $this->‪getSubpagesForPageId($targetRow['pid']);
142  if (in_array($targetPageId, $subpages, true)) {
143  // Set pointer in array to $targetPid
144  while (current($subpages) !== $targetPageId) {
145  if (next($subpages) === false) {
146  // We reached the end of the array and couldn't find the target pid (how?). Fall back to pid
147  return (int)$targetRow['pid'];
148  }
149  }
150  $previousItem = prev($subpages);
151  if ($previousItem !== false) {
152  return $previousItem * -1;
153  }
154  }
155 
156  return (int)$targetRow['pid'];
157  }
158 
159  protected function ‪getSubpagesForPageId(int $pageId): array
160  {
161  $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable('pages');
162  $queryBuilder
163  ->getRestrictions()
164  ->removeAll()
165  ->add(GeneralUtility::makeInstance(DeletedRestriction::class))
166  ->add(GeneralUtility::makeInstance(WorkspaceRestriction::class, $this->‪getBackendUser()->workspace));
167 
168  return $queryBuilder
169  ->select('uid')
170  ->from('pages')
171  ->where(
172  $queryBuilder->expr()->eq('pid', $queryBuilder->createNamedParameter($pageId)),
173  $queryBuilder->expr()->eq('sys_language_uid', 0),
175  $this->getBackendUser()->getPagePermsClause(‪Permission::PAGE_SHOW)
176  )
177  )
178  ->orderBy('sorting')
179  ->executeQuery()
180  ->fetchFirstColumn();
181  }
182 
183  protected function ‪pageHasSubpages(int $pageId): bool
184  {
185  $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable('pages');
186  $queryBuilder
187  ->getRestrictions()
188  ->removeAll()
189  ->add(GeneralUtility::makeInstance(DeletedRestriction::class))
190  ->add(GeneralUtility::makeInstance(WorkspaceRestriction::class, $this->‪getBackendUser()->workspace));
191 
192  $count = (int)$queryBuilder
193  ->count('uid')
194  ->from('pages')
195  ->where(
196  $queryBuilder->expr()->eq('pid', $queryBuilder->createNamedParameter($pageId)),
197  $queryBuilder->expr()->eq('sys_language_uid', 0),
199  $this->‪getBackendUser()->getPagePermsClause(‪Permission::PAGE_SHOW)
200  )
201  )
202  ->executeQuery()
203  ->fetchOne();
204 
205  return $count > 0;
206  }
207 
209  {
210  return ‪$GLOBALS['BE_USER'];
211  }
212 }
‪TYPO3\CMS\Core\Localization\LanguageServiceFactory
Definition: LanguageServiceFactory.php:25
‪TYPO3\CMS\Backend\Controller\Page\MovePageController\getSubpagesForPageId
‪getSubpagesForPageId(int $pageId)
Definition: MovePageController.php:158
‪TYPO3\CMS\Backend\Controller\Page\MovePageController\mainAction
‪mainAction(ServerRequestInterface $request)
Definition: MovePageController.php:57
‪TYPO3\CMS\Backend\View\BackendViewFactory
Definition: BackendViewFactory.php:35
‪TYPO3\CMS\Core\Configuration\ExtensionConfiguration
Definition: ExtensionConfiguration.php:47
‪TYPO3\CMS\Backend\Controller\Page\MovePageController\getContentVariables
‪getContentVariables(int $pageIdToMove, int $targetPid)
Definition: MovePageController.php:106
‪TYPO3\CMS\Backend\Controller\Page\MovePageController\getBackendUser
‪getBackendUser()
Definition: MovePageController.php:207
‪TYPO3\CMS\Backend\Controller\Page\MovePageController\pageHasSubpages
‪pageHasSubpages(int $pageId)
Definition: MovePageController.php:182
‪TYPO3\CMS\Core\Page\JavaScriptModuleInstruction\create
‪static create(string $name, string $exportName=null)
Definition: JavaScriptModuleInstruction.php:47
‪TYPO3\CMS\Backend\Template\PageRendererBackendSetupTrait
Definition: PageRendererBackendSetupTrait.php:45
‪TYPO3\CMS\Core\Page\JavaScriptModuleInstruction
Definition: JavaScriptModuleInstruction.php:23
‪TYPO3\CMS\Backend\Controller\Page\MovePageController
Definition: MovePageController.php:47
‪TYPO3\CMS\Backend\Controller\Page
Definition: LocalizationController.php:18
‪TYPO3\CMS\Backend\Controller\Page\MovePageController\getTargetForAboveInsert
‪getTargetForAboveInsert(array $targetRow)
Definition: MovePageController.php:137
‪TYPO3\CMS\Core\Type\Bitmask\Permission
Definition: Permission.php:26
‪TYPO3\CMS\Core\Page\PageRenderer
Definition: PageRenderer.php:44
‪TYPO3\CMS\Core\Database\Query\QueryHelper
Definition: QueryHelper.php:32
‪TYPO3\CMS\Backend\Routing\UriBuilder
Definition: UriBuilder.php:44
‪TYPO3\CMS\Core\Authentication\BackendUserAuthentication
Definition: BackendUserAuthentication.php:62
‪TYPO3\CMS\Core\Type\Bitmask\Permission\PAGE_SHOW
‪const PAGE_SHOW
Definition: Permission.php:35
‪TYPO3\CMS\Backend\Controller\Page\MovePageController\__construct
‪__construct(private PageRenderer $pageRenderer, private BackendViewFactory $backendViewFactory, private UriBuilder $uriBuilder, private LanguageServiceFactory $languageServiceFactory, private ExtensionConfiguration $extensionConfiguration)
Definition: MovePageController.php:49
‪TYPO3\CMS\Core\Database\Query\QueryHelper\stripLogicalOperatorPrefix
‪static string stripLogicalOperatorPrefix(string $constraint)
Definition: QueryHelper.php:171
‪$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\Type\Bitmask\Permission\PAGE_EDIT
‪const PAGE_EDIT
Definition: Permission.php:40
‪TYPO3\CMS\Backend\Template\PageRendererBackendSetupTrait\setUpBasicPageRendererForBackend
‪setUpBasicPageRendererForBackend(PageRenderer $pageRenderer, ExtensionConfiguration $extensionConfiguration, ServerRequestInterface $request, LanguageService $languageService,)
Definition: PageRendererBackendSetupTrait.php:49
‪TYPO3\CMS\Backend\Attribute\AsController
Definition: AsController.php:25
‪TYPO3\CMS\Core\Database\ConnectionPool
Definition: ConnectionPool.php:46
‪TYPO3\CMS\Core\Utility\GeneralUtility
Definition: GeneralUtility.php:52
‪TYPO3\CMS\Core\Http\HtmlResponse
Definition: HtmlResponse.php:28
‪TYPO3\CMS\Core\Database\Query\Restriction\WorkspaceRestriction
Definition: WorkspaceRestriction.php:39