1 | <?php |
||
2 | |||
3 | /** |
||
4 | * Performs a search in an array of settings |
||
5 | * |
||
6 | * @package ElkArte Forum |
||
7 | * @copyright ElkArte Forum contributors |
||
8 | * @license BSD http://opensource.org/licenses/BSD-3-Clause (see accompanying LICENSE.txt file) |
||
9 | * |
||
10 | * This file contains code covered by: |
||
11 | * copyright: 2011 Simple Machines (http://www.simplemachines.org) |
||
12 | * |
||
13 | * @version 2.0 dev |
||
14 | * |
||
15 | */ |
||
16 | |||
17 | namespace ElkArte; |
||
18 | |||
19 | use ElkArte\Helper\Util; |
||
20 | use ElkArte\Languages\Txt; |
||
21 | |||
22 | /** |
||
23 | * Perform a search in the admin settings (and maybe other settings as well) |
||
24 | */ |
||
25 | class AdminSettingsSearch |
||
26 | { |
||
27 | /** @var array All the settings we have found */ |
||
28 | protected $_search_data; |
||
29 | |||
30 | /** @var string Sections are supposed to be stored in a menu, and the menu is in $context['menu_name'] */ |
||
31 | protected $_menu_name; |
||
32 | |||
33 | /** @var string[] An array of settings used in the search */ |
||
34 | protected $_settings = []; |
||
35 | |||
36 | /** |
||
37 | * Constructor! |
||
38 | * |
||
39 | * @param string[] $language_files - Language file names |
||
40 | * @param string[] $include_files - File names to include (see _include_files for details on the structure) |
||
41 | * @param array $settings_search - Settings to search in (see _load_settings for details on the structure) |
||
42 | */ |
||
43 | public function __construct($language_files = [], $include_files = [], $settings_search = []) |
||
44 | { |
||
45 | if (!empty($language_files)) |
||
46 | { |
||
47 | Txt::load(implode('+', $language_files)); |
||
48 | } |
||
49 | |||
50 | if (!empty($include_files)) |
||
51 | { |
||
52 | $this->_include_files($include_files); |
||
53 | } |
||
54 | |||
55 | 2 | if (!empty($settings_search)) |
|
56 | { |
||
57 | 2 | $this->_settings = $this->_load_settings($settings_search); |
|
58 | } |
||
59 | 2 | } |
|
60 | |||
61 | /** |
||
62 | 2 | * Includes a set of files. |
|
63 | * |
||
64 | * @param string[] $include_files - array of file names (without extension), |
||
65 | * it's possible to specify an array of arrays instead of an array of strings, |
||
66 | * in that case the index 0 is the directory of the file, while the 1 is the file name. |
||
67 | 2 | * |
|
68 | * If a directory is not specified it will default to the value of the constant ADMINDIR e.g. |
||
69 | 2 | * $include_files = array('file_name.controller', 'file_name2.controller', array('dir_name', 'file_name3.controller')) |
|
70 | */ |
||
71 | 2 | protected function _include_files($include_files) |
|
72 | { |
||
73 | foreach ($include_files as $file) |
||
74 | { |
||
75 | if (is_array($file)) |
||
76 | { |
||
77 | $dir = $file[0]; |
||
78 | $file = $file[1]; |
||
79 | } |
||
80 | else |
||
81 | { |
||
82 | $dir = ADMINDIR; |
||
83 | } |
||
84 | |||
85 | require_once($dir . '/' . $file . '.php'); |
||
86 | } |
||
87 | } |
||
88 | |||
89 | /** |
||
90 | * Loads all the settings |
||
91 | * |
||
92 | * @param array $settings_search - An array that defines where to look for settings. The structure is: |
||
93 | * array( method name, url, controller name ) |
||
94 | * |
||
95 | * @return array |
||
96 | */ |
||
97 | private function _load_settings($settings_search) |
||
98 | { |
||
99 | $settings = []; |
||
100 | |||
101 | foreach ($settings_search as $setting_area) |
||
102 | { |
||
103 | // Get a list of their variables. |
||
104 | if (isset($setting_area[2])) |
||
105 | { |
||
106 | // an OOP controller: get the settings from the settings method. |
||
107 | $controller = new $setting_area[2](new EventManager()); |
||
108 | $controller->setUser(User::$info); |
||
109 | $controller->pre_dispatch(); |
||
110 | $config_vars = $controller->{$setting_area[0]}(); |
||
111 | } |
||
112 | else |
||
113 | { |
||
114 | // a good ole' procedural controller: get the settings from the function. |
||
115 | $config_vars = $setting_area[0](true); |
||
116 | } |
||
117 | |||
118 | foreach ($config_vars as $var) |
||
119 | { |
||
120 | 2 | if (empty($var[1])) |
|
121 | { |
||
122 | 2 | continue; |
|
123 | } |
||
124 | 2 | ||
125 | if (in_array($var[0], ['permissions', 'callback', 'message', 'warning', 'title', 'desc'])) |
||
126 | { |
||
127 | 2 | continue; |
|
128 | } |
||
129 | |||
130 | 2 | $settings[] = [$this->_get_label($var), $setting_area[1], 'named_link' => $var[1]]; |
|
131 | 2 | } |
|
132 | 2 | } |
|
133 | 2 | ||
134 | return $settings; |
||
135 | } |
||
136 | |||
137 | /** |
||
138 | * Checks if any configuration settings have label text that should be included in the search |
||
139 | * |
||
140 | * @param array $var |
||
141 | 2 | * |
|
142 | * @return string |
||
143 | 2 | */ |
|
144 | private function _get_label($var) |
||
145 | 2 | { |
|
146 | global $txt; |
||
147 | |||
148 | // Special case for file and db which go var, label, db, etc |
||
149 | if (isset($var[2]) && in_array($var[2], ['file', 'db'])) |
||
150 | 2 | { |
|
151 | $save = $var[1]; |
||
152 | $var[1] = $var[0]; |
||
153 | } |
||
154 | |||
155 | // See if there are any labels that might fit? |
||
156 | if (isset($var['text_label'])) |
||
157 | { |
||
158 | return $var['text_label']; |
||
159 | } |
||
160 | |||
161 | 2 | if (isset($txt[$var[1]])) |
|
162 | { |
||
163 | 2 | return $txt[$var[1]]; |
|
164 | } |
||
165 | |||
166 | 2 | if (isset($txt['setting_' . $var[1]])) |
|
167 | { |
||
168 | 2 | return $txt['setting_' . $var[1]]; |
|
169 | } |
||
170 | |||
171 | if (isset($txt['groups_' . $var[1]])) |
||
172 | 2 | { |
|
173 | return $txt['groups_' . $var[1]]; |
||
174 | 2 | } |
|
175 | |||
176 | if (!is_array($var) && isset($txt[$var])) |
||
177 | 2 | { |
|
178 | return $txt[$var]; |
||
179 | 2 | } |
|
180 | |||
181 | return $save ?? $var[1]; |
||
182 | 2 | } |
|
183 | |||
184 | 2 | /** |
|
185 | * Initialize the search populating the array to search in |
||
186 | * |
||
187 | 2 | * @param string $menu_name - The name of the menu to look into |
|
188 | * @param array $additional_settings - Possible additional settings (see _load_settings for the array structure) |
||
189 | */ |
||
190 | public function initSearch($menu_name, $additional_settings = []) |
||
191 | { |
||
192 | 2 | $this->_menu_name = $menu_name; |
|
193 | |||
194 | // This is the huge array that defines everything ... it's items are formatted as follows: |
||
195 | // 0 = Language index (Can be array of indexes) to search through for this setting. |
||
196 | // 1 = URL for this indexes page. |
||
197 | // 2 = Help index for help associated with this item (If different from 0) |
||
198 | $this->_search_data = [ |
||
199 | // All the major sections of the forum. |
||
200 | 'sections' => $this->_load_search_sections(), |
||
201 | 'settings' => array_merge( |
||
202 | 2 | $additional_settings, |
|
203 | $this->_settings |
||
204 | 2 | ), |
|
205 | ]; |
||
206 | } |
||
207 | |||
208 | /** |
||
209 | * Loads all the admin sections |
||
210 | 2 | */ |
|
211 | private function _load_search_sections() |
||
212 | 2 | { |
|
213 | 2 | global $context; |
|
214 | 2 | ||
215 | 2 | $sections = []; |
|
216 | |||
217 | // Go through the admin menu structure trying to find suitably named areas! |
||
218 | 2 | foreach ($context[$this->_menu_name]['sections'] as $section) |
|
219 | { |
||
220 | foreach ($section['areas'] as $menu_key => $menu_item) |
||
221 | { |
||
222 | $sections[] = [$menu_item['label'], 'area=' . $menu_key, $menu_key]; |
||
223 | 2 | if (!empty($menu_item['subsections'])) |
|
224 | { |
||
225 | 2 | foreach ($menu_item['subsections'] as $key => $sublabel) |
|
226 | { |
||
227 | 2 | if (isset($sublabel['label'])) |
|
228 | { |
||
229 | $sections[] = [$sublabel['label'], 'area=' . $menu_key . ';sa=' . $key, $menu_key]; |
||
230 | 2 | } |
|
231 | } |
||
232 | 2 | } |
|
233 | } |
||
234 | 2 | } |
|
235 | 2 | ||
236 | return $sections; |
||
237 | 2 | } |
|
238 | |||
239 | 2 | /** |
|
240 | * Actually perform the search of a term in the array |
||
241 | 2 | * |
|
242 | * @param string $search_term - The term to search |
||
243 | * |
||
244 | * @return string[] - an array of search results with 4 indexes: |
||
245 | * - url |
||
246 | * - name |
||
247 | * - type |
||
248 | 2 | * - help |
|
249 | */ |
||
250 | public function doSearch($search_term) |
||
251 | { |
||
252 | global $scripturl, $context; |
||
253 | |||
254 | $search_results = []; |
||
255 | |||
256 | foreach ($this->_search_data as $section => $data) |
||
257 | { |
||
258 | foreach ($data as $item) |
||
259 | { |
||
260 | $search_result = $this->_find_term($search_term, $item); |
||
261 | |||
262 | 2 | if (!empty($search_result)) |
|
263 | { |
||
264 | 2 | $search_result['type'] = $section; |
|
265 | $search_result['url'] = $item[1] . ';' . $context['session_var'] . '=' . $context['session_id']; |
||
266 | 2 | ||
267 | if (strpos($item[1], 'area') === 0) |
||
268 | 2 | { |
|
269 | $search_result['url'] = $scripturl . '?action=admin;' . $search_result['url'] . ($section === 'settings' && !empty($item['named_link']) ? '#' . $item['named_link'] : ''); |
||
270 | 2 | } |
|
271 | |||
272 | 2 | $search_results[] = $search_result; |
|
273 | } |
||
274 | 2 | } |
|
275 | } |
||
276 | 2 | ||
277 | 2 | return $search_results; |
|
0 ignored issues
–
show
Bug
Best Practice
introduced
by
![]() |
|||
278 | } |
||
279 | 2 | ||
280 | /** |
||
281 | 2 | * Find a term inside an $item |
|
282 | * |
||
283 | * @param string $search_term - The term to search |
||
284 | 2 | * @param string|string[] $item - A string or array of strings that may be |
|
285 | * standalone strings, index for $txt, partial index for $txt['setting_' . $item] |
||
286 | * |
||
287 | * @return string[] - An empty array if $search_term is not found, otherwise |
||
288 | * part of the search_result array (consisting of 'name' and 'help') |
||
289 | 2 | * of the term the result was found |
|
290 | */ |
||
291 | protected function _find_term($search_term, $item) |
||
292 | { |
||
293 | global $helptxt; |
||
294 | |||
295 | $found = false; |
||
296 | $return = []; |
||
297 | |||
298 | if (!is_array($item[0])) |
||
299 | { |
||
300 | $item[0] = [$item[0]]; |
||
301 | } |
||
302 | |||
303 | 2 | foreach ($item[0] as $term) |
|
304 | { |
||
305 | 2 | if (stripos($term, $search_term) !== false) |
|
306 | { |
||
307 | 2 | $found = $term; |
|
308 | 2 | } |
|
309 | } |
||
310 | 2 | ||
311 | // Format the name - and remove any descriptions the entry may have. |
||
312 | 2 | if ($found !== false) |
|
313 | { |
||
314 | $name = preg_replace('~<(?:div|span)\sclass="smalltext">.+?</(?:div|span)>~s', '', $found); |
||
315 | 2 | ||
316 | $return = [ |
||
317 | 2 | 'name' => $name, |
|
318 | 'help' => Util::shorten_text(isset($item[2], $helptxt[$item[2]]) ? strip_tags($helptxt[$item[2]]) : (isset($helptxt[$found]) ? strip_tags($helptxt[$found]) : ''), 255), |
||
319 | 2 | ]; |
|
320 | } |
||
321 | |||
322 | return $return; |
||
323 | } |
||
324 | } |
||
325 |