6db4562dca1d2ba885ec5d047a5fdeb07fb05319
[Packages/TYPO3.CMS.git] / t3lib / tree / pagetree / class.t3lib_tree_pagetree_dataprovider.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 * Abstract Tree Data Provider
30 *
31 * @author Stefan Galinski <stefan.galinski@gmail.com>
32 * @package TYPO3
33 * @subpackage t3lib
34 */
35 class t3lib_tree_pagetree_DataProvider extends t3lib_tree_AbstractDataProvider {
36 /**
37 * Node limit that should be loaded for this request per mount
38 *
39 * @var int
40 */
41 protected $nodeLimit = 500;
42
43 /**
44 * Current amount of nodes
45 *
46 * @var int
47 */
48 protected $nodeCounter = 0;
49
50 /**
51 * Hidden Records
52 *
53 * @var array
54 */
55 protected $hiddenRecords = array();
56
57 /**
58 * Constructor
59 */
60 public function __construct() {
61 $this->hiddenRecords = t3lib_div::trimExplode(
62 ',',
63 $GLOBALS['BE_USER']->getTSConfigVal('options.hideRecords.pages')
64 );
65 }
66
67 /**
68 * Returns the root node
69 *
70 * @return t3lib_tree_Node
71 */
72 public function getRoot() {
73 /** @var $node t3lib_tree_pagetree_Node */
74 $node = t3lib_div::makeInstance('t3lib_tree_pagetree_Node');
75 $node->setId('root');
76 $node->setExpanded(true);
77
78 return $node;
79 }
80
81 /**
82 * Fetches the sub-nodes of the given node
83 *
84 * @param t3lib_tree_Node $node
85 * @param int $mountPoint
86 * @param int $level internally used variable as a recursion limiter
87 * @return t3lib_tree_NodeCollection
88 */
89 public function getNodes(t3lib_tree_Node $node, $mountPoint = 0, $level = 0) {
90 /** @var $nodeCollection t3lib_tree_pagetree_NodeCollection */
91 $nodeCollection = t3lib_div::makeInstance('t3lib_tree_pagetree_NodeCollection');
92 if ($level >= 99) {
93 return $nodeCollection;
94 }
95
96 $subpages = $this->getSubpages($node->getId());
97 if (!is_array($subpages) || !count($subpages)) {
98 return $nodeCollection;
99 }
100
101 foreach ($subpages as $subpage) {
102 if (in_array($subpage['uid'], $this->hiddenRecords)) {
103 continue;
104 }
105
106 $subpage = t3lib_befunc::getRecordWSOL('pages', $subpage['uid'], '*', '', TRUE, TRUE);
107 if (!$subpage) {
108 continue;
109 }
110
111 $subNode = t3lib_tree_pagetree_Commands::getNewNode($subpage, $mountPoint);
112 if ($this->nodeCounter < $this->nodeLimit) {
113 $childNodes = $this->getNodes($subNode, $mountPoint, $level + 1);
114 $subNode->setChildNodes($childNodes);
115 $this->nodeCounter += $childNodes->count();
116 } else {
117 $subNode->setLeaf(!$this->hasNodeSubPages($subNode->getId()));
118 }
119
120 $nodeCollection->append($subNode);
121 }
122
123 return $nodeCollection;
124 }
125
126 /**
127 * Returns a node collection of filtered nodes
128 *
129 * @param t3lib_tree_Node $node
130 * @param string $searchFilter
131 * @param int $mountPoint
132 * @return void
133 */
134 public function getFilteredNodes(t3lib_tree_Node $node, $searchFilter, $mountPoint = 0) {
135 /** @var $nodeCollection t3lib_tree_pagetree_NodeCollection */
136 $nodeCollection = t3lib_div::makeInstance('t3lib_tree_pagetree_NodeCollection');
137
138 $records = $this->getSubpages(-1, $searchFilter);
139 if (!is_array($records) || !count($records)) {
140 return $nodeCollection;
141 }
142
143 $isNumericSearchFilter = (is_numeric($searchFilter) && $searchFilter > 0);
144 $nodeId = intval($node->getId());
145 foreach ($records as $record) {
146 $record = t3lib_tree_pagetree_Commands::getNodeRecord($record['uid']);
147 if (intval($record['pid']) === -1 || in_array($record['uid'], $this->hiddenRecords)) {
148 continue;
149 }
150
151 $rootline = t3lib_BEfunc::BEgetRootLine($record['uid'], ' AND uid != ' . $nodeId);
152 $rootline = array_reverse($rootline);
153 if ($nodeId === 0) {
154 array_shift($rootline);
155 }
156 $reference = $nodeCollection;
157
158 $inFilteredRootline = FALSE;
159 $amountOfRootlineElements = count($rootline);
160 for ($i = 0; $i < $amountOfRootlineElements; ++$i) {
161 $rootlineElement = $rootline[$i];
162 if (intval($rootlineElement['pid']) === $nodeId) {
163 $inFilteredRootline = TRUE;
164 }
165
166 if (!$inFilteredRootline) {
167 continue;
168 }
169
170 $rootlineElement = t3lib_tree_pagetree_Commands::getNodeRecord($rootlineElement['uid']);
171 $ident = intval($rootlineElement['sorting']) . intval($rootlineElement['uid']);
172 if ($reference->offsetExists($ident)) {
173 /** @var $refNode t3lib_tree_pagetree_Node */
174 $refNode = $reference->offsetGet($ident);
175 $refNode->setExpanded(TRUE);
176 $refNode->setLeaf(FALSE);
177
178 $reference = $refNode->getChildNodes();
179 continue;
180 }
181
182 $refNode = t3lib_tree_pagetree_Commands::getNewNode($rootlineElement, $mountPoint);
183 $replacement = '<span class="typo3-pagetree-filteringTree-highlight">$1</span>';
184 if ($isNumericSearchFilter && intval($rootlineElement['uid']) === intval($searchFilter)) {
185 $text = str_replace('$1', $refNode->getText(), $replacement);
186 } else {
187 $text = preg_replace('/(' . $searchFilter . ')/i', $replacement, $refNode->getText());
188 }
189
190 $refNode->setText(
191 $text,
192 $refNode->getTextSourceField(),
193 $refNode->getPrefix(),
194 $refNode->getSuffix()
195 );
196
197 /** @var $childCollection t3lib_tree_pagetree_NodeCollection */
198 $childCollection = t3lib_div::makeInstance('t3lib_tree_pagetree_NodeCollection');
199
200 if (($i +1) >= $amountOfRootlineElements) {
201 $childNodes = $this->getNodes($refNode, $mountPoint);
202 foreach ($childNodes as $childNode) {
203 /** @var $childNode t3lib_tree_pagetree_Node */
204 $childRecord = $childNode->getRecord();
205 $childIdent = intval($childRecord['sorting']) . intval($childRecord['uid']);
206 $childCollection->offsetSet($childIdent, $childNode);
207 }
208 $refNode->setChildNodes($childNodes);
209 }
210
211 $refNode->setChildNodes($childCollection);
212 $reference->offsetSet($ident, $refNode);
213 $reference->ksort();
214
215 $reference = $childCollection;
216 }
217 }
218
219 return $nodeCollection;
220 }
221
222 /**
223 * Returns the page tree mounts for the current user
224 *
225 * Note: If you add the search filter parameter, the nodes will be filtered by this string.
226 *
227 * @param string $searchFilter
228 * @return array
229 */
230 public function getTreeMounts($searchFilter = '') {
231 /** @var $nodeCollection t3lib_tree_pagetree_NodeCollection */
232 $nodeCollection = t3lib_div::makeInstance('t3lib_tree_pagetree_NodeCollection');
233
234 $isTemporaryMountPoint = FALSE;
235 $mountPoints = intval($GLOBALS['BE_USER']->uc['pageTree_temporaryMountPoint']);
236 if (!$mountPoints) {
237 $mountPoints = array_map('intval', $GLOBALS['BE_USER']->returnWebmounts());
238 $mountPoints = array_unique($mountPoints);
239 } else {
240 $isTemporaryMountPoint = TRUE;
241 $mountPoints = array($mountPoints);
242 }
243
244 if (!count($mountPoints)) {
245 return $nodeCollection;
246 }
247
248 $showRootlineAboveMounts = $GLOBALS['BE_USER']->getTSConfigVal('options.pageTree.showPathAboveMounts');
249 $class = (count($mountPoints) <= 1 ? 'typo3-pagetree-node-notExpandable' : '');
250 foreach ($mountPoints as $mountPoint) {
251 if ($mountPoint === 0) {
252 $sitename = 'TYPO3';
253 if ($GLOBALS['TYPO3_CONF_VARS']['SYS']['sitename'] !== '') {
254 $sitename = $GLOBALS['TYPO3_CONF_VARS']['SYS']['sitename'];
255 }
256
257 $record = array(
258 'uid' => 0,
259 'title' => $sitename,
260 );
261 $subNode = t3lib_tree_pagetree_Commands::getNewNode($record);
262 $subNode->setLabelIsEditable(FALSE);
263 $subNode->setType('pages_root');
264 } else {
265 $record = t3lib_BEfunc::getRecordWSOL('pages', $mountPoint, '*', '', TRUE);
266 if (!$record) {
267 continue;
268 }
269
270 $subNode = t3lib_tree_pagetree_Commands::getNewNode($record, $mountPoint);
271 if ($showRootlineAboveMounts && !$isTemporaryMountPoint) {
272 $rootline = t3lib_tree_pagetree_Commands::getMountPointPath($record['uid']);
273 $subNode->setReadableRootline($rootline);
274 }
275 }
276
277 $subNode->setIsMountPoint(TRUE);
278 $subNode->setExpanded(TRUE);
279 $subNode->setDraggable(FALSE);
280 $subNode->setIsDropTarget(FALSE);
281 $subNode->setCls($class);
282
283 if ($searchFilter === '') {
284 $childNodes = $this->getNodes($subNode, $mountPoint);
285 } else {
286 $childNodes = $this->getFilteredNodes($subNode, $searchFilter, $mountPoint);
287 $subNode->setExpanded(TRUE);
288 }
289
290 $subNode->setChildNodes($childNodes);
291 $nodeCollection->append($subNode);
292 }
293
294 return $nodeCollection;
295 }
296
297 /**
298 * Returns the where clause for fetching pages
299 *
300 * @param int $id
301 * @param string $searchFilter
302 * @return string
303 */
304 protected function getWhereClause($id, $searchFilter = '') {
305 $where = $GLOBALS['BE_USER']->getPagePermsClause(1) .
306 t3lib_BEfunc::deleteClause('pages') .
307 t3lib_BEfunc::versioningPlaceholderClause('pages');
308
309 if (is_numeric($id) && $id >= 0) {
310 $where .= ' AND pid= ' . $GLOBALS['TYPO3_DB']->fullQuoteStr(intval($id), 'pages');
311 }
312
313 if ($searchFilter !== '') {
314 if (is_numeric($searchFilter) && $searchFilter > 0) {
315 $seachWhere .= 'uid = ' . intval($searchFilter) . ' OR ';
316 }
317
318 $searchFilter = $GLOBALS['TYPO3_DB']->fullQuoteStr('%' . $searchFilter . '%', 'pages');
319 $useNavTitle = $GLOBALS['BE_USER']->getTSConfigVal('options.pageTree.showNavTitle');
320
321 if ($useNavTitle) {
322 $seachWhere .= '(nav_title LIKE ' . $searchFilter .
323 ' OR (nav_title = "" && title LIKE ' . $searchFilter . '))';
324 } else {
325 $seachWhere .= 'title LIKE ' . $searchFilter;
326 }
327
328 $where .= ' AND (' . $seachWhere . ')';
329 }
330
331 return $where;
332 }
333
334 /**
335 * Returns all sub-pages of a given id
336 *
337 * @param int $id
338 * @param string $searchFilter
339 * @return array
340 */
341 protected function getSubpages($id, $searchFilter = '') {
342 $where = $this->getWhereClause($id, $searchFilter);
343 $subpages = $GLOBALS['TYPO3_DB']->exec_SELECTgetRows(
344 'uid', 'pages', $where, '', 'sorting', '', 'uid'
345 );
346
347 return $subpages;
348 }
349
350 /**
351 * Returns true if the node has child's
352 *
353 * @param int $id
354 * @return bool
355 */
356 protected function hasNodeSubPages($id) {
357 $where = $this->getWhereClause($id);
358 $subpage = $GLOBALS['TYPO3_DB']->exec_SELECTgetSingleRow(
359 'uid', 'pages', $where, '', 'sorting', '', 'uid'
360 );
361
362 $returnValue = TRUE;
363 if (!$subpage['uid']) {
364 $returnValue = FALSE;
365 }
366
367 return $returnValue;
368 }
369 }
370
371 if (defined('TYPO3_MODE') && isset($GLOBALS['TYPO3_CONF_VARS'][TYPO3_MODE]['XCLASS']['t3lib/tree/pagetree/class.t3lib_tree_pagetree_dataprovider.php'])) {
372 include_once($GLOBALS['TYPO3_CONF_VARS'][TYPO3_MODE]['XCLASS']['t3lib/tree/pagetree/class.t3lib_tree_pagetree_dataprovider.php']);
373 }
374
375 ?>