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