[ Index ] |
PHP Cross Reference of phpBB-3.1.12-deutsch |
[Summary view] [Print] [Text view]
1 <?php 2 /** 3 * 4 * This file is part of the phpBB Forum Software package. 5 * 6 * @copyright (c) phpBB Limited <https://www.phpbb.com> 7 * @license GNU General Public License, version 2 (GPL-2.0) 8 * 9 * For full copyright and license information, please see 10 * the docs/CREDITS.txt file. 11 * 12 */ 13 14 /** 15 * @ignore 16 */ 17 if (!defined('IN_PHPBB')) 18 { 19 exit; 20 } 21 22 /** 23 * - Able to check for new module versions (modes changed/adjusted/added/removed) 24 * Icons for: 25 * - module enabled and displayed (common) 26 * - module enabled and not displayed 27 * - module deactivated 28 * - category (enabled) 29 * - category disabled 30 */ 31 32 class acp_modules 33 { 34 var $module_class = ''; 35 var $parent_id; 36 var $u_action; 37 38 function main($id, $mode) 39 { 40 global $db, $user, $auth, $template, $module, $request; 41 global $config, $phpbb_admin_path, $phpbb_root_path, $phpEx; 42 43 // Set a global define for modules we might include (the author is able to prevent execution of code by checking this constant) 44 define('MODULE_INCLUDE', true); 45 46 $user->add_lang('acp/modules'); 47 $this->tpl_name = 'acp_modules'; 48 49 $form_key = 'acp_modules'; 50 add_form_key($form_key); 51 52 // module class 53 $this->module_class = $mode; 54 55 if ($this->module_class == 'ucp') 56 { 57 $user->add_lang('ucp'); 58 } 59 else if ($this->module_class == 'mcp') 60 { 61 $user->add_lang('mcp'); 62 } 63 64 if ($module->p_class != $this->module_class) 65 { 66 $module->add_mod_info($this->module_class); 67 } 68 69 $this->page_title = strtoupper($this->module_class); 70 71 $this->parent_id = request_var('parent_id', 0); 72 $module_id = request_var('m', 0); 73 $action = request_var('action', ''); 74 $errors = array(); 75 76 switch ($action) 77 { 78 case 'delete': 79 if (!$module_id) 80 { 81 trigger_error($user->lang['NO_MODULE_ID'] . adm_back_link($this->u_action . '&parent_id=' . $this->parent_id), E_USER_WARNING); 82 } 83 84 if (confirm_box(true)) 85 { 86 // Make sure we are not directly within a module 87 if ($module_id == $this->parent_id) 88 { 89 $sql = 'SELECT parent_id 90 FROM ' . MODULES_TABLE . ' 91 WHERE module_id = ' . $module_id; 92 $result = $db->sql_query($sql); 93 $this->parent_id = (int) $db->sql_fetchfield('parent_id'); 94 $db->sql_freeresult($result); 95 } 96 97 $errors = $this->delete_module($module_id); 98 99 if (!sizeof($errors)) 100 { 101 $this->remove_cache_file(); 102 trigger_error($user->lang['MODULE_DELETED'] . adm_back_link($this->u_action . '&parent_id=' . $this->parent_id)); 103 } 104 } 105 else 106 { 107 confirm_box(false, 'DELETE_MODULE', build_hidden_fields(array( 108 'i' => $id, 109 'mode' => $mode, 110 'parent_id' => $this->parent_id, 111 'module_id' => $module_id, 112 'action' => $action, 113 ))); 114 } 115 116 break; 117 118 case 'enable': 119 case 'disable': 120 if (!$module_id) 121 { 122 trigger_error($user->lang['NO_MODULE_ID'] . adm_back_link($this->u_action . '&parent_id=' . $this->parent_id), E_USER_WARNING); 123 } 124 125 if (!check_link_hash($request->variable('hash', ''), 'acp_modules')) 126 { 127 trigger_error($user->lang['FORM_INVALID'] . adm_back_link($this->u_action . '&parent_id=' . $this->parent_id), E_USER_WARNING); 128 } 129 130 $sql = 'SELECT * 131 FROM ' . MODULES_TABLE . " 132 WHERE module_class = '" . $db->sql_escape($this->module_class) . "' 133 AND module_id = $module_id"; 134 $result = $db->sql_query($sql); 135 $row = $db->sql_fetchrow($result); 136 $db->sql_freeresult($result); 137 138 if (!$row) 139 { 140 trigger_error($user->lang['NO_MODULE'] . adm_back_link($this->u_action . '&parent_id=' . $this->parent_id), E_USER_WARNING); 141 } 142 143 $sql = 'UPDATE ' . MODULES_TABLE . ' 144 SET module_enabled = ' . (($action == 'enable') ? 1 : 0) . " 145 WHERE module_class = '" . $db->sql_escape($this->module_class) . "' 146 AND module_id = $module_id"; 147 $db->sql_query($sql); 148 149 add_log('admin', 'LOG_MODULE_' . strtoupper($action), $this->lang_name($row['module_langname'])); 150 $this->remove_cache_file(); 151 152 break; 153 154 case 'move_up': 155 case 'move_down': 156 if (!$module_id) 157 { 158 trigger_error($user->lang['NO_MODULE_ID'] . adm_back_link($this->u_action . '&parent_id=' . $this->parent_id), E_USER_WARNING); 159 } 160 161 if (!check_link_hash($request->variable('hash', ''), 'acp_modules')) 162 { 163 trigger_error($user->lang['FORM_INVALID'] . adm_back_link($this->u_action . '&parent_id=' . $this->parent_id), E_USER_WARNING); 164 } 165 166 $sql = 'SELECT * 167 FROM ' . MODULES_TABLE . " 168 WHERE module_class = '" . $db->sql_escape($this->module_class) . "' 169 AND module_id = $module_id"; 170 $result = $db->sql_query($sql); 171 $row = $db->sql_fetchrow($result); 172 $db->sql_freeresult($result); 173 174 if (!$row) 175 { 176 trigger_error($user->lang['NO_MODULE'] . adm_back_link($this->u_action . '&parent_id=' . $this->parent_id), E_USER_WARNING); 177 } 178 179 $move_module_name = $this->move_module_by($row, $action, 1); 180 181 if ($move_module_name !== false) 182 { 183 add_log('admin', 'LOG_MODULE_' . strtoupper($action), $this->lang_name($row['module_langname']), $move_module_name); 184 $this->remove_cache_file(); 185 } 186 187 if ($request->is_ajax()) 188 { 189 $json_response = new \phpbb\json_response; 190 $json_response->send(array( 191 'success' => ($move_module_name !== false), 192 )); 193 } 194 195 break; 196 197 case 'quickadd': 198 $quick_install = request_var('quick_install', ''); 199 200 if (confirm_box(true)) 201 { 202 if (!$quick_install || strpos($quick_install, '::') === false) 203 { 204 break; 205 } 206 207 list($module_basename, $module_mode) = explode('::', $quick_install); 208 209 // Check if module name and mode exist... 210 $fileinfo = $this->get_module_infos($module_basename); 211 $fileinfo = $fileinfo[$module_basename]; 212 213 if (isset($fileinfo['modes'][$module_mode])) 214 { 215 $module_data = array( 216 'module_basename' => $module_basename, 217 'module_enabled' => 0, 218 'module_display' => (isset($fileinfo['modes'][$module_mode]['display'])) ? $fileinfo['modes'][$module_mode]['display'] : 1, 219 'parent_id' => $this->parent_id, 220 'module_class' => $this->module_class, 221 'module_langname' => $fileinfo['modes'][$module_mode]['title'], 222 'module_mode' => $module_mode, 223 'module_auth' => $fileinfo['modes'][$module_mode]['auth'], 224 ); 225 226 $errors = $this->update_module_data($module_data); 227 228 if (!sizeof($errors)) 229 { 230 $this->remove_cache_file(); 231 232 trigger_error($user->lang['MODULE_ADDED'] . adm_back_link($this->u_action . '&parent_id=' . $this->parent_id)); 233 } 234 } 235 } 236 else 237 { 238 confirm_box(false, 'ADD_MODULE', build_hidden_fields(array( 239 'i' => $id, 240 'mode' => $mode, 241 'parent_id' => $this->parent_id, 242 'action' => 'quickadd', 243 'quick_install' => $quick_install, 244 ))); 245 } 246 247 break; 248 249 case 'edit': 250 251 if (!$module_id) 252 { 253 trigger_error($user->lang['NO_MODULE_ID'] . adm_back_link($this->u_action . '&parent_id=' . $this->parent_id), E_USER_WARNING); 254 } 255 256 $module_row = $this->get_module_row($module_id); 257 258 // no break 259 260 case 'add': 261 262 if ($action == 'add') 263 { 264 $module_row = array( 265 'module_basename' => '', 266 'module_enabled' => 0, 267 'module_display' => 1, 268 'parent_id' => 0, 269 'module_langname' => utf8_normalize_nfc(request_var('module_langname', '', true)), 270 'module_mode' => '', 271 'module_auth' => '', 272 ); 273 } 274 275 $module_data = array(); 276 277 $module_data['module_basename'] = request_var('module_basename', (string) $module_row['module_basename']); 278 $module_data['module_enabled'] = request_var('module_enabled', (int) $module_row['module_enabled']); 279 $module_data['module_display'] = request_var('module_display', (int) $module_row['module_display']); 280 $module_data['parent_id'] = request_var('module_parent_id', (int) $module_row['parent_id']); 281 $module_data['module_class'] = $this->module_class; 282 $module_data['module_langname'] = utf8_normalize_nfc(request_var('module_langname', (string) $module_row['module_langname'], true)); 283 $module_data['module_mode'] = request_var('module_mode', (string) $module_row['module_mode']); 284 285 $submit = (isset($_POST['submit'])) ? true : false; 286 287 if ($submit) 288 { 289 if (!check_form_key($form_key)) 290 { 291 trigger_error($user->lang['FORM_INVALID'] . adm_back_link($this->u_action . '&parent_id=' . $this->parent_id), E_USER_WARNING); 292 } 293 294 if (!$module_data['module_langname']) 295 { 296 trigger_error($user->lang['NO_MODULE_LANGNAME'] . adm_back_link($this->u_action . '&parent_id=' . $this->parent_id), E_USER_WARNING); 297 } 298 299 $module_type = request_var('module_type', 'category'); 300 301 if ($module_type == 'category') 302 { 303 $module_data['module_basename'] = $module_data['module_mode'] = $module_data['module_auth'] = ''; 304 $module_data['module_display'] = 1; 305 } 306 307 if ($action == 'edit') 308 { 309 $module_data['module_id'] = $module_id; 310 } 311 312 // Adjust auth row 313 if ($module_data['module_basename'] && $module_data['module_mode']) 314 { 315 $fileinfo = $this->get_module_infos($module_data['module_basename']); 316 $module_data['module_auth'] = $fileinfo[$module_data['module_basename']]['modes'][$module_data['module_mode']]['auth']; 317 } 318 319 $errors = $this->update_module_data($module_data); 320 321 if (!sizeof($errors)) 322 { 323 $this->remove_cache_file(); 324 325 trigger_error((($action == 'add') ? $user->lang['MODULE_ADDED'] : $user->lang['MODULE_EDITED']) . adm_back_link($this->u_action . '&parent_id=' . $this->parent_id)); 326 } 327 } 328 329 // Category/not category? 330 $is_cat = (!$module_data['module_basename']) ? true : false; 331 332 // Get module information 333 $module_infos = $this->get_module_infos(); 334 335 // Build name options 336 $s_name_options = $s_mode_options = ''; 337 foreach ($module_infos as $option => $values) 338 { 339 if (!$module_data['module_basename']) 340 { 341 $module_data['module_basename'] = $option; 342 } 343 344 // Name options 345 $s_name_options .= '<option value="' . $option . '"' . (($option == $module_data['module_basename']) ? ' selected="selected"' : '') . '>' . $this->lang_name($values['title']) . ' [' . $option . ']</option>'; 346 347 $template->assign_block_vars('m_names', array('NAME' => $option, 'A_NAME' => addslashes($option))); 348 349 // Build module modes 350 foreach ($values['modes'] as $m_mode => $m_values) 351 { 352 if ($option == $module_data['module_basename']) 353 { 354 $s_mode_options .= '<option value="' . $m_mode . '"' . (($m_mode == $module_data['module_mode']) ? ' selected="selected"' : '') . '>' . $this->lang_name($m_values['title']) . '</option>'; 355 } 356 357 $template->assign_block_vars('m_names.modes', array( 358 'OPTION' => $m_mode, 359 'VALUE' => $this->lang_name($m_values['title']), 360 'A_OPTION' => addslashes($m_mode), 361 'A_VALUE' => addslashes($this->lang_name($m_values['title']))) 362 ); 363 } 364 } 365 366 $s_cat_option = '<option value="0"' . (($module_data['parent_id'] == 0) ? ' selected="selected"' : '') . '>' . $user->lang['NO_PARENT'] . '</option>'; 367 368 $template->assign_vars(array_merge(array( 369 'S_EDIT_MODULE' => true, 370 'S_IS_CAT' => $is_cat, 371 '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), 372 'S_MODULE_NAMES' => $s_name_options, 373 'S_MODULE_MODES' => $s_mode_options, 374 'U_BACK' => $this->u_action . '&parent_id=' . $this->parent_id, 375 'U_EDIT_ACTION' => $this->u_action . '&parent_id=' . $this->parent_id, 376 377 'L_TITLE' => $user->lang[strtoupper($action) . '_MODULE'], 378 379 'MODULENAME' => $this->lang_name($module_data['module_langname']), 380 'ACTION' => $action, 381 'MODULE_ID' => $module_id, 382 383 ), 384 array_change_key_case($module_data, CASE_UPPER)) 385 ); 386 387 if (sizeof($errors)) 388 { 389 $template->assign_vars(array( 390 'S_ERROR' => true, 391 'ERROR_MSG' => implode('<br />', $errors)) 392 ); 393 } 394 395 return; 396 397 break; 398 } 399 400 // Default management page 401 if (sizeof($errors)) 402 { 403 if ($request->is_ajax()) 404 { 405 $json_response = new \phpbb\json_response; 406 $json_response->send(array( 407 'MESSAGE_TITLE' => $user->lang('ERROR'), 408 'MESSAGE_TEXT' => implode('<br />', $errors), 409 'SUCCESS' => false, 410 )); 411 } 412 413 $template->assign_vars(array( 414 'S_ERROR' => true, 415 'ERROR_MSG' => implode('<br />', $errors)) 416 ); 417 } 418 419 if (!$this->parent_id) 420 { 421 $navigation = strtoupper($this->module_class); 422 } 423 else 424 { 425 $navigation = '<a href="' . $this->u_action . '">' . strtoupper($this->module_class) . '</a>'; 426 427 $modules_nav = $this->get_module_branch($this->parent_id, 'parents', 'descending'); 428 429 foreach ($modules_nav as $row) 430 { 431 $langname = $this->lang_name($row['module_langname']); 432 433 if ($row['module_id'] == $this->parent_id) 434 { 435 $navigation .= ' -> ' . $langname; 436 } 437 else 438 { 439 $navigation .= ' -> <a href="' . $this->u_action . '&parent_id=' . $row['module_id'] . '">' . $langname . '</a>'; 440 } 441 } 442 } 443 444 // Jumpbox 445 $module_box = $this->make_module_select($this->parent_id, false, false, false, false); 446 447 $sql = 'SELECT * 448 FROM ' . MODULES_TABLE . " 449 WHERE parent_id = {$this->parent_id} 450 AND module_class = '" . $db->sql_escape($this->module_class) . "' 451 ORDER BY left_id"; 452 $result = $db->sql_query($sql); 453 454 if ($row = $db->sql_fetchrow($result)) 455 { 456 do 457 { 458 $langname = $this->lang_name($row['module_langname']); 459 460 if (!$row['module_enabled']) 461 { 462 $module_image = '<img src="images/icon_folder_lock.gif" alt="' . $user->lang['DEACTIVATED_MODULE'] .'" />'; 463 } 464 else 465 { 466 $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'] . '" />'; 467 } 468 469 $url = $this->u_action . '&parent_id=' . $this->parent_id . '&m=' . $row['module_id']; 470 471 $template->assign_block_vars('modules', array( 472 'MODULE_IMAGE' => $module_image, 473 'MODULE_TITLE' => $langname, 474 'MODULE_ENABLED' => ($row['module_enabled']) ? true : false, 475 'MODULE_DISPLAYED' => ($row['module_display']) ? true : false, 476 477 'S_ACP_CAT_SYSTEM' => ($this->module_class == 'acp' && $row['module_langname'] == 'ACP_CAT_SYSTEM') ? true : false, 478 'S_ACP_MODULE_MANAGEMENT' => ($this->module_class == 'acp' && ($row['module_basename'] == 'modules' || $row['module_langname'] == 'ACP_MODULE_MANAGEMENT')) ? true : false, 479 480 'U_MODULE' => $this->u_action . '&parent_id=' . $row['module_id'], 481 'U_MOVE_UP' => $url . '&action=move_up&hash=' . generate_link_hash('acp_modules'), 482 'U_MOVE_DOWN' => $url . '&action=move_down&hash=' . generate_link_hash('acp_modules'), 483 'U_EDIT' => $url . '&action=edit', 484 'U_DELETE' => $url . '&action=delete', 485 'U_ENABLE' => $url . '&action=enable&hash=' . generate_link_hash('acp_modules'), 486 'U_DISABLE' => $url . '&action=disable&hash=' . generate_link_hash('acp_modules')) 487 ); 488 } 489 while ($row = $db->sql_fetchrow($result)); 490 } 491 else if ($this->parent_id) 492 { 493 $row = $this->get_module_row($this->parent_id); 494 495 $url = $this->u_action . '&parent_id=' . $this->parent_id . '&m=' . $row['module_id']; 496 497 $template->assign_vars(array( 498 'S_NO_MODULES' => true, 499 'MODULE_TITLE' => $langname, 500 'MODULE_ENABLED' => ($row['module_enabled']) ? true : false, 501 'MODULE_DISPLAYED' => ($row['module_display']) ? true : false, 502 503 'U_EDIT' => $url . '&action=edit', 504 'U_DELETE' => $url . '&action=delete', 505 'U_ENABLE' => $url . '&action=enable&hash=' . generate_link_hash('acp_modules'), 506 'U_DISABLE' => $url . '&action=disable&hash=' . generate_link_hash('acp_modules')) 507 ); 508 } 509 $db->sql_freeresult($result); 510 511 // Quick adding module 512 $module_infos = $this->get_module_infos(); 513 514 // Build quick options 515 $s_install_options = ''; 516 foreach ($module_infos as $option => $values) 517 { 518 // Name options 519 $s_install_options .= '<optgroup label="' . $this->lang_name($values['title']) . ' [' . $option . ']">'; 520 521 // Build module modes 522 foreach ($values['modes'] as $m_mode => $m_values) 523 { 524 $s_install_options .= '<option value="' . $option . '::' . $m_mode . '"> ' . $this->lang_name($m_values['title']) . '</option>'; 525 } 526 527 $s_install_options .= '</optgroup>'; 528 } 529 530 $template->assign_vars(array( 531 'U_SEL_ACTION' => $this->u_action, 532 'U_ACTION' => $this->u_action . '&parent_id=' . $this->parent_id, 533 'NAVIGATION' => $navigation, 534 'MODULE_BOX' => $module_box, 535 'PARENT_ID' => $this->parent_id, 536 'S_INSTALL_OPTIONS' => $s_install_options, 537 ) 538 ); 539 } 540 541 /** 542 * Get row for specified module 543 */ 544 function get_module_row($module_id) 545 { 546 global $db, $user; 547 548 $sql = 'SELECT * 549 FROM ' . MODULES_TABLE . " 550 WHERE module_class = '" . $db->sql_escape($this->module_class) . "' 551 AND module_id = $module_id"; 552 $result = $db->sql_query($sql); 553 $row = $db->sql_fetchrow($result); 554 $db->sql_freeresult($result); 555 556 if (!$row) 557 { 558 trigger_error($user->lang['NO_MODULE'] . adm_back_link($this->u_action . '&parent_id=' . $this->parent_id), E_USER_WARNING); 559 } 560 561 return $row; 562 } 563 564 /** 565 * Get available module information from module files 566 * 567 * @param string $module 568 * @param bool|string $module_class 569 * @param bool $use_all_available Use all available instead of just all 570 * enabled extensions 571 * @return array 572 */ 573 function get_module_infos($module = '', $module_class = false, $use_all_available = false) 574 { 575 global $phpbb_extension_manager, $phpbb_root_path, $phpEx; 576 577 $module_class = ($module_class === false) ? $this->module_class : $module_class; 578 579 $directory = $phpbb_root_path . 'includes/' . $module_class . '/info/'; 580 $fileinfo = array(); 581 582 $finder = $phpbb_extension_manager->get_finder($use_all_available); 583 584 $modules = $finder 585 ->extension_suffix('_module') 586 ->extension_directory("/$module_class") 587 ->core_path("includes/$module_class/info/") 588 ->core_prefix($module_class . '_') 589 ->get_classes(true); 590 591 foreach ($modules as $cur_module) 592 { 593 // Skip entries we do not need if we know the module we are 594 // looking for 595 if ($module && strpos(str_replace('\\', '_', $cur_module), $module) === false && $module !== $cur_module) 596 { 597 continue; 598 } 599 600 $info_class = preg_replace('/_module$/', '_info', $cur_module); 601 602 // If the class does not exist it might be following the old 603 // format. phpbb_acp_info_acp_foo needs to be turned into 604 // acp_foo_info and the respective file has to be included 605 // manually because it does not support auto loading 606 $old_info_class_file = str_replace("phpbb_{$module_class}_info_", '', $cur_module); 607 $old_info_class = $old_info_class_file . '_info'; 608 609 if (class_exists($old_info_class)) 610 { 611 $info_class = $old_info_class; 612 } 613 else if (!class_exists($info_class)) 614 { 615 $info_class = $old_info_class; 616 // need to check class exists again because previous checks triggered autoloading 617 if (!class_exists($info_class) && file_exists($directory . $old_info_class_file . '.' . $phpEx)) 618 { 619 include($directory . $old_info_class_file . '.' . $phpEx); 620 } 621 } 622 623 if (class_exists($info_class)) 624 { 625 $info = new $info_class(); 626 $module_info = $info->module(); 627 628 $main_class = (isset($module_info['filename'])) ? $module_info['filename'] : $cur_module; 629 630 $fileinfo[$main_class] = $module_info; 631 } 632 } 633 634 ksort($fileinfo); 635 636 return $fileinfo; 637 } 638 639 /** 640 * Simple version of jumpbox, just lists modules 641 */ 642 function make_module_select($select_id = false, $ignore_id = false, $ignore_acl = false, $ignore_nonpost = false, $ignore_emptycat = true, $ignore_noncat = false) 643 { 644 global $db, $user, $auth, $config; 645 646 $sql = 'SELECT module_id, module_enabled, module_basename, parent_id, module_langname, left_id, right_id, module_auth 647 FROM ' . MODULES_TABLE . " 648 WHERE module_class = '" . $db->sql_escape($this->module_class) . "' 649 ORDER BY left_id ASC"; 650 $result = $db->sql_query($sql); 651 652 $right = $iteration = 0; 653 $padding_store = array('0' => ''); 654 $module_list = $padding = ''; 655 656 while ($row = $db->sql_fetchrow($result)) 657 { 658 if ($row['left_id'] < $right) 659 { 660 $padding .= ' '; 661 $padding_store[$row['parent_id']] = $padding; 662 } 663 else if ($row['left_id'] > $right + 1) 664 { 665 $padding = (isset($padding_store[$row['parent_id']])) ? $padding_store[$row['parent_id']] : ''; 666 } 667 668 $right = $row['right_id']; 669 670 if (!$ignore_acl && $row['module_auth']) 671 { 672 // We use zero as the forum id to check - global setting. 673 if (!p_master::module_auth($row['module_auth'], 0)) 674 { 675 continue; 676 } 677 } 678 679 // ignore this module? 680 if ((is_array($ignore_id) && in_array($row['module_id'], $ignore_id)) || $row['module_id'] == $ignore_id) 681 { 682 continue; 683 } 684 685 // empty category 686 if (!$row['module_basename'] && ($row['left_id'] + 1 == $row['right_id']) && $ignore_emptycat) 687 { 688 continue; 689 } 690 691 // ignore non-category? 692 if ($row['module_basename'] && $ignore_noncat) 693 { 694 continue; 695 } 696 697 $selected = (is_array($select_id)) ? ((in_array($row['module_id'], $select_id)) ? ' selected="selected"' : '') : (($row['module_id'] == $select_id) ? ' selected="selected"' : ''); 698 699 $langname = $this->lang_name($row['module_langname']); 700 $module_list .= '<option value="' . $row['module_id'] . '"' . $selected . ((!$row['module_enabled']) ? ' class="disabled"' : '') . '>' . $padding . $langname . '</option>'; 701 702 $iteration++; 703 } 704 $db->sql_freeresult($result); 705 706 unset($padding_store); 707 708 return $module_list; 709 } 710 711 /** 712 * Get module branch 713 */ 714 function get_module_branch($module_id, $type = 'all', $order = 'descending', $include_module = true) 715 { 716 global $db; 717 718 switch ($type) 719 { 720 case 'parents': 721 $condition = 'm1.left_id BETWEEN m2.left_id AND m2.right_id'; 722 break; 723 724 case 'children': 725 $condition = 'm2.left_id BETWEEN m1.left_id AND m1.right_id'; 726 break; 727 728 default: 729 $condition = 'm2.left_id BETWEEN m1.left_id AND m1.right_id OR m1.left_id BETWEEN m2.left_id AND m2.right_id'; 730 break; 731 } 732 733 $rows = array(); 734 735 $sql = 'SELECT m2.* 736 FROM ' . MODULES_TABLE . ' m1 737 LEFT JOIN ' . MODULES_TABLE . " m2 ON ($condition) 738 WHERE m1.module_class = '" . $db->sql_escape($this->module_class) . "' 739 AND m2.module_class = '" . $db->sql_escape($this->module_class) . "' 740 AND m1.module_id = $module_id 741 ORDER BY m2.left_id " . (($order == 'descending') ? 'ASC' : 'DESC'); 742 $result = $db->sql_query($sql); 743 744 while ($row = $db->sql_fetchrow($result)) 745 { 746 if (!$include_module && $row['module_id'] == $module_id) 747 { 748 continue; 749 } 750 751 $rows[] = $row; 752 } 753 $db->sql_freeresult($result); 754 755 return $rows; 756 } 757 758 /** 759 * Remove modules cache file 760 */ 761 function remove_cache_file() 762 { 763 global $phpbb_container; 764 765 // Sanitise for future path use, it's escaped as appropriate for queries 766 $p_class = str_replace(array('.', '/', '\\'), '', basename($this->module_class)); 767 768 $phpbb_container->get('cache.driver')->destroy('_modules_' . $p_class); 769 770 // Additionally remove sql cache 771 $phpbb_container->get('cache.driver')->destroy('sql', MODULES_TABLE); 772 } 773 774 /** 775 * Return correct language name 776 */ 777 function lang_name($module_langname) 778 { 779 global $user; 780 781 return (!empty($user->lang[$module_langname])) ? $user->lang[$module_langname] : $module_langname; 782 } 783 784 /** 785 * Update/Add module 786 * 787 * @param array &$module_data The module data 788 * @param bool $run_inline if set to true errors will be returned and no logs being written 789 */ 790 function update_module_data(&$module_data, $run_inline = false) 791 { 792 global $db, $user; 793 794 if (!isset($module_data['module_id'])) 795 { 796 // no module_id means we're creating a new category/module 797 if ($module_data['parent_id']) 798 { 799 $sql = 'SELECT left_id, right_id 800 FROM ' . MODULES_TABLE . " 801 WHERE module_class = '" . $db->sql_escape($module_data['module_class']) . "' 802 AND module_id = " . (int) $module_data['parent_id']; 803 $result = $db->sql_query($sql); 804 $row = $db->sql_fetchrow($result); 805 $db->sql_freeresult($result); 806 807 if (!$row) 808 { 809 if ($run_inline) 810 { 811 return 'PARENT_NO_EXIST'; 812 } 813 814 trigger_error($user->lang['PARENT_NO_EXIST'] . adm_back_link($this->u_action . '&parent_id=' . $this->parent_id), E_USER_WARNING); 815 } 816 817 // Workaround 818 $row['left_id'] = (int) $row['left_id']; 819 $row['right_id'] = (int) $row['right_id']; 820 821 $sql = 'UPDATE ' . MODULES_TABLE . " 822 SET left_id = left_id + 2, right_id = right_id + 2 823 WHERE module_class = '" . $db->sql_escape($module_data['module_class']) . "' 824 AND left_id > {$row['right_id']}"; 825 $db->sql_query($sql); 826 827 $sql = 'UPDATE ' . MODULES_TABLE . " 828 SET right_id = right_id + 2 829 WHERE module_class = '" . $db->sql_escape($module_data['module_class']) . "' 830 AND {$row['left_id']} BETWEEN left_id AND right_id"; 831 $db->sql_query($sql); 832 833 $module_data['left_id'] = (int) $row['right_id']; 834 $module_data['right_id'] = (int) $row['right_id'] + 1; 835 } 836 else 837 { 838 $sql = 'SELECT MAX(right_id) AS right_id 839 FROM ' . MODULES_TABLE . " 840 WHERE module_class = '" . $db->sql_escape($module_data['module_class']) . "'"; 841 $result = $db->sql_query($sql); 842 $row = $db->sql_fetchrow($result); 843 $db->sql_freeresult($result); 844 845 $module_data['left_id'] = (int) $row['right_id'] + 1; 846 $module_data['right_id'] = (int) $row['right_id'] + 2; 847 } 848 849 $sql = 'INSERT INTO ' . MODULES_TABLE . ' ' . $db->sql_build_array('INSERT', $module_data); 850 $db->sql_query($sql); 851 852 $module_data['module_id'] = $db->sql_nextid(); 853 854 if (!$run_inline) 855 { 856 add_log('admin', 'LOG_MODULE_ADD', $this->lang_name($module_data['module_langname'])); 857 } 858 } 859 else 860 { 861 $row = $this->get_module_row($module_data['module_id']); 862 863 if ($module_data['module_basename'] && !$row['module_basename']) 864 { 865 // we're turning a category into a module 866 $branch = $this->get_module_branch($module_data['module_id'], 'children', 'descending', false); 867 868 if (sizeof($branch)) 869 { 870 return array($user->lang['NO_CATEGORY_TO_MODULE']); 871 } 872 } 873 874 if ($row['parent_id'] != $module_data['parent_id']) 875 { 876 $this->move_module($module_data['module_id'], $module_data['parent_id']); 877 } 878 879 $update_ary = $module_data; 880 unset($update_ary['module_id']); 881 882 $sql = 'UPDATE ' . MODULES_TABLE . ' 883 SET ' . $db->sql_build_array('UPDATE', $update_ary) . " 884 WHERE module_class = '" . $db->sql_escape($module_data['module_class']) . "' 885 AND module_id = " . (int) $module_data['module_id']; 886 $db->sql_query($sql); 887 888 if (!$run_inline) 889 { 890 add_log('admin', 'LOG_MODULE_EDIT', $this->lang_name($module_data['module_langname'])); 891 } 892 } 893 894 return array(); 895 } 896 897 /** 898 * Move module around the tree 899 */ 900 function move_module($from_module_id, $to_parent_id) 901 { 902 global $db; 903 904 $moved_modules = $this->get_module_branch($from_module_id, 'children', 'descending'); 905 $from_data = $moved_modules[0]; 906 $diff = sizeof($moved_modules) * 2; 907 908 $moved_ids = array(); 909 for ($i = 0, $size = sizeof($moved_modules); $i < $size; ++$i) 910 { 911 $moved_ids[] = $moved_modules[$i]['module_id']; 912 } 913 914 // Resync parents 915 $sql = 'UPDATE ' . MODULES_TABLE . " 916 SET right_id = right_id - $diff 917 WHERE module_class = '" . $db->sql_escape($this->module_class) . "' 918 AND left_id < " . (int) $from_data['right_id'] . ' 919 AND right_id > ' . (int) $from_data['right_id']; 920 $db->sql_query($sql); 921 922 // Resync righthand side of tree 923 $sql = 'UPDATE ' . MODULES_TABLE . " 924 SET left_id = left_id - $diff, right_id = right_id - $diff 925 WHERE module_class = '" . $db->sql_escape($this->module_class) . "' 926 AND left_id > " . (int) $from_data['right_id']; 927 $db->sql_query($sql); 928 929 if ($to_parent_id > 0) 930 { 931 $to_data = $this->get_module_row($to_parent_id); 932 933 // Resync new parents 934 $sql = 'UPDATE ' . MODULES_TABLE . " 935 SET right_id = right_id + $diff 936 WHERE module_class = '" . $db->sql_escape($this->module_class) . "' 937 AND " . (int) $to_data['right_id'] . ' BETWEEN left_id AND right_id 938 AND ' . $db->sql_in_set('module_id', $moved_ids, true); 939 $db->sql_query($sql); 940 941 // Resync the righthand side of the tree 942 $sql = 'UPDATE ' . MODULES_TABLE . " 943 SET left_id = left_id + $diff, right_id = right_id + $diff 944 WHERE module_class = '" . $db->sql_escape($this->module_class) . "' 945 AND left_id > " . (int) $to_data['right_id'] . ' 946 AND ' . $db->sql_in_set('module_id', $moved_ids, true); 947 $db->sql_query($sql); 948 949 // Resync moved branch 950 $to_data['right_id'] += $diff; 951 if ($to_data['right_id'] > $from_data['right_id']) 952 { 953 $diff = '+ ' . ($to_data['right_id'] - $from_data['right_id'] - 1); 954 } 955 else 956 { 957 $diff = '- ' . abs($to_data['right_id'] - $from_data['right_id'] - 1); 958 } 959 } 960 else 961 { 962 $sql = 'SELECT MAX(right_id) AS right_id 963 FROM ' . MODULES_TABLE . " 964 WHERE module_class = '" . $db->sql_escape($this->module_class) . "' 965 AND " . $db->sql_in_set('module_id', $moved_ids, true); 966 $result = $db->sql_query($sql); 967 $row = $db->sql_fetchrow($result); 968 $db->sql_freeresult($result); 969 970 $diff = '+ ' . (int) ($row['right_id'] - $from_data['left_id'] + 1); 971 } 972 973 $sql = 'UPDATE ' . MODULES_TABLE . " 974 SET left_id = left_id $diff, right_id = right_id $diff 975 WHERE module_class = '" . $db->sql_escape($this->module_class) . "' 976 AND " . $db->sql_in_set('module_id', $moved_ids); 977 $db->sql_query($sql); 978 } 979 980 /** 981 * Remove module from tree 982 */ 983 function delete_module($module_id) 984 { 985 global $db, $user; 986 987 $row = $this->get_module_row($module_id); 988 989 $branch = $this->get_module_branch($module_id, 'children', 'descending', false); 990 991 if (sizeof($branch)) 992 { 993 return array($user->lang['CANNOT_REMOVE_MODULE']); 994 } 995 996 // If not move 997 $diff = 2; 998 $sql = 'DELETE FROM ' . MODULES_TABLE . " 999 WHERE module_class = '" . $db->sql_escape($this->module_class) . "' 1000 AND module_id = $module_id"; 1001 $db->sql_query($sql); 1002 1003 $row['right_id'] = (int) $row['right_id']; 1004 $row['left_id'] = (int) $row['left_id']; 1005 1006 // Resync tree 1007 $sql = 'UPDATE ' . MODULES_TABLE . " 1008 SET right_id = right_id - $diff 1009 WHERE module_class = '" . $db->sql_escape($this->module_class) . "' 1010 AND left_id < {$row['right_id']} AND right_id > {$row['right_id']}"; 1011 $db->sql_query($sql); 1012 1013 $sql = 'UPDATE ' . MODULES_TABLE . " 1014 SET left_id = left_id - $diff, right_id = right_id - $diff 1015 WHERE module_class = '" . $db->sql_escape($this->module_class) . "' 1016 AND left_id > {$row['right_id']}"; 1017 $db->sql_query($sql); 1018 1019 add_log('admin', 'LOG_MODULE_REMOVED', $this->lang_name($row['module_langname'])); 1020 1021 return array(); 1022 1023 } 1024 1025 /** 1026 * Move module position by $steps up/down 1027 */ 1028 function move_module_by($module_row, $action = 'move_up', $steps = 1) 1029 { 1030 global $db; 1031 1032 /** 1033 * Fetch all the siblings between the module's current spot 1034 * and where we want to move it to. If there are less than $steps 1035 * siblings between the current spot and the target then the 1036 * module will move as far as possible 1037 */ 1038 $sql = 'SELECT module_id, left_id, right_id, module_langname 1039 FROM ' . MODULES_TABLE . " 1040 WHERE module_class = '" . $db->sql_escape($this->module_class) . "' 1041 AND parent_id = " . (int) $module_row['parent_id'] . ' 1042 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'); 1043 $result = $db->sql_query_limit($sql, $steps); 1044 1045 $target = array(); 1046 while ($row = $db->sql_fetchrow($result)) 1047 { 1048 $target = $row; 1049 } 1050 $db->sql_freeresult($result); 1051 1052 if (!sizeof($target)) 1053 { 1054 // The module is already on top or bottom 1055 return false; 1056 } 1057 1058 /** 1059 * $left_id and $right_id define the scope of the nodes that are affected by the move. 1060 * $diff_up and $diff_down are the values to substract or add to each node's left_id 1061 * and right_id in order to move them up or down. 1062 * $move_up_left and $move_up_right define the scope of the nodes that are moving 1063 * up. Other nodes in the scope of ($left_id, $right_id) are considered to move down. 1064 */ 1065 if ($action == 'move_up') 1066 { 1067 $left_id = (int) $target['left_id']; 1068 $right_id = (int) $module_row['right_id']; 1069 1070 $diff_up = (int) ($module_row['left_id'] - $target['left_id']); 1071 $diff_down = (int) ($module_row['right_id'] + 1 - $module_row['left_id']); 1072 1073 $move_up_left = (int) $module_row['left_id']; 1074 $move_up_right = (int) $module_row['right_id']; 1075 } 1076 else 1077 { 1078 $left_id = (int) $module_row['left_id']; 1079 $right_id = (int) $target['right_id']; 1080 1081 $diff_up = (int) ($module_row['right_id'] + 1 - $module_row['left_id']); 1082 $diff_down = (int) ($target['right_id'] - $module_row['right_id']); 1083 1084 $move_up_left = (int) ($module_row['right_id'] + 1); 1085 $move_up_right = (int) $target['right_id']; 1086 } 1087 1088 // Now do the dirty job 1089 $sql = 'UPDATE ' . MODULES_TABLE . " 1090 SET left_id = left_id + CASE 1091 WHEN left_id BETWEEN {$move_up_left} AND {$move_up_right} THEN -{$diff_up} 1092 ELSE {$diff_down} 1093 END, 1094 right_id = right_id + CASE 1095 WHEN right_id BETWEEN {$move_up_left} AND {$move_up_right} THEN -{$diff_up} 1096 ELSE {$diff_down} 1097 END 1098 WHERE module_class = '" . $db->sql_escape($this->module_class) . "' 1099 AND left_id BETWEEN {$left_id} AND {$right_id} 1100 AND right_id BETWEEN {$left_id} AND {$right_id}"; 1101 $db->sql_query($sql); 1102 1103 $this->remove_cache_file(); 1104 1105 return $this->lang_name($target['module_langname']); 1106 } 1107 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Thu Jan 11 00:25:41 2018 | Cross-referenced by PHPXref 0.7.1 |