5
* @version $Id: acp_modules.php,v 1.51 2007/10/05 14:36:32 acydburn Exp $
6
* @copyright (c) 2005 phpBB Group
7
* @license http://opensource.org/licenses/gpl-license.php GNU Public License
14
if (!defined('IN_PHPBB'))
20
* - Able to check for new module versions (modes changed/adjusted/added/removed)
22
* - module enabled and displayed (common)
23
* - module enabled and not displayed
24
* - module deactivated
25
* - category (enabled)
34
var $module_class = '';
38
function main($id, $mode)
40
global $db, $user, $auth, $template, $module;
41
global $config, $phpbb_admin_path, $phpbb_root_path, $phpEx;
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);
46
$user->add_lang('acp/modules');
47
$this->tpl_name = 'acp_modules';
50
$this->module_class = $mode;
52
if ($this->module_class == 'ucp')
54
$user->add_lang('ucp');
56
else if ($this->module_class == 'mcp')
58
$user->add_lang('mcp');
61
if ($module->p_class != $this->module_class)
63
$module->add_mod_info($this->module_class);
66
$this->page_title = strtoupper($this->module_class);
68
$this->parent_id = request_var('parent_id', 0);
69
$module_id = request_var('m', 0);
70
$action = request_var('action', '');
78
trigger_error($user->lang['NO_MODULE_ID'] . adm_back_link($this->u_action . '&parent_id=' . $this->parent_id), E_USER_WARNING);
81
if (confirm_box(true))
83
// Make sure we are not directly within a module
84
if ($module_id == $this->parent_id)
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);
94
$errors = $this->delete_module($module_id);
98
$this->remove_cache_file();
99
trigger_error($user->lang['MODULE_DELETED'] . adm_back_link($this->u_action . '&parent_id=' . $this->parent_id));
104
confirm_box(false, 'DELETE_MODULE', build_hidden_fields(array(
107
'parent_id' => $this->parent_id,
108
'module_id' => $module_id,
119
trigger_error($user->lang['NO_MODULE_ID'] . adm_back_link($this->u_action . '&parent_id=' . $this->parent_id), E_USER_WARNING);
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);
132
trigger_error($user->lang['NO_MODULE'] . adm_back_link($this->u_action . '&parent_id=' . $this->parent_id), E_USER_WARNING);
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);
141
add_log('admin', 'LOG_MODULE_' . strtoupper($action), $this->lang_name($row['module_langname']));
142
$this->remove_cache_file();
150
trigger_error($user->lang['NO_MODULE_ID'] . adm_back_link($this->u_action . '&parent_id=' . $this->parent_id), E_USER_WARNING);
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);
163
trigger_error($user->lang['NO_MODULE'] . adm_back_link($this->u_action . '&parent_id=' . $this->parent_id), E_USER_WARNING);
166
$move_module_name = $this->move_module_by($row, $action, 1);
168
if ($move_module_name !== false)
170
add_log('admin', 'LOG_MODULE_' . strtoupper($action), $this->lang_name($row['module_langname']), $move_module_name);
171
$this->remove_cache_file();
177
$quick_install = request_var('quick_install', '');
179
if (confirm_box(true))
181
if (!$quick_install || strpos($quick_install, '::') === false)
186
list($module_basename, $module_mode) = explode('::', $quick_install);
188
// Check if module name and mode exist...
189
$fileinfo = $this->get_module_infos($module_basename);
190
$fileinfo = $fileinfo[$module_basename];
192
if (isset($fileinfo['modes'][$module_mode]))
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'],
205
$errors = $this->update_module_data($module_data);
207
if (!sizeof($errors))
209
$this->remove_cache_file();
211
trigger_error($user->lang['MODULE_ADDED'] . adm_back_link($this->u_action . '&parent_id=' . $this->parent_id));
217
confirm_box(false, 'ADD_MODULE', build_hidden_fields(array(
220
'parent_id' => $this->parent_id,
221
'action' => 'quickadd',
222
'quick_install' => $quick_install,
232
trigger_error($user->lang['NO_MODULE_ID'] . adm_back_link($this->u_action . '&parent_id=' . $this->parent_id), E_USER_WARNING);
235
$module_row = $this->get_module_row($module_id);
241
if ($action == 'add')
244
'module_basename' => '',
245
'module_enabled' => 0,
246
'module_display' => 1,
248
'module_langname' => utf8_normalize_nfc(request_var('module_langname', '', true)),
254
$module_data = array();
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']);
264
$submit = (isset($_POST['submit'])) ? true : false;
268
if (!$module_data['module_langname'])
270
trigger_error($user->lang['NO_MODULE_LANGNAME'] . adm_back_link($this->u_action . '&parent_id=' . $this->parent_id), E_USER_WARNING);
273
$module_type = request_var('module_type', 'category');
275
if ($module_type == 'category')
277
$module_data['module_basename'] = $module_data['module_mode'] = $module_data['module_auth'] = '';
278
$module_data['module_display'] = 1;
281
if ($action == 'edit')
283
$module_data['module_id'] = $module_id;
287
if ($module_data['module_basename'] && $module_data['module_mode'])
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'];
293
$errors = $this->update_module_data($module_data);
295
if (!sizeof($errors))
297
$this->remove_cache_file();
299
trigger_error((($action == 'add') ? $user->lang['MODULE_ADDED'] : $user->lang['MODULE_EDITED']) . adm_back_link($this->u_action . '&parent_id=' . $this->parent_id));
303
// Category/not category?
304
$is_cat = (!$module_data['module_basename']) ? true : false;
306
// Get module information
307
$module_infos = $this->get_module_infos();
309
// Build name options
310
$s_name_options = $s_mode_options = '';
311
foreach ($module_infos as $option => $values)
313
if (!$module_data['module_basename'])
315
$module_data['module_basename'] = $option;
319
$s_name_options .= '<option value="' . $option . '"' . (($option == $module_data['module_basename']) ? ' selected="selected"' : '') . '>' . $this->lang_name($values['title']) . ' [' . $this->module_class . '_' . $option . ']</option>';
321
$template->assign_block_vars('m_names', array('NAME' => $option, 'A_NAME' => addslashes($option)));
323
// Build module modes
324
foreach ($values['modes'] as $m_mode => $m_values)
326
if ($option == $module_data['module_basename'])
328
$s_mode_options .= '<option value="' . $m_mode . '"' . (($m_mode == $module_data['module_mode']) ? ' selected="selected"' : '') . '>' . $this->lang_name($m_values['title']) . '</option>';
331
$template->assign_block_vars('m_names.modes', array(
333
'VALUE' => $this->lang_name($m_values['title']),
334
'A_OPTION' => addslashes($m_mode),
335
'A_VALUE' => addslashes($this->lang_name($m_values['title'])))
340
$s_cat_option = '<option value="0"' . (($module_data['parent_id'] == 0) ? ' selected="selected"' : '') . '>' . $user->lang['NO_PARENT'] . '</option>';
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,
351
'L_TITLE' => $user->lang[strtoupper($action) . '_MODULE'],
353
'MODULENAME' => $this->lang_name($module_data['module_langname']),
355
'MODULE_ID' => $module_id,
358
array_change_key_case($module_data, CASE_UPPER))
363
$template->assign_vars(array(
365
'ERROR_MSG' => implode('<br />', $errors))
374
// Default management page
377
$template->assign_vars(array(
379
'ERROR_MSG' => implode('<br />', $errors))
383
if (!$this->parent_id)
385
$navigation = strtoupper($this->module_class);
389
$navigation = '<a href="' . $this->u_action . '">' . strtoupper($this->module_class) . '</a>';
391
$modules_nav = $this->get_module_branch($this->parent_id, 'parents', 'descending');
393
foreach ($modules_nav as $row)
395
$langname = $this->lang_name($row['module_langname']);
397
if ($row['module_id'] == $this->parent_id)
399
$navigation .= ' -> ' . $langname;
403
$navigation .= ' -> <a href="' . $this->u_action . '&parent_id=' . $row['module_id'] . '">' . $langname . '</a>';
409
$module_box = $this->make_module_select($this->parent_id, false, false, false, false);
412
FROM ' . MODULES_TABLE . "
413
WHERE parent_id = {$this->parent_id}
414
AND module_class = '" . $db->sql_escape($this->module_class) . "'
416
$result = $db->sql_query($sql);
418
if ($row = $db->sql_fetchrow($result))
422
$langname = $this->lang_name($row['module_langname']);
424
if (!$row['module_enabled'])
426
$module_image = '<img src="images/icon_folder_lock.gif" alt="' . $user->lang['DEACTIVATED_MODULE'] .'" />';
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'] . '" />';
433
$url = $this->u_action . '&parent_id=' . $this->parent_id . '&m=' . $row['module_id'];
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,
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,
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')
453
while ($row = $db->sql_fetchrow($result));
455
else if ($this->parent_id)
457
$row = $this->get_module_row($this->parent_id);
459
$url = $this->u_action . '&parent_id=' . $this->parent_id . '&m=' . $row['module_id'];
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,
467
'U_EDIT' => $url . '&action=edit',
468
'U_DELETE' => $url . '&action=delete',
469
'U_ENABLE' => $url . '&action=enable',
470
'U_DISABLE' => $url . '&action=disable')
473
$db->sql_freeresult($result);
475
// Quick adding module
476
$module_infos = $this->get_module_infos();
478
// Build quick options
479
$s_install_options = '';
480
foreach ($module_infos as $option => $values)
483
$s_install_options .= '<optgroup label="' . $this->lang_name($values['title']) . ' [' . $this->module_class . '_' . $option . ']">';
485
// Build module modes
486
foreach ($values['modes'] as $m_mode => $m_values)
488
$s_install_options .= '<option value="' . $option . '::' . $m_mode . '"> ' . $this->lang_name($m_values['title']) . '</option>';
491
$s_install_options .= '</optgroup>';
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,
506
* Get row for specified module
508
function get_module_row($module_id)
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);
522
trigger_error($user->lang['NO_MODULE'] . adm_back_link($this->u_action . '&parent_id=' . $this->parent_id), E_USER_WARNING);
529
* Get available module information from module files
531
function get_module_infos($module = '', $module_class = false)
533
global $phpbb_root_path, $phpEx;
535
$module_class = ($module_class === false) ? $this->module_class : $module_class;
537
$directory = $phpbb_root_path . 'includes/' . $module_class . '/info/';
542
$dh = @opendir($directory);
549
while (($file = readdir($dh)) !== false)
552
if (preg_match('/^' . $module_class . '_.+\.' . $phpEx . '$/', $file))
554
$class = str_replace(".$phpEx", '', $file) . '_info';
556
if (!class_exists($class))
558
include($directory . $file);
561
// Get module title tag
562
if (class_exists($class))
564
$c_class = new $class();
565
$module_info = $c_class->module();
566
$fileinfo[str_replace($module_class . '_', '', $module_info['filename'])] = $module_info;
576
$filename = $module_class . '_' . basename($module);
577
$class = $module_class . '_' . basename($module) . '_info';
579
if (!class_exists($class))
581
include($directory . $filename . '.' . $phpEx);
584
// Get module title tag
585
if (class_exists($class))
587
$c_class = new $class();
588
$module_info = $c_class->module();
589
$fileinfo[str_replace($module_class . '_', '', $module_info['filename'])] = $module_info;
597
* Simple version of jumpbox, just lists modules
599
function make_module_select($select_id = false, $ignore_id = false, $ignore_acl = false, $ignore_nonpost = false, $ignore_emptycat = true, $ignore_noncat = false)
601
global $db, $user, $auth, $config;
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);
609
$right = $iteration = 0;
610
$padding_store = array('0' => '');
611
$module_list = $padding = '';
613
while ($row = $db->sql_fetchrow($result))
615
if ($row['left_id'] < $right)
617
$padding .= ' ';
618
$padding_store[$row['parent_id']] = $padding;
620
else if ($row['left_id'] > $right + 1)
622
$padding = (isset($padding_store[$row['parent_id']])) ? $padding_store[$row['parent_id']] : '';
625
$right = $row['right_id'];
627
if (!$ignore_acl && $row['module_auth'])
629
// We use zero as the forum id to check - global setting.
630
if (!p_master::module_auth($row['module_auth'], 0))
636
// ignore this module?
637
if ((is_array($ignore_id) && in_array($row['module_id'], $ignore_id)) || $row['module_id'] == $ignore_id)
643
if (!$row['module_basename'] && ($row['left_id'] + 1 == $row['right_id']) && $ignore_emptycat)
648
// ignore non-category?
649
if ($row['module_basename'] && $ignore_noncat)
654
$selected = (is_array($select_id)) ? ((in_array($row['module_id'], $select_id)) ? ' selected="selected"' : '') : (($row['module_id'] == $select_id) ? ' selected="selected"' : '');
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>';
661
unset($padding_store);
669
function get_module_branch($module_id, $type = 'all', $order = 'descending', $include_module = true)
676
$condition = 'm1.left_id BETWEEN m2.left_id AND m2.right_id';
680
$condition = 'm2.left_id BETWEEN m1.left_id AND m1.right_id';
684
$condition = 'm2.left_id BETWEEN m1.left_id AND m1.right_id OR m1.left_id BETWEEN m2.left_id AND m2.right_id';
691
FROM ' . MODULES_TABLE . ' m1
692
LEFT JOIN ' . MODULES_TABLE . " m2 ON ($condition)
693
WHERE m1.module_class = '" . $db->sql_escape($this->module_class) . "'
694
AND m2.module_class = '" . $db->sql_escape($this->module_class) . "'
695
AND m1.module_id = $module_id
696
ORDER BY m2.left_id " . (($order == 'descending') ? 'ASC' : 'DESC');
697
$result = $db->sql_query($sql);
699
while ($row = $db->sql_fetchrow($result))
701
if (!$include_module && $row['module_id'] == $module_id)
708
$db->sql_freeresult($result);
714
* Remove modules cache file
716
function remove_cache_file()
720
// Sanitise for future path use, it's escaped as appropriate for queries
721
$p_class = str_replace(array('.', '/', '\\'), '', basename($this->module_class));
723
$cache->destroy('_modules_' . $p_class);
725
// Additionally remove sql cache
726
$cache->destroy('sql', MODULES_TABLE);
730
* Return correct language name
732
function lang_name($module_langname)
736
return (!empty($user->lang[$module_langname])) ? $user->lang[$module_langname] : $module_langname;
742
* @param bool $run_inline if set to true errors will be returned and no logs being written
744
function update_module_data(&$module_data, $run_inline = false)
748
if (!isset($module_data['module_id']))
750
// no module_id means we're creating a new category/module
751
if ($module_data['parent_id'])
753
$sql = 'SELECT left_id, right_id
754
FROM ' . MODULES_TABLE . "
755
WHERE module_class = '" . $db->sql_escape($module_data['module_class']) . "'
756
AND module_id = " . (int) $module_data['parent_id'];
757
$result = $db->sql_query($sql);
758
$row = $db->sql_fetchrow($result);
759
$db->sql_freeresult($result);
765
return 'PARENT_NO_EXIST';
768
trigger_error($user->lang['PARENT_NO_EXIST'] . adm_back_link($this->u_action . '&parent_id=' . $this->parent_id), E_USER_WARNING);
772
$row['left_id'] = (int) $row['left_id'];
773
$row['right_id'] = (int) $row['right_id'];
775
$sql = 'UPDATE ' . MODULES_TABLE . "
776
SET left_id = left_id + 2, right_id = right_id + 2
777
WHERE module_class = '" . $db->sql_escape($module_data['module_class']) . "'
778
AND left_id > {$row['right_id']}";
779
$db->sql_query($sql);
781
$sql = 'UPDATE ' . MODULES_TABLE . "
782
SET right_id = right_id + 2
783
WHERE module_class = '" . $db->sql_escape($module_data['module_class']) . "'
784
AND {$row['left_id']} BETWEEN left_id AND right_id";
785
$db->sql_query($sql);
787
$module_data['left_id'] = (int) $row['right_id'];
788
$module_data['right_id'] = (int) $row['right_id'] + 1;
792
$sql = 'SELECT MAX(right_id) AS right_id
793
FROM ' . MODULES_TABLE . "
794
WHERE module_class = '" . $db->sql_escape($module_data['module_class']) . "'";
795
$result = $db->sql_query($sql);
796
$row = $db->sql_fetchrow($result);
797
$db->sql_freeresult($result);
799
$module_data['left_id'] = (int) $row['right_id'] + 1;
800
$module_data['right_id'] = (int) $row['right_id'] + 2;
803
$sql = 'INSERT INTO ' . MODULES_TABLE . ' ' . $db->sql_build_array('INSERT', $module_data);
804
$db->sql_query($sql);
806
$module_data['module_id'] = $db->sql_nextid();
810
add_log('admin', 'LOG_MODULE_ADD', $this->lang_name($module_data['module_langname']));
815
$row = $this->get_module_row($module_data['module_id']);
817
if ($module_data['module_basename'] && !$row['module_basename'])
819
// we're turning a category into a module
820
$branch = $this->get_module_branch($module_data['module_id'], 'children', 'descending', false);
824
return array($user->lang['NO_CATEGORY_TO_MODULE']);
828
if ($row['parent_id'] != $module_data['parent_id'])
830
$this->move_module($module_data['module_id'], $module_data['parent_id']);
833
$update_ary = $module_data;
834
unset($update_ary['module_id']);
836
$sql = 'UPDATE ' . MODULES_TABLE . '
837
SET ' . $db->sql_build_array('UPDATE', $update_ary) . "
838
WHERE module_class = '" . $db->sql_escape($module_data['module_class']) . "'
839
AND module_id = " . (int) $module_data['module_id'];
840
$db->sql_query($sql);
844
add_log('admin', 'LOG_MODULE_EDIT', $this->lang_name($module_data['module_langname']));
852
* Move module around the tree
854
function move_module($from_module_id, $to_parent_id)
858
$moved_modules = $this->get_module_branch($from_module_id, 'children', 'descending');
859
$from_data = $moved_modules[0];
860
$diff = sizeof($moved_modules) * 2;
862
$moved_ids = array();
863
for ($i = 0; $i < sizeof($moved_modules); ++$i)
865
$moved_ids[] = $moved_modules[$i]['module_id'];
869
$sql = 'UPDATE ' . MODULES_TABLE . "
870
SET right_id = right_id - $diff
871
WHERE module_class = '" . $db->sql_escape($this->module_class) . "'
872
AND left_id < " . (int) $from_data['right_id'] . '
873
AND right_id > ' . (int) $from_data['right_id'];
874
$db->sql_query($sql);
876
// Resync righthand side of tree
877
$sql = 'UPDATE ' . MODULES_TABLE . "
878
SET left_id = left_id - $diff, right_id = right_id - $diff
879
WHERE module_class = '" . $db->sql_escape($this->module_class) . "'
880
AND left_id > " . (int) $from_data['right_id'];
881
$db->sql_query($sql);
883
if ($to_parent_id > 0)
885
$to_data = $this->get_module_row($to_parent_id);
887
// Resync new parents
888
$sql = 'UPDATE ' . MODULES_TABLE . "
889
SET right_id = right_id + $diff
890
WHERE module_class = '" . $db->sql_escape($this->module_class) . "'
891
AND " . (int) $to_data['right_id'] . ' BETWEEN left_id AND right_id
892
AND ' . $db->sql_in_set('module_id', $moved_ids, true);
893
$db->sql_query($sql);
895
// Resync the righthand side of the tree
896
$sql = 'UPDATE ' . MODULES_TABLE . "
897
SET left_id = left_id + $diff, right_id = right_id + $diff
898
WHERE module_class = '" . $db->sql_escape($this->module_class) . "'
899
AND left_id > " . (int) $to_data['right_id'] . '
900
AND ' . $db->sql_in_set('module_id', $moved_ids, true);
901
$db->sql_query($sql);
903
// Resync moved branch
904
$to_data['right_id'] += $diff;
905
if ($to_data['right_id'] > $from_data['right_id'])
907
$diff = '+ ' . ($to_data['right_id'] - $from_data['right_id'] - 1);
911
$diff = '- ' . abs($to_data['right_id'] - $from_data['right_id'] - 1);
916
$sql = 'SELECT MAX(right_id) AS right_id
917
FROM ' . MODULES_TABLE . "
918
WHERE module_class = '" . $db->sql_escape($this->module_class) . "'
919
AND " . $db->sql_in_set('module_id', $moved_ids, true);
920
$result = $db->sql_query($sql);
921
$row = $db->sql_fetchrow($result);
922
$db->sql_freeresult($result);
924
$diff = '+ ' . (int) ($row['right_id'] - $from_data['left_id'] + 1);
927
$sql = 'UPDATE ' . MODULES_TABLE . "
928
SET left_id = left_id $diff, right_id = right_id $diff
929
WHERE module_class = '" . $db->sql_escape($this->module_class) . "'
930
AND " . $db->sql_in_set('module_id', $moved_ids);
931
$db->sql_query($sql);
935
* Remove module from tree
937
function delete_module($module_id)
941
$row = $this->get_module_row($module_id);
943
$branch = $this->get_module_branch($module_id, 'children', 'descending', false);
947
return array($user->lang['CANNOT_REMOVE_MODULE']);
952
$sql = 'DELETE FROM ' . MODULES_TABLE . "
953
WHERE module_class = '" . $db->sql_escape($this->module_class) . "'
954
AND module_id = $module_id";
955
$db->sql_query($sql);
957
$row['right_id'] = (int) $row['right_id'];
958
$row['left_id'] = (int) $row['left_id'];
961
$sql = 'UPDATE ' . MODULES_TABLE . "
962
SET right_id = right_id - $diff
963
WHERE module_class = '" . $db->sql_escape($this->module_class) . "'
964
AND left_id < {$row['right_id']} AND right_id > {$row['right_id']}";
965
$db->sql_query($sql);
967
$sql = 'UPDATE ' . MODULES_TABLE . "
968
SET left_id = left_id - $diff, right_id = right_id - $diff
969
WHERE module_class = '" . $db->sql_escape($this->module_class) . "'
970
AND left_id > {$row['right_id']}";
971
$db->sql_query($sql);
973
add_log('admin', 'LOG_MODULE_REMOVED', $this->lang_name($row['module_langname']));
980
* Move module position by $steps up/down
982
function move_module_by($module_row, $action = 'move_up', $steps = 1)
987
* Fetch all the siblings between the module's current spot
988
* and where we want to move it to. If there are less than $steps
989
* siblings between the current spot and the target then the
990
* module will move as far as possible
992
$sql = 'SELECT module_id, left_id, right_id, module_langname
993
FROM ' . MODULES_TABLE . "
994
WHERE module_class = '" . $db->sql_escape($this->module_class) . "'
995
AND parent_id = " . (int) $module_row['parent_id'] . '
996
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');
997
$result = $db->sql_query_limit($sql, $steps);
1000
while ($row = $db->sql_fetchrow($result))
1004
$db->sql_freeresult($result);
1006
if (!sizeof($target))
1008
// The module is already on top or bottom
1013
* $left_id and $right_id define the scope of the nodes that are affected by the move.
1014
* $diff_up and $diff_down are the values to substract or add to each node's left_id
1015
* and right_id in order to move them up or down.
1016
* $move_up_left and $move_up_right define the scope of the nodes that are moving
1017
* up. Other nodes in the scope of ($left_id, $right_id) are considered to move down.
1019
if ($action == 'move_up')
1021
$left_id = (int) $target['left_id'];
1022
$right_id = (int) $module_row['right_id'];
1024
$diff_up = (int) ($module_row['left_id'] - $target['left_id']);
1025
$diff_down = (int) ($module_row['right_id'] + 1 - $module_row['left_id']);
1027
$move_up_left = (int) $module_row['left_id'];
1028
$move_up_right = (int) $module_row['right_id'];
1032
$left_id = (int) $module_row['left_id'];
1033
$right_id = (int) $target['right_id'];
1035
$diff_up = (int) ($module_row['right_id'] + 1 - $module_row['left_id']);
1036
$diff_down = (int) ($target['right_id'] - $module_row['right_id']);
1038
$move_up_left = (int) ($module_row['right_id'] + 1);
1039
$move_up_right = (int) $target['right_id'];
1042
// Now do the dirty job
1043
$sql = 'UPDATE ' . MODULES_TABLE . "
1044
SET left_id = left_id + CASE
1045
WHEN left_id BETWEEN {$move_up_left} AND {$move_up_right} THEN -{$diff_up}
1048
right_id = right_id + CASE
1049
WHEN right_id BETWEEN {$move_up_left} AND {$move_up_right} THEN -{$diff_up}
1052
WHERE module_class = '" . $db->sql_escape($this->module_class) . "'
1053
AND left_id BETWEEN {$left_id} AND {$right_id}
1054
AND right_id BETWEEN {$left_id} AND {$right_id}";
1055
$db->sql_query($sql);
1057
$this->remove_cache_file();
1059
return $this->lang_name($target['module_langname']);
b'\\ No newline at end of file'