[BUGFIX] Keep selected page active after save & close
[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\Utility\BackendUtility;
18 use TYPO3\CMS\Core\Utility\GeneralUtility;
19
20 /**
21 * Commands for the Page tree
22 */
23 class ExtdirectTreeCommands
24 {
25 /**
26 * Visibly the page
27 *
28 * @param stdClass $nodeData
29 * @return array
30 */
31 public function visiblyNode($nodeData)
32 {
33 /** @var $node \TYPO3\CMS\Backend\Tree\Pagetree\PagetreeNode */
34 $node = GeneralUtility::makeInstance(\TYPO3\CMS\Backend\Tree\Pagetree\PagetreeNode::class, (array)$nodeData);
35 try {
36 Commands::visiblyNode($node);
37 $newNode = Commands::getNode($node->getId());
38 $newNode->setLeaf($node->isLeafNode());
39 $returnValue = $newNode->toArray();
40 } catch (\Exception $exception) {
41 $returnValue = array(
42 'success' => false,
43 'error' => $exception->getMessage()
44 );
45 }
46 return $returnValue;
47 }
48
49 /**
50 * Hide the page
51 *
52 * @param stdClass $nodeData
53 * @return array
54 */
55 public function disableNode($nodeData)
56 {
57 /** @var $node \TYPO3\CMS\Backend\Tree\Pagetree\PagetreeNode */
58 $node = GeneralUtility::makeInstance(\TYPO3\CMS\Backend\Tree\Pagetree\PagetreeNode::class, (array)$nodeData);
59 try {
60 Commands::disableNode($node);
61 $newNode = Commands::getNode($node->getId());
62 $newNode->setLeaf($node->isLeafNode());
63 $returnValue = $newNode->toArray();
64 } catch (\Exception $exception) {
65 $returnValue = array(
66 'success' => false,
67 'message' => $exception->getMessage()
68 );
69 }
70 return $returnValue;
71 }
72
73 /**
74 * Delete the page
75 *
76 * @param stdClass $nodeData
77 * @return array
78 */
79 public function deleteNode($nodeData)
80 {
81 /** @var $node \TYPO3\CMS\Backend\Tree\Pagetree\PagetreeNode */
82 $node = GeneralUtility::makeInstance(\TYPO3\CMS\Backend\Tree\Pagetree\PagetreeNode::class, (array)$nodeData);
83 try {
84 Commands::deleteNode($node);
85 $returnValue = array();
86 if ($GLOBALS['BE_USER']->workspace) {
87 $record = Commands::getNodeRecord($node->getId());
88 if ($record['_ORIG_uid']) {
89 $newNode = Commands::getNewNode($record);
90 $returnValue = $newNode->toArray();
91 }
92 }
93 } catch (\Exception $exception) {
94 $returnValue = array(
95 'success' => false,
96 'message' => $exception->getMessage()
97 );
98 }
99 return $returnValue;
100 }
101
102 /**
103 * Restore the page
104 *
105 * @param stdClass $nodeData
106 * @param int $destination
107 * @return array
108 */
109 public function restoreNode($nodeData, $destination)
110 {
111 /** @var $node \TYPO3\CMS\Backend\Tree\Pagetree\PagetreeNode */
112 $node = GeneralUtility::makeInstance(\TYPO3\CMS\Backend\Tree\Pagetree\PagetreeNode::class, (array)$nodeData);
113 try {
114 Commands::restoreNode($node, $destination);
115 $newNode = Commands::getNode($node->getId());
116 $returnValue = $newNode->toArray();
117 } catch (\Exception $exception) {
118 $returnValue = array(
119 'success' => false,
120 'message' => $exception->getMessage()
121 );
122 }
123 return $returnValue;
124 }
125
126 /**
127 * Updates the given field with a new text value, may be used to inline update
128 * the title field in the new page tree
129 *
130 * @param stdClass $nodeData
131 * @param string $updatedLabel
132 * @return array
133 */
134 public function updateLabel($nodeData, $updatedLabel)
135 {
136 if ($updatedLabel === '') {
137 return array();
138 }
139 /** @var $node \TYPO3\CMS\Backend\Tree\Pagetree\PagetreeNode */
140 $node = GeneralUtility::makeInstance(\TYPO3\CMS\Backend\Tree\Pagetree\PagetreeNode::class, (array)$nodeData);
141 try {
142 Commands::updateNodeLabel($node, $updatedLabel);
143 $shortendedText = GeneralUtility::fixed_lgd_cs($updatedLabel, (int)$GLOBALS['BE_USER']->uc['titleLen']);
144 $returnValue = array(
145 'editableText' => $updatedLabel,
146 'updatedText' => htmlspecialchars($shortendedText)
147 );
148 } catch (\Exception $exception) {
149 $returnValue = array(
150 'success' => false,
151 'message' => $exception->getMessage()
152 );
153 }
154 return $returnValue;
155 }
156
157 /**
158 * Sets a temporary mount point
159 *
160 * @param stdClass $nodeData
161 * @return array
162 */
163 public static function setTemporaryMountPoint($nodeData)
164 {
165 /** @var $node \TYPO3\CMS\Backend\Tree\Pagetree\PagetreeNode */
166 $node = GeneralUtility::makeInstance(\TYPO3\CMS\Backend\Tree\Pagetree\PagetreeNode::class, (array)$nodeData);
167 $GLOBALS['BE_USER']->uc['pageTree_temporaryMountPoint'] = $node->getId();
168 $GLOBALS['BE_USER']->writeUC($GLOBALS['BE_USER']->uc);
169 return Commands::getMountPointPath();
170 }
171
172 /**
173 * Moves the source node directly as the first child of the destination node
174 *
175 * @param stdClass $nodeData
176 * @param int $destination
177 * @return array
178 */
179 public function moveNodeToFirstChildOfDestination($nodeData, $destination)
180 {
181 /** @var $node \TYPO3\CMS\Backend\Tree\Pagetree\PagetreeNode */
182 $node = GeneralUtility::makeInstance(\TYPO3\CMS\Backend\Tree\Pagetree\PagetreeNode::class, (array)$nodeData);
183 try {
184 Commands::moveNode($node, $destination);
185 $newNode = Commands::getNode($node->getId(), false);
186 $newNode->setLeaf($node->isLeafNode());
187 $returnValue = $newNode->toArray();
188 } catch (\Exception $exception) {
189 $returnValue = array(
190 'success' => false,
191 'message' => $exception->getMessage()
192 );
193 }
194 return $returnValue;
195 }
196
197 /**
198 * Moves the source node directly after the destination node
199 *
200 * @param stdClass $nodeData
201 * @param int $destination
202 * @return void
203 */
204 public function moveNodeAfterDestination($nodeData, $destination)
205 {
206 /** @var $node \TYPO3\CMS\Backend\Tree\Pagetree\PagetreeNode */
207 $node = GeneralUtility::makeInstance(\TYPO3\CMS\Backend\Tree\Pagetree\PagetreeNode::class, (array)$nodeData);
208 try {
209 Commands::moveNode($node, -$destination);
210 $newNode = Commands::getNode($node->getId(), false);
211 $newNode->setLeaf($node->isLeafNode());
212 $returnValue = $newNode->toArray();
213 } catch (\Exception $exception) {
214 $returnValue = array(
215 'success' => false,
216 'message' => $exception->getMessage()
217 );
218 }
219 return $returnValue;
220 }
221
222 /**
223 * Copies the source node directly as the first child of the destination node and
224 * returns the created node.
225 *
226 * @param stdClass $nodeData
227 * @param int $destination
228 * @return array
229 */
230 public function copyNodeToFirstChildOfDestination($nodeData, $destination)
231 {
232 /** @var $node \TYPO3\CMS\Backend\Tree\Pagetree\PagetreeNode */
233 $node = GeneralUtility::makeInstance(\TYPO3\CMS\Backend\Tree\Pagetree\PagetreeNode::class, (array)$nodeData);
234 /** @var $dataProvider \TYPO3\CMS\Backend\Tree\Pagetree\DataProvider */
235 $dataProvider = GeneralUtility::makeInstance(\TYPO3\CMS\Backend\Tree\Pagetree\DataProvider::class);
236 try {
237 $newPageId = Commands::copyNode($node, $destination);
238 $newNode = Commands::getNode($newPageId);
239 $newNode->setLeaf($node->isLeafNode());
240 $returnValue = $newNode->toArray();
241 } catch (\Exception $exception) {
242 $returnValue = array(
243 'success' => false,
244 'message' => $exception->getMessage()
245 );
246 }
247 return $returnValue;
248 }
249
250 /**
251 * Copies the source node directly after the destination node and returns the
252 * created node.
253 *
254 * @param stdClass $nodeData
255 * @param int $destination
256 * @return array
257 */
258 public function copyNodeAfterDestination($nodeData, $destination)
259 {
260 /** @var $node \TYPO3\CMS\Backend\Tree\Pagetree\PagetreeNode */
261 $node = GeneralUtility::makeInstance(\TYPO3\CMS\Backend\Tree\Pagetree\PagetreeNode::class, (array)$nodeData);
262 /** @var $dataProvider \TYPO3\CMS\Backend\Tree\Pagetree\DataProvider */
263 $dataProvider = GeneralUtility::makeInstance(\TYPO3\CMS\Backend\Tree\Pagetree\DataProvider::class);
264 try {
265 $newPageId = Commands::copyNode($node, -$destination);
266 $newNode = Commands::getNode($newPageId);
267 $newNode->setLeaf($node->isLeafNode());
268 $returnValue = $newNode->toArray();
269 } catch (\Exception $exception) {
270 $returnValue = array(
271 'success' => false,
272 'message' => $exception->getMessage()
273 );
274 }
275 return $returnValue;
276 }
277
278 /**
279 * Inserts a new node as the first child node of the destination node and returns the created node.
280 *
281 * @param stdClass $parentNodeData
282 * @param int $pageType
283 * @return array
284 */
285 public function insertNodeToFirstChildOfDestination($parentNodeData, $pageType)
286 {
287 /** @var $parentNode \TYPO3\CMS\Backend\Tree\Pagetree\PagetreeNode */
288 $parentNode = GeneralUtility::makeInstance(\TYPO3\CMS\Backend\Tree\Pagetree\PagetreeNode::class, (array)$parentNodeData);
289 try {
290 $newPageId = Commands::createNode($parentNode, $parentNode->getId(), $pageType);
291 $returnValue = Commands::getNode($newPageId)->toArray();
292 } catch (\Exception $exception) {
293 $returnValue = array(
294 'success' => false,
295 'message' => $exception->getMessage()
296 );
297 }
298 return $returnValue;
299 }
300
301 /**
302 * Inserts a new node directly after the destination node and returns the created node.
303 *
304 * @param stdClass $parentNodeData
305 * @param int $destination
306 * @param int $pageType
307 * @return array
308 */
309 public function insertNodeAfterDestination($parentNodeData, $destination, $pageType)
310 {
311 /** @var $parentNode \TYPO3\CMS\Backend\Tree\Pagetree\PagetreeNode */
312 $parentNode = GeneralUtility::makeInstance(\TYPO3\CMS\Backend\Tree\Pagetree\PagetreeNode::class, (array)$parentNodeData);
313 try {
314 $newPageId = Commands::createNode($parentNode, -$destination, $pageType);
315 $returnValue = Commands::getNode($newPageId)->toArray();
316 } catch (\Exception $exception) {
317 $returnValue = array(
318 'success' => false,
319 'message' => $exception->getMessage()
320 );
321 }
322 return $returnValue;
323 }
324
325 /**
326 * Returns the view link of a given node
327 *
328 * @param \stdClass $nodeData
329 * @return string
330 */
331 public static function getViewLink($nodeData)
332 {
333 /** @var $node \TYPO3\CMS\Backend\Tree\Pagetree\PagetreeNode */
334 $node = GeneralUtility::makeInstance(\TYPO3\CMS\Backend\Tree\Pagetree\PagetreeNode::class, (array)$nodeData);
335 $javascriptLink = BackendUtility::viewOnClick($node->getId());
336 $extractedLink = '';
337 if (preg_match('/window\\.open\\(\'([^\']+)\'/i', $javascriptLink, $match)) {
338 // Clean JSON-serialized ampersands ('&')
339 // @see GeneralUtility::quoteJSvalue()
340 $extractedLink = json_decode('"' . trim($match[1], '"') . '"', JSON_HEX_AMP);
341 };
342 return $extractedLink;
343 }
344
345 /**
346 * Adds the rootline of a given node to the tree expansion state and adds the node
347 * itself as the current selected page. This leads to the expansion and selection of
348 * the node in the tree after a refresh.
349 *
350 * @static
351 * @param string $stateId
352 * @param int $nodeId
353 * @return array
354 */
355 public static function addRootlineOfNodeToStateHash($stateId, $nodeId)
356 {
357 $mountPoints = array_map('intval', $GLOBALS['BE_USER']->returnWebmounts());
358 if (empty($mountPoints)) {
359 $mountPoints = array(0);
360 }
361 if (!empty($GLOBALS['BE_USER']->uc['pageTree_temporaryMountPoint'])){
362 $mountPoints[] = (int)$GLOBALS['BE_USER']->uc['pageTree_temporaryMountPoint'];
363 }
364 $mountPoints = array_unique($mountPoints);
365 /** @var $userSettingsController \TYPO3\CMS\Backend\Controller\UserSettingsController */
366 $userSettingsController = GeneralUtility::makeInstance(\TYPO3\CMS\Backend\Controller\UserSettingsController::class);
367 $state = $userSettingsController->process('get', 'BackendComponents.States.' . $stateId);
368 if (empty($state)) {
369 $state = new \StdClass();
370 $state->stateHash = new \StdClass();
371 }
372 $state->stateHash = (object)$state->stateHash;
373 $rootline = BackendUtility::BEgetRootLine($nodeId, '', $GLOBALS['BE_USER']->workspace != 0);
374 $rootlineIds = array();
375 foreach ($rootline as $pageData) {
376 $rootlineIds[] = (int)$pageData['uid'];
377 }
378 foreach ($mountPoints as $mountPoint) {
379 if (!in_array($mountPoint, $rootlineIds, true)) {
380 continue;
381 }
382 $isFirstNode = true;
383 foreach ($rootline as $pageData) {
384 $node = Commands::getNewNode($pageData, $mountPoint);
385 if ($isFirstNode) {
386 $isFirstNode = false;
387 $state->stateHash->lastSelectedNode = $node->calculateNodeId();
388 } else {
389 $state->stateHash->{$node->calculateNodeId('')} = 1;
390 }
391 }
392 }
393 $userSettingsController->process('set', 'BackendComponents.States.' . $stateId, $state);
394 return (array)$state->stateHash;
395 }
396 }