Verzeichnisstruktur phpBB-3.1.0
- Veröffentlicht
- 27.10.2014
So funktioniert es
|
Auf das letzte Element klicken. Dies geht jeweils ein Schritt zurück |
Auf das Icon klicken, dies öffnet das Verzeichnis. Nochmal klicken schließt das Verzeichnis. |
|
(Beispiel Datei-Icons)
|
Auf das Icon klicken um den Quellcode anzuzeigen |
acp_modules.php
0001 <?php
0002 /**
0003 *
0004 * This file is part of the phpBB Forum Software package.
0005 *
0006 * @copyright (c) phpBB Limited <https://www.phpbb.com>
0007 * @license GNU General Public License, version 2 (GPL-2.0)
0008 *
0009 * For full copyright and license information, please see
0010 * the docs/CREDITS.txt file.
0011 *
0012 */
0013
0014 /**
0015 * @ignore
0016 */
0017 if (!defined('IN_PHPBB'))
0018 {
0019 exit;
0020 }
0021
0022 /**
0023 * - Able to check for new module versions (modes changed/adjusted/added/removed)
0024 * Icons for:
0025 * - module enabled and displayed (common)
0026 * - module enabled and not displayed
0027 * - module deactivated
0028 * - category (enabled)
0029 * - category disabled
0030 */
0031
0032 class acp_modules
0033 {
0034 var $module_class = '';
0035 var $parent_id;
0036 var $u_action;
0037
0038 function main($id, $mode)
0039 {
0040 global $db, $user, $auth, $template, $module, $request;
0041 global $config, $phpbb_admin_path, $phpbb_root_path, $phpEx;
0042
0043 // Set a global define for modules we might include (the author is able to prevent execution of code by checking this constant)
0044 define('MODULE_INCLUDE', true);
0045
0046 $user->add_lang('acp/modules');
0047 $this->tpl_name = 'acp_modules';
0048
0049 // module class
0050 $this->module_class = $mode;
0051
0052 if ($this->module_class == 'ucp')
0053 {
0054 $user->add_lang('ucp');
0055 }
0056 else if ($this->module_class == 'mcp')
0057 {
0058 $user->add_lang('mcp');
0059 }
0060
0061 if ($module->p_class != $this->module_class)
0062 {
0063 $module->add_mod_info($this->module_class);
0064 }
0065
0066 $this->page_title = strtoupper($this->module_class);
0067
0068 $this->parent_id = request_var('parent_id', 0);
0069 $module_id = request_var('m', 0);
0070 $action = request_var('action', '');
0071 $errors = array();
0072
0073 switch ($action)
0074 {
0075 case 'delete':
0076 if (!$module_id)
0077 {
0078 trigger_error($user->lang['NO_MODULE_ID'] . adm_back_link($this->u_action . '&parent_id=' . $this->parent_id), E_USER_WARNING);
0079 }
0080
0081 if (confirm_box(true))
0082 {
0083 // Make sure we are not directly within a module
0084 if ($module_id == $this->parent_id)
0085 {
0086 $sql = 'SELECT parent_id
0087 FROM ' . MODULES_TABLE . '
0088 WHERE module_id = ' . $module_id;
0089 $result = $db->sql_query($sql);
0090 $this->parent_id = (int) $db->sql_fetchfield('parent_id');
0091 $db->sql_freeresult($result);
0092 }
0093
0094 $errors = $this->delete_module($module_id);
0095
0096 if (!sizeof($errors))
0097 {
0098 $this->remove_cache_file();
0099 trigger_error($user->lang['MODULE_DELETED'] . adm_back_link($this->u_action . '&parent_id=' . $this->parent_id));
0100 }
0101 }
0102 else
0103 {
0104 confirm_box(false, 'DELETE_MODULE', build_hidden_fields(array(
0105 'i' => $id,
0106 'mode' => $mode,
0107 'parent_id' => $this->parent_id,
0108 'module_id' => $module_id,
0109 'action' => $action,
0110 )));
0111 }
0112
0113 break;
0114
0115 case 'enable':
0116 case 'disable':
0117 if (!$module_id)
0118 {
0119 trigger_error($user->lang['NO_MODULE_ID'] . adm_back_link($this->u_action . '&parent_id=' . $this->parent_id), E_USER_WARNING);
0120 }
0121
0122 $sql = 'SELECT *
0123 FROM ' . MODULES_TABLE . "
0124 WHERE module_class = '" . $db->sql_escape($this->module_class) . "'
0125 AND module_id = $module_id";
0126 $result = $db->sql_query($sql);
0127 $row = $db->sql_fetchrow($result);
0128 $db->sql_freeresult($result);
0129
0130 if (!$row)
0131 {
0132 trigger_error($user->lang['NO_MODULE'] . adm_back_link($this->u_action . '&parent_id=' . $this->parent_id), E_USER_WARNING);
0133 }
0134
0135 $sql = 'UPDATE ' . MODULES_TABLE . '
0136 SET module_enabled = ' . (($action == 'enable') ? 1 : 0) . "
0137 WHERE module_class = '" . $db->sql_escape($this->module_class) . "'
0138 AND module_id = $module_id";
0139 $db->sql_query($sql);
0140
0141 add_log('admin', 'LOG_MODULE_' . strtoupper($action), $this->lang_name($row['module_langname']));
0142 $this->remove_cache_file();
0143
0144 break;
0145
0146 case 'move_up':
0147 case 'move_down':
0148 if (!$module_id)
0149 {
0150 trigger_error($user->lang['NO_MODULE_ID'] . adm_back_link($this->u_action . '&parent_id=' . $this->parent_id), E_USER_WARNING);
0151 }
0152
0153 $sql = 'SELECT *
0154 FROM ' . MODULES_TABLE . "
0155 WHERE module_class = '" . $db->sql_escape($this->module_class) . "'
0156 AND module_id = $module_id";
0157 $result = $db->sql_query($sql);
0158 $row = $db->sql_fetchrow($result);
0159 $db->sql_freeresult($result);
0160
0161 if (!$row)
0162 {
0163 trigger_error($user->lang['NO_MODULE'] . adm_back_link($this->u_action . '&parent_id=' . $this->parent_id), E_USER_WARNING);
0164 }
0165
0166 $move_module_name = $this->move_module_by($row, $action, 1);
0167
0168 if ($move_module_name !== false)
0169 {
0170 add_log('admin', 'LOG_MODULE_' . strtoupper($action), $this->lang_name($row['module_langname']), $move_module_name);
0171 $this->remove_cache_file();
0172 }
0173
0174 if ($request->is_ajax())
0175 {
0176 $json_response = new \phpbb\json_response;
0177 $json_response->send(array(
0178 'success' => ($move_module_name !== false),
0179 ));
0180 }
0181
0182 break;
0183
0184 case 'quickadd':
0185 $quick_install = request_var('quick_install', '');
0186
0187 if (confirm_box(true))
0188 {
0189 if (!$quick_install || strpos($quick_install, '::') === false)
0190 {
0191 break;
0192 }
0193
0194 list($module_basename, $module_mode) = explode('::', $quick_install);
0195
0196 // Check if module name and mode exist...
0197 $fileinfo = $this->get_module_infos($module_basename);
0198 $fileinfo = $fileinfo[$module_basename];
0199
0200 if (isset($fileinfo['modes'][$module_mode]))
0201 {
0202 $module_data = array(
0203 'module_basename' => $module_basename,
0204 'module_enabled' => 0,
0205 'module_display' => (isset($fileinfo['modes'][$module_mode]['display'])) ? $fileinfo['modes'][$module_mode]['display'] : 1,
0206 'parent_id' => $this->parent_id,
0207 'module_class' => $this->module_class,
0208 'module_langname' => $fileinfo['modes'][$module_mode]['title'],
0209 'module_mode' => $module_mode,
0210 'module_auth' => $fileinfo['modes'][$module_mode]['auth'],
0211 );
0212
0213 $errors = $this->update_module_data($module_data);
0214
0215 if (!sizeof($errors))
0216 {
0217 $this->remove_cache_file();
0218
0219 trigger_error($user->lang['MODULE_ADDED'] . adm_back_link($this->u_action . '&parent_id=' . $this->parent_id));
0220 }
0221 }
0222 }
0223 else
0224 {
0225 confirm_box(false, 'ADD_MODULE', build_hidden_fields(array(
0226 'i' => $id,
0227 'mode' => $mode,
0228 'parent_id' => $this->parent_id,
0229 'action' => 'quickadd',
0230 'quick_install' => $quick_install,
0231 )));
0232 }
0233
0234 break;
0235
0236 case 'edit':
0237
0238 if (!$module_id)
0239 {
0240 trigger_error($user->lang['NO_MODULE_ID'] . adm_back_link($this->u_action . '&parent_id=' . $this->parent_id), E_USER_WARNING);
0241 }
0242
0243 $module_row = $this->get_module_row($module_id);
0244
0245 // no break
0246
0247 case 'add':
0248
0249 if ($action == 'add')
0250 {
0251 $module_row = array(
0252 'module_basename' => '',
0253 'module_enabled' => 0,
0254 'module_display' => 1,
0255 'parent_id' => 0,
0256 'module_langname' => utf8_normalize_nfc(request_var('module_langname', '', true)),
0257 'module_mode' => '',
0258 'module_auth' => '',
0259 );
0260 }
0261
0262 $module_data = array();
0263
0264 $module_data['module_basename'] = request_var('module_basename', (string) $module_row['module_basename']);
0265 $module_data['module_enabled'] = request_var('module_enabled', (int) $module_row['module_enabled']);
0266 $module_data['module_display'] = request_var('module_display', (int) $module_row['module_display']);
0267 $module_data['parent_id'] = request_var('module_parent_id', (int) $module_row['parent_id']);
0268 $module_data['module_class'] = $this->module_class;
0269 $module_data['module_langname'] = utf8_normalize_nfc(request_var('module_langname', (string) $module_row['module_langname'], true));
0270 $module_data['module_mode'] = request_var('module_mode', (string) $module_row['module_mode']);
0271
0272 $submit = (isset($_POST['submit'])) ? true : false;
0273
0274 if ($submit)
0275 {
0276 if (!$module_data['module_langname'])
0277 {
0278 trigger_error($user->lang['NO_MODULE_LANGNAME'] . adm_back_link($this->u_action . '&parent_id=' . $this->parent_id), E_USER_WARNING);
0279 }
0280
0281 $module_type = request_var('module_type', 'category');
0282
0283 if ($module_type == 'category')
0284 {
0285 $module_data['module_basename'] = $module_data['module_mode'] = $module_data['module_auth'] = '';
0286 $module_data['module_display'] = 1;
0287 }
0288
0289 if ($action == 'edit')
0290 {
0291 $module_data['module_id'] = $module_id;
0292 }
0293
0294 // Adjust auth row
0295 if ($module_data['module_basename'] && $module_data['module_mode'])
0296 {
0297 $fileinfo = $this->get_module_infos($module_data['module_basename']);
0298 $module_data['module_auth'] = $fileinfo[$module_data['module_basename']]['modes'][$module_data['module_mode']]['auth'];
0299 }
0300
0301 $errors = $this->update_module_data($module_data);
0302
0303 if (!sizeof($errors))
0304 {
0305 $this->remove_cache_file();
0306
0307 trigger_error((($action == 'add') ? $user->lang['MODULE_ADDED'] : $user->lang['MODULE_EDITED']) . adm_back_link($this->u_action . '&parent_id=' . $this->parent_id));
0308 }
0309 }
0310
0311 // Category/not category?
0312 $is_cat = (!$module_data['module_basename']) ? true : false;
0313
0314 // Get module information
0315 $module_infos = $this->get_module_infos();
0316
0317 // Build name options
0318 $s_name_options = $s_mode_options = '';
0319 foreach ($module_infos as $option => $values)
0320 {
0321 if (!$module_data['module_basename'])
0322 {
0323 $module_data['module_basename'] = $option;
0324 }
0325
0326 // Name options
0327 $s_name_options .= '<option value="' . $option . '"' . (($option == $module_data['module_basename']) ? ' selected="selected"' : '') . '>' . $this->lang_name($values['title']) . ' [' . $option . ']</option>';
0328
0329 $template->assign_block_vars('m_names', array('NAME' => $option, 'A_NAME' => addslashes($option)));
0330
0331 // Build module modes
0332 foreach ($values['modes'] as $m_mode => $m_values)
0333 {
0334 if ($option == $module_data['module_basename'])
0335 {
0336 $s_mode_options .= '<option value="' . $m_mode . '"' . (($m_mode == $module_data['module_mode']) ? ' selected="selected"' : '') . '>' . $this->lang_name($m_values['title']) . '</option>';
0337 }
0338
0339 $template->assign_block_vars('m_names.modes', array(
0340 'OPTION' => $m_mode,
0341 'VALUE' => $this->lang_name($m_values['title']),
0342 'A_OPTION' => addslashes($m_mode),
0343 'A_VALUE' => addslashes($this->lang_name($m_values['title'])))
0344 );
0345 }
0346 }
0347
0348 $s_cat_option = '<option value="0"' . (($module_data['parent_id'] == 0) ? ' selected="selected"' : '') . '>' . $user->lang['NO_PARENT'] . '</option>';
0349
0350 $template->assign_vars(array_merge(array(
0351 'S_EDIT_MODULE' => true,
0352 'S_IS_CAT' => $is_cat,
0353 'S_CAT_OPTIONS' => $s_cat_option . $this->make_module_select($module_data['parent_id'], ($action == 'edit') ? $module_row['module_id'] : false, false, false, false, true),
0354 'S_MODULE_NAMES' => $s_name_options,
0355 'S_MODULE_MODES' => $s_mode_options,
0356 'U_BACK' => $this->u_action . '&parent_id=' . $this->parent_id,
0357 'U_EDIT_ACTION' => $this->u_action . '&parent_id=' . $this->parent_id,
0358
0359 'L_TITLE' => $user->lang[strtoupper($action) . '_MODULE'],
0360
0361 'MODULENAME' => $this->lang_name($module_data['module_langname']),
0362 'ACTION' => $action,
0363 'MODULE_ID' => $module_id,
0364
0365 ),
0366 array_change_key_case($module_data, CASE_UPPER))
0367 );
0368
0369 if (sizeof($errors))
0370 {
0371 $template->assign_vars(array(
0372 'S_ERROR' => true,
0373 'ERROR_MSG' => implode('<br />', $errors))
0374 );
0375 }
0376
0377 return;
0378
0379 break;
0380 }
0381
0382 // Default management page
0383 if (sizeof($errors))
0384 {
0385 if ($request->is_ajax())
0386 {
0387 $json_response = new \phpbb\json_response;
0388 $json_response->send(array(
0389 'MESSAGE_TITLE' => $user->lang('ERROR'),
0390 'MESSAGE_TEXT' => implode('<br />', $errors),
0391 'SUCCESS' => false,
0392 ));
0393 }
0394
0395 $template->assign_vars(array(
0396 'S_ERROR' => true,
0397 'ERROR_MSG' => implode('<br />', $errors))
0398 );
0399 }
0400
0401 if (!$this->parent_id)
0402 {
0403 $navigation = strtoupper($this->module_class);
0404 }
0405 else
0406 {
0407 $navigation = '<a href="' . $this->u_action . '">' . strtoupper($this->module_class) . '</a>';
0408
0409 $modules_nav = $this->get_module_branch($this->parent_id, 'parents', 'descending');
0410
0411 foreach ($modules_nav as $row)
0412 {
0413 $langname = $this->lang_name($row['module_langname']);
0414
0415 if ($row['module_id'] == $this->parent_id)
0416 {
0417 $navigation .= ' -> ' . $langname;
0418 }
0419 else
0420 {
0421 $navigation .= ' -> <a href="' . $this->u_action . '&parent_id=' . $row['module_id'] . '">' . $langname . '</a>';
0422 }
0423 }
0424 }
0425
0426 // Jumpbox
0427 $module_box = $this->make_module_select($this->parent_id, false, false, false, false);
0428
0429 $sql = 'SELECT *
0430 FROM ' . MODULES_TABLE . "
0431 WHERE parent_id = {$this->parent_id}
0432 AND module_class = '" . $db->sql_escape($this->module_class) . "'
0433 ORDER BY left_id";
0434 $result = $db->sql_query($sql);
0435
0436 if ($row = $db->sql_fetchrow($result))
0437 {
0438 do
0439 {
0440 $langname = $this->lang_name($row['module_langname']);
0441
0442 if (!$row['module_enabled'])
0443 {
0444 $module_image = '<img src="images/icon_folder_lock.gif" alt="' . $user->lang['DEACTIVATED_MODULE'] .'" />';
0445 }
0446 else
0447 {
0448 $module_image = (!$row['module_basename'] || $row['left_id'] + 1 != $row['right_id']) ? '<img src="images/icon_subfolder.gif" alt="' . $user->lang['CATEGORY'] . '" />' : '<img src="images/icon_folder.gif" alt="' . $user->lang['MODULE'] . '" />';
0449 }
0450
0451 $url = $this->u_action . '&parent_id=' . $this->parent_id . '&m=' . $row['module_id'];
0452
0453 $template->assign_block_vars('modules', array(
0454 'MODULE_IMAGE' => $module_image,
0455 'MODULE_TITLE' => $langname,
0456 'MODULE_ENABLED' => ($row['module_enabled']) ? true : false,
0457 'MODULE_DISPLAYED' => ($row['module_display']) ? true : false,
0458
0459 'S_ACP_CAT_SYSTEM' => ($this->module_class == 'acp' && $row['module_langname'] == 'ACP_CAT_SYSTEM') ? true : false,
0460 'S_ACP_MODULE_MANAGEMENT' => ($this->module_class == 'acp' && ($row['module_basename'] == 'modules' || $row['module_langname'] == 'ACP_MODULE_MANAGEMENT')) ? true : false,
0461
0462 'U_MODULE' => $this->u_action . '&parent_id=' . $row['module_id'],
0463 'U_MOVE_UP' => $url . '&action=move_up',
0464 'U_MOVE_DOWN' => $url . '&action=move_down',
0465 'U_EDIT' => $url . '&action=edit',
0466 'U_DELETE' => $url . '&action=delete',
0467 'U_ENABLE' => $url . '&action=enable',
0468 'U_DISABLE' => $url . '&action=disable')
0469 );
0470 }
0471 while ($row = $db->sql_fetchrow($result));
0472 }
0473 else if ($this->parent_id)
0474 {
0475 $row = $this->get_module_row($this->parent_id);
0476
0477 $url = $this->u_action . '&parent_id=' . $this->parent_id . '&m=' . $row['module_id'];
0478
0479 $template->assign_vars(array(
0480 'S_NO_MODULES' => true,
0481 'MODULE_TITLE' => $langname,
0482 'MODULE_ENABLED' => ($row['module_enabled']) ? true : false,
0483 'MODULE_DISPLAYED' => ($row['module_display']) ? true : false,
0484
0485 'U_EDIT' => $url . '&action=edit',
0486 'U_DELETE' => $url . '&action=delete',
0487 'U_ENABLE' => $url . '&action=enable',
0488 'U_DISABLE' => $url . '&action=disable')
0489 );
0490 }
0491 $db->sql_freeresult($result);
0492
0493 // Quick adding module
0494 $module_infos = $this->get_module_infos();
0495
0496 // Build quick options
0497 $s_install_options = '';
0498 foreach ($module_infos as $option => $values)
0499 {
0500 // Name options
0501 $s_install_options .= '<optgroup label="' . $this->lang_name($values['title']) . ' [' . $option . ']">';
0502
0503 // Build module modes
0504 foreach ($values['modes'] as $m_mode => $m_values)
0505 {
0506 $s_install_options .= '<option value="' . $option . '::' . $m_mode . '"> ' . $this->lang_name($m_values['title']) . '</option>';
0507 }
0508
0509 $s_install_options .= '</optgroup>';
0510 }
0511
0512 $template->assign_vars(array(
0513 'U_SEL_ACTION' => $this->u_action,
0514 'U_ACTION' => $this->u_action . '&parent_id=' . $this->parent_id,
0515 'NAVIGATION' => $navigation,
0516 'MODULE_BOX' => $module_box,
0517 'PARENT_ID' => $this->parent_id,
0518 'S_INSTALL_OPTIONS' => $s_install_options,
0519 )
0520 );
0521 }
0522
0523 /**
0524 * Get row for specified module
0525 */
0526 function get_module_row($module_id)
0527 {
0528 global $db, $user;
0529
0530 $sql = 'SELECT *
0531 FROM ' . MODULES_TABLE . "
0532 WHERE module_class = '" . $db->sql_escape($this->module_class) . "'
0533 AND module_id = $module_id";
0534 $result = $db->sql_query($sql);
0535 $row = $db->sql_fetchrow($result);
0536 $db->sql_freeresult($result);
0537
0538 if (!$row)
0539 {
0540 trigger_error($user->lang['NO_MODULE'] . adm_back_link($this->u_action . '&parent_id=' . $this->parent_id), E_USER_WARNING);
0541 }
0542
0543 return $row;
0544 }
0545
0546 /**
0547 * Get available module information from module files
0548 *
0549 * @param string $module
0550 * @param bool|string $module_class
0551 * @param bool $use_all_available Use all available instead of just all
0552 * enabled extensions
0553 * @return array
0554 */
0555 function get_module_infos($module = '', $module_class = false, $use_all_available = false)
0556 {
0557 global $phpbb_extension_manager, $phpbb_root_path, $phpEx;
0558
0559 $module_class = ($module_class === false) ? $this->module_class : $module_class;
0560
0561 $directory = $phpbb_root_path . 'includes/' . $module_class . '/info/';
0562 $fileinfo = array();
0563
0564 $finder = $phpbb_extension_manager->get_finder($use_all_available);
0565
0566 $modules = $finder
0567 ->extension_suffix('_module')
0568 ->extension_directory("/$module_class")
0569 ->core_path("includes/$module_class/info/")
0570 ->core_prefix($module_class . '_')
0571 ->get_classes(true);
0572
0573 foreach ($modules as $cur_module)
0574 {
0575 // Skip entries we do not need if we know the module we are
0576 // looking for
0577 if ($module && strpos(str_replace('\\', '_', $cur_module), $module) === false && $module !== $cur_module)
0578 {
0579 continue;
0580 }
0581
0582 $info_class = preg_replace('/_module$/', '_info', $cur_module);
0583
0584 // If the class does not exist it might be following the old
0585 // format. phpbb_acp_info_acp_foo needs to be turned into
0586 // acp_foo_info and the respective file has to be included
0587 // manually because it does not support auto loading
0588 $old_info_class_file = str_replace("phpbb_{$module_class}_info_", '', $cur_module);
0589 $old_info_class = $old_info_class_file . '_info';
0590
0591 if (class_exists($old_info_class))
0592 {
0593 $info_class = $old_info_class;
0594 }
0595 else if (!class_exists($info_class))
0596 {
0597 $info_class = $old_info_class;
0598 // need to check class exists again because previous checks triggered autoloading
0599 if (!class_exists($info_class) && file_exists($directory . $old_info_class_file . '.' . $phpEx))
0600 {
0601 include($directory . $old_info_class_file . '.' . $phpEx);
0602 }
0603 }
0604
0605 if (class_exists($info_class))
0606 {
0607 $info = new $info_class();
0608 $module_info = $info->module();
0609
0610 $main_class = (isset($module_info['filename'])) ? $module_info['filename'] : $cur_module;
0611
0612 $fileinfo[$main_class] = $module_info;
0613 }
0614 }
0615
0616 ksort($fileinfo);
0617
0618 return $fileinfo;
0619 }
0620
0621 /**
0622 * Simple version of jumpbox, just lists modules
0623 */
0624 function make_module_select($select_id = false, $ignore_id = false, $ignore_acl = false, $ignore_nonpost = false, $ignore_emptycat = true, $ignore_noncat = false)
0625 {
0626 global $db, $user, $auth, $config;
0627
0628 $sql = 'SELECT module_id, module_enabled, module_basename, parent_id, module_langname, left_id, right_id, module_auth
0629 FROM ' . MODULES_TABLE . "
0630 WHERE module_class = '" . $db->sql_escape($this->module_class) . "'
0631 ORDER BY left_id ASC";
0632 $result = $db->sql_query($sql);
0633
0634 $right = $iteration = 0;
0635 $padding_store = array('0' => '');
0636 $module_list = $padding = '';
0637
0638 while ($row = $db->sql_fetchrow($result))
0639 {
0640 if ($row['left_id'] < $right)
0641 {
0642 $padding .= ' ';
0643 $padding_store[$row['parent_id']] = $padding;
0644 }
0645 else if ($row['left_id'] > $right + 1)
0646 {
0647 $padding = (isset($padding_store[$row['parent_id']])) ? $padding_store[$row['parent_id']] : '';
0648 }
0649
0650 $right = $row['right_id'];
0651
0652 if (!$ignore_acl && $row['module_auth'])
0653 {
0654 // We use zero as the forum id to check - global setting.
0655 if (!p_master::module_auth($row['module_auth'], 0))
0656 {
0657 continue;
0658 }
0659 }
0660
0661 // ignore this module?
0662 if ((is_array($ignore_id) && in_array($row['module_id'], $ignore_id)) || $row['module_id'] == $ignore_id)
0663 {
0664 continue;
0665 }
0666
0667 // empty category
0668 if (!$row['module_basename'] && ($row['left_id'] + 1 == $row['right_id']) && $ignore_emptycat)
0669 {
0670 continue;
0671 }
0672
0673 // ignore non-category?
0674 if ($row['module_basename'] && $ignore_noncat)
0675 {
0676 continue;
0677 }
0678
0679 $selected = (is_array($select_id)) ? ((in_array($row['module_id'], $select_id)) ? ' selected="selected"' : '') : (($row['module_id'] == $select_id) ? ' selected="selected"' : '');
0680
0681 $langname = $this->lang_name($row['module_langname']);
0682 $module_list .= '<option value="' . $row['module_id'] . '"' . $selected . ((!$row['module_enabled']) ? ' class="disabled"' : '') . '>' . $padding . $langname . '</option>';
0683
0684 $iteration++;
0685 }
0686 $db->sql_freeresult($result);
0687
0688 unset($padding_store);
0689
0690 return $module_list;
0691 }
0692
0693 /**
0694 * Get module branch
0695 */
0696 function get_module_branch($module_id, $type = 'all', $order = 'descending', $include_module = true)
0697 {
0698 global $db;
0699
0700 switch ($type)
0701 {
0702 case 'parents':
0703 $condition = 'm1.left_id BETWEEN m2.left_id AND m2.right_id';
0704 break;
0705
0706 case 'children':
0707 $condition = 'm2.left_id BETWEEN m1.left_id AND m1.right_id';
0708 break;
0709
0710 default:
0711 $condition = 'm2.left_id BETWEEN m1.left_id AND m1.right_id OR m1.left_id BETWEEN m2.left_id AND m2.right_id';
0712 break;
0713 }
0714
0715 $rows = array();
0716
0717 $sql = 'SELECT m2.*
0718 FROM ' . MODULES_TABLE . ' m1
0719 LEFT JOIN ' . MODULES_TABLE . " m2 ON ($condition)
0720 WHERE m1.module_class = '" . $db->sql_escape($this->module_class) . "'
0721 AND m2.module_class = '" . $db->sql_escape($this->module_class) . "'
0722 AND m1.module_id = $module_id
0723 ORDER BY m2.left_id " . (($order == 'descending') ? 'ASC' : 'DESC');
0724 $result = $db->sql_query($sql);
0725
0726 while ($row = $db->sql_fetchrow($result))
0727 {
0728 if (!$include_module && $row['module_id'] == $module_id)
0729 {
0730 continue;
0731 }
0732
0733 $rows[] = $row;
0734 }
0735 $db->sql_freeresult($result);
0736
0737 return $rows;
0738 }
0739
0740 /**
0741 * Remove modules cache file
0742 */
0743 function remove_cache_file()
0744 {
0745 global $phpbb_container;
0746
0747 // Sanitise for future path use, it's escaped as appropriate for queries
0748 $p_class = str_replace(array('.', '/', '\\'), '', basename($this->module_class));
0749
0750 $phpbb_container->get('cache.driver')->destroy('_modules_' . $p_class);
0751
0752 // Additionally remove sql cache
0753 $phpbb_container->get('cache.driver')->destroy('sql', MODULES_TABLE);
0754 }
0755
0756 /**
0757 * Return correct language name
0758 */
0759 function lang_name($module_langname)
0760 {
0761 global $user;
0762
0763 return (!empty($user->lang[$module_langname])) ? $user->lang[$module_langname] : $module_langname;
0764 }
0765
0766 /**
0767 * Update/Add module
0768 *
0769 * @param array &$module_data The module data
0770 * @param bool $run_inline if set to true errors will be returned and no logs being written
0771 */
0772 function update_module_data(&$module_data, $run_inline = false)
0773 {
0774 global $db, $user;
0775
0776 if (!isset($module_data['module_id']))
0777 {
0778 // no module_id means we're creating a new category/module
0779 if ($module_data['parent_id'])
0780 {
0781 $sql = 'SELECT left_id, right_id
0782 FROM ' . MODULES_TABLE . "
0783 WHERE module_class = '" . $db->sql_escape($module_data['module_class']) . "'
0784 AND module_id = " . (int) $module_data['parent_id'];
0785 $result = $db->sql_query($sql);
0786 $row = $db->sql_fetchrow($result);
0787 $db->sql_freeresult($result);
0788
0789 if (!$row)
0790 {
0791 if ($run_inline)
0792 {
0793 return 'PARENT_NO_EXIST';
0794 }
0795
0796 trigger_error($user->lang['PARENT_NO_EXIST'] . adm_back_link($this->u_action . '&parent_id=' . $this->parent_id), E_USER_WARNING);
0797 }
0798
0799 // Workaround
0800 $row['left_id'] = (int) $row['left_id'];
0801 $row['right_id'] = (int) $row['right_id'];
0802
0803 $sql = 'UPDATE ' . MODULES_TABLE . "
0804 SET left_id = left_id + 2, right_id = right_id + 2
0805 WHERE module_class = '" . $db->sql_escape($module_data['module_class']) . "'
0806 AND left_id > {$row['right_id']}";
0807 $db->sql_query($sql);
0808
0809 $sql = 'UPDATE ' . MODULES_TABLE . "
0810 SET right_id = right_id + 2
0811 WHERE module_class = '" . $db->sql_escape($module_data['module_class']) . "'
0812 AND {$row['left_id']} BETWEEN left_id AND right_id";
0813 $db->sql_query($sql);
0814
0815 $module_data['left_id'] = (int) $row['right_id'];
0816 $module_data['right_id'] = (int) $row['right_id'] + 1;
0817 }
0818 else
0819 {
0820 $sql = 'SELECT MAX(right_id) AS right_id
0821 FROM ' . MODULES_TABLE . "
0822 WHERE module_class = '" . $db->sql_escape($module_data['module_class']) . "'";
0823 $result = $db->sql_query($sql);
0824 $row = $db->sql_fetchrow($result);
0825 $db->sql_freeresult($result);
0826
0827 $module_data['left_id'] = (int) $row['right_id'] + 1;
0828 $module_data['right_id'] = (int) $row['right_id'] + 2;
0829 }
0830
0831 $sql = 'INSERT INTO ' . MODULES_TABLE . ' ' . $db->sql_build_array('INSERT', $module_data);
0832 $db->sql_query($sql);
0833
0834 $module_data['module_id'] = $db->sql_nextid();
0835
0836 if (!$run_inline)
0837 {
0838 add_log('admin', 'LOG_MODULE_ADD', $this->lang_name($module_data['module_langname']));
0839 }
0840 }
0841 else
0842 {
0843 $row = $this->get_module_row($module_data['module_id']);
0844
0845 if ($module_data['module_basename'] && !$row['module_basename'])
0846 {
0847 // we're turning a category into a module
0848 $branch = $this->get_module_branch($module_data['module_id'], 'children', 'descending', false);
0849
0850 if (sizeof($branch))
0851 {
0852 return array($user->lang['NO_CATEGORY_TO_MODULE']);
0853 }
0854 }
0855
0856 if ($row['parent_id'] != $module_data['parent_id'])
0857 {
0858 $this->move_module($module_data['module_id'], $module_data['parent_id']);
0859 }
0860
0861 $update_ary = $module_data;
0862 unset($update_ary['module_id']);
0863
0864 $sql = 'UPDATE ' . MODULES_TABLE . '
0865 SET ' . $db->sql_build_array('UPDATE', $update_ary) . "
0866 WHERE module_class = '" . $db->sql_escape($module_data['module_class']) . "'
0867 AND module_id = " . (int) $module_data['module_id'];
0868 $db->sql_query($sql);
0869
0870 if (!$run_inline)
0871 {
0872 add_log('admin', 'LOG_MODULE_EDIT', $this->lang_name($module_data['module_langname']));
0873 }
0874 }
0875
0876 return array();
0877 }
0878
0879 /**
0880 * Move module around the tree
0881 */
0882 function move_module($from_module_id, $to_parent_id)
0883 {
0884 global $db;
0885
0886 $moved_modules = $this->get_module_branch($from_module_id, 'children', 'descending');
0887 $from_data = $moved_modules[0];
0888 $diff = sizeof($moved_modules) * 2;
0889
0890 $moved_ids = array();
0891 for ($i = 0; $i < sizeof($moved_modules); ++$i)
0892 {
0893 $moved_ids[] = $moved_modules[$i]['module_id'];
0894 }
0895
0896 // Resync parents
0897 $sql = 'UPDATE ' . MODULES_TABLE . "
0898 SET right_id = right_id - $diff
0899 WHERE module_class = '" . $db->sql_escape($this->module_class) . "'
0900 AND left_id < " . (int) $from_data['right_id'] . '
0901 AND right_id > ' . (int) $from_data['right_id'];
0902 $db->sql_query($sql);
0903
0904 // Resync righthand side of tree
0905 $sql = 'UPDATE ' . MODULES_TABLE . "
0906 SET left_id = left_id - $diff, right_id = right_id - $diff
0907 WHERE module_class = '" . $db->sql_escape($this->module_class) . "'
0908 AND left_id > " . (int) $from_data['right_id'];
0909 $db->sql_query($sql);
0910
0911 if ($to_parent_id > 0)
0912 {
0913 $to_data = $this->get_module_row($to_parent_id);
0914
0915 // Resync new parents
0916 $sql = 'UPDATE ' . MODULES_TABLE . "
0917 SET right_id = right_id + $diff
0918 WHERE module_class = '" . $db->sql_escape($this->module_class) . "'
0919 AND " . (int) $to_data['right_id'] . ' BETWEEN left_id AND right_id
0920 AND ' . $db->sql_in_set('module_id', $moved_ids, true);
0921 $db->sql_query($sql);
0922
0923 // Resync the righthand side of the tree
0924 $sql = 'UPDATE ' . MODULES_TABLE . "
0925 SET left_id = left_id + $diff, right_id = right_id + $diff
0926 WHERE module_class = '" . $db->sql_escape($this->module_class) . "'
0927 AND left_id > " . (int) $to_data['right_id'] . '
0928 AND ' . $db->sql_in_set('module_id', $moved_ids, true);
0929 $db->sql_query($sql);
0930
0931 // Resync moved branch
0932 $to_data['right_id'] += $diff;
0933 if ($to_data['right_id'] > $from_data['right_id'])
0934 {
0935 $diff = '+ ' . ($to_data['right_id'] - $from_data['right_id'] - 1);
0936 }
0937 else
0938 {
0939 $diff = '- ' . abs($to_data['right_id'] - $from_data['right_id'] - 1);
0940 }
0941 }
0942 else
0943 {
0944 $sql = 'SELECT MAX(right_id) AS right_id
0945 FROM ' . MODULES_TABLE . "
0946 WHERE module_class = '" . $db->sql_escape($this->module_class) . "'
0947 AND " . $db->sql_in_set('module_id', $moved_ids, true);
0948 $result = $db->sql_query($sql);
0949 $row = $db->sql_fetchrow($result);
0950 $db->sql_freeresult($result);
0951
0952 $diff = '+ ' . (int) ($row['right_id'] - $from_data['left_id'] + 1);
0953 }
0954
0955 $sql = 'UPDATE ' . MODULES_TABLE . "
0956 SET left_id = left_id $diff, right_id = right_id $diff
0957 WHERE module_class = '" . $db->sql_escape($this->module_class) . "'
0958 AND " . $db->sql_in_set('module_id', $moved_ids);
0959 $db->sql_query($sql);
0960 }
0961
0962 /**
0963 * Remove module from tree
0964 */
0965 function delete_module($module_id)
0966 {
0967 global $db, $user;
0968
0969 $row = $this->get_module_row($module_id);
0970
0971 $branch = $this->get_module_branch($module_id, 'children', 'descending', false);
0972
0973 if (sizeof($branch))
0974 {
0975 return array($user->lang['CANNOT_REMOVE_MODULE']);
0976 }
0977
0978 // If not move
0979 $diff = 2;
0980 $sql = 'DELETE FROM ' . MODULES_TABLE . "
0981 WHERE module_class = '" . $db->sql_escape($this->module_class) . "'
0982 AND module_id = $module_id";
0983 $db->sql_query($sql);
0984
0985 $row['right_id'] = (int) $row['right_id'];
0986 $row['left_id'] = (int) $row['left_id'];
0987
0988 // Resync tree
0989 $sql = 'UPDATE ' . MODULES_TABLE . "
0990 SET right_id = right_id - $diff
0991 WHERE module_class = '" . $db->sql_escape($this->module_class) . "'
0992 AND left_id < {$row['right_id']} AND right_id > {$row['right_id']}";
0993 $db->sql_query($sql);
0994
0995 $sql = 'UPDATE ' . MODULES_TABLE . "
0996 SET left_id = left_id - $diff, right_id = right_id - $diff
0997 WHERE module_class = '" . $db->sql_escape($this->module_class) . "'
0998 AND left_id > {$row['right_id']}";
0999 $db->sql_query($sql);
1000
1001 add_log('admin', 'LOG_MODULE_REMOVED', $this->lang_name($row['module_langname']));
1002
1003 return array();
1004
1005 }
1006
1007 /**
1008 * Move module position by $steps up/down
1009 */
1010 function move_module_by($module_row, $action = 'move_up', $steps = 1)
1011 {
1012 global $db;
1013
1014 /**
1015 * Fetch all the siblings between the module's current spot
1016 * and where we want to move it to. If there are less than $steps
1017 * siblings between the current spot and the target then the
1018 * module will move as far as possible
1019 */
1020 $sql = 'SELECT module_id, left_id, right_id, module_langname
1021 FROM ' . MODULES_TABLE . "
1022 WHERE module_class = '" . $db->sql_escape($this->module_class) . "'
1023 AND parent_id = " . (int) $module_row['parent_id'] . '
1024 AND ' . (($action == 'move_up') ? 'right_id < ' . (int) $module_row['right_id'] . ' ORDER BY right_id DESC' : 'left_id > ' . (int) $module_row['left_id'] . ' ORDER BY left_id ASC');
1025 $result = $db->sql_query_limit($sql, $steps);
1026
1027 $target = array();
1028 while ($row = $db->sql_fetchrow($result))
1029 {
1030 $target = $row;
1031 }
1032 $db->sql_freeresult($result);
1033
1034 if (!sizeof($target))
1035 {
1036 // The module is already on top or bottom
1037 return false;
1038 }
1039
1040 /**
1041 * $left_id and $right_id define the scope of the nodes that are affected by the move.
1042 * $diff_up and $diff_down are the values to substract or add to each node's left_id
1043 * and right_id in order to move them up or down.
1044 * $move_up_left and $move_up_right define the scope of the nodes that are moving
1045 * up. Other nodes in the scope of ($left_id, $right_id) are considered to move down.
1046 */
1047 if ($action == 'move_up')
1048 {
1049 $left_id = (int) $target['left_id'];
1050 $right_id = (int) $module_row['right_id'];
1051
1052 $diff_up = (int) ($module_row['left_id'] - $target['left_id']);
1053 $diff_down = (int) ($module_row['right_id'] + 1 - $module_row['left_id']);
1054
1055 $move_up_left = (int) $module_row['left_id'];
1056 $move_up_right = (int) $module_row['right_id'];
1057 }
1058 else
1059 {
1060 $left_id = (int) $module_row['left_id'];
1061 $right_id = (int) $target['right_id'];
1062
1063 $diff_up = (int) ($module_row['right_id'] + 1 - $module_row['left_id']);
1064 $diff_down = (int) ($target['right_id'] - $module_row['right_id']);
1065
1066 $move_up_left = (int) ($module_row['right_id'] + 1);
1067 $move_up_right = (int) $target['right_id'];
1068 }
1069
1070 // Now do the dirty job
1071 $sql = 'UPDATE ' . MODULES_TABLE . "
1072 SET left_id = left_id + CASE
1073 WHEN left_id BETWEEN {$move_up_left} AND {$move_up_right} THEN -{$diff_up}
1074 ELSE {$diff_down}
1075 END,
1076 right_id = right_id + CASE
1077 WHEN right_id BETWEEN {$move_up_left} AND {$move_up_right} THEN -{$diff_up}
1078 ELSE {$diff_down}
1079 END
1080 WHERE module_class = '" . $db->sql_escape($this->module_class) . "'
1081 AND left_id BETWEEN {$left_id} AND {$right_id}
1082 AND right_id BETWEEN {$left_id} AND {$right_id}";
1083 $db->sql_query($sql);
1084
1085 $this->remove_cache_file();
1086
1087 return $this->lang_name($target['module_langname']);
1088 }
1089 }
1090