[BUGFIX] Caching framework: Reduce code duplication in db backend
[Packages/TYPO3.CMS.git] / t3lib / class.t3lib_foldertree.php
1 <?php
2 /***************************************************************
3 * Copyright notice
4 *
5 * (c) 1999-2011 Kasper Skårhøj (kasperYYYY@typo3.com)
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 * Generate a folder tree
29 *
30 * Revised for TYPO3 3.6 November/2003 by Kasper Skårhøj
31 *
32 * @author Kasper Skårhøj <kasperYYYY@typo3.com>
33 * @coauthor René Fritz <r.fritz@colorcube.de>
34 */
35 /**
36 * [CLASS/FUNCTION INDEX of SCRIPT]
37 *
38 *
39 *
40 * 82: class t3lib_folderTree extends t3lib_treeView
41 * 89: function t3lib_folderTree()
42 * 107: function wrapIcon($icon,$row)
43 * 130: function wrapTitle($title,$row,$bank=0)
44 * 145: function getId($v)
45 * 155: function getJumpToParam($v)
46 * 167: function getTitleStr($row,$titleLen=30)
47 * 177: function getBrowsableTree()
48 * 240: function getFolderTree($files_path, $depth=999, $depthData='')
49 * 320: function getCount($files_path)
50 * 336: function initializePositionSaving()
51 *
52 * TOTAL FUNCTIONS: 10
53 * (This index is automatically created/updated by the extension "extdeveval")
54 *
55 */
56
57
58 /**
59 * Extension class for the t3lib_treeView class, specially made for browsing folders in the File module
60 *
61 * @author Kasper Skårhøj <kasperYYYY@typo3.com>
62 * @coauthor René Fritz <r.fritz@colorcube.de>
63 * @package TYPO3
64 * @subpackage t3lib
65 * @see class t3lib_treeView
66 */
67 class t3lib_folderTree extends t3lib_treeView {
68
69 /**
70 * Constructor function of the class
71 *
72 * @return void
73 */
74 function __construct() {
75 parent::init();
76
77 $this->MOUNTS = $GLOBALS['FILEMOUNTS'];
78
79 $this->treeName = 'folder';
80 $this->titleAttrib = ''; //don't apply any title
81 $this->domIdPrefix = 'folder';
82 }
83
84 /**
85 * Wrapping the folder icon
86 *
87 * @param string The image tag for the icon
88 * @param array The row for the current element
89 * @return string The processed icon input value.
90 * @access private
91 */
92 function wrapIcon($icon, $row) {
93 // Add title attribute to input icon tag
94 $theFolderIcon = $this->addTagAttributes($icon, ($this->titleAttrib ? $this->titleAttrib . '="' . $this->getTitleAttrib($row) . '"' : ''));
95
96 // Wrap icon in click-menu link.
97 if (!$this->ext_IconMode) {
98 $theFolderIcon = $GLOBALS['TBE_TEMPLATE']->wrapClickMenuOnIcon($theFolderIcon, $row['path'], '', 0);
99 } elseif (!strcmp($this->ext_IconMode, 'titlelink')) {
100 $aOnClick = 'return jumpTo(\'' . $this->getJumpToParam($row) . '\',this,\'' . $this->domIdPrefix . $this->getId($row) . '\',' . $this->bank . ');';
101 $theFolderIcon = '<a href="#" onclick="' . htmlspecialchars($aOnClick) . '">' . $theFolderIcon . '</a>';
102 }
103 return $theFolderIcon;
104 }
105
106 /**
107 * Wrapping $title in a-tags.
108 *
109 * @param string Title string
110 * @param string Item record
111 * @param integer Bank pointer (which mount point number)
112 * @return string
113 * @access private
114 */
115 function wrapTitle($title, $row, $bank = 0) {
116 $aOnClick = 'return jumpTo(\'' . $this->getJumpToParam($row) . '\',this,\'' . $this->domIdPrefix . $this->getId($row) . '\',' . $bank . ');';
117 $CSM = '';
118 if ($GLOBALS['TYPO3_CONF_VARS']['BE']['useOnContextMenuHandler']) {
119 $CSM = ' oncontextmenu="' . htmlspecialchars($GLOBALS['TBE_TEMPLATE']->wrapClickMenuOnIcon('', $row['path'], '', 0, '', '', TRUE)) . '"';
120 }
121 return '<a href="#" title="' . htmlspecialchars($row['title']) . '" onclick="' . htmlspecialchars($aOnClick) . '"' . $CSM . '>' . $title . '</a>';
122 }
123
124 /**
125 * Returns the id from the record - for folders, this is an md5 hash.
126 *
127 * @param array Record array
128 * @return integer The "uid" field value.
129 */
130 function getId($v) {
131 return t3lib_div::md5Int($v['path']);
132 }
133
134 /**
135 * Returns jump-url parameter value.
136 *
137 * @param array The record array.
138 * @return string The jump-url parameter.
139 */
140 function getJumpToParam($v) {
141 return rawurlencode($v['path']);
142 }
143
144 /**
145 * Returns the title for the input record. If blank, a "no title" labele (localized) will be returned.
146 * '_title' is used for setting an alternative title for folders.
147 *
148 * @param array The input row array (where the key "_title" is used for the title)
149 * @param integer Title length (30)
150 * @return string The title.
151 */
152 function getTitleStr($row, $titleLen = 30) {
153 return $row['_title'] ? $row['_title'] : parent::getTitleStr($row, $titleLen);
154 }
155
156 /**
157 * Will create and return the HTML code for a browsable tree of folders.
158 * Is based on the mounts found in the internal array ->MOUNTS (set in the constructor)
159 *
160 * @return string HTML code for the browsable tree
161 */
162 function getBrowsableTree() {
163
164 // Get stored tree structure AND updating it if needed according to incoming PM GET var.
165 $this->initializePositionSaving();
166
167 // Init done:
168 $titleLen = intval($this->BE_USER->uc['titleLen']);
169 $treeArr = array();
170
171 // Traverse mounts:
172 foreach ($this->MOUNTS as $key => $val) {
173 $md5_uid = md5($val['path']);
174 $specUID = hexdec(substr($md5_uid, 0, 6));
175 $this->specUIDmap[$specUID] = $val['path'];
176
177 // Set first:
178 $this->bank = $val['nkey'];
179 $isOpen = $this->stored[$val['nkey']][$specUID] || $this->expandFirst;
180 $this->reset();
181
182 // Set PM icon:
183 $cmd = $this->bank . '_' . ($isOpen ? '0_' : '1_') . $specUID . '_' . $this->treeName;
184 $icon = '<img' . t3lib_iconWorks::skinImg($this->backPath, 'gfx/ol/' . ($isOpen ? 'minus' : 'plus') . 'only.gif', 'width="18" height="16"') . ' alt="" />';
185 $firstHtml = $this->PM_ATagWrap($icon, $cmd);
186
187 switch ($val['type']) {
188 case 'user':
189 $icon = 'gfx/i/_icon_ftp_user.gif';
190 break;
191 case 'group':
192 $icon = 'gfx/i/_icon_ftp_group.gif';
193 break;
194 case 'readonly':
195 $icon = 'gfx/i/_icon_ftp_readonly.gif';
196 break;
197 default:
198 $icon = 'gfx/i/_icon_ftp.gif';
199 break;
200 }
201
202 // Preparing rootRec for the mount
203 $firstHtml .= $this->wrapIcon('<img' . t3lib_iconWorks::skinImg($this->backPath, $icon, 'width="18" height="16"') . ' alt="" />', $val);
204 $row = array();
205 $row['path'] = $val['path'];
206 $row['uid'] = $specUID;
207 $row['title'] = $val['name'];
208
209 // Add the root of the mount to ->tree
210 $this->tree[] = array('HTML' => $firstHtml, 'row' => $row, 'bank' => $this->bank);
211
212 // If the mount is expanded, go down:
213 if ($isOpen) {
214 // Set depth:
215 $depthD = '<img' . t3lib_iconWorks::skinImg($this->backPath, 'gfx/ol/blank.gif', 'width="18" height="16"') . ' alt="" />';
216 $this->getFolderTree($val['path'], 999, $depthD, $val['type']);
217 }
218
219 // Add tree:
220 $treeArr = array_merge($treeArr, $this->tree);
221 }
222 return $this->printTree($treeArr);
223 }
224
225 /**
226 * Fetches the data for the tree
227 *
228 * @param string Abs file path
229 * @param integer Max depth (recursivity limit)
230 * @param string HTML-code prefix for recursive calls.
231 * @return integer The count of items on the level
232 * @see getBrowsableTree()
233 */
234 function getFolderTree($files_path, $depth = 999, $depthData = '', $type = '') {
235
236 // This generates the directory tree
237 $dirs = t3lib_div::get_dirs($files_path);
238
239 $c = 0;
240 if (is_array($dirs)) {
241 $depth = intval($depth);
242 $HTML = '';
243 $a = 0;
244 $c = count($dirs);
245 sort($dirs);
246
247 foreach ($dirs as $key => $val) {
248 $a++;
249 $this->tree[] = array(); // Reserve space.
250 end($this->tree);
251 $treeKey = key($this->tree); // Get the key for this space
252 $LN = ($a == $c) ? 'blank' : 'line';
253
254 $val = preg_replace('/^\.\//', '', $val);
255 $title = $val;
256 $path = $files_path . $val . '/';
257 $webpath = t3lib_BEfunc::getPathType_web_nonweb($path);
258
259 $md5_uid = md5($path);
260 $specUID = hexdec(substr($md5_uid, 0, 6));
261 $this->specUIDmap[$specUID] = $path;
262 $row = array();
263 $row['path'] = $path;
264 $row['uid'] = $specUID;
265 $row['title'] = $title;
266
267 if ($depth > 1 && $this->expandNext($specUID)) {
268 $nextCount = $this->getFolderTree(
269 $path,
270 $depth - 1,
271 $this->makeHTML ? $depthData . '<img' . t3lib_iconWorks::skinImg($this->backPath, 'gfx/ol/' . $LN . '.gif', 'width="18" height="16"') . ' alt="" />' : '',
272 $type
273 );
274 $exp = 1; // Set "did expand" flag
275 } else {
276 $nextCount = $this->getCount($path);
277 $exp = 0; // Clear "did expand" flag
278 }
279
280 // Set HTML-icons, if any:
281 if ($this->makeHTML) {
282 $HTML = $depthData . $this->PMicon($row, $a, $c, $nextCount, $exp);
283
284 $icon = 'gfx/i/_icon_' . $webpath . 'folders' . ($type == 'readonly' ? '_ro' : '') . '.gif';
285 if ($val == '_temp_') {
286 $icon = 'gfx/i/sysf.gif';
287 $row['title'] = $GLOBALS['LANG']->sl('LLL:EXT:lang/locallang_mod_file_list.xml:temp', TRUE);
288 $row['_title'] = '<strong>' . $GLOBALS['LANG']->sl('LLL:EXT:lang/locallang_mod_file_list.xml:temp', TRUE) . '</strong>';
289 }
290 if ($val == '_recycler_') {
291 $icon = 'gfx/i/recycler.gif';
292 $row['title'] = $GLOBALS['LANG']->sl('LLL:EXT:lang/locallang_mod_file_list.xml:recycler', TRUE);
293 $row['_title'] = '<strong>' . $GLOBALS['LANG']->sl('LLL:EXT:lang/locallang_mod_file_list.xml:recycler', TRUE) . '</strong>';
294 }
295 $HTML .= $this->wrapIcon('<img' . t3lib_iconWorks::skinImg($this->backPath, $icon, 'width="18" height="16"') . ' alt="" />', $row);
296 }
297
298 // Finally, add the row/HTML content to the ->tree array in the reserved key.
299 $this->tree[$treeKey] = Array(
300 'row' => $row,
301 'HTML' => $HTML,
302 'bank' => $this->bank
303 );
304 }
305 }
306 return $c;
307 }
308
309 /**
310 * Counts the number of directories in a file path.
311 *
312 * @param string File path.
313 * @return integer
314 */
315 function getCount($files_path) {
316 // This generates the directory tree
317 $dirs = t3lib_div::get_dirs($files_path);
318 $c = 0;
319 if (is_array($dirs)) {
320 $c = count($dirs);
321 }
322 return $c;
323 }
324
325 /**
326 * Get stored tree structure AND updating it if needed according to incoming PM GET var.
327 *
328 * @return void
329 * @access private
330 */
331 function initializePositionSaving() {
332 // Get stored tree structure:
333 $this->stored = unserialize($this->BE_USER->uc['browseTrees'][$this->treeName]);
334
335 // Mapping md5-hash to shorter number:
336 $hashMap = array();
337 foreach ($this->MOUNTS as $key => $val) {
338 $nkey = hexdec(substr($key, 0, 4));
339 $hashMap[$nkey] = $key;
340 $this->MOUNTS[$key]['nkey'] = $nkey;
341 }
342
343 // PM action:
344 // (If an plus/minus icon has been clicked, the PM GET var is sent and we must update the stored positions in the tree):
345 $PM = explode('_', t3lib_div::_GP('PM')); // 0: mount key, 1: set/clear boolean, 2: item ID (cannot contain "_"), 3: treeName
346 if (count($PM) == 4 && $PM[3] == $this->treeName) {
347 if (isset($this->MOUNTS[$hashMap[$PM[0]]])) {
348 if ($PM[1]) { // set
349 $this->stored[$PM[0]][$PM[2]] = 1;
350 $this->savePosition($this->treeName);
351 } else { // clear
352 unset($this->stored[$PM[0]][$PM[2]]);
353 $this->savePosition($this->treeName);
354 }
355 }
356 }
357 }
358 }
359
360 if (defined('TYPO3_MODE') && isset($GLOBALS['TYPO3_CONF_VARS'][TYPO3_MODE]['XCLASS']['t3lib/class.t3lib_foldertree.php'])) {
361 include_once($GLOBALS['TYPO3_CONF_VARS'][TYPO3_MODE]['XCLASS']['t3lib/class.t3lib_foldertree.php']);
362 }
363
364 ?>