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