1 | <?php
|
---|
2 | /**
|
---|
3 | *
|
---|
4 | * @package phpBB3
|
---|
5 | * @version $Id: functions_module.php 9095 2008-11-23 12:42:34Z acydburn $
|
---|
6 | * @copyright (c) 2005 phpBB Group
|
---|
7 | * @license http://opensource.org/licenses/gpl-license.php GNU Public License
|
---|
8 | *
|
---|
9 | */
|
---|
10 |
|
---|
11 | /**
|
---|
12 | * @ignore
|
---|
13 | */
|
---|
14 | if (!defined('IN_PHPBB'))
|
---|
15 | {
|
---|
16 | exit;
|
---|
17 | }
|
---|
18 |
|
---|
19 | /**
|
---|
20 | * Class handling all types of 'plugins' (a future term)
|
---|
21 | * @package phpBB3
|
---|
22 | */
|
---|
23 | class p_master
|
---|
24 | {
|
---|
25 | var $p_id;
|
---|
26 | var $p_class;
|
---|
27 | var $p_name;
|
---|
28 | var $p_mode;
|
---|
29 | var $p_parent;
|
---|
30 |
|
---|
31 | var $include_path = false;
|
---|
32 | var $active_module = false;
|
---|
33 | var $active_module_row_id = false;
|
---|
34 | var $acl_forum_id = false;
|
---|
35 | var $module_ary = array();
|
---|
36 |
|
---|
37 | /**
|
---|
38 | * Constuctor
|
---|
39 | * Set module include path
|
---|
40 | */
|
---|
41 | function p_master($include_path = false)
|
---|
42 | {
|
---|
43 | global $phpbb_root_path;
|
---|
44 |
|
---|
45 | $this->include_path = ($include_path !== false) ? $include_path : $phpbb_root_path . 'includes/';
|
---|
46 |
|
---|
47 | // Make sure the path ends with /
|
---|
48 | if (substr($this->include_path, -1) !== '/')
|
---|
49 | {
|
---|
50 | $this->include_path .= '/';
|
---|
51 | }
|
---|
52 | }
|
---|
53 |
|
---|
54 | /**
|
---|
55 | * Set custom include path for modules
|
---|
56 | * Schema for inclusion is include_path . modulebase
|
---|
57 | *
|
---|
58 | * @param string $include_path include path to be used.
|
---|
59 | * @access public
|
---|
60 | */
|
---|
61 | function set_custom_include_path($include_path)
|
---|
62 | {
|
---|
63 | $this->include_path = $include_path;
|
---|
64 |
|
---|
65 | // Make sure the path ends with /
|
---|
66 | if (substr($this->include_path, -1) !== '/')
|
---|
67 | {
|
---|
68 | $this->include_path .= '/';
|
---|
69 | }
|
---|
70 | }
|
---|
71 |
|
---|
72 | /**
|
---|
73 | * List modules
|
---|
74 | *
|
---|
75 | * This creates a list, stored in $this->module_ary of all available
|
---|
76 | * modules for the given class (ucp, mcp and acp). Additionally
|
---|
77 | * $this->module_y_ary is created with indentation information for
|
---|
78 | * displaying the module list appropriately. Only modules for which
|
---|
79 | * the user has access rights are included in these lists.
|
---|
80 | */
|
---|
81 | function list_modules($p_class)
|
---|
82 | {
|
---|
83 | global $auth, $db, $user, $cache;
|
---|
84 | global $config, $phpbb_root_path, $phpEx;
|
---|
85 |
|
---|
86 | // Sanitise for future path use, it's escaped as appropriate for queries
|
---|
87 | $this->p_class = str_replace(array('.', '/', '\\'), '', basename($p_class));
|
---|
88 |
|
---|
89 | // Get cached modules
|
---|
90 | if (($this->module_cache = $cache->get('_modules_' . $this->p_class)) === false)
|
---|
91 | {
|
---|
92 | // Get modules
|
---|
93 | $sql = 'SELECT *
|
---|
94 | FROM ' . MODULES_TABLE . "
|
---|
95 | WHERE module_class = '" . $db->sql_escape($this->p_class) . "'
|
---|
96 | ORDER BY left_id ASC";
|
---|
97 | $result = $db->sql_query($sql);
|
---|
98 |
|
---|
99 | $rows = array();
|
---|
100 | while ($row = $db->sql_fetchrow($result))
|
---|
101 | {
|
---|
102 | $rows[$row['module_id']] = $row;
|
---|
103 | }
|
---|
104 | $db->sql_freeresult($result);
|
---|
105 |
|
---|
106 | $this->module_cache = array();
|
---|
107 | foreach ($rows as $module_id => $row)
|
---|
108 | {
|
---|
109 | $this->module_cache['modules'][] = $row;
|
---|
110 | $this->module_cache['parents'][$row['module_id']] = $this->get_parents($row['parent_id'], $row['left_id'], $row['right_id'], $rows);
|
---|
111 | }
|
---|
112 | unset($rows);
|
---|
113 |
|
---|
114 | $cache->put('_modules_' . $this->p_class, $this->module_cache);
|
---|
115 | }
|
---|
116 |
|
---|
117 | if (empty($this->module_cache))
|
---|
118 | {
|
---|
119 | $this->module_cache = array('modules' => array(), 'parents' => array());
|
---|
120 | }
|
---|
121 |
|
---|
122 | // We "could" build a true tree with this function - maybe mod authors want to use this...
|
---|
123 | // Functions for traversing and manipulating the tree are not available though
|
---|
124 | // We might re-structure the module system to use true trees in 3.2.x...
|
---|
125 | // $tree = $this->build_tree($this->module_cache['modules'], $this->module_cache['parents']);
|
---|
126 |
|
---|
127 | // Clean up module cache array to only let survive modules the user can access
|
---|
128 | $right_id = false;
|
---|
129 | foreach ($this->module_cache['modules'] as $key => $row)
|
---|
130 | {
|
---|
131 | // Not allowed to view module?
|
---|
132 | if (!$this->module_auth($row['module_auth']))
|
---|
133 | {
|
---|
134 | unset($this->module_cache['modules'][$key]);
|
---|
135 | continue;
|
---|
136 | }
|
---|
137 |
|
---|
138 | // Category with no members, ignore
|
---|
139 | if (!$row['module_basename'] && ($row['left_id'] + 1 == $row['right_id']))
|
---|
140 | {
|
---|
141 | unset($this->module_cache['modules'][$key]);
|
---|
142 | continue;
|
---|
143 | }
|
---|
144 |
|
---|
145 | // Skip branch
|
---|
146 | if ($right_id !== false)
|
---|
147 | {
|
---|
148 | if ($row['left_id'] < $right_id)
|
---|
149 | {
|
---|
150 | unset($this->module_cache['modules'][$key]);
|
---|
151 | continue;
|
---|
152 | }
|
---|
153 |
|
---|
154 | $right_id = false;
|
---|
155 | }
|
---|
156 |
|
---|
157 | // Not enabled?
|
---|
158 | if (!$row['module_enabled'])
|
---|
159 | {
|
---|
160 | // If category is disabled then disable every child too
|
---|
161 | unset($this->module_cache['modules'][$key]);
|
---|
162 | $right_id = $row['right_id'];
|
---|
163 | continue;
|
---|
164 | }
|
---|
165 | }
|
---|
166 |
|
---|
167 | // Re-index (this is needed, else we are not able to array_slice later)
|
---|
168 | $this->module_cache['modules'] = array_merge($this->module_cache['modules']);
|
---|
169 |
|
---|
170 | // Include MOD _info files for populating language entries within the menus
|
---|
171 | $this->add_mod_info($this->p_class);
|
---|
172 |
|
---|
173 | // Now build the module array, but exclude completely empty categories...
|
---|
174 | $right_id = false;
|
---|
175 | $names = array();
|
---|
176 |
|
---|
177 | foreach ($this->module_cache['modules'] as $key => $row)
|
---|
178 | {
|
---|
179 | // Skip branch
|
---|
180 | if ($right_id !== false)
|
---|
181 | {
|
---|
182 | if ($row['left_id'] < $right_id)
|
---|
183 | {
|
---|
184 | continue;
|
---|
185 | }
|
---|
186 |
|
---|
187 | $right_id = false;
|
---|
188 | }
|
---|
189 |
|
---|
190 | // Category with no members on their way down (we have to check every level)
|
---|
191 | if (!$row['module_basename'])
|
---|
192 | {
|
---|
193 | $empty_category = true;
|
---|
194 |
|
---|
195 | // We go through the branch and look for an activated module
|
---|
196 | foreach (array_slice($this->module_cache['modules'], $key + 1) as $temp_row)
|
---|
197 | {
|
---|
198 | if ($temp_row['left_id'] > $row['left_id'] && $temp_row['left_id'] < $row['right_id'])
|
---|
199 | {
|
---|
200 | // Module there
|
---|
201 | if ($temp_row['module_basename'] && $temp_row['module_enabled'])
|
---|
202 | {
|
---|
203 | $empty_category = false;
|
---|
204 | break;
|
---|
205 | }
|
---|
206 | continue;
|
---|
207 | }
|
---|
208 | break;
|
---|
209 | }
|
---|
210 |
|
---|
211 | // Skip the branch
|
---|
212 | if ($empty_category)
|
---|
213 | {
|
---|
214 | $right_id = $row['right_id'];
|
---|
215 | continue;
|
---|
216 | }
|
---|
217 | }
|
---|
218 |
|
---|
219 | $depth = sizeof($this->module_cache['parents'][$row['module_id']]);
|
---|
220 |
|
---|
221 | // We need to prefix the functions to not create a naming conflict
|
---|
222 |
|
---|
223 | // Function for building 'url_extra'
|
---|
224 | $url_func = '_module_' . $row['module_basename'] . '_url';
|
---|
225 |
|
---|
226 | // Function for building the language name
|
---|
227 | $lang_func = '_module_' . $row['module_basename'] . '_lang';
|
---|
228 |
|
---|
229 | // Custom function for calling parameters on module init (for example assigning template variables)
|
---|
230 | $custom_func = '_module_' . $row['module_basename'];
|
---|
231 |
|
---|
232 | $names[$row['module_basename'] . '_' . $row['module_mode']][] = true;
|
---|
233 |
|
---|
234 | $module_row = array(
|
---|
235 | 'depth' => $depth,
|
---|
236 |
|
---|
237 | 'id' => (int) $row['module_id'],
|
---|
238 | 'parent' => (int) $row['parent_id'],
|
---|
239 | 'cat' => ($row['right_id'] > $row['left_id'] + 1) ? true : false,
|
---|
240 |
|
---|
241 | 'is_duplicate' => ($row['module_basename'] && sizeof($names[$row['module_basename'] . '_' . $row['module_mode']]) > 1) ? true : false,
|
---|
242 |
|
---|
243 | 'name' => (string) $row['module_basename'],
|
---|
244 | 'mode' => (string) $row['module_mode'],
|
---|
245 | 'display' => (int) $row['module_display'],
|
---|
246 |
|
---|
247 | 'url_extra' => (function_exists($url_func)) ? $url_func($row['module_mode'], $row) : '',
|
---|
248 |
|
---|
249 | 'lang' => ($row['module_basename'] && function_exists($lang_func)) ? $lang_func($row['module_mode'], $row['module_langname']) : ((!empty($user->lang[$row['module_langname']])) ? $user->lang[$row['module_langname']] : $row['module_langname']),
|
---|
250 | 'langname' => $row['module_langname'],
|
---|
251 |
|
---|
252 | 'left' => $row['left_id'],
|
---|
253 | 'right' => $row['right_id'],
|
---|
254 | );
|
---|
255 |
|
---|
256 | if (function_exists($custom_func))
|
---|
257 | {
|
---|
258 | $custom_func($row['module_mode'], $module_row);
|
---|
259 | }
|
---|
260 |
|
---|
261 | $this->module_ary[] = $module_row;
|
---|
262 | }
|
---|
263 |
|
---|
264 | unset($this->module_cache['modules'], $names);
|
---|
265 | }
|
---|
266 |
|
---|
267 | /**
|
---|
268 | * Check if a certain main module is accessible/loaded
|
---|
269 | * By giving the module mode you are able to additionally check for only one mode within the main module
|
---|
270 | *
|
---|
271 | * @param string $module_basename The module base name, for example logs, reports, main (for the mcp).
|
---|
272 | * @param mixed $module_mode The module mode to check. If provided the mode will be checked in addition for presence.
|
---|
273 | *
|
---|
274 | * @return bool Returns true if module is loaded and accessible, else returns false
|
---|
275 | */
|
---|
276 | function loaded($module_basename, $module_mode = false)
|
---|
277 | {
|
---|
278 | if (empty($this->loaded_cache))
|
---|
279 | {
|
---|
280 | $this->loaded_cache = array();
|
---|
281 |
|
---|
282 | foreach ($this->module_ary as $row)
|
---|
283 | {
|
---|
284 | if (!$row['name'])
|
---|
285 | {
|
---|
286 | continue;
|
---|
287 | }
|
---|
288 |
|
---|
289 | if (!isset($this->loaded_cache[$row['name']]))
|
---|
290 | {
|
---|
291 | $this->loaded_cache[$row['name']] = array();
|
---|
292 | }
|
---|
293 |
|
---|
294 | if (!$row['mode'])
|
---|
295 | {
|
---|
296 | continue;
|
---|
297 | }
|
---|
298 |
|
---|
299 | $this->loaded_cache[$row['name']][$row['mode']] = true;
|
---|
300 | }
|
---|
301 | }
|
---|
302 |
|
---|
303 | if ($module_mode === false)
|
---|
304 | {
|
---|
305 | return (isset($this->loaded_cache[$module_basename])) ? true : false;
|
---|
306 | }
|
---|
307 |
|
---|
308 | return (!empty($this->loaded_cache[$module_basename][$module_mode])) ? true : false;
|
---|
309 | }
|
---|
310 |
|
---|
311 | /**
|
---|
312 | * Check module authorisation
|
---|
313 | */
|
---|
314 | function module_auth($module_auth, $forum_id = false)
|
---|
315 | {
|
---|
316 | global $auth, $config;
|
---|
317 |
|
---|
318 | $module_auth = trim($module_auth);
|
---|
319 |
|
---|
320 | // Generally allowed to access module if module_auth is empty
|
---|
321 | if (!$module_auth)
|
---|
322 | {
|
---|
323 | return true;
|
---|
324 | }
|
---|
325 |
|
---|
326 | // With the code below we make sure only those elements get eval'd we really want to be checked
|
---|
327 | preg_match_all('/(?:
|
---|
328 | "[^"\\\\]*(?:\\\\.[^"\\\\]*)*" |
|
---|
329 | \'[^\'\\\\]*(?:\\\\.[^\'\\\\]*)*\' |
|
---|
330 | [(),] |
|
---|
331 | [^\s(),]+)/x', $module_auth, $match);
|
---|
332 |
|
---|
333 | $tokens = $match[0];
|
---|
334 | for ($i = 0, $size = sizeof($tokens); $i < $size; $i++)
|
---|
335 | {
|
---|
336 | $token = &$tokens[$i];
|
---|
337 |
|
---|
338 | switch ($token)
|
---|
339 | {
|
---|
340 | case ')':
|
---|
341 | case '(':
|
---|
342 | case '&&':
|
---|
343 | case '||':
|
---|
344 | case ',':
|
---|
345 | break;
|
---|
346 |
|
---|
347 | default:
|
---|
348 | if (!preg_match('#(?:acl_([a-z0-9_]+)(,\$id)?)|(?:\$id)|(?:aclf_([a-z0-9_]+))|(?:cfg_([a-z0-9_]+))|(?:request_([a-zA-Z0-9_]+))#', $token))
|
---|
349 | {
|
---|
350 | $token = '';
|
---|
351 | }
|
---|
352 | break;
|
---|
353 | }
|
---|
354 | }
|
---|
355 |
|
---|
356 | $module_auth = implode(' ', $tokens);
|
---|
357 |
|
---|
358 | // Make sure $id seperation is working fine
|
---|
359 | $module_auth = str_replace(' , ', ',', $module_auth);
|
---|
360 |
|
---|
361 | $forum_id = ($forum_id === false) ? $this->acl_forum_id : $forum_id;
|
---|
362 |
|
---|
363 | $is_auth = false;
|
---|
364 | eval('$is_auth = (int) (' . preg_replace(array('#acl_([a-z0-9_]+)(,\$id)?#', '#\$id#', '#aclf_([a-z0-9_]+)#', '#cfg_([a-z0-9_]+)#', '#request_([a-zA-Z0-9_]+)#'), array('(int) $auth->acl_get(\'\\1\'\\2)', '(int) $forum_id', '(int) $auth->acl_getf_global(\'\\1\')', '(int) $config[\'\\1\']', '!empty($_REQUEST[\'\\1\'])'), $module_auth) . ');');
|
---|
365 |
|
---|
366 | return $is_auth;
|
---|
367 | }
|
---|
368 |
|
---|
369 | /**
|
---|
370 | * Set active module
|
---|
371 | */
|
---|
372 | function set_active($id = false, $mode = false)
|
---|
373 | {
|
---|
374 | $icat = false;
|
---|
375 | $this->active_module = false;
|
---|
376 |
|
---|
377 | if (request_var('icat', ''))
|
---|
378 | {
|
---|
379 | $icat = $id;
|
---|
380 | $id = request_var('icat', '');
|
---|
381 | }
|
---|
382 |
|
---|
383 | $category = false;
|
---|
384 | foreach ($this->module_ary as $row_id => $item_ary)
|
---|
385 | {
|
---|
386 | // If this is a module and it's selected, active
|
---|
387 | // If this is a category and the module is the first within it, active
|
---|
388 | // If this is a module and no mode selected, select first mode
|
---|
389 | // If no category or module selected, go active for first module in first category
|
---|
390 | if (
|
---|
391 | (($item_ary['name'] === $id || $item_ary['id'] === (int) $id) && (($item_ary['mode'] == $mode && !$item_ary['cat']) || ($icat && $item_ary['cat']))) ||
|
---|
392 | ($item_ary['parent'] === $category && !$item_ary['cat'] && !$icat && $item_ary['display']) ||
|
---|
393 | (($item_ary['name'] === $id || $item_ary['id'] === (int) $id) && !$mode && !$item_ary['cat']) ||
|
---|
394 | (!$id && !$mode && !$item_ary['cat'] && $item_ary['display'])
|
---|
395 | )
|
---|
396 | {
|
---|
397 | if ($item_ary['cat'])
|
---|
398 | {
|
---|
399 | $id = $icat;
|
---|
400 | $icat = false;
|
---|
401 |
|
---|
402 | continue;
|
---|
403 | }
|
---|
404 |
|
---|
405 | $this->p_id = $item_ary['id'];
|
---|
406 | $this->p_parent = $item_ary['parent'];
|
---|
407 | $this->p_name = $item_ary['name'];
|
---|
408 | $this->p_mode = $item_ary['mode'];
|
---|
409 | $this->p_left = $item_ary['left'];
|
---|
410 | $this->p_right = $item_ary['right'];
|
---|
411 |
|
---|
412 | $this->module_cache['parents'] = $this->module_cache['parents'][$this->p_id];
|
---|
413 | $this->active_module = $item_ary['id'];
|
---|
414 | $this->active_module_row_id = $row_id;
|
---|
415 |
|
---|
416 | break;
|
---|
417 | }
|
---|
418 | else if (($item_ary['cat'] && $item_ary['id'] === (int) $id) || ($item_ary['parent'] === $category && $item_ary['cat']))
|
---|
419 | {
|
---|
420 | $category = $item_ary['id'];
|
---|
421 | }
|
---|
422 | }
|
---|
423 | }
|
---|
424 |
|
---|
425 | /**
|
---|
426 | * Loads currently active module
|
---|
427 | *
|
---|
428 | * This method loads a given module, passing it the relevant id and mode.
|
---|
429 | */
|
---|
430 | function load_active($mode = false, $module_url = false, $execute_module = true)
|
---|
431 | {
|
---|
432 | global $phpbb_root_path, $phpbb_admin_path, $phpEx, $user;
|
---|
433 |
|
---|
434 | $module_path = $this->include_path . $this->p_class;
|
---|
435 | $icat = request_var('icat', '');
|
---|
436 |
|
---|
437 | if ($this->active_module === false)
|
---|
438 | {
|
---|
439 | trigger_error('Module not accessible', E_USER_ERROR);
|
---|
440 | }
|
---|
441 |
|
---|
442 | if (!class_exists("{$this->p_class}_$this->p_name"))
|
---|
443 | {
|
---|
444 | if (!file_exists("$module_path/{$this->p_class}_$this->p_name.$phpEx"))
|
---|
445 | {
|
---|
446 | trigger_error("Cannot find module $module_path/{$this->p_class}_$this->p_name.$phpEx", E_USER_ERROR);
|
---|
447 | }
|
---|
448 |
|
---|
449 | include("$module_path/{$this->p_class}_$this->p_name.$phpEx");
|
---|
450 |
|
---|
451 | if (!class_exists("{$this->p_class}_$this->p_name"))
|
---|
452 | {
|
---|
453 | trigger_error("Module file $module_path/{$this->p_class}_$this->p_name.$phpEx does not contain correct class [{$this->p_class}_$this->p_name]", E_USER_ERROR);
|
---|
454 | }
|
---|
455 |
|
---|
456 | if (!empty($mode))
|
---|
457 | {
|
---|
458 | $this->p_mode = $mode;
|
---|
459 | }
|
---|
460 |
|
---|
461 | // Create a new instance of the desired module ... if it has a
|
---|
462 | // constructor it will of course be executed
|
---|
463 | $instance = "{$this->p_class}_$this->p_name";
|
---|
464 |
|
---|
465 | $this->module = new $instance($this);
|
---|
466 |
|
---|
467 | // We pre-define the action parameter we are using all over the place
|
---|
468 | if (defined('IN_ADMIN'))
|
---|
469 | {
|
---|
470 | // Is first module automatically enabled a duplicate and the category not passed yet?
|
---|
471 | if (!$icat && $this->module_ary[$this->active_module_row_id]['is_duplicate'])
|
---|
472 | {
|
---|
473 | $icat = $this->module_ary[$this->active_module_row_id]['parent'];
|
---|
474 | }
|
---|
475 |
|
---|
476 | // Not being able to overwrite ;)
|
---|
477 | $this->module->u_action = append_sid("{$phpbb_admin_path}index.$phpEx", "i={$this->p_name}") . (($icat) ? '&icat=' . $icat : '') . "&mode={$this->p_mode}";
|
---|
478 | }
|
---|
479 | else
|
---|
480 | {
|
---|
481 | // If user specified the module url we will use it...
|
---|
482 | if ($module_url !== false)
|
---|
483 | {
|
---|
484 | $this->module->u_action = $module_url;
|
---|
485 | }
|
---|
486 | else
|
---|
487 | {
|
---|
488 | $this->module->u_action = $phpbb_root_path . (($user->page['page_dir']) ? $user->page['page_dir'] . '/' : '') . $user->page['page_name'];
|
---|
489 | }
|
---|
490 |
|
---|
491 | $this->module->u_action = append_sid($this->module->u_action, "i={$this->p_name}") . (($icat) ? '&icat=' . $icat : '') . "&mode={$this->p_mode}";
|
---|
492 | }
|
---|
493 |
|
---|
494 | // Add url_extra parameter to u_action url
|
---|
495 | if (!empty($this->module_ary) && $this->active_module !== false && $this->module_ary[$this->active_module_row_id]['url_extra'])
|
---|
496 | {
|
---|
497 | $this->module->u_action .= $this->module_ary[$this->active_module_row_id]['url_extra'];
|
---|
498 | }
|
---|
499 |
|
---|
500 | // Assign the module path for re-usage
|
---|
501 | $this->module->module_path = $module_path . '/';
|
---|
502 |
|
---|
503 | // Execute the main method for the new instance, we send the module id and mode as parameters
|
---|
504 | // Users are able to call the main method after this function to be able to assign additional parameters manually
|
---|
505 | if ($execute_module)
|
---|
506 | {
|
---|
507 | $this->module->main($this->p_name, $this->p_mode);
|
---|
508 | }
|
---|
509 |
|
---|
510 | return;
|
---|
511 | }
|
---|
512 | }
|
---|
513 |
|
---|
514 | /**
|
---|
515 | * Appending url parameter to the currently active module.
|
---|
516 | *
|
---|
517 | * This function is called for adding specific url parameters while executing the current module.
|
---|
518 | * It is doing the same as the _module_{name}_url() function, apart from being able to be called after
|
---|
519 | * having dynamically parsed specific parameters. This allows more freedom in choosing additional parameters.
|
---|
520 | * One example can be seen in /includes/mcp/mcp_notes.php - $this->p_master->adjust_url() call.
|
---|
521 | *
|
---|
522 | * @param string $url_extra Extra url parameters, e.g.: &u=$user_id
|
---|
523 | *
|
---|
524 | */
|
---|
525 | function adjust_url($url_extra)
|
---|
526 | {
|
---|
527 | if (empty($this->module_ary[$this->active_module_row_id]))
|
---|
528 | {
|
---|
529 | return;
|
---|
530 | }
|
---|
531 |
|
---|
532 | $row = &$this->module_ary[$this->active_module_row_id];
|
---|
533 |
|
---|
534 | // We check for the same url_extra in $row['url_extra'] to overcome doubled additions...
|
---|
535 | if (strpos($row['url_extra'], $url_extra) === false)
|
---|
536 | {
|
---|
537 | $row['url_extra'] .= $url_extra;
|
---|
538 | }
|
---|
539 | }
|
---|
540 |
|
---|
541 | /**
|
---|
542 | * Check if a module is active
|
---|
543 | */
|
---|
544 | function is_active($id, $mode = false)
|
---|
545 | {
|
---|
546 | // If we find a name by this id and being enabled we have our active one...
|
---|
547 | foreach ($this->module_ary as $row_id => $item_ary)
|
---|
548 | {
|
---|
549 | if (($item_ary['name'] === $id || $item_ary['id'] === (int) $id) && $item_ary['display'])
|
---|
550 | {
|
---|
551 | if ($mode === false || $mode === $item_ary['mode'])
|
---|
552 | {
|
---|
553 | return true;
|
---|
554 | }
|
---|
555 | }
|
---|
556 | }
|
---|
557 |
|
---|
558 | return false;
|
---|
559 | }
|
---|
560 |
|
---|
561 | /**
|
---|
562 | * Get parents
|
---|
563 | */
|
---|
564 | function get_parents($parent_id, $left_id, $right_id, &$all_parents)
|
---|
565 | {
|
---|
566 | global $db;
|
---|
567 |
|
---|
568 | $parents = array();
|
---|
569 |
|
---|
570 | if ($parent_id > 0)
|
---|
571 | {
|
---|
572 | foreach ($all_parents as $module_id => $row)
|
---|
573 | {
|
---|
574 | if ($row['left_id'] < $left_id && $row['right_id'] > $right_id)
|
---|
575 | {
|
---|
576 | $parents[$module_id] = $row['parent_id'];
|
---|
577 | }
|
---|
578 |
|
---|
579 | if ($row['left_id'] > $left_id)
|
---|
580 | {
|
---|
581 | break;
|
---|
582 | }
|
---|
583 | }
|
---|
584 | }
|
---|
585 |
|
---|
586 | return $parents;
|
---|
587 | }
|
---|
588 |
|
---|
589 | /**
|
---|
590 | * Get tree branch
|
---|
591 | */
|
---|
592 | function get_branch($left_id, $right_id, $remaining)
|
---|
593 | {
|
---|
594 | $branch = array();
|
---|
595 |
|
---|
596 | foreach ($remaining as $key => $row)
|
---|
597 | {
|
---|
598 | if ($row['left_id'] > $left_id && $row['left_id'] < $right_id)
|
---|
599 | {
|
---|
600 | $branch[] = $row;
|
---|
601 | continue;
|
---|
602 | }
|
---|
603 | break;
|
---|
604 | }
|
---|
605 |
|
---|
606 | return $branch;
|
---|
607 | }
|
---|
608 |
|
---|
609 | /**
|
---|
610 | * Build true binary tree from given array
|
---|
611 | * Not in use
|
---|
612 | */
|
---|
613 | function build_tree(&$modules, &$parents)
|
---|
614 | {
|
---|
615 | $tree = array();
|
---|
616 |
|
---|
617 | foreach ($modules as $row)
|
---|
618 | {
|
---|
619 | $branch = &$tree;
|
---|
620 |
|
---|
621 | if ($row['parent_id'])
|
---|
622 | {
|
---|
623 | // Go through the tree to find our branch
|
---|
624 | $parent_tree = $parents[$row['module_id']];
|
---|
625 |
|
---|
626 | foreach ($parent_tree as $id => $value)
|
---|
627 | {
|
---|
628 | if (!isset($branch[$id]) && isset($branch['child']))
|
---|
629 | {
|
---|
630 | $branch = &$branch['child'];
|
---|
631 | }
|
---|
632 | $branch = &$branch[$id];
|
---|
633 | }
|
---|
634 | $branch = &$branch['child'];
|
---|
635 | }
|
---|
636 |
|
---|
637 | $branch[$row['module_id']] = $row;
|
---|
638 | if (!isset($branch[$row['module_id']]['child']))
|
---|
639 | {
|
---|
640 | $branch[$row['module_id']]['child'] = array();
|
---|
641 | }
|
---|
642 | }
|
---|
643 |
|
---|
644 | return $tree;
|
---|
645 | }
|
---|
646 |
|
---|
647 | /**
|
---|
648 | * Build navigation structure
|
---|
649 | */
|
---|
650 | function assign_tpl_vars($module_url)
|
---|
651 | {
|
---|
652 | global $template;
|
---|
653 |
|
---|
654 | $current_id = $right_id = false;
|
---|
655 |
|
---|
656 | // Make sure the module_url has a question mark set, effectively determining the delimiter to use
|
---|
657 | $delim = (strpos($module_url, '?') === false) ? '?' : '&';
|
---|
658 |
|
---|
659 | $current_padding = $current_depth = 0;
|
---|
660 | $linear_offset = 'l_block1';
|
---|
661 | $tabular_offset = 't_block2';
|
---|
662 |
|
---|
663 | // Generate the list of modules, we'll do this in two ways ...
|
---|
664 | // 1) In a linear fashion
|
---|
665 | // 2) In a combined tabbed + linear fashion ... tabs for the categories
|
---|
666 | // and a linear list for subcategories/items
|
---|
667 | foreach ($this->module_ary as $row_id => $item_ary)
|
---|
668 | {
|
---|
669 | // Skip hidden modules
|
---|
670 | if (!$item_ary['display'])
|
---|
671 | {
|
---|
672 | continue;
|
---|
673 | }
|
---|
674 |
|
---|
675 | // Skip branch
|
---|
676 | if ($right_id !== false)
|
---|
677 | {
|
---|
678 | if ($item_ary['left'] < $right_id)
|
---|
679 | {
|
---|
680 | continue;
|
---|
681 | }
|
---|
682 |
|
---|
683 | $right_id = false;
|
---|
684 | }
|
---|
685 |
|
---|
686 | // Category with no members on their way down (we have to check every level)
|
---|
687 | if (!$item_ary['name'])
|
---|
688 | {
|
---|
689 | $empty_category = true;
|
---|
690 |
|
---|
691 | // We go through the branch and look for an activated module
|
---|
692 | foreach (array_slice($this->module_ary, $row_id + 1) as $temp_row)
|
---|
693 | {
|
---|
694 | if ($temp_row['left'] > $item_ary['left'] && $temp_row['left'] < $item_ary['right'])
|
---|
695 | {
|
---|
696 | // Module there and displayed?
|
---|
697 | if ($temp_row['name'] && $temp_row['display'])
|
---|
698 | {
|
---|
699 | $empty_category = false;
|
---|
700 | break;
|
---|
701 | }
|
---|
702 | continue;
|
---|
703 | }
|
---|
704 | break;
|
---|
705 | }
|
---|
706 |
|
---|
707 | // Skip the branch
|
---|
708 | if ($empty_category)
|
---|
709 | {
|
---|
710 | $right_id = $item_ary['right'];
|
---|
711 | continue;
|
---|
712 | }
|
---|
713 | }
|
---|
714 |
|
---|
715 | // Select first id we can get
|
---|
716 | if (!$current_id && (isset($this->module_cache['parents'][$item_ary['id']]) || $item_ary['id'] == $this->p_id))
|
---|
717 | {
|
---|
718 | $current_id = $item_ary['id'];
|
---|
719 | }
|
---|
720 |
|
---|
721 | $depth = $item_ary['depth'];
|
---|
722 |
|
---|
723 | if ($depth > $current_depth)
|
---|
724 | {
|
---|
725 | $linear_offset = $linear_offset . '.l_block' . ($depth + 1);
|
---|
726 | $tabular_offset = ($depth + 1 > 2) ? $tabular_offset . '.t_block' . ($depth + 1) : $tabular_offset;
|
---|
727 | }
|
---|
728 | else if ($depth < $current_depth)
|
---|
729 | {
|
---|
730 | for ($i = $current_depth - $depth; $i > 0; $i--)
|
---|
731 | {
|
---|
732 | $linear_offset = substr($linear_offset, 0, strrpos($linear_offset, '.'));
|
---|
733 | $tabular_offset = ($i + $depth > 1) ? substr($tabular_offset, 0, strrpos($tabular_offset, '.')) : $tabular_offset;
|
---|
734 | }
|
---|
735 | }
|
---|
736 |
|
---|
737 | $u_title = $module_url . $delim . 'i=' . (($item_ary['cat']) ? $item_ary['id'] : $item_ary['name'] . (($item_ary['is_duplicate']) ? '&icat=' . $current_id : '') . '&mode=' . $item_ary['mode']);
|
---|
738 |
|
---|
739 | // Was not allowed in categories before - /*!$item_ary['cat'] && */
|
---|
740 | $u_title .= (isset($item_ary['url_extra'])) ? $item_ary['url_extra'] : '';
|
---|
741 |
|
---|
742 | // Only output a categories items if it's currently selected
|
---|
743 | if (!$depth || ($depth && (in_array($item_ary['parent'], array_values($this->module_cache['parents'])) || $item_ary['parent'] == $this->p_parent)))
|
---|
744 | {
|
---|
745 | $use_tabular_offset = (!$depth) ? 't_block1' : $tabular_offset;
|
---|
746 |
|
---|
747 | $tpl_ary = array(
|
---|
748 | 'L_TITLE' => $item_ary['lang'],
|
---|
749 | 'S_SELECTED' => (isset($this->module_cache['parents'][$item_ary['id']]) || $item_ary['id'] == $this->p_id) ? true : false,
|
---|
750 | 'U_TITLE' => $u_title
|
---|
751 | );
|
---|
752 |
|
---|
753 | $template->assign_block_vars($use_tabular_offset, array_merge($tpl_ary, array_change_key_case($item_ary, CASE_UPPER)));
|
---|
754 | }
|
---|
755 |
|
---|
756 | $tpl_ary = array(
|
---|
757 | 'L_TITLE' => $item_ary['lang'],
|
---|
758 | 'S_SELECTED' => (isset($this->module_cache['parents'][$item_ary['id']]) || $item_ary['id'] == $this->p_id) ? true : false,
|
---|
759 | 'U_TITLE' => $u_title
|
---|
760 | );
|
---|
761 |
|
---|
762 | $template->assign_block_vars($linear_offset, array_merge($tpl_ary, array_change_key_case($item_ary, CASE_UPPER)));
|
---|
763 |
|
---|
764 | $current_depth = $depth;
|
---|
765 | }
|
---|
766 | }
|
---|
767 |
|
---|
768 | /**
|
---|
769 | * Returns desired template name
|
---|
770 | */
|
---|
771 | function get_tpl_name()
|
---|
772 | {
|
---|
773 | return $this->module->tpl_name . '.html';
|
---|
774 | }
|
---|
775 |
|
---|
776 | /**
|
---|
777 | * Returns the desired page title
|
---|
778 | */
|
---|
779 | function get_page_title()
|
---|
780 | {
|
---|
781 | global $user;
|
---|
782 |
|
---|
783 | if (!isset($this->module->page_title))
|
---|
784 | {
|
---|
785 | return '';
|
---|
786 | }
|
---|
787 |
|
---|
788 | return (isset($user->lang[$this->module->page_title])) ? $user->lang[$this->module->page_title] : $this->module->page_title;
|
---|
789 | }
|
---|
790 |
|
---|
791 | /**
|
---|
792 | * Load module as the current active one without the need for registering it
|
---|
793 | */
|
---|
794 | function load($class, $name, $mode = false)
|
---|
795 | {
|
---|
796 | $this->p_class = $class;
|
---|
797 | $this->p_name = $name;
|
---|
798 |
|
---|
799 | // Set active module to true instead of using the id
|
---|
800 | $this->active_module = true;
|
---|
801 |
|
---|
802 | $this->load_active($mode);
|
---|
803 | }
|
---|
804 |
|
---|
805 | /**
|
---|
806 | * Display module
|
---|
807 | */
|
---|
808 | function display($page_title, $display_online_list = true)
|
---|
809 | {
|
---|
810 | global $template, $user;
|
---|
811 |
|
---|
812 | // Generate the page
|
---|
813 | if (defined('IN_ADMIN') && isset($user->data['session_admin']) && $user->data['session_admin'])
|
---|
814 | {
|
---|
815 | adm_page_header($page_title);
|
---|
816 | }
|
---|
817 | else
|
---|
818 | {
|
---|
819 | page_header($page_title, $display_online_list);
|
---|
820 | }
|
---|
821 |
|
---|
822 | $template->set_filenames(array(
|
---|
823 | 'body' => $this->get_tpl_name())
|
---|
824 | );
|
---|
825 |
|
---|
826 | if (defined('IN_ADMIN') && isset($user->data['session_admin']) && $user->data['session_admin'])
|
---|
827 | {
|
---|
828 | adm_page_footer();
|
---|
829 | }
|
---|
830 | else
|
---|
831 | {
|
---|
832 | page_footer();
|
---|
833 | }
|
---|
834 | }
|
---|
835 |
|
---|
836 | /**
|
---|
837 | * Toggle whether this module will be displayed or not
|
---|
838 | */
|
---|
839 | function set_display($id, $mode = false, $display = true)
|
---|
840 | {
|
---|
841 | foreach ($this->module_ary as $row_id => $item_ary)
|
---|
842 | {
|
---|
843 | if (($item_ary['name'] === $id || $item_ary['id'] === (int) $id) && (!$mode || $item_ary['mode'] === $mode))
|
---|
844 | {
|
---|
845 | $this->module_ary[$row_id]['display'] = (int) $display;
|
---|
846 | }
|
---|
847 | }
|
---|
848 | }
|
---|
849 |
|
---|
850 | /**
|
---|
851 | * Add custom MOD info language file
|
---|
852 | */
|
---|
853 | function add_mod_info($module_class)
|
---|
854 | {
|
---|
855 | global $user, $phpEx;
|
---|
856 |
|
---|
857 | if (file_exists($user->lang_path . $user->lang_name . '/mods'))
|
---|
858 | {
|
---|
859 | $add_files = array();
|
---|
860 |
|
---|
861 | $dir = @opendir($user->lang_path . $user->lang_name . '/mods');
|
---|
862 |
|
---|
863 | if ($dir)
|
---|
864 | {
|
---|
865 | while (($entry = readdir($dir)) !== false)
|
---|
866 | {
|
---|
867 | if (strpos($entry, 'info_' . strtolower($module_class) . '_') === 0 && substr(strrchr($entry, '.'), 1) == $phpEx)
|
---|
868 | {
|
---|
869 | $add_files[] = 'mods/' . substr(basename($entry), 0, -(strlen($phpEx) + 1));
|
---|
870 | }
|
---|
871 | }
|
---|
872 | closedir($dir);
|
---|
873 | }
|
---|
874 |
|
---|
875 | if (sizeof($add_files))
|
---|
876 | {
|
---|
877 | $user->add_lang($add_files);
|
---|
878 | }
|
---|
879 | }
|
---|
880 | }
|
---|
881 | }
|
---|
882 |
|
---|
883 | ?>
|
---|