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