[ Index ]

PHP Cross Reference of Unnamed Project

title

Body

[close]

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

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


Generated: Wed Oct 2 15:03:47 2013 Cross-referenced by PHPXref 0.7.1