95b2301e9766792d18e2cf7591fa478069b43ae4
[Packages/TYPO3.CMS.git] / typo3 / sysext / backend / Classes / Tree / Pagetree / ExtdirectTreeCommands.php
1 <?php
2 namespace TYPO3\CMS\Backend\Tree\Pagetree;
3
4 /*
5 * This file is part of the TYPO3 CMS project.
6 *
7 * It is free software; you can redistribute it and/or modify it under
8 * the terms of the GNU General Public License, either version 2
9 * of the License, or any later version.
10 *
11 * For the full copyright and license information, please read the
12 * LICENSE.txt file that was distributed with this source code.
13 *
14 * The TYPO3 project - inspiring people to share!
15 */
16
17 use TYPO3\CMS\Backend\Controller\UserSettingsController;
18 use TYPO3\CMS\Backend\Utility\BackendUtility;
19 use TYPO3\CMS\Core\Authentication\BackendUserAuthentication;
20 use TYPO3\CMS\Core\Utility\GeneralUtility;
21
22 /**
23 * Commands for the Page tree
24 */
25 class ExtdirectTreeCommands
26 {
27 /**
28 * Visibly the page
29 *
30 * @param \stdClass $nodeData
31 * @return array
32 */
33 public function visiblyNode($nodeData)
34 {
35 /** @var $node PagetreeNode */
36 $node = GeneralUtility::makeInstance(PagetreeNode::class, (array)$nodeData);
37 try {
38 Commands::visiblyNode($node);
39 $newNode = Commands::getNode($node->getId());
40 $newNode->setLeaf($node->isLeafNode());
41 $returnValue = $newNode->toArray();
42 } catch (\Exception $exception) {
43 $returnValue = array(
44 'success' => false,
45 'error' => $exception->getMessage()
46 );
47 }
48 return $returnValue;
49 }
50
51 /**
52 * Hide the page
53 *
54 * @param \stdClass $nodeData
55 * @return array
56 */
57 public function disableNode($nodeData)
58 {
59 /** @var $node PagetreeNode */
60 $node = GeneralUtility::makeInstance(PagetreeNode::class, (array)$nodeData);
61 try {
62 Commands::disableNode($node);
63 $newNode = Commands::getNode($node->getId());
64 $newNode->setLeaf($node->isLeafNode());
65 $returnValue = $newNode->toArray();
66 } catch (\Exception $exception) {
67 $returnValue = array(
68 'success' => false,
69 'message' => $exception->getMessage()
70 );
71 }
72 return $returnValue;
73 }
74
75 /**
76 * Delete the page
77 *
78 * @param \stdClass $nodeData
79 * @return array
80 */
81 public function deleteNode($nodeData)
82 {
83 /** @var $node PagetreeNode */
84 $node = GeneralUtility::makeInstance(PagetreeNode::class, (array)$nodeData);
85 try {
86 Commands::deleteNode($node);
87 $returnValue = array();
88 if (static::getBackendUser()->workspace) {
89 $record = Commands::getNodeRecord($node->getId());
90 if ($record['_ORIG_uid']) {
91 $newNode = Commands::getNewNode($record);
92 $returnValue = $newNode->toArray();
93 }
94 }
95 } catch (\Exception $exception) {
96 $returnValue = array(
97 'success' => false,
98 'message' => $exception->getMessage()
99 );
100 }
101 return $returnValue;
102 }
103
104 /**
105 * Restore the page
106 *
107 * @param \stdClass $nodeData
108 * @param int $destination
109 * @return array
110 */
111 public function restoreNode($nodeData, $destination)
112 {
113 /** @var $node PagetreeNode */
114 $node = GeneralUtility::makeInstance(PagetreeNode::class, (array)$nodeData);
115 try {
116 Commands::restoreNode($node, $destination);
117 $newNode = Commands::getNode($node->getId());
118 $returnValue = $newNode->toArray();
119 } catch (\Exception $exception) {
120 $returnValue = array(
121 'success' => false,
122 'message' => $exception->getMessage()
123 );
124 }
125 return $returnValue;
126 }
127
128 /**
129 * Updates the given field with a new text value, may be used to inline update
130 * the title field in the new page tree
131 *
132 * @param \stdClass $nodeData
133 * @param string $updatedLabel
134 * @return array
135 */
136 public function updateLabel($nodeData, $updatedLabel)
137 {
138 if ($updatedLabel === '') {
139 return array();
140 }
141 /** @var $node PagetreeNode */
142 $node = GeneralUtility::makeInstance(PagetreeNode::class, (array)$nodeData);
143 try {
144 Commands::updateNodeLabel($node, $updatedLabel);
145 $shortendedText = GeneralUtility::fixed_lgd_cs($updatedLabel, (int)static::getBackendUser()->uc['titleLen']);
146 $returnValue = array(
147 'editableText' => $updatedLabel,
148 'updatedText' => htmlspecialchars($shortendedText)
149 );
150 } catch (\Exception $exception) {
151 $returnValue = array(
152 'success' => false,
153 'message' => $exception->getMessage()
154 );
155 }
156 return $returnValue;
157 }
158
159 /**
160 * Clear cache of the page
161 *
162 * @param \stdClass $nodeData
163 * @return void
164 */
165 public static function clearCacheOfPage($nodeData)
166 {
167 $node = GeneralUtility::makeInstance(PagetreeNode::class, (array)$nodeData);
168 $tce = GeneralUtility::makeInstance(\TYPO3\CMS\Core\DataHandling\DataHandler::class);
169 $tce->start(array(), array());
170 $tce->clear_cacheCmd($node->getId());
171 }
172
173 /**
174 * Sets a temporary mount point
175 *
176 * @param \stdClass $nodeData
177 * @return array
178 */
179 public static function setTemporaryMountPoint($nodeData)
180 {
181 /** @var $node PagetreeNode */
182 $node = GeneralUtility::makeInstance(PagetreeNode::class, (array)$nodeData);
183 static::getBackendUser()->uc['pageTree_temporaryMountPoint'] = $node->getId();
184 static::getBackendUser()->writeUC(static::getBackendUser()->uc);
185 return Commands::getMountPointPath();
186 }
187
188 /**
189 * Moves the source node directly as the first child of the destination node
190 *
191 * @param \stdClass $nodeData
192 * @param int $destination
193 * @return array
194 */
195 public function moveNodeToFirstChildOfDestination($nodeData, $destination)
196 {
197 /** @var $node PagetreeNode */
198 $node = GeneralUtility::makeInstance(PagetreeNode::class, (array)$nodeData);
199 try {
200 Commands::moveNode($node, $destination);
201 $newNode = Commands::getNode($node->getId(), false);
202 $newNode->setLeaf($node->isLeafNode());
203 $returnValue = $newNode->toArray();
204 } catch (\Exception $exception) {
205 $returnValue = array(
206 'success' => false,
207 'message' => $exception->getMessage()
208 );
209 }
210 return $returnValue;
211 }
212
213 /**
214 * Moves the source node directly after the destination node
215 *
216 * @param \stdClass $nodeData
217 * @param int $destination
218 * @return array
219 */
220 public function moveNodeAfterDestination($nodeData, $destination)
221 {
222 /** @var $node PagetreeNode */
223 $node = GeneralUtility::makeInstance(PagetreeNode::class, (array)$nodeData);
224 try {
225 Commands::moveNode($node, -$destination);
226 $newNode = Commands::getNode($node->getId(), false);
227 $newNode->setLeaf($node->isLeafNode());
228 $returnValue = $newNode->toArray();
229 } catch (\Exception $exception) {
230 $returnValue = array(
231 'success' => false,
232 'message' => $exception->getMessage()
233 );
234 }
235 return $returnValue;
236 }
237
238 /**
239 * Copies the source node directly as the first child of the destination node and
240 * returns the created node.
241 *
242 * @param \stdClass $nodeData
243 * @param int $destination
244 * @return array
245 */
246 public function copyNodeToFirstChildOfDestination($nodeData, $destination)
247 {
248 /** @var $node PagetreeNode */
249 $node = GeneralUtility::makeInstance(PagetreeNode::class, (array)$nodeData);
250 try {
251 $newPageId = Commands::copyNode($node, $destination);
252 $newNode = Commands::getNode($newPageId);
253 $newNode->setLeaf($node->isLeafNode());
254 $returnValue = $newNode->toArray();
255 } catch (\Exception $exception) {
256 $returnValue = array(
257 'success' => false,
258 'message' => $exception->getMessage()
259 );
260 }
261 return $returnValue;
262 }
263
264 /**
265 * Copies the source node directly after the destination node and returns the
266 * created node.
267 *
268 * @param \stdClass $nodeData
269 * @param int $destination
270 * @return array
271 */
272 public function copyNodeAfterDestination($nodeData, $destination)
273 {
274 /** @var $node PagetreeNode */
275 $node = GeneralUtility::makeInstance(PagetreeNode::class, (array)$nodeData);
276 try {
277 $newPageId = Commands::copyNode($node, -$destination);
278 $newNode = Commands::getNode($newPageId);
279 $newNode->setLeaf($node->isLeafNode());
280 $returnValue = $newNode->toArray();
281 } catch (\Exception $exception) {
282 $returnValue = array(
283 'success' => false,
284 'message' => $exception->getMessage()
285 );
286 }
287 return $returnValue;
288 }
289
290 /**
291 * Inserts a new node as the first child node of the destination node and returns the created node.
292 *
293 * @param \stdClass $parentNodeData
294 * @param int $pageType
295 * @return array
296 */
297 public function insertNodeToFirstChildOfDestination($parentNodeData, $pageType)
298 {
299 /** @var $parentNode PagetreeNode */
300 $parentNode = GeneralUtility::makeInstance(PagetreeNode::class, (array)$parentNodeData);
301 try {
302 $newPageId = Commands::createNode($parentNode, $parentNode->getId(), $pageType);
303 $returnValue = Commands::getNode($newPageId)->toArray();
304 } catch (\Exception $exception) {
305 $returnValue = array(
306 'success' => false,
307 'message' => $exception->getMessage()
308 );
309 }
310 return $returnValue;
311 }
312
313 /**
314 * Inserts a new node directly after the destination node and returns the created node.
315 *
316 * @param \stdClass $parentNodeData
317 * @param int $destination
318 * @param int $pageType
319 * @return array
320 */
321 public function insertNodeAfterDestination($parentNodeData, $destination, $pageType)
322 {
323 /** @var $parentNode PagetreeNode */
324 $parentNode = GeneralUtility::makeInstance(PagetreeNode::class, (array)$parentNodeData);
325 try {
326 $newPageId = Commands::createNode($parentNode, -$destination, $pageType);
327 $returnValue = Commands::getNode($newPageId)->toArray();
328 } catch (\Exception $exception) {
329 $returnValue = array(
330 'success' => false,
331 'message' => $exception->getMessage()
332 );
333 }
334 return $returnValue;
335 }
336
337 /**
338 * Returns the view link of a given node
339 *
340 * @param \stdClass $nodeData
341 * @return string
342 */
343 public static function getViewLink($nodeData)
344 {
345 /** @var $node PagetreeNode */
346 $node = GeneralUtility::makeInstance(PagetreeNode::class, (array)$nodeData);
347 $javascriptLink = BackendUtility::viewOnClick($node->getId());
348 $extractedLink = '';
349 if (preg_match('/window\\.open\\(\'([^\']+)\'/i', $javascriptLink, $match)) {
350 // Clean JSON-serialized ampersands ('&')
351 // @see GeneralUtility::quoteJSvalue()
352 $extractedLink = json_decode('"' . trim($match[1], '"') . '"', JSON_HEX_AMP);
353 };
354 return $extractedLink;
355 }
356
357 /**
358 * Adds the rootline of a given node to the tree expansion state and adds the node
359 * itself as the current selected page. This leads to the expansion and selection of
360 * the node in the tree after a refresh.
361 *
362 * @static
363 * @param string $stateId
364 * @param int $nodeId
365 * @return array
366 */
367 public static function addRootlineOfNodeToStateHash($stateId, $nodeId)
368 {
369 $mountPoints = array_map('intval', static::getBackendUser()->returnWebmounts());
370 if (empty($mountPoints)) {
371 $mountPoints = array(0);
372 }
373 if (!empty(static::getBackendUser()->uc['pageTree_temporaryMountPoint'])) {
374 $mountPoints[] = (int)static::getBackendUser()->uc['pageTree_temporaryMountPoint'];
375 }
376 $mountPoints = array_unique($mountPoints);
377 /** @var $userSettingsController UserSettingsController */
378 $userSettingsController = GeneralUtility::makeInstance(UserSettingsController::class);
379 $state = $userSettingsController->process('get', 'BackendComponents.States.' . $stateId);
380 if (empty($state)) {
381 $state = new \stdClass();
382 $state->stateHash = new \stdClass();
383 }
384 $state->stateHash = (object)$state->stateHash;
385 $rootline = BackendUtility::BEgetRootLine($nodeId, '', (int)static::getBackendUser()->workspace !== 0);
386 $rootlineIds = array();
387 foreach ($rootline as $pageData) {
388 $rootlineIds[] = (int)$pageData['uid'];
389 }
390 foreach ($mountPoints as $mountPoint) {
391 if (!in_array($mountPoint, $rootlineIds, true)) {
392 continue;
393 }
394 $isFirstNode = true;
395 foreach ($rootline as $pageData) {
396 $node = Commands::getNewNode($pageData, $mountPoint);
397 if ($isFirstNode) {
398 $isFirstNode = false;
399 $state->stateHash->lastSelectedNode = $node->calculateNodeId();
400 } else {
401 $state->stateHash->{$node->calculateNodeId('')} = 1;
402 }
403 }
404 }
405 $userSettingsController->process('set', 'BackendComponents.States.' . $stateId, $state);
406 return (array)$state->stateHash;
407 }
408
409 /**
410 * Gets the path steps for a given page.
411 * This methods considers multiple mount points,
412 * thus the returned array is multidimensional, e.g.
413 *
414 * array(
415 * array('p0', 'p1', 'p13', 'p44'),
416 * array('p0', 'p13-1', 'p44-1'),
417 * )
418 *
419 * @param int $pageId
420 * @return array
421 */
422 public static function getNodePaths($pageId)
423 {
424 $pagePaths = array();
425 $mountPoints = array_map('intval', static::getBackendUser()->returnWebmounts());
426 if (empty($mountPoints)) {
427 $mountPoints = array(0);
428 }
429 $mountPoints[] = (int)static::getBackendUser()->uc['pageTree_temporaryMountPoint'];
430 $mountPoints = array_unique($mountPoints);
431 $rootLine = BackendUtility::BEgetRootLine($pageId, '', (int)static::getBackendUser()->workspace !== 0);
432 $rootLineIds = array();
433 foreach ($rootLine as $rootLineLevel) {
434 $rootLineIds[] = (int)$rootLineLevel['uid'];
435 }
436 foreach ($mountPoints as $mountPoint) {
437 $pagePath = array();
438 if (!in_array($mountPoint, $rootLineIds, true)) {
439 continue;
440 }
441 foreach ($rootLine as $rootLineLevel) {
442 $node = Commands::getNewNode($rootLineLevel, $mountPoint);
443 array_unshift($pagePath, $node->calculateNodeId());
444 // Break if mount-point has been reached
445 if ($mountPoint === (int)$rootLineLevel['uid']) {
446 break;
447 }
448 }
449 // Attach valid partial root-lines
450 if (!empty($pagePath)) {
451 if ($mountPoint !== 0) {
452 array_unshift($pagePath, Commands::getNewNode(array('uid' => 0))->calculateNodeId());
453 }
454 $pagePaths[] = $pagePath;
455 }
456 }
457 return $pagePaths;
458 }
459
460 /**
461 * @return BackendUserAuthentication
462 */
463 protected static function getBackendUser()
464 {
465 return $GLOBALS['BE_USER'];
466 }
467 }