Verzeichnisstruktur phpBB-3.1.0


Veröffentlicht
27.10.2014

So funktioniert es


Auf das letzte Element klicken. Dies geht jeweils ein Schritt zurück

Auf das Icon klicken, dies öffnet das Verzeichnis. Nochmal klicken schließt das Verzeichnis.
Auf den Verzeichnisnamen klicken, dies zeigt nur das Verzeichnis mit Inhalt an

      (Beispiel Datei-Icons)

Auf das Icon klicken um den Quellcode anzuzeigen

acp_modules.php

Zuletzt modifiziert: 09.10.2024, 12:52 - Dateigröße: 32.17 KiB


 0001  <?php
 0002  /**
 0003  *
 0004  * This file is part of the phpBB Forum Software package.
 0005  *
 0006  * @copyright (c) phpBB Limited <https://www.phpbb.com>
 0007  * @license GNU General Public License, version 2 (GPL-2.0)
 0008  *
 0009  * For full copyright and license information, please see
 0010  * the docs/CREDITS.txt file.
 0011  *
 0012  */
 0013   
 0014  /**
 0015  * @ignore
 0016  */
 0017  if (!defined('IN_PHPBB'))
 0018  {
 0019      exit;
 0020  }
 0021   
 0022  /**
 0023  * - Able to check for new module versions (modes changed/adjusted/added/removed)
 0024  * Icons for:
 0025  * - module enabled and displayed (common)
 0026  * - module enabled and not displayed
 0027  * - module deactivated
 0028  * - category (enabled)
 0029  * - category disabled
 0030  */
 0031   
 0032  class acp_modules
 0033  {
 0034      var $module_class = '';
 0035      var $parent_id;
 0036      var $u_action;
 0037   
 0038      function main($id, $mode)
 0039      {
 0040          global $db, $user, $auth, $template, $module, $request;
 0041          global $config, $phpbb_admin_path, $phpbb_root_path, $phpEx;
 0042   
 0043          // Set a global define for modules we might include (the author is able to prevent execution of code by checking this constant)
 0044          define('MODULE_INCLUDE', true);
 0045   
 0046          $user->add_lang('acp/modules');
 0047          $this->tpl_name = 'acp_modules';
 0048   
 0049          // module class
 0050          $this->module_class = $mode;
 0051   
 0052          if ($this->module_class == 'ucp')
 0053          {
 0054              $user->add_lang('ucp');
 0055          }
 0056          else if ($this->module_class == 'mcp')
 0057          {
 0058              $user->add_lang('mcp');
 0059          }
 0060   
 0061          if ($module->p_class != $this->module_class)
 0062          {
 0063              $module->add_mod_info($this->module_class);
 0064          }
 0065   
 0066          $this->page_title = strtoupper($this->module_class);
 0067   
 0068          $this->parent_id = request_var('parent_id', 0);
 0069          $module_id = request_var('m', 0);
 0070          $action = request_var('action', '');
 0071          $errors = array();
 0072   
 0073          switch ($action)
 0074          {
 0075              case 'delete':
 0076                  if (!$module_id)
 0077                  {
 0078                      trigger_error($user->lang['NO_MODULE_ID'] . adm_back_link($this->u_action . '&amp;parent_id=' . $this->parent_id), E_USER_WARNING);
 0079                  }
 0080   
 0081                  if (confirm_box(true))
 0082                  {
 0083                      // Make sure we are not directly within a module
 0084                      if ($module_id == $this->parent_id)
 0085                      {
 0086                          $sql = 'SELECT parent_id
 0087                              FROM ' . MODULES_TABLE . '
 0088                              WHERE module_id = ' . $module_id;
 0089                          $result = $db->sql_query($sql);
 0090                          $this->parent_id = (int) $db->sql_fetchfield('parent_id');
 0091                          $db->sql_freeresult($result);
 0092                      }
 0093   
 0094                      $errors = $this->delete_module($module_id);
 0095   
 0096                      if (!sizeof($errors))
 0097                      {
 0098                          $this->remove_cache_file();
 0099                          trigger_error($user->lang['MODULE_DELETED'] . adm_back_link($this->u_action . '&amp;parent_id=' . $this->parent_id));
 0100                      }
 0101                  }
 0102                  else
 0103                  {
 0104                      confirm_box(false, 'DELETE_MODULE', build_hidden_fields(array(
 0105                          'i'            => $id,
 0106                          'mode'        => $mode,
 0107                          'parent_id'    => $this->parent_id,
 0108                          'module_id'    => $module_id,
 0109                          'action'    => $action,
 0110                      )));
 0111                  }
 0112   
 0113              break;
 0114   
 0115              case 'enable':
 0116              case 'disable':
 0117                  if (!$module_id)
 0118                  {
 0119                      trigger_error($user->lang['NO_MODULE_ID'] . adm_back_link($this->u_action . '&amp;parent_id=' . $this->parent_id), E_USER_WARNING);
 0120                  }
 0121   
 0122                  $sql = 'SELECT *
 0123                      FROM ' . MODULES_TABLE . "
 0124                      WHERE module_class = '" . $db->sql_escape($this->module_class) . "'
 0125                          AND module_id = $module_id";
 0126                  $result = $db->sql_query($sql);
 0127                  $row = $db->sql_fetchrow($result);
 0128                  $db->sql_freeresult($result);
 0129   
 0130                  if (!$row)
 0131                  {
 0132                      trigger_error($user->lang['NO_MODULE'] . adm_back_link($this->u_action . '&amp;parent_id=' . $this->parent_id), E_USER_WARNING);
 0133                  }
 0134   
 0135                  $sql = 'UPDATE ' . MODULES_TABLE . '
 0136                      SET module_enabled = ' . (($action == 'enable') ? 1 : 0) . "
 0137                      WHERE module_class = '" . $db->sql_escape($this->module_class) . "'
 0138                          AND module_id = $module_id";
 0139                  $db->sql_query($sql);
 0140   
 0141                  add_log('admin', 'LOG_MODULE_' . strtoupper($action), $this->lang_name($row['module_langname']));
 0142                  $this->remove_cache_file();
 0143   
 0144              break;
 0145   
 0146              case 'move_up':
 0147              case 'move_down':
 0148                  if (!$module_id)
 0149                  {
 0150                      trigger_error($user->lang['NO_MODULE_ID'] . adm_back_link($this->u_action . '&amp;parent_id=' . $this->parent_id), E_USER_WARNING);
 0151                  }
 0152   
 0153                  $sql = 'SELECT *
 0154                      FROM ' . MODULES_TABLE . "
 0155                      WHERE module_class = '" . $db->sql_escape($this->module_class) . "'
 0156                          AND module_id = $module_id";
 0157                  $result = $db->sql_query($sql);
 0158                  $row = $db->sql_fetchrow($result);
 0159                  $db->sql_freeresult($result);
 0160   
 0161                  if (!$row)
 0162                  {
 0163                      trigger_error($user->lang['NO_MODULE'] . adm_back_link($this->u_action . '&amp;parent_id=' . $this->parent_id), E_USER_WARNING);
 0164                  }
 0165   
 0166                  $move_module_name = $this->move_module_by($row, $action, 1);
 0167   
 0168                  if ($move_module_name !== false)
 0169                  {
 0170                      add_log('admin', 'LOG_MODULE_' . strtoupper($action), $this->lang_name($row['module_langname']), $move_module_name);
 0171                      $this->remove_cache_file();
 0172                  }
 0173   
 0174                  if ($request->is_ajax())
 0175                  {
 0176                      $json_response = new \phpbb\json_response;
 0177                      $json_response->send(array(
 0178                          'success'    => ($move_module_name !== false),
 0179                      ));
 0180                  }
 0181   
 0182              break;
 0183   
 0184              case 'quickadd':
 0185                  $quick_install = request_var('quick_install', '');
 0186   
 0187                  if (confirm_box(true))
 0188                  {
 0189                      if (!$quick_install || strpos($quick_install, '::') === false)
 0190                      {
 0191                          break;
 0192                      }
 0193   
 0194                      list($module_basename, $module_mode) = explode('::', $quick_install);
 0195   
 0196                      // Check if module name and mode exist...
 0197                      $fileinfo = $this->get_module_infos($module_basename);
 0198                      $fileinfo = $fileinfo[$module_basename];
 0199   
 0200                      if (isset($fileinfo['modes'][$module_mode]))
 0201                      {
 0202                          $module_data = array(
 0203                              'module_basename'    => $module_basename,
 0204                              'module_enabled'    => 0,
 0205                              'module_display'    => (isset($fileinfo['modes'][$module_mode]['display'])) ? $fileinfo['modes'][$module_mode]['display'] : 1,
 0206                              'parent_id'            => $this->parent_id,
 0207                              'module_class'        => $this->module_class,
 0208                              'module_langname'    => $fileinfo['modes'][$module_mode]['title'],
 0209                              'module_mode'        => $module_mode,
 0210                              'module_auth'        => $fileinfo['modes'][$module_mode]['auth'],
 0211                          );
 0212   
 0213                          $errors = $this->update_module_data($module_data);
 0214   
 0215                          if (!sizeof($errors))
 0216                          {
 0217                              $this->remove_cache_file();
 0218   
 0219                              trigger_error($user->lang['MODULE_ADDED'] . adm_back_link($this->u_action . '&amp;parent_id=' . $this->parent_id));
 0220                          }
 0221                      }
 0222                  }
 0223                  else
 0224                  {
 0225                      confirm_box(false, 'ADD_MODULE', build_hidden_fields(array(
 0226                          'i'            => $id,
 0227                          'mode'        => $mode,
 0228                          'parent_id'    => $this->parent_id,
 0229                          'action'    => 'quickadd',
 0230                          'quick_install'    => $quick_install,
 0231                      )));
 0232                  }
 0233   
 0234              break;
 0235   
 0236              case 'edit':
 0237   
 0238                  if (!$module_id)
 0239                  {
 0240                      trigger_error($user->lang['NO_MODULE_ID'] . adm_back_link($this->u_action . '&amp;parent_id=' . $this->parent_id), E_USER_WARNING);
 0241                  }
 0242   
 0243                  $module_row = $this->get_module_row($module_id);
 0244   
 0245              // no break
 0246   
 0247              case 'add':
 0248   
 0249                  if ($action == 'add')
 0250                  {
 0251                      $module_row = array(
 0252                          'module_basename'    => '',
 0253                          'module_enabled'    => 0,
 0254                          'module_display'    => 1,
 0255                          'parent_id'            => 0,
 0256                          'module_langname'    => utf8_normalize_nfc(request_var('module_langname', '', true)),
 0257                          'module_mode'        => '',
 0258                          'module_auth'        => '',
 0259                      );
 0260                  }
 0261   
 0262                  $module_data = array();
 0263   
 0264                  $module_data['module_basename'] = request_var('module_basename', (string) $module_row['module_basename']);
 0265                  $module_data['module_enabled'] = request_var('module_enabled', (int) $module_row['module_enabled']);
 0266                  $module_data['module_display'] = request_var('module_display', (int) $module_row['module_display']);
 0267                  $module_data['parent_id'] = request_var('module_parent_id', (int) $module_row['parent_id']);
 0268                  $module_data['module_class'] = $this->module_class;
 0269                  $module_data['module_langname'] = utf8_normalize_nfc(request_var('module_langname', (string) $module_row['module_langname'], true));
 0270                  $module_data['module_mode'] = request_var('module_mode', (string) $module_row['module_mode']);
 0271   
 0272                  $submit = (isset($_POST['submit'])) ? true : false;
 0273   
 0274                  if ($submit)
 0275                  {
 0276                      if (!$module_data['module_langname'])
 0277                      {
 0278                          trigger_error($user->lang['NO_MODULE_LANGNAME'] . adm_back_link($this->u_action . '&amp;parent_id=' . $this->parent_id), E_USER_WARNING);
 0279                      }
 0280   
 0281                      $module_type = request_var('module_type', 'category');
 0282   
 0283                      if ($module_type == 'category')
 0284                      {
 0285                          $module_data['module_basename'] = $module_data['module_mode'] = $module_data['module_auth'] = '';
 0286                          $module_data['module_display'] = 1;
 0287                      }
 0288   
 0289                      if ($action == 'edit')
 0290                      {
 0291                          $module_data['module_id'] = $module_id;
 0292                      }
 0293   
 0294                      // Adjust auth row
 0295                      if ($module_data['module_basename'] && $module_data['module_mode'])
 0296                      {
 0297                          $fileinfo = $this->get_module_infos($module_data['module_basename']);
 0298                          $module_data['module_auth'] = $fileinfo[$module_data['module_basename']]['modes'][$module_data['module_mode']]['auth'];
 0299                      }
 0300   
 0301                      $errors = $this->update_module_data($module_data);
 0302   
 0303                      if (!sizeof($errors))
 0304                      {
 0305                          $this->remove_cache_file();
 0306   
 0307                          trigger_error((($action == 'add') ? $user->lang['MODULE_ADDED'] : $user->lang['MODULE_EDITED']) . adm_back_link($this->u_action . '&amp;parent_id=' . $this->parent_id));
 0308                      }
 0309                  }
 0310   
 0311                  // Category/not category?
 0312                  $is_cat = (!$module_data['module_basename']) ? true : false;
 0313   
 0314                  // Get module information
 0315                  $module_infos = $this->get_module_infos();
 0316   
 0317                  // Build name options
 0318                  $s_name_options = $s_mode_options = '';
 0319                  foreach ($module_infos as $option => $values)
 0320                  {
 0321                      if (!$module_data['module_basename'])
 0322                      {
 0323                          $module_data['module_basename'] = $option;
 0324                      }
 0325   
 0326                      // Name options
 0327                      $s_name_options .= '<option value="' . $option . '"' . (($option == $module_data['module_basename']) ? ' selected="selected"' : '') . '>' . $this->lang_name($values['title']) . ' [' . $option . ']</option>';
 0328   
 0329                      $template->assign_block_vars('m_names', array('NAME' => $option, 'A_NAME' => addslashes($option)));
 0330   
 0331                      // Build module modes
 0332                      foreach ($values['modes'] as $m_mode => $m_values)
 0333                      {
 0334                          if ($option == $module_data['module_basename'])
 0335                          {
 0336                              $s_mode_options .= '<option value="' . $m_mode . '"' . (($m_mode == $module_data['module_mode']) ? ' selected="selected"' : '') . '>' . $this->lang_name($m_values['title']) . '</option>';
 0337                          }
 0338   
 0339                          $template->assign_block_vars('m_names.modes', array(
 0340                              'OPTION'        => $m_mode,
 0341                              'VALUE'            => $this->lang_name($m_values['title']),
 0342                              'A_OPTION'        => addslashes($m_mode),
 0343                              'A_VALUE'        => addslashes($this->lang_name($m_values['title'])))
 0344                          );
 0345                      }
 0346                  }
 0347   
 0348                  $s_cat_option = '<option value="0"' . (($module_data['parent_id'] == 0) ? ' selected="selected"' : '') . '>' . $user->lang['NO_PARENT'] . '</option>';
 0349   
 0350                  $template->assign_vars(array_merge(array(
 0351                      'S_EDIT_MODULE'        => true,
 0352                      'S_IS_CAT'            => $is_cat,
 0353                      '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),
 0354                      'S_MODULE_NAMES'    => $s_name_options,
 0355                      'S_MODULE_MODES'    => $s_mode_options,
 0356                      'U_BACK'            => $this->u_action . '&amp;parent_id=' . $this->parent_id,
 0357                      'U_EDIT_ACTION'        => $this->u_action . '&amp;parent_id=' . $this->parent_id,
 0358   
 0359                      'L_TITLE'            => $user->lang[strtoupper($action) . '_MODULE'],
 0360   
 0361                      'MODULENAME'        => $this->lang_name($module_data['module_langname']),
 0362                      'ACTION'            => $action,
 0363                      'MODULE_ID'            => $module_id,
 0364   
 0365                  ),
 0366                      array_change_key_case($module_data, CASE_UPPER))
 0367                  );
 0368   
 0369                  if (sizeof($errors))
 0370                  {
 0371                      $template->assign_vars(array(
 0372                          'S_ERROR'    => true,
 0373                          'ERROR_MSG'    => implode('<br />', $errors))
 0374                      );
 0375                  }
 0376   
 0377                  return;
 0378   
 0379              break;
 0380          }
 0381   
 0382          // Default management page
 0383          if (sizeof($errors))
 0384          {
 0385              if ($request->is_ajax())
 0386              {
 0387                  $json_response = new \phpbb\json_response;
 0388                  $json_response->send(array(
 0389                      'MESSAGE_TITLE'    => $user->lang('ERROR'),
 0390                      'MESSAGE_TEXT'    => implode('<br />', $errors),
 0391                      'SUCCESS'    => false,
 0392                  ));
 0393              }
 0394   
 0395              $template->assign_vars(array(
 0396                  'S_ERROR'    => true,
 0397                  'ERROR_MSG'    => implode('<br />', $errors))
 0398              );
 0399          }
 0400   
 0401          if (!$this->parent_id)
 0402          {
 0403              $navigation = strtoupper($this->module_class);
 0404          }
 0405          else
 0406          {
 0407              $navigation = '<a href="' . $this->u_action . '">' . strtoupper($this->module_class) . '</a>';
 0408   
 0409              $modules_nav = $this->get_module_branch($this->parent_id, 'parents', 'descending');
 0410   
 0411              foreach ($modules_nav as $row)
 0412              {
 0413                  $langname = $this->lang_name($row['module_langname']);
 0414   
 0415                  if ($row['module_id'] == $this->parent_id)
 0416                  {
 0417                      $navigation .= ' -&gt; ' . $langname;
 0418                  }
 0419                  else
 0420                  {
 0421                      $navigation .= ' -&gt; <a href="' . $this->u_action . '&amp;parent_id=' . $row['module_id'] . '">' . $langname . '</a>';
 0422                  }
 0423              }
 0424          }
 0425   
 0426          // Jumpbox
 0427          $module_box = $this->make_module_select($this->parent_id, false, false, false, false);
 0428   
 0429          $sql = 'SELECT *
 0430              FROM ' . MODULES_TABLE . "
 0431              WHERE parent_id = {$this->parent_id}
 0432                  AND module_class = '" . $db->sql_escape($this->module_class) . "'
 0433              ORDER BY left_id";
 0434          $result = $db->sql_query($sql);
 0435   
 0436          if ($row = $db->sql_fetchrow($result))
 0437          {
 0438              do
 0439              {
 0440                  $langname = $this->lang_name($row['module_langname']);
 0441   
 0442                  if (!$row['module_enabled'])
 0443                  {
 0444                      $module_image = '<img src="images/icon_folder_lock.gif" alt="' . $user->lang['DEACTIVATED_MODULE'] .'" />';
 0445                  }
 0446                  else
 0447                  {
 0448                      $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'] . '" />';
 0449                  }
 0450   
 0451                  $url = $this->u_action . '&amp;parent_id=' . $this->parent_id . '&amp;m=' . $row['module_id'];
 0452   
 0453                  $template->assign_block_vars('modules', array(
 0454                      'MODULE_IMAGE'        => $module_image,
 0455                      'MODULE_TITLE'        => $langname,
 0456                      'MODULE_ENABLED'    => ($row['module_enabled']) ? true : false,
 0457                      'MODULE_DISPLAYED'    => ($row['module_display']) ? true : false,
 0458   
 0459                      'S_ACP_CAT_SYSTEM'            => ($this->module_class == 'acp' && $row['module_langname'] == 'ACP_CAT_SYSTEM') ? true : false,
 0460                      'S_ACP_MODULE_MANAGEMENT'    => ($this->module_class == 'acp' && ($row['module_basename'] == 'modules' || $row['module_langname'] == 'ACP_MODULE_MANAGEMENT')) ? true : false,
 0461   
 0462                      'U_MODULE'            => $this->u_action . '&amp;parent_id=' . $row['module_id'],
 0463                      'U_MOVE_UP'            => $url . '&amp;action=move_up',
 0464                      'U_MOVE_DOWN'        => $url . '&amp;action=move_down',
 0465                      'U_EDIT'            => $url . '&amp;action=edit',
 0466                      'U_DELETE'            => $url . '&amp;action=delete',
 0467                      'U_ENABLE'            => $url . '&amp;action=enable',
 0468                      'U_DISABLE'            => $url . '&amp;action=disable')
 0469                  );
 0470              }
 0471              while ($row = $db->sql_fetchrow($result));
 0472          }
 0473          else if ($this->parent_id)
 0474          {
 0475              $row = $this->get_module_row($this->parent_id);
 0476   
 0477              $url = $this->u_action . '&amp;parent_id=' . $this->parent_id . '&amp;m=' . $row['module_id'];
 0478   
 0479              $template->assign_vars(array(
 0480                  'S_NO_MODULES'        => true,
 0481                  'MODULE_TITLE'        => $langname,
 0482                  'MODULE_ENABLED'    => ($row['module_enabled']) ? true : false,
 0483                  'MODULE_DISPLAYED'    => ($row['module_display']) ? true : false,
 0484   
 0485                  'U_EDIT'            => $url . '&amp;action=edit',
 0486                  'U_DELETE'            => $url . '&amp;action=delete',
 0487                  'U_ENABLE'            => $url . '&amp;action=enable',
 0488                  'U_DISABLE'            => $url . '&amp;action=disable')
 0489              );
 0490          }
 0491          $db->sql_freeresult($result);
 0492   
 0493          // Quick adding module
 0494          $module_infos = $this->get_module_infos();
 0495   
 0496          // Build quick options
 0497          $s_install_options = '';
 0498          foreach ($module_infos as $option => $values)
 0499          {
 0500              // Name options
 0501              $s_install_options .= '<optgroup label="' . $this->lang_name($values['title']) . ' [' . $option . ']">';
 0502   
 0503              // Build module modes
 0504              foreach ($values['modes'] as $m_mode => $m_values)
 0505              {
 0506                  $s_install_options .= '<option value="' . $option . '::' . $m_mode . '">&nbsp; &nbsp;' . $this->lang_name($m_values['title']) . '</option>';
 0507              }
 0508   
 0509              $s_install_options .= '</optgroup>';
 0510          }
 0511   
 0512          $template->assign_vars(array(
 0513              'U_SEL_ACTION'        => $this->u_action,
 0514              'U_ACTION'            => $this->u_action . '&amp;parent_id=' . $this->parent_id,
 0515              'NAVIGATION'        => $navigation,
 0516              'MODULE_BOX'        => $module_box,
 0517              'PARENT_ID'            => $this->parent_id,
 0518              'S_INSTALL_OPTIONS'    => $s_install_options,
 0519              )
 0520          );
 0521      }
 0522   
 0523      /**
 0524      * Get row for specified module
 0525      */
 0526      function get_module_row($module_id)
 0527      {
 0528          global $db, $user;
 0529   
 0530          $sql = 'SELECT *
 0531              FROM ' . MODULES_TABLE . "
 0532              WHERE module_class = '" . $db->sql_escape($this->module_class) . "'
 0533                  AND module_id = $module_id";
 0534          $result = $db->sql_query($sql);
 0535          $row = $db->sql_fetchrow($result);
 0536          $db->sql_freeresult($result);
 0537   
 0538          if (!$row)
 0539          {
 0540              trigger_error($user->lang['NO_MODULE'] . adm_back_link($this->u_action . '&amp;parent_id=' . $this->parent_id), E_USER_WARNING);
 0541          }
 0542   
 0543          return $row;
 0544      }
 0545   
 0546      /**
 0547      * Get available module information from module files
 0548      *
 0549      * @param string $module
 0550      * @param bool|string $module_class
 0551      * @param bool $use_all_available Use all available instead of just all
 0552      *                         enabled extensions
 0553      * @return array
 0554      */
 0555      function get_module_infos($module = '', $module_class = false, $use_all_available = false)
 0556      {
 0557          global $phpbb_extension_manager, $phpbb_root_path, $phpEx;
 0558   
 0559          $module_class = ($module_class === false) ? $this->module_class : $module_class;
 0560   
 0561          $directory = $phpbb_root_path . 'includes/' . $module_class . '/info/';
 0562          $fileinfo = array();
 0563   
 0564          $finder = $phpbb_extension_manager->get_finder($use_all_available);
 0565   
 0566          $modules = $finder
 0567              ->extension_suffix('_module')
 0568              ->extension_directory("/$module_class")
 0569              ->core_path("includes/$module_class/info/")
 0570              ->core_prefix($module_class . '_')
 0571              ->get_classes(true);
 0572   
 0573          foreach ($modules as $cur_module)
 0574          {
 0575              // Skip entries we do not need if we know the module we are
 0576              // looking for
 0577              if ($module && strpos(str_replace('\\', '_', $cur_module), $module) === false && $module !== $cur_module)
 0578              {
 0579                  continue;
 0580              }
 0581   
 0582              $info_class = preg_replace('/_module$/', '_info', $cur_module);
 0583   
 0584              // If the class does not exist it might be following the old
 0585              // format. phpbb_acp_info_acp_foo needs to be turned into
 0586              // acp_foo_info and the respective file has to be included
 0587              // manually because it does not support auto loading
 0588              $old_info_class_file = str_replace("phpbb_{$module_class}_info_", '', $cur_module);
 0589              $old_info_class = $old_info_class_file . '_info';
 0590   
 0591              if (class_exists($old_info_class))
 0592              {
 0593                  $info_class = $old_info_class;
 0594              }
 0595              else if (!class_exists($info_class))
 0596              {
 0597                  $info_class = $old_info_class;
 0598                  // need to check class exists again because previous checks triggered autoloading
 0599                  if (!class_exists($info_class) && file_exists($directory . $old_info_class_file . '.' . $phpEx))
 0600                  {
 0601                      include($directory . $old_info_class_file . '.' . $phpEx);
 0602                  }
 0603              }
 0604   
 0605              if (class_exists($info_class))
 0606              {
 0607                  $info = new $info_class();
 0608                  $module_info = $info->module();
 0609   
 0610                  $main_class = (isset($module_info['filename'])) ? $module_info['filename'] : $cur_module;
 0611   
 0612                  $fileinfo[$main_class] = $module_info;
 0613              }
 0614          }
 0615   
 0616          ksort($fileinfo);
 0617   
 0618          return $fileinfo;
 0619      }
 0620   
 0621      /**
 0622      * Simple version of jumpbox, just lists modules
 0623      */
 0624      function make_module_select($select_id = false, $ignore_id = false, $ignore_acl = false, $ignore_nonpost = false, $ignore_emptycat = true, $ignore_noncat = false)
 0625      {
 0626          global $db, $user, $auth, $config;
 0627   
 0628          $sql = 'SELECT module_id, module_enabled, module_basename, parent_id, module_langname, left_id, right_id, module_auth
 0629              FROM ' . MODULES_TABLE . "
 0630              WHERE module_class = '" . $db->sql_escape($this->module_class) . "'
 0631              ORDER BY left_id ASC";
 0632          $result = $db->sql_query($sql);
 0633   
 0634          $right = $iteration = 0;
 0635          $padding_store = array('0' => '');
 0636          $module_list = $padding = '';
 0637   
 0638          while ($row = $db->sql_fetchrow($result))
 0639          {
 0640              if ($row['left_id'] < $right)
 0641              {
 0642                  $padding .= '&nbsp; &nbsp;';
 0643                  $padding_store[$row['parent_id']] = $padding;
 0644              }
 0645              else if ($row['left_id'] > $right + 1)
 0646              {
 0647                  $padding = (isset($padding_store[$row['parent_id']])) ? $padding_store[$row['parent_id']] : '';
 0648              }
 0649   
 0650              $right = $row['right_id'];
 0651   
 0652              if (!$ignore_acl && $row['module_auth'])
 0653              {
 0654                  // We use zero as the forum id to check - global setting.
 0655                  if (!p_master::module_auth($row['module_auth'], 0))
 0656                  {
 0657                      continue;
 0658                  }
 0659              }
 0660   
 0661              // ignore this module?
 0662              if ((is_array($ignore_id) && in_array($row['module_id'], $ignore_id)) || $row['module_id'] == $ignore_id)
 0663              {
 0664                  continue;
 0665              }
 0666   
 0667              // empty category
 0668              if (!$row['module_basename'] && ($row['left_id'] + 1 == $row['right_id']) && $ignore_emptycat)
 0669              {
 0670                  continue;
 0671              }
 0672   
 0673              // ignore non-category?
 0674              if ($row['module_basename'] && $ignore_noncat)
 0675              {
 0676                  continue;
 0677              }
 0678   
 0679              $selected = (is_array($select_id)) ? ((in_array($row['module_id'], $select_id)) ? ' selected="selected"' : '') : (($row['module_id'] == $select_id) ? ' selected="selected"' : '');
 0680   
 0681              $langname = $this->lang_name($row['module_langname']);
 0682              $module_list .= '<option value="' . $row['module_id'] . '"' . $selected . ((!$row['module_enabled']) ? ' class="disabled"' : '') . '>' . $padding . $langname . '</option>';
 0683   
 0684              $iteration++;
 0685          }
 0686          $db->sql_freeresult($result);
 0687   
 0688          unset($padding_store);
 0689   
 0690          return $module_list;
 0691      }
 0692   
 0693      /**
 0694      * Get module branch
 0695      */
 0696      function get_module_branch($module_id, $type = 'all', $order = 'descending', $include_module = true)
 0697      {
 0698          global $db;
 0699   
 0700          switch ($type)
 0701          {
 0702              case 'parents':
 0703                  $condition = 'm1.left_id BETWEEN m2.left_id AND m2.right_id';
 0704              break;
 0705   
 0706              case 'children':
 0707                  $condition = 'm2.left_id BETWEEN m1.left_id AND m1.right_id';
 0708              break;
 0709   
 0710              default:
 0711                  $condition = 'm2.left_id BETWEEN m1.left_id AND m1.right_id OR m1.left_id BETWEEN m2.left_id AND m2.right_id';
 0712              break;
 0713          }
 0714   
 0715          $rows = array();
 0716   
 0717          $sql = 'SELECT m2.*
 0718              FROM ' . MODULES_TABLE . ' m1
 0719              LEFT JOIN ' . MODULES_TABLE . " m2 ON ($condition)
 0720              WHERE m1.module_class = '" . $db->sql_escape($this->module_class) . "'
 0721                  AND m2.module_class = '" . $db->sql_escape($this->module_class) . "'
 0722                  AND m1.module_id = $module_id
 0723              ORDER BY m2.left_id " . (($order == 'descending') ? 'ASC' : 'DESC');
 0724          $result = $db->sql_query($sql);
 0725   
 0726          while ($row = $db->sql_fetchrow($result))
 0727          {
 0728              if (!$include_module && $row['module_id'] == $module_id)
 0729              {
 0730                  continue;
 0731              }
 0732   
 0733              $rows[] = $row;
 0734          }
 0735          $db->sql_freeresult($result);
 0736   
 0737          return $rows;
 0738      }
 0739   
 0740      /**
 0741      * Remove modules cache file
 0742      */
 0743      function remove_cache_file()
 0744      {
 0745          global $phpbb_container;
 0746   
 0747          // Sanitise for future path use, it's escaped as appropriate for queries
 0748          $p_class = str_replace(array('.', '/', '\\'), '', basename($this->module_class));
 0749   
 0750          $phpbb_container->get('cache.driver')->destroy('_modules_' . $p_class);
 0751   
 0752          // Additionally remove sql cache
 0753          $phpbb_container->get('cache.driver')->destroy('sql', MODULES_TABLE);
 0754      }
 0755   
 0756      /**
 0757      * Return correct language name
 0758      */
 0759      function lang_name($module_langname)
 0760      {
 0761          global $user;
 0762   
 0763          return (!empty($user->lang[$module_langname])) ? $user->lang[$module_langname] : $module_langname;
 0764      }
 0765   
 0766      /**
 0767      * Update/Add module
 0768      *
 0769      * @param array    &$module_data    The module data
 0770      * @param bool    $run_inline     if set to true errors will be returned and no logs being written
 0771      */
 0772      function update_module_data(&$module_data, $run_inline = false)
 0773      {
 0774          global $db, $user;
 0775   
 0776          if (!isset($module_data['module_id']))
 0777          {
 0778              // no module_id means we're creating a new category/module
 0779              if ($module_data['parent_id'])
 0780              {
 0781                  $sql = 'SELECT left_id, right_id
 0782                      FROM ' . MODULES_TABLE . "
 0783                      WHERE module_class = '" . $db->sql_escape($module_data['module_class']) . "'
 0784                          AND module_id = " . (int) $module_data['parent_id'];
 0785                  $result = $db->sql_query($sql);
 0786                  $row = $db->sql_fetchrow($result);
 0787                  $db->sql_freeresult($result);
 0788   
 0789                  if (!$row)
 0790                  {
 0791                      if ($run_inline)
 0792                      {
 0793                          return 'PARENT_NO_EXIST';
 0794                      }
 0795   
 0796                      trigger_error($user->lang['PARENT_NO_EXIST'] . adm_back_link($this->u_action . '&amp;parent_id=' . $this->parent_id), E_USER_WARNING);
 0797                  }
 0798   
 0799                  // Workaround
 0800                  $row['left_id'] = (int) $row['left_id'];
 0801                  $row['right_id'] = (int) $row['right_id'];
 0802   
 0803                  $sql = 'UPDATE ' . MODULES_TABLE . "
 0804                      SET left_id = left_id + 2, right_id = right_id + 2
 0805                      WHERE module_class = '" . $db->sql_escape($module_data['module_class']) . "'
 0806                          AND left_id > {$row['right_id']}";
 0807                  $db->sql_query($sql);
 0808   
 0809                  $sql = 'UPDATE ' . MODULES_TABLE . "
 0810                      SET right_id = right_id + 2
 0811                      WHERE module_class = '" . $db->sql_escape($module_data['module_class']) . "'
 0812                          AND {$row['left_id']} BETWEEN left_id AND right_id";
 0813                  $db->sql_query($sql);
 0814   
 0815                  $module_data['left_id'] = (int) $row['right_id'];
 0816                  $module_data['right_id'] = (int) $row['right_id'] + 1;
 0817              }
 0818              else
 0819              {
 0820                  $sql = 'SELECT MAX(right_id) AS right_id
 0821                      FROM ' . MODULES_TABLE . "
 0822                      WHERE module_class = '" . $db->sql_escape($module_data['module_class']) . "'";
 0823                  $result = $db->sql_query($sql);
 0824                  $row = $db->sql_fetchrow($result);
 0825                  $db->sql_freeresult($result);
 0826   
 0827                  $module_data['left_id'] = (int) $row['right_id'] + 1;
 0828                  $module_data['right_id'] = (int) $row['right_id'] + 2;
 0829              }
 0830   
 0831              $sql = 'INSERT INTO ' . MODULES_TABLE . ' ' . $db->sql_build_array('INSERT', $module_data);
 0832              $db->sql_query($sql);
 0833   
 0834              $module_data['module_id'] = $db->sql_nextid();
 0835   
 0836              if (!$run_inline)
 0837              {
 0838                  add_log('admin', 'LOG_MODULE_ADD', $this->lang_name($module_data['module_langname']));
 0839              }
 0840          }
 0841          else
 0842          {
 0843              $row = $this->get_module_row($module_data['module_id']);
 0844   
 0845              if ($module_data['module_basename'] && !$row['module_basename'])
 0846              {
 0847                  // we're turning a category into a module
 0848                  $branch = $this->get_module_branch($module_data['module_id'], 'children', 'descending', false);
 0849   
 0850                  if (sizeof($branch))
 0851                  {
 0852                      return array($user->lang['NO_CATEGORY_TO_MODULE']);
 0853                  }
 0854              }
 0855   
 0856              if ($row['parent_id'] != $module_data['parent_id'])
 0857              {
 0858                  $this->move_module($module_data['module_id'], $module_data['parent_id']);
 0859              }
 0860   
 0861              $update_ary = $module_data;
 0862              unset($update_ary['module_id']);
 0863   
 0864              $sql = 'UPDATE ' . MODULES_TABLE . '
 0865                  SET ' . $db->sql_build_array('UPDATE', $update_ary) . "
 0866                  WHERE module_class = '" . $db->sql_escape($module_data['module_class']) . "'
 0867                      AND module_id = " . (int) $module_data['module_id'];
 0868              $db->sql_query($sql);
 0869   
 0870              if (!$run_inline)
 0871              {
 0872                  add_log('admin', 'LOG_MODULE_EDIT', $this->lang_name($module_data['module_langname']));
 0873              }
 0874          }
 0875   
 0876          return array();
 0877      }
 0878   
 0879      /**
 0880      * Move module around the tree
 0881      */
 0882      function move_module($from_module_id, $to_parent_id)
 0883      {
 0884          global $db;
 0885   
 0886          $moved_modules = $this->get_module_branch($from_module_id, 'children', 'descending');
 0887          $from_data = $moved_modules[0];
 0888          $diff = sizeof($moved_modules) * 2;
 0889   
 0890          $moved_ids = array();
 0891          for ($i = 0; $i < sizeof($moved_modules); ++$i)
 0892          {
 0893              $moved_ids[] = $moved_modules[$i]['module_id'];
 0894          }
 0895   
 0896          // Resync parents
 0897          $sql = 'UPDATE ' . MODULES_TABLE . "
 0898              SET right_id = right_id - $diff
 0899              WHERE module_class = '" . $db->sql_escape($this->module_class) . "'
 0900                  AND left_id < " . (int) $from_data['right_id'] . '
 0901                  AND right_id > ' . (int) $from_data['right_id'];
 0902          $db->sql_query($sql);
 0903   
 0904          // Resync righthand side of tree
 0905          $sql = 'UPDATE ' . MODULES_TABLE . "
 0906              SET left_id = left_id - $diff, right_id = right_id - $diff
 0907              WHERE module_class = '" . $db->sql_escape($this->module_class) . "'
 0908                  AND left_id > " . (int) $from_data['right_id'];
 0909          $db->sql_query($sql);
 0910   
 0911          if ($to_parent_id > 0)
 0912          {
 0913              $to_data = $this->get_module_row($to_parent_id);
 0914   
 0915              // Resync new parents
 0916              $sql = 'UPDATE ' . MODULES_TABLE . "
 0917                  SET right_id = right_id + $diff
 0918                  WHERE module_class = '" . $db->sql_escape($this->module_class) . "'
 0919                      AND " . (int) $to_data['right_id'] . ' BETWEEN left_id AND right_id
 0920                      AND ' . $db->sql_in_set('module_id', $moved_ids, true);
 0921              $db->sql_query($sql);
 0922   
 0923              // Resync the righthand side of the tree
 0924              $sql = 'UPDATE ' . MODULES_TABLE . "
 0925                  SET left_id = left_id + $diff, right_id = right_id + $diff
 0926                  WHERE module_class = '" . $db->sql_escape($this->module_class) . "'
 0927                      AND left_id > " . (int) $to_data['right_id'] . '
 0928                      AND ' . $db->sql_in_set('module_id', $moved_ids, true);
 0929              $db->sql_query($sql);
 0930   
 0931              // Resync moved branch
 0932              $to_data['right_id'] += $diff;
 0933              if ($to_data['right_id'] > $from_data['right_id'])
 0934              {
 0935                  $diff = '+ ' . ($to_data['right_id'] - $from_data['right_id'] - 1);
 0936              }
 0937              else
 0938              {
 0939                  $diff = '- ' . abs($to_data['right_id'] - $from_data['right_id'] - 1);
 0940              }
 0941          }
 0942          else
 0943          {
 0944              $sql = 'SELECT MAX(right_id) AS right_id
 0945                  FROM ' . MODULES_TABLE . "
 0946                  WHERE module_class = '" . $db->sql_escape($this->module_class) . "'
 0947                      AND " . $db->sql_in_set('module_id', $moved_ids, true);
 0948              $result = $db->sql_query($sql);
 0949              $row = $db->sql_fetchrow($result);
 0950              $db->sql_freeresult($result);
 0951   
 0952              $diff = '+ ' . (int) ($row['right_id'] - $from_data['left_id'] + 1);
 0953          }
 0954   
 0955          $sql = 'UPDATE ' . MODULES_TABLE . "
 0956              SET left_id = left_id $diff, right_id = right_id $diff
 0957              WHERE module_class = '" . $db->sql_escape($this->module_class) . "'
 0958                  AND " . $db->sql_in_set('module_id', $moved_ids);
 0959          $db->sql_query($sql);
 0960      }
 0961   
 0962      /**
 0963      * Remove module from tree
 0964      */
 0965      function delete_module($module_id)
 0966      {
 0967          global $db, $user;
 0968   
 0969          $row = $this->get_module_row($module_id);
 0970   
 0971          $branch = $this->get_module_branch($module_id, 'children', 'descending', false);
 0972   
 0973          if (sizeof($branch))
 0974          {
 0975              return array($user->lang['CANNOT_REMOVE_MODULE']);
 0976          }
 0977   
 0978          // If not move
 0979          $diff = 2;
 0980          $sql = 'DELETE FROM ' . MODULES_TABLE . "
 0981              WHERE module_class = '" . $db->sql_escape($this->module_class) . "'
 0982                  AND module_id = $module_id";
 0983          $db->sql_query($sql);
 0984   
 0985          $row['right_id'] = (int) $row['right_id'];
 0986          $row['left_id'] = (int) $row['left_id'];
 0987   
 0988          // Resync tree
 0989          $sql = 'UPDATE ' . MODULES_TABLE . "
 0990              SET right_id = right_id - $diff
 0991              WHERE module_class = '" . $db->sql_escape($this->module_class) . "'
 0992                  AND left_id < {$row['right_id']} AND right_id > {$row['right_id']}";
 0993          $db->sql_query($sql);
 0994   
 0995          $sql = 'UPDATE ' . MODULES_TABLE . "
 0996              SET left_id = left_id - $diff, right_id = right_id - $diff
 0997              WHERE module_class = '" . $db->sql_escape($this->module_class) . "'
 0998                  AND left_id > {$row['right_id']}";
 0999          $db->sql_query($sql);
 1000   
 1001          add_log('admin', 'LOG_MODULE_REMOVED', $this->lang_name($row['module_langname']));
 1002   
 1003          return array();
 1004   
 1005      }
 1006   
 1007      /**
 1008      * Move module position by $steps up/down
 1009      */
 1010      function move_module_by($module_row, $action = 'move_up', $steps = 1)
 1011      {
 1012          global $db;
 1013   
 1014          /**
 1015          * Fetch all the siblings between the module's current spot
 1016          * and where we want to move it to. If there are less than $steps
 1017          * siblings between the current spot and the target then the
 1018          * module will move as far as possible
 1019          */
 1020          $sql = 'SELECT module_id, left_id, right_id, module_langname
 1021              FROM ' . MODULES_TABLE . "
 1022              WHERE module_class = '" . $db->sql_escape($this->module_class) . "'
 1023                  AND parent_id = " . (int) $module_row['parent_id'] . '
 1024                  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');
 1025          $result = $db->sql_query_limit($sql, $steps);
 1026   
 1027          $target = array();
 1028          while ($row = $db->sql_fetchrow($result))
 1029          {
 1030              $target = $row;
 1031          }
 1032          $db->sql_freeresult($result);
 1033   
 1034          if (!sizeof($target))
 1035          {
 1036              // The module is already on top or bottom
 1037              return false;
 1038          }
 1039   
 1040          /**
 1041          * $left_id and $right_id define the scope of the nodes that are affected by the move.
 1042          * $diff_up and $diff_down are the values to substract or add to each node's left_id
 1043          * and right_id in order to move them up or down.
 1044          * $move_up_left and $move_up_right define the scope of the nodes that are moving
 1045          * up. Other nodes in the scope of ($left_id, $right_id) are considered to move down.
 1046          */
 1047          if ($action == 'move_up')
 1048          {
 1049              $left_id = (int) $target['left_id'];
 1050              $right_id = (int) $module_row['right_id'];
 1051   
 1052              $diff_up = (int) ($module_row['left_id'] - $target['left_id']);
 1053              $diff_down = (int) ($module_row['right_id'] + 1 - $module_row['left_id']);
 1054   
 1055              $move_up_left = (int) $module_row['left_id'];
 1056              $move_up_right = (int) $module_row['right_id'];
 1057          }
 1058          else
 1059          {
 1060              $left_id = (int) $module_row['left_id'];
 1061              $right_id = (int) $target['right_id'];
 1062   
 1063              $diff_up = (int) ($module_row['right_id'] + 1 - $module_row['left_id']);
 1064              $diff_down = (int) ($target['right_id'] - $module_row['right_id']);
 1065   
 1066              $move_up_left = (int) ($module_row['right_id'] + 1);
 1067              $move_up_right = (int) $target['right_id'];
 1068          }
 1069   
 1070          // Now do the dirty job
 1071          $sql = 'UPDATE ' . MODULES_TABLE . "
 1072              SET left_id = left_id + CASE
 1073                  WHEN left_id BETWEEN {$move_up_left} AND {$move_up_right} THEN -{$diff_up}
 1074                  ELSE {$diff_down}
 1075              END,
 1076              right_id = right_id + CASE
 1077                  WHEN right_id BETWEEN {$move_up_left} AND {$move_up_right} THEN -{$diff_up}
 1078                  ELSE {$diff_down}
 1079              END
 1080              WHERE module_class = '" . $db->sql_escape($this->module_class) . "'
 1081                  AND left_id BETWEEN {$left_id} AND {$right_id}
 1082                  AND right_id BETWEEN {$left_id} AND {$right_id}";
 1083          $db->sql_query($sql);
 1084   
 1085          $this->remove_cache_file();
 1086   
 1087          return $this->lang_name($target['module_langname']);
 1088      }
 1089  }
 1090