Merged new PageTree (version for TYPO3 4.5 Beta 3)
[Packages/TYPO3.CMS.git] / typo3 / sysext / pagetree / classes / class.tx_pagetree_dataprovider.php
1 <?php
2 /***************************************************************
3 * Copyright notice
4 *
5 * (c) 2010 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 tx_pagetree
34 */
35 class tx_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 * Returns the root node
52 *
53 * @return t3lib_tree_Node
54 */
55 public function getRoot() {
56 /** @var $node tx_pagetree_Node */
57 $node = t3lib_div::makeInstance('tx_pagetree_Node');
58 $node->setId('root');
59 $node->setExpanded(true);
60
61 return $node;
62 }
63
64 /**
65 * Fetches the sub-nodes of the given node
66 *
67 * @param t3lib_tree_Node $node
68 * @param int $mountPoint
69 * @param int $level internally used variable as a recursion limiter
70 * @return t3lib_tree_NodeCollection
71 */
72 public function getNodes(t3lib_tree_Node $node, $mountPoint = 0, $level = 0) {
73 /** @var $nodeCollection tx_pagetree_NodeCollection */
74 $nodeCollection = t3lib_div::makeInstance('tx_pagetree_NodeCollection');
75 if ($level >= 99) {
76 return $nodeCollection;
77 }
78
79 $subpages = $this->getSubpages($node->getId());
80 if (!is_array($subpages) || !count($subpages)) {
81 return $nodeCollection;
82 }
83
84 foreach ($subpages as $subpage) {
85 $subpage = t3lib_befunc::getRecordWSOL('pages', $subpage['uid'], '*', '', TRUE, TRUE);
86 if (!$subpage) {
87 continue;
88 }
89
90 $subNode = tx_pagetree_Commands::getNewNode($subpage, $mountPoint);
91 if ($this->nodeCounter < $this->nodeLimit) {
92 $childNodes = $this->getNodes($subNode, $mountPoint, $level + 1);
93 $subNode->setChildNodes($childNodes);
94 $this->nodeCounter += $childNodes->count();
95 } else {
96 $subNode->setLeaf(!$this->hasNodeSubPages($subNode->getId()));
97 }
98
99 $nodeCollection->append($subNode);
100 }
101
102 return $nodeCollection;
103 }
104
105 /**
106 * Returns a node collection of filtered nodes
107 *
108 * @param int $nodeId
109 * @param string $searchFilter
110 * @param int $mountPoint
111 * @return void
112 */
113 public function getFilteredNodes($nodeId, $searchFilter, $mountPoint = 0) {
114 $nodeId = intval($nodeId);
115
116 /** @var $nodeCollection tx_pagetree_NodeCollection */
117 $nodeCollection = t3lib_div::makeInstance('tx_pagetree_NodeCollection');
118
119 $subpages = $this->getSubpages(-1, $searchFilter);
120 if (!is_array($subpages) || !count($subpages)) {
121 return $nodeCollection;
122 }
123
124 foreach ($subpages as $subpage) {
125 $rootline = array_reverse(t3lib_BEfunc::BEgetRootLine($subpage['uid']));
126 array_shift($rootline);
127 $reference = $nodeCollection;
128
129 $inFilteredRootline = FALSE;
130 foreach ($rootline as $rootlineElement) {
131 if (intval($rootlineElement['pid']) === $nodeId) {
132 $inFilteredRootline = TRUE;
133 }
134
135 if (!$inFilteredRootline) {
136 continue;
137 }
138
139 $rootlineElement = tx_pagetree_Commands::getNodeRecord($rootlineElement['uid']);
140 if ($reference->offsetExists($rootlineElement['uid'])) {
141 /** @var $node tx_pagetree_Node */
142 $node = $reference->offsetGet($rootlineElement['uid']);
143 $node->setExpanded(TRUE);
144 $node->setLeaf(FALSE);
145
146 $reference = $node->getChildNodes();
147 continue;
148 }
149
150 /** @var $childCollection tx_pagetree_NodeCollection */
151 $childCollection = t3lib_div::makeInstance('tx_pagetree_NodeCollection');
152
153 $node = tx_pagetree_Commands::getNewNode($rootlineElement, $mountPoint);
154 $node->setChildNodes($childCollection);
155
156 $text = preg_replace(
157 '/(' . $searchFilter . ')/i',
158 '<span class="typo3-pagetree-filteringTree-highlight">$1</span>',
159 $node->getText()
160 );
161 $node->setText($text, $node->getTextSourceField(), $node->getPrefix());
162
163 $reference->offsetSet($rootlineElement['uid'], $node);
164 $reference = $childCollection;
165 }
166 }
167
168 return $nodeCollection;
169 }
170
171 /**
172 * Returns the page tree mounts for the current user
173 *
174 * Note: If you add the search filter parameter, the nodes will be filtered by this string.
175 *
176 * @param string $searchFilter
177 * @return array
178 */
179 public function getTreeMounts($searchFilter = '') {
180 /** @var $nodeCollection tx_pagetree_NodeCollection */
181 $nodeCollection = t3lib_div::makeInstance('tx_pagetree_NodeCollection');
182
183 $isTemporaryMountPoint = FALSE;
184 $webmountIds = intval($GLOBALS['BE_USER']->uc['pageTree_temporaryMountPoint']);
185 if (!$webmountIds) {
186 $webmountIds = array_map('intval', $GLOBALS['BE_USER']->returnWebmounts());
187 $webmountIds = array_unique($webmountIds);
188 } else {
189 $isTemporaryMountPoint = TRUE;
190 $webmountIds = array($webmountIds);
191 }
192
193 if (!count($webmountIds)) {
194 return $nodeCollection;
195 }
196
197 $class = (count($webmountIds) <= 1 ? 'typo3-pagetree-node-notExpandable' : '');
198 foreach ($webmountIds as $webmount) {
199 if ($webmount === 0) {
200 $sitename = 'TYPO3';
201 if ($GLOBALS['TYPO3_CONF_VARS']['SYS']['sitename'] !== '') {
202 $sitename = $GLOBALS['TYPO3_CONF_VARS']['SYS']['sitename'];
203 }
204
205 $record = array(
206 'uid' => 0,
207 'title' => $sitename,
208 );
209 $subNode = tx_pagetree_Commands::getNewNode($record);
210 $subNode->setLabelIsEditable(FALSE);
211 } else {
212 $record = t3lib_BEfunc::getRecordWSOL('pages', $webmount, '*', '', TRUE);
213 if (!$record) {
214 continue;
215 }
216
217 $subNode = tx_pagetree_Commands::getNewNode($record, $webmount);
218 }
219
220 if ($webmount === 0 || $isTemporaryMountPoint) {
221 $subNode->setType('pages_root');
222 }
223
224 $subNode->setExpanded(TRUE);
225 $subNode->setDraggable(FALSE);
226 $subNode->setIsDropTarget(FALSE);
227 $subNode->setCls($class);
228
229 if ($searchFilter === '') {
230 $childNodes = $this->getNodes($subNode, $webmount);
231 } else {
232 $childNodes = $this->getFilteredNodes(intval($record['uid']), $searchFilter, $webmount);
233 $subNode->setExpanded(TRUE);
234 }
235
236 $subNode->setChildNodes($childNodes);
237 $nodeCollection->append($subNode);
238 }
239
240 return $nodeCollection;
241 }
242
243 /**
244 * Returns the where clause for fetching pages
245 *
246 * @param int $id
247 * @param string $searchFilter
248 * @return string
249 */
250 protected function getWhereClause($id, $searchFilter = '') {
251 $where = $GLOBALS['BE_USER']->getPagePermsClause(1) .
252 t3lib_BEfunc::deleteClause('pages') .
253 t3lib_BEfunc::versioningPlaceholderClause('pages');
254
255 if (is_numeric($id) && $id >= 0) {
256 $where .= ' AND pid= ' . $GLOBALS['TYPO3_DB']->fullQuoteStr(intval($id), 'pages');
257 }
258
259 if ($searchFilter !== '') {
260 $searchFilter = $GLOBALS['TYPO3_DB']->fullQuoteStr('%' . $searchFilter . '%', 'pages');
261 $useNavTitle = $GLOBALS['BE_USER']->getTSConfigVal('options.pageTree.showNavTitle');
262
263 if ($useNavTitle) {
264 $where .= ' AND (nav_title LIKE ' . $searchFilter .
265 ' OR (nav_title = "" && title LIKE ' . $searchFilter . '))';
266 } else {
267 $where .= ' AND title LIKE ' . $searchFilter;
268 }
269 }
270
271 return $where;
272 }
273
274 /**
275 * Returns all sub-pages of a given id
276 *
277 * @param int $id
278 * @param string $searchFilter
279 * @return array
280 */
281 protected function getSubpages($id, $searchFilter = '') {
282 $where = $this->getWhereClause($id, $searchFilter);
283 $subpages = $GLOBALS['TYPO3_DB']->exec_SELECTgetRows(
284 'uid', 'pages', $where, '', 'sorting', '', 'uid'
285 );
286
287 return $subpages;
288 }
289
290 /**
291 * Returns true if the node has child's
292 *
293 * @param int $id
294 * @return bool
295 */
296 protected function hasNodeSubPages($id) {
297 $where = $this->getWhereClause($id);
298 $subpage = $GLOBALS['TYPO3_DB']->exec_SELECTgetSingleRow(
299 'uid', 'pages', $where, '', 'sorting', '', 'uid'
300 );
301
302 $returnValue = TRUE;
303 if (!$subpage['uid']) {
304 $returnValue = FALSE;
305 }
306
307 return $returnValue;
308 }
309 }
310
311 if (defined('TYPO3_MODE') && isset($GLOBALS['TYPO3_CONF_VARS'][TYPO3_MODE]['XCLASS']['typo3/sysext/pagetree/classes/class.tx_pagetree_dataprovider.php'])) {
312 include_once($GLOBALS['TYPO3_CONF_VARS'][TYPO3_MODE]['XCLASS']['typo3/sysext/pagetree/classes/class.tx_pagetree_dataprovider.php']);
313 }
314
315 ?>