[BUGFIX] Disable restricted users to handle page records in pagetree
[Packages/TYPO3.CMS.git] / typo3 / sysext / backend / Classes / Tree / Pagetree / Commands.php
1 <?php
2 namespace TYPO3\CMS\Backend\Tree\Pagetree;
3
4 /***************************************************************
5 * Copyright notice
6 *
7 * (c) 2010-2013 TYPO3 Tree Team <http://forge.typo3.org/projects/typo3v4-extjstrees>
8 * All rights reserved
9 *
10 * This script is part of the TYPO3 project. The TYPO3 project is
11 * free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
15 *
16 * The GNU General Public License can be found at
17 * http://www.gnu.org/copyleft/gpl.html.
18 * A copy is found in the textfile GPL.txt and important notices to the license
19 * from the author is found in LICENSE.txt distributed with these scripts.
20 *
21 *
22 * This script is distributed in the hope that it will be useful,
23 * but WITHOUT ANY WARRANTY; without even the implied warranty of
24 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25 * GNU General Public License for more details.
26 *
27 * This copyright notice MUST APPEAR in all copies of the script!
28 ***************************************************************/
29
30 use TYPO3\CMS\Backend\Utility\BackendUtility;
31 use TYPO3\CMS\Backend\Utility\IconUtility;
32 use TYPO3\CMS\Core\Utility\GeneralUtility;
33 use TYPO3\CMS\Core\Utility\MathUtility;
34
35 /**
36 * Page Tree and Context Menu Commands
37 *
38 * @author Stefan Galinski <stefan.galinski@gmail.com>
39 */
40 class Commands {
41
42 /**
43 * @var boolean|null
44 */
45 static protected $useNavTitle = NULL;
46
47 /**
48 * @var boolean|null
49 */
50 static protected $addIdAsPrefix = NULL;
51
52 /**
53 * @var boolean|null
54 */
55 static protected $addDomainName = NULL;
56
57 /**
58 * @var array|null
59 */
60 static protected $backgroundColors = NULL;
61
62 /**
63 * @var integer|null
64 */
65 static protected $titleLength = NULL;
66
67 /**
68 * Visibly the page
69 *
70 * @param \TYPO3\CMS\Backend\Tree\Pagetree\PagetreeNode $node
71 * @return void
72 */
73 static public function visiblyNode(\TYPO3\CMS\Backend\Tree\Pagetree\PagetreeNode $node) {
74 $data['pages'][$node->getWorkspaceId()]['hidden'] = 0;
75 self::processTceCmdAndDataMap(array(), $data);
76 }
77
78 /**
79 * Hide the page
80 *
81 * @param \TYPO3\CMS\Backend\Tree\Pagetree\PagetreeNode $node
82 * @return void
83 */
84 static public function disableNode(\TYPO3\CMS\Backend\Tree\Pagetree\PagetreeNode $node) {
85 $data['pages'][$node->getWorkspaceId()]['hidden'] = 1;
86 self::processTceCmdAndDataMap(array(), $data);
87 }
88
89 /**
90 * Delete the page
91 *
92 * @param \TYPO3\CMS\Backend\Tree\Pagetree\PagetreeNode $node
93 * @return void
94 */
95 static public function deleteNode(\TYPO3\CMS\Backend\Tree\Pagetree\PagetreeNode $node) {
96 $cmd['pages'][$node->getId()]['delete'] = 1;
97 self::processTceCmdAndDataMap($cmd);
98 }
99
100 /**
101 * Restore the page
102 *
103 * @param \TYPO3\CMS\Backend\Tree\Pagetree\PagetreeNode $node
104 * @param integer $targetId
105 * @return void
106 */
107 static public function restoreNode(\TYPO3\CMS\Backend\Tree\Pagetree\PagetreeNode $node, $targetId) {
108 $cmd['pages'][$node->getId()]['undelete'] = 1;
109 self::processTceCmdAndDataMap($cmd);
110 if ($node->getId() !== $targetId) {
111 self::moveNode($node, $targetId);
112 }
113 }
114
115 /**
116 * Updates the node label
117 *
118 * @param \TYPO3\CMS\Backend\Tree\Pagetree\PagetreeNode $node
119 * @param string $updatedLabel
120 * @return void
121 */
122 static public function updateNodeLabel(\TYPO3\CMS\Backend\Tree\Pagetree\PagetreeNode $node, $updatedLabel) {
123 if ($GLOBALS['BE_USER']->checkLanguageAccess(0)) {
124 $data['pages'][$node->getWorkspaceId()][$node->getTextSourceField()] = $updatedLabel;
125 self::processTceCmdAndDataMap(array(), $data);
126 } else {
127 throw new \RuntimeException(implode(chr(10), array('Editing title of page id \'' . $node->getWorkspaceId() . '\' failed. Editing default language is not allowed.')), 1365513336);
128 }
129 }
130
131 /**
132 * Copies a page and returns the id of the new page
133 *
134 * Node: Use a negative target id to specify a sibling target else the parent is used
135 *
136 * @param \TYPO3\CMS\Backend\Tree\Pagetree\PagetreeNode $sourceNode
137 * @param integer $targetId
138 * @return integer
139 */
140 static public function copyNode(\TYPO3\CMS\Backend\Tree\Pagetree\PagetreeNode $sourceNode, $targetId) {
141 $cmd['pages'][$sourceNode->getId()]['copy'] = $targetId;
142 $returnValue = self::processTceCmdAndDataMap($cmd);
143 return $returnValue['pages'][$sourceNode->getId()];
144 }
145
146 /**
147 * Moves a page
148 *
149 * Node: Use a negative target id to specify a sibling target else the parent is used
150 *
151 * @param \TYPO3\CMS\Backend\Tree\Pagetree\PagetreeNode $sourceNode
152 * @param integer $targetId
153 * @return void
154 */
155 static public function moveNode(\TYPO3\CMS\Backend\Tree\Pagetree\PagetreeNode $sourceNode, $targetId) {
156 $cmd['pages'][$sourceNode->getId()]['move'] = $targetId;
157 self::processTceCmdAndDataMap($cmd);
158 }
159
160 /**
161 * Creates a page of the given doktype and returns the id of the created page
162 *
163 * @param \TYPO3\CMS\Backend\Tree\Pagetree\PagetreeNode $parentNode
164 * @param integer $targetId
165 * @param integer $pageType
166 * @return integer
167 */
168 static public function createNode(\TYPO3\CMS\Backend\Tree\Pagetree\PagetreeNode $parentNode, $targetId, $pageType) {
169 $placeholder = 'NEW12345';
170 $pid = intval($parentNode->getWorkspaceId());
171 $targetId = intval($targetId);
172
173 // Use page TsConfig as default page initialization
174 $pageTs = BackendUtility::getPagesTSconfig($pid);
175 if (array_key_exists('TCAdefaults.', $pageTs) && array_key_exists('pages.', $pageTs['TCAdefaults.'])) {
176 $data['pages'][$placeholder] = $pageTs['TCAdefaults.']['pages.'];
177 } else {
178 $data['pages'][$placeholder] = array();
179 }
180
181 $data['pages'][$placeholder]['pid'] = $pid;
182 $data['pages'][$placeholder]['doktype'] = $pageType;
183 $data['pages'][$placeholder]['title'] = $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.xlf:tree.defaultPageTitle', TRUE);
184 $newPageId = self::processTceCmdAndDataMap(array(), $data);
185 $node = self::getNode($newPageId[$placeholder]);
186 if ($pid !== $targetId) {
187 self::moveNode($node, $targetId);
188 }
189
190 return $newPageId[$placeholder];
191 }
192
193 /**
194 * Process TCEMAIN commands and data maps
195 *
196 * Command Map:
197 * Used for moving, recover, remove and some more operations.
198 *
199 * Data Map:
200 * Used for creating and updating records,
201 *
202 * This API contains all necessary access checks.
203 *
204 * @param array $cmd
205 * @param array $data
206 * @return array
207 * @throws \RuntimeException if an error happened while the TCE processing
208 */
209 static protected function processTceCmdAndDataMap(array $cmd, array $data = array()) {
210 /** @var $tce \TYPO3\CMS\Core\DataHandling\DataHandler */
211 $tce = GeneralUtility::makeInstance('TYPO3\\CMS\\Core\\DataHandling\\DataHandler');
212 $tce->stripslashes_values = 0;
213 $tce->start($data, $cmd);
214 $tce->copyTree = MathUtility::forceIntegerInRange($GLOBALS['BE_USER']->uc['copyLevels'], 0, 100);
215 if (count($cmd)) {
216 $tce->process_cmdmap();
217 $returnValues = $tce->copyMappingArray_merged;
218 } elseif (count($data)) {
219 $tce->process_datamap();
220 $returnValues = $tce->substNEWwithIDs;
221 } else {
222 $returnValues = array();
223 }
224 // check errors
225 if (count($tce->errorLog)) {
226 throw new \RuntimeException(implode(chr(10), $tce->errorLog), 1333754629);
227 }
228 return $returnValues;
229 }
230
231 /**
232 * Returns a node from the given node id
233 *
234 * @param integer $nodeId
235 * @param boolean $unsetMovePointers
236 * @return \TYPO3\CMS\Backend\Tree\Pagetree\PagetreeNode
237 */
238 static public function getNode($nodeId, $unsetMovePointers = TRUE) {
239 $record = self::getNodeRecord($nodeId, $unsetMovePointers);
240 return self::getNewNode($record);
241 }
242
243 /**
244 * Returns the mount point path for a temporary mount or the given id
245 *
246 * @param integer $uid
247 * @return string
248 */
249 static public function getMountPointPath($uid = -1) {
250 if ($uid === -1) {
251 $uid = intval($GLOBALS['BE_USER']->uc['pageTree_temporaryMountPoint']);
252 }
253 if ($uid <= 0) {
254 return '';
255 }
256 if (self::$useNavTitle === NULL) {
257 self::$useNavTitle = $GLOBALS['BE_USER']->getTSConfigVal('options.pageTree.showNavTitle');
258 }
259 $rootline = array_reverse(BackendUtility::BEgetRootLine($uid));
260 array_shift($rootline);
261 $path = array();
262 foreach ($rootline as $rootlineElement) {
263 $record = self::getNodeRecord($rootlineElement['uid']);
264 $text = $record['title'];
265 if (self::$useNavTitle && trim($record['nav_title']) !== '') {
266 $text = $record['nav_title'];
267 }
268 $path[] = htmlspecialchars($text);
269 }
270 return '/' . implode('/', $path);
271 }
272
273 /**
274 * Returns a node record from a given id
275 *
276 * @param integer $nodeId
277 * @param boolean $unsetMovePointers
278 * @return array
279 */
280 static public function getNodeRecord($nodeId, $unsetMovePointers = TRUE) {
281 $record = BackendUtility::getRecordWSOL('pages', $nodeId, '*', '', TRUE, $unsetMovePointers);
282 return $record;
283 }
284
285 /**
286 * Returns the first configured domain name for a page
287 *
288 * @param integer $uid
289 * @return string
290 */
291 static public function getDomainName($uid) {
292 $whereClause = 'pid=' . intval($uid) . BackendUtility::deleteClause('sys_domain') . BackendUtility::BEenableFields('sys_domain');
293 $domain = $GLOBALS['TYPO3_DB']->exec_SELECTgetSingleRow('domainName', 'sys_domain', $whereClause, '', 'sorting');
294 return is_array($domain) ? htmlspecialchars($domain['domainName']) : '';
295 }
296
297 /**
298 * Creates a node with the given record information
299 *
300 * @param array $record
301 * @param integer $mountPoint
302 * @return \TYPO3\CMS\Backend\Tree\Pagetree\PagetreeNode
303 */
304 static public function getNewNode($record, $mountPoint = 0) {
305 if (self::$titleLength === NULL) {
306 self::$useNavTitle = $GLOBALS['BE_USER']->getTSConfigVal('options.pageTree.showNavTitle');
307 self::$addIdAsPrefix = $GLOBALS['BE_USER']->getTSConfigVal('options.pageTree.showPageIdWithTitle');
308 self::$addDomainName = $GLOBALS['BE_USER']->getTSConfigVal('options.pageTree.showDomainNameWithTitle');
309 self::$backgroundColors = $GLOBALS['BE_USER']->getTSConfigProp('options.pageTree.backgroundColor');
310 self::$titleLength = intval($GLOBALS['BE_USER']->uc['titleLen']);
311 }
312 /** @var $subNode \TYPO3\CMS\Backend\Tree\Pagetree\PagetreeNode */
313 $subNode = GeneralUtility::makeInstance('TYPO3\\CMS\\Backend\\Tree\\Pagetree\\PagetreeNode');
314 $subNode->setRecord($record);
315 $subNode->setCls($record['_CSSCLASS']);
316 $subNode->setType('pages');
317 $subNode->setId($record['uid']);
318 $subNode->setMountPoint($mountPoint);
319 $subNode->setWorkspaceId($record['_ORIG_uid'] ? $record['_ORIG_uid'] : $record['uid']);
320 $subNode->setBackgroundColor(self::$backgroundColors[$record['uid']]);
321 $field = 'title';
322 $text = $record['title'];
323 if (self::$useNavTitle && trim($record['nav_title']) !== '') {
324 $field = 'nav_title';
325 $text = $record['nav_title'];
326 }
327 if (trim($text) === '') {
328 $visibleText = '[' . $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.xlf:labels.no_title', TRUE) . ']';
329 } else {
330 $visibleText = $text;
331 }
332 $visibleText = GeneralUtility::fixed_lgd_cs($visibleText, self::$titleLength);
333 $suffix = '';
334 if (self::$addDomainName) {
335 $domain = self::getDomainName($record['uid']);
336 $suffix = $domain !== '' ? ' [' . $domain . ']' : '';
337 }
338 $qtip = str_replace(' - ', '<br />', htmlspecialchars(BackendUtility::titleAttribForPages($record, '', FALSE)));
339 $prefix = '';
340 $lockInfo = BackendUtility::isRecordLocked('pages', $record['uid']);
341 if (is_array($lockInfo)) {
342 $qtip .= '<br />' . htmlspecialchars($lockInfo['msg']);
343 $prefix .= IconUtility::getSpriteIcon('status-warning-in-use', array(
344 'class' => 'typo3-pagetree-status'
345 ));
346 }
347 // Call stats information hook
348 $stat = '';
349 if (is_array($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['GLOBAL']['recStatInfoHooks'])) {
350 $_params = array('pages', $record['uid']);
351 $fakeThis = NULL;
352 foreach ($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['GLOBAL']['recStatInfoHooks'] as $_funcRef) {
353 $stat .= GeneralUtility::callUserFunction($_funcRef, $_params, $fakeThis);
354 }
355 }
356 $prefix .= htmlspecialchars(self::$addIdAsPrefix ? '[' . $record['uid'] . '] ' : '');
357 $subNode->setEditableText($text);
358 $subNode->setText(htmlspecialchars($visibleText), $field, $prefix, htmlspecialchars($suffix) . $stat);
359 $subNode->setQTip($qtip);
360 if ($record['uid'] !== 0) {
361 $spriteIconCode = IconUtility::getSpriteIconForRecord('pages', $record);
362 } else {
363 $spriteIconCode = IconUtility::getSpriteIcon('apps-pagetree-root');
364 }
365 $subNode->setSpriteIconCode($spriteIconCode);
366 if (!$subNode->canCreateNewPages() || intval($record['t3ver_state']) === 2) {
367 $subNode->setIsDropTarget(FALSE);
368 }
369 if (!$subNode->canBeEdited() || !$subNode->canBeRemoved() || intval($record['t3ver_state']) === 2) {
370 $subNode->setDraggable(FALSE);
371 }
372 return $subNode;
373 }
374
375 }
376
377
378 ?>