phpBB
Statistics
| Revision:

root / branches / phpBB-3_0_0 / phpBB / includes / functions_module.php

History | View | Annotate | Download (23 kB)

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