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