[ Index ]

PHP Cross Reference of phpBB 3.0 Beta 3

title

Body

[close]

/includes/acp/ -> acp_modules.php (source)

   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 . '&amp;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 . '&amp;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 . '&amp;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 . '&amp;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 . '&amp;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 . '&amp;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 . '&amp;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 . '&amp;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 . '&amp;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 . '&amp;parent_id=' . $this->parent_id,
 311                      'U_EDIT_ACTION'        => $this->u_action . '&amp;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 .= ' -&gt; ' . $langname;
 362                  }
 363                  else
 364                  {
 365                      $navigation .= ' -&gt; <a href="' . $this->u_action . '&amp;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 . '&amp;parent_id=' . $this->parent_id . '&amp;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 . '&amp;parent_id=' . $row['module_id'],
 407                      'U_MOVE_UP'            => $url . '&amp;action=move_up',
 408                      'U_MOVE_DOWN'        => $url . '&amp;action=move_down',
 409                      'U_EDIT'            => $url . '&amp;action=edit',
 410                      'U_DELETE'            => $url . '&amp;action=delete',
 411                      'U_ENABLE'            => $url . '&amp;action=enable',
 412                      'U_DISABLE'            => $url . '&amp;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 . '&amp;parent_id=' . $this->parent_id . '&amp;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 . '&amp;action=edit',
 430                  'U_DELETE'            => $url . '&amp;action=delete',
 431                  'U_ENABLE'            => $url . '&amp;action=enable',
 432                  'U_DISABLE'            => $url . '&amp;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 . '">&nbsp; &nbsp;' . $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 . '&amp;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 . '&amp;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 .= '&nbsp; &nbsp;';
 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 . '&amp;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  ?>


Generated: Wed Nov 22 00:35:05 2006 Cross-referenced by PHPXref 0.6