[CLEANUP] \TYPO3\CMS\Lowlevel\Utility\ArrayBrowser
[Packages/TYPO3.CMS.git] / typo3 / sysext / lowlevel / Classes / Utility / ArrayBrowser.php
1 <?php
2 namespace TYPO3\CMS\Lowlevel\Utility;
3
4 /*
5 * This file is part of the TYPO3 CMS project.
6 *
7 * It is free software; you can redistribute it and/or modify it under
8 * the terms of the GNU General Public License, either version 2
9 * of the License, or any later version.
10 *
11 * For the full copyright and license information, please read the
12 * LICENSE.txt file that was distributed with this source code.
13 *
14 * The TYPO3 project - inspiring people to share!
15 */
16
17 use TYPO3\CMS\Backend\Utility\BackendUtility;
18 use TYPO3\CMS\Backend\Utility\IconUtility;
19 use TYPO3\CMS\Core\Utility\GeneralUtility;
20 use TYPO3\CMS\Core\Utility\MathUtility;
21
22 /**
23 * Class for displaying an array as a tree
24 * See the extension 'lowlevel' /config (Backend module 'Tools > Configuration')
25 *
26 * @author Kasper Skårhøj <kasperYYYY@typo3.com>
27 * @see \TYPO3\CMS\Lowlevel\Utility\ArrayBrowser::main()
28 */
29 class ArrayBrowser {
30
31 /**
32 * @var bool
33 */
34 public $expAll = FALSE;
35
36 /**
37 * If set, will expand all (depthKeys is obsolete then) (and no links are applied)
38 *
39 * @var bool
40 */
41 public $dontLinkVar = FALSE;
42
43 /**
44 * If set, the variable keys are not linked.
45 *
46 * @var array
47 */
48 public $depthKeys = array();
49
50 /**
51 * Array defining which keys to expand. Typically set from outside from some session
52 * variable - otherwise the array will collapse.
53 *
54 * @var array
55 */
56 public $searchKeys = array();
57
58 /**
59 * After calling the getSearchKeys function this array is populated with the
60 * key-positions in the array which contains values matching the search.
61 *
62 * @var int
63 */
64 public $fixedLgd = 1;
65
66 /**
67 * If set, the values are truncated with "..." appended if longer than a certain
68 * length.
69 *
70 * @var int
71 */
72 public $regexMode = 0;
73
74 /**
75 * If set, search for string with regex, otherwise stristr()
76 *
77 * @var bool
78 */
79 public $searchKeysToo = FALSE;
80
81 /**
82 * If set, array keys are subject to the search too.
83 *
84 * @var string
85 */
86 public $varName = '';
87
88 /**
89 * Set var name here if you want links to the variable name.
90 *
91 * Make browseable tree
92 * Before calling this function you may want to set some of the internal vars like
93 * depthKeys, regexMode and fixedLgd.
94 * For examples see \TYPO3\CMS\Lowlevel\Utility\ArrayBrowser::main()
95 *
96 * @param array $arr The array to display
97 * @param string $depth_in Key-position id. Build up during recursive calls - [key1].[key2].[key3] - an so on.
98 * @param string $depthData Depth-data - basically a prefix for the icons. For calling this function from outside, let it stay blank.
99 * @return string HTML for the tree
100 * @see \TYPO3\CMS\Lowlevel\Utility\ArrayBrowser::main()
101 */
102 public function tree($arr, $depth_in, $depthData) {
103 $HTML = '';
104 $a = 0;
105 if ($depth_in) {
106 $depth_in = $depth_in . '.';
107 }
108 $c = count($arr);
109 foreach ($arr as $key => $value) {
110 $a++;
111 $depth = $depth_in . $key;
112 $goto = 'a' . substr(md5($depth), 0, 6);
113 if (is_object($value) && !$value instanceof \Traversable) {
114 $value = (array)$value;
115 }
116 $isArray = is_array($value) || $value instanceof \Traversable;
117 $deeper = $isArray && ($this->depthKeys[$depth] || $this->expAll);
118 $LN = $a == $c ? 'blank' : 'line';
119 $BTM = $a == $c ? 'bottom' : '';
120 $PM = $isArray ? ($deeper ? 'minus' : 'plus') : 'join';
121 $HTML .= $depthData;
122 $theIcon = '<img' . IconUtility::skinImg($GLOBALS['BACK_PATH'], ('gfx/ol/' . $PM . $BTM . '.gif'), 'width="18" height="16"') . ' align="top" border="0" alt="" />';
123 if ($PM == 'join') {
124 $HTML .= $theIcon;
125 } else {
126 $HTML .= ($this->expAll ? '' : '<a id="' . $goto . '" href="' . htmlspecialchars((BackendUtility::getModuleUrl(GeneralUtility::_GP('M')) . '&node[' . $depth . ']=' . ($deeper ? 0 : 1) . '#' . $goto)) . '">') . $theIcon . ($this->expAll ? '' : '</a>');
127 }
128 $label = $key;
129 $HTML .= $this->wrapArrayKey($label, $depth, !$isArray ? $value : '');
130 if (!$isArray) {
131 $theValue = $value;
132 if ($this->searchKeys[$depth]) {
133 $HTML .= ' = <span style="color:red;">' . $this->wrapValue($theValue) . '</span>';
134 } else {
135 $HTML .= ' = ' . $this->wrapValue($theValue);
136 }
137 }
138 $HTML .= '<br />';
139 if ($deeper) {
140 $HTML .= $this->tree(
141 $value,
142 $depth,
143 $depthData . '<img' . IconUtility::skinImg($GLOBALS['BACK_PATH'], ('gfx/ol/' . $LN . '.gif'), 'width="18" height="16"') . ' align="top" alt="" />'
144 );
145 }
146 }
147 return $HTML;
148 }
149
150 /**
151 * Wrapping the value in bold tags etc.
152 *
153 * @param string $theValue The title string
154 * @return string Title string, htmlspecialchars()'ed
155 */
156 public function wrapValue($theValue) {
157 $wrappedValue = '';
158 if ((string)$theValue !== '') {
159 $wrappedValue = '<strong>' . htmlspecialchars($theValue) . '</strong>';
160 }
161 return $wrappedValue;
162 }
163
164 /**
165 * Wrapping the value in bold tags etc.
166 *
167 * @param string $label The title string
168 * @param string $depth Depth path
169 * @param string $theValue The value for the array entry.
170 * @return string Title string, htmlspecialchars()'ed
171 */
172 public function wrapArrayKey($label, $depth, $theValue) {
173 // Protect label:
174 $label = htmlspecialchars($label);
175
176 // If varname is set:
177 if ($this->varName && !$this->dontLinkVar) {
178 $variableName = $this->varName
179 . '[\'' . str_replace('.', '\'][\'', $depth) . '\'] = '
180 . (!MathUtility::canBeInterpretedAsInteger($theValue) ? '\''
181 . addslashes($theValue) . '\'' : $theValue) . '; ';
182 $label = '<a href="'
183 . htmlspecialchars((BackendUtility::getModuleUrl(GeneralUtility::_GP('M'))
184 . '&varname=' . urlencode($variableName)))
185 . '#varname">' . $label . '</a>';
186 }
187
188 return $label;
189 }
190
191 /**
192 * Creates an array with "depthKeys" which will expand the array to show the search results
193 *
194 * @param array $keyArr The array to search for the value
195 * @param string $depth_in Depth string - blank for first call (will build up during recursive calling creating
196 * an id of the position: [key1].[key2].[key3]
197 * @param string $searchString The string to search for
198 * @param array $keyArray Key array, for first call pass empty array
199 * @return array
200 */
201 public function getSearchKeys($keyArr, $depth_in, $searchString, $keyArray) {
202 if ($depth_in) {
203 $depth_in = $depth_in . '.';
204 }
205 foreach ($keyArr as $key => $value) {
206 $depth = $depth_in . $key;
207 $deeper = is_array($keyArr[$key]);
208 if ($this->regexMode) {
209 if (
210 preg_match('/' . $searchString . '/', $keyArr[$key])
211 || $this->searchKeysToo && preg_match('/' . $searchString . '/', $key)
212 ) {
213 $this->searchKeys[$depth] = 1;
214 }
215 } else {
216 if (
217 !$deeper && stristr($keyArr[$key], $searchString)
218 || $this->searchKeysToo && stristr($key, $searchString)
219 ) {
220 $this->searchKeys[$depth] = 1;
221 }
222 }
223 if ($deeper) {
224 $cS = count($this->searchKeys);
225 $keyArray = $this->getSearchKeys($keyArr[$key], $depth, $searchString, $keyArray);
226 if ($cS != count($this->searchKeys)) {
227 $keyArray[$depth] = 1;
228 }
229 }
230 }
231 return $keyArray;
232 }
233
234 /**
235 * Function modifying the depthKey array
236 *
237 * @param array $arr Array with instructions to open/close nodes.
238 * @param array $settings Input depth_key array
239 * @return array Output depth_key array with entries added/removed based on $arr
240 * @see \TYPO3\CMS\Lowlevel\Utility\ArrayBrowser::main()
241 */
242 public function depthKeys($arr, $settings) {
243 $tsbrArray = array();
244 foreach ($arr as $theK => $theV) {
245 $theKeyParts = explode('.', $theK);
246 $depth = '';
247 $c = count($theKeyParts);
248 $a = 0;
249 foreach ($theKeyParts as $p) {
250 $a++;
251 $depth .= ($depth ? '.' : '') . $p;
252 $tsbrArray[$depth] = $c == $a ? $theV : 1;
253 }
254 }
255 // Modify settings
256 foreach ($tsbrArray as $theK => $theV) {
257 if ($theV) {
258 $settings[$theK] = 1;
259 } else {
260 unset($settings[$theK]);
261 }
262 }
263 return $settings;
264 }
265
266 }