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