Verzeichnisstruktur phpBB-3.0.0


Veröffentlicht
12.12.2007

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

install_update.php

Zuletzt modifiziert: 09.10.2024, 12:50 - Dateigröße: 46.99 KiB


 0001  <?php
 0002  /**
 0003  *
 0004  * @package install
 0005  * @version $Id$
 0006  * @copyright (c) 2006 phpBB Group
 0007  * @license http://opensource.org/licenses/gpl-license.php GNU Public License
 0008  *
 0009  * @todo check for writable cache/store/files directory
 0010  */
 0011   
 0012  /**
 0013  */
 0014  if (!defined('IN_INSTALL'))
 0015  {
 0016      // Someone has tried to access the file directly. This is not a good idea, so exit
 0017      exit;
 0018  }
 0019   
 0020  if (!empty($setmodules))
 0021  {
 0022      // If phpBB is not installed we do not include this module
 0023      if (@file_exists($phpbb_root_path . 'config.' . $phpEx) && !@file_exists($phpbb_root_path . 'cache/install_lock'))
 0024      {
 0025          include_once($phpbb_root_path . 'config.' . $phpEx);
 0026   
 0027          if (!defined('PHPBB_INSTALLED'))
 0028          {
 0029              return;
 0030          }
 0031      }
 0032      else
 0033      {
 0034          return;
 0035      }
 0036   
 0037      $module[] = array(
 0038          'module_type'        => 'update',
 0039          'module_title'        => 'UPDATE',
 0040          'module_filename'    => substr(basename(__FILE__), 0, -strlen($phpEx)-1),
 0041          'module_order'        => 30,
 0042          'module_subs'        => '',
 0043          'module_stages'        => array('INTRO', 'VERSION_CHECK', 'UPDATE_DB', 'FILE_CHECK', 'UPDATE_FILES'),
 0044          'module_reqs'        => ''
 0045      );
 0046  }
 0047   
 0048  /**
 0049  * Update Installation
 0050  * @package install
 0051  */
 0052  class install_update extends module
 0053  {
 0054      var $p_master;
 0055      var $update_info;
 0056      
 0057      var $old_location;
 0058      var $new_location;
 0059      var $latest_version;
 0060      var $current_version;
 0061      var $unequal_version;
 0062   
 0063      // Set to false
 0064      var $test_update = false;
 0065   
 0066      function install_update(&$p_master)
 0067      {
 0068          $this->p_master = &$p_master;
 0069      }
 0070   
 0071      function main($mode, $sub)
 0072      {
 0073          global $template, $phpEx, $phpbb_root_path, $user, $db, $config, $cache, $auth;
 0074   
 0075          $this->tpl_name = 'install_update';
 0076          $this->page_title = 'UPDATE_INSTALLATION';
 0077          $this->unequal_version = false;
 0078   
 0079          $this->old_location = $phpbb_root_path . 'install/update/old/';
 0080          $this->new_location = $phpbb_root_path . 'install/update/new/';
 0081   
 0082          // Init DB
 0083          require($phpbb_root_path . 'config.' . $phpEx);
 0084          require($phpbb_root_path . 'includes/db/' . $dbms . '.' . $phpEx);
 0085          require($phpbb_root_path . 'includes/constants.' . $phpEx);
 0086   
 0087          // Special options for conflicts/modified files
 0088          define('MERGE_NO_MERGE_NEW', 1);
 0089          define('MERGE_NO_MERGE_MOD', 2);
 0090          define('MERGE_NEW_FILE', 3);
 0091          define('MERGE_MOD_FILE', 4);
 0092   
 0093          $db = new $sql_db();
 0094   
 0095          // Connect to DB
 0096          $db->sql_connect($dbhost, $dbuser, $dbpasswd, $dbname, $dbport, false, false);
 0097   
 0098          // We do not need this any longer, unset for safety purposes
 0099          unset($dbpasswd);
 0100   
 0101          $config = array();
 0102   
 0103          $sql = 'SELECT config_name, config_value
 0104              FROM ' . CONFIG_TABLE;
 0105          $result = $db->sql_query($sql);
 0106   
 0107          while ($row = $db->sql_fetchrow($result))
 0108          {
 0109              $config[$row['config_name']] = $row['config_value'];
 0110          }
 0111          $db->sql_freeresult($result);
 0112   
 0113          // Force template recompile
 0114          $config['load_tplcompile'] = 1;
 0115   
 0116          // First of all, init the user session
 0117          $user->session_begin();
 0118          $auth->acl($user->data);
 0119   
 0120          $user->setup('install');
 0121   
 0122          // If we are within the intro page we need to make sure we get up-to-date version info
 0123          if ($sub == 'intro')
 0124          {
 0125              $cache->destroy('_version_info');
 0126          }
 0127   
 0128          // Set custom template again. ;)
 0129          $template->set_custom_template('../adm/style', 'admin');
 0130   
 0131          // still, the acp template is never stored in the database
 0132          $user->theme['template_storedb'] = false;
 0133   
 0134          // Get current and latest version
 0135          if (($latest_version = $cache->get('_version_info')) === false)
 0136          {
 0137              $this->latest_version = $this->get_file('version_info');
 0138              $cache->put('_version_info', $this->latest_version);
 0139          }
 0140          else
 0141          {
 0142              $this->latest_version = $latest_version;
 0143          }
 0144   
 0145          // For the current version we trick a bit. ;)
 0146          $this->current_version = (!empty($config['version_update_from'])) ? $config['version_update_from'] : $config['version'];
 0147   
 0148          $up_to_date = (version_compare(str_replace('rc', 'RC', strtolower($this->current_version)), str_replace('rc', 'RC', strtolower($this->latest_version)), '<')) ? false : true;
 0149   
 0150          // Check for a valid update directory, else point the user to the phpbb.com website
 0151          if (!file_exists($phpbb_root_path . 'install/update') || !file_exists($phpbb_root_path . 'install/update/index.' . $phpEx) || !file_exists($this->old_location) || !file_exists($this->new_location))
 0152          {
 0153              $template->assign_vars(array(
 0154                  'S_ERROR'        => true,
 0155                  'ERROR_MSG'        => ($up_to_date) ? $user->lang['NO_UPDATE_FILES_UP_TO_DATE'] : sprintf($user->lang['NO_UPDATE_FILES_OUTDATED'], $config['version'], $this->current_version, $this->latest_version))
 0156              );
 0157   
 0158              return;
 0159          }
 0160   
 0161          $this->update_info = $this->get_file('update_info');
 0162   
 0163          // Make sure the update directory holds the correct information
 0164          // Since admins are able to run the update/checks more than once we only check if the current version is lower or equal than the version to which we update to.
 0165          if (version_compare(str_replace('rc', 'RC', strtolower($this->current_version)), str_replace('rc', 'RC', strtolower($this->update_info['version']['to'])), '>'))
 0166          {
 0167              $template->assign_vars(array(
 0168                  'S_ERROR'        => true,
 0169                  'ERROR_MSG'        => sprintf($user->lang['INCOMPATIBLE_UPDATE_FILES'], $config['version'], $this->update_info['version']['from'], $this->update_info['version']['to']))
 0170              );
 0171   
 0172              return;
 0173          }
 0174   
 0175          // Check if the update files stored are for the latest version...
 0176          if ($this->latest_version != $this->update_info['version']['to'])
 0177          {
 0178              $this->unequal_version = true;
 0179   
 0180              $template->assign_vars(array(
 0181                  'S_WARNING'        => true,
 0182                  'WARNING_MSG'    => sprintf($user->lang['OLD_UPDATE_FILES'], $this->update_info['version']['from'], $this->update_info['version']['to'], $this->latest_version))
 0183              );
 0184          }
 0185   
 0186          if ($this->test_update === false)
 0187          {
 0188              // Got the updater template itself updated? If so, we are able to directly use it - but only if all three files are present
 0189              if (in_array('adm/style/install_update.html', $this->update_info['files']))
 0190              {
 0191                  $this->tpl_name = '../../install/update/new/adm/style/install_update';
 0192              }
 0193   
 0194              // What about the language file? Got it updated?
 0195              if (in_array('language/en/install.php', $this->update_info['files']))
 0196              {
 0197                  $lang = array();
 0198                  include($this->new_location . 'language/en/install.php');
 0199                  // only add new keys to user's language in english
 0200                  $new_keys = array_diff(array_keys($lang), array_keys($user->lang));
 0201                  foreach ($new_keys as $i => $new_key)
 0202                  {
 0203                      $user->lang[$new_key] = $lang[$new_key];
 0204                  }
 0205              }
 0206          }
 0207   
 0208          // Include renderer and engine
 0209          $this->include_file('includes/diff/diff.' . $phpEx);
 0210          $this->include_file('includes/diff/engine.' . $phpEx);
 0211          $this->include_file('includes/diff/renderer.' . $phpEx);
 0212   
 0213          // Make sure we stay at the file check if checking the files again
 0214          if (!empty($_POST['check_again']))
 0215          {
 0216              $sub = $this->p_master->sub = 'file_check';
 0217          }
 0218   
 0219          switch ($sub)
 0220          {
 0221              case 'intro':
 0222                  $this->page_title = 'UPDATE_INSTALLATION';
 0223   
 0224                  $template->assign_vars(array(
 0225                      'S_INTRO'        => true,
 0226                      'U_ACTION'        => append_sid($this->p_master->module_url, "mode=$mode&amp;sub=version_check"),
 0227                  ));
 0228   
 0229                  // Make sure the update list is destroyed.
 0230                  $cache->destroy('_update_list');
 0231                  $cache->destroy('_diff_files');
 0232              break;
 0233   
 0234              case 'version_check':
 0235                  $this->page_title = 'STAGE_VERSION_CHECK';
 0236   
 0237                  $template->assign_vars(array(
 0238                      'S_UP_TO_DATE'        => $up_to_date,
 0239                      'S_VERSION_CHECK'    => true,
 0240   
 0241                      'U_ACTION'                => append_sid($this->p_master->module_url, "mode=$mode&amp;sub=file_check"),
 0242                      'U_DB_UPDATE_ACTION'    => append_sid($this->p_master->module_url, "mode=$mode&amp;sub=update_db"),
 0243   
 0244                      'LATEST_VERSION'    => $this->latest_version,
 0245                      'CURRENT_VERSION'    => $this->current_version)
 0246                  );
 0247   
 0248                  // Print out version the update package updates to
 0249                  if ($this->unequal_version)
 0250                  {
 0251                      $template->assign_var('PACKAGE_VERSION', $this->update_info['version']['to']);
 0252                  }
 0253   
 0254              break;
 0255   
 0256              case 'update_db':
 0257   
 0258                  // Make sure the database update is valid for the latest version
 0259                  $valid = false;
 0260                  $updates_to_version = '';
 0261   
 0262                  if (file_exists($phpbb_root_path . 'install/database_update.' . $phpEx))
 0263                  {
 0264                      include_once($phpbb_root_path . 'install/database_update.' . $phpEx);
 0265   
 0266                      if ($updates_to_version === $this->update_info['version']['to'])
 0267                      {
 0268                          $valid = true;
 0269                      }
 0270                  }
 0271   
 0272                  // Should not happen at all
 0273                  if (!$valid)
 0274                  {
 0275                      trigger_error($user->lang['DATABASE_UPDATE_INFO_OLD'], E_USER_ERROR);
 0276                  }
 0277   
 0278                  // Just a precaution
 0279                  $cache->purge();
 0280   
 0281                  // Redirect the user to the database update script with some explanations...
 0282                  $template->assign_vars(array(
 0283                      'S_DB_UPDATE'            => true,
 0284                      'S_DB_UPDATE_FINISHED'    => ($config['version'] == $this->update_info['version']['to']) ? true : false,
 0285                      'U_DB_UPDATE'            => append_sid($phpbb_root_path . 'install/database_update.' . $phpEx, 'type=1&amp;language=' . $user->data['user_lang']),
 0286                      'U_DB_UPDATE_ACTION'    => append_sid($this->p_master->module_url, "mode=$mode&amp;sub=update_db"),
 0287                      'U_ACTION'                => append_sid($this->p_master->module_url, "mode=$mode&amp;sub=file_check"),
 0288                  ));
 0289   
 0290              break;
 0291   
 0292              case 'file_check':
 0293   
 0294                  // Make sure the previous file collection is no longer valid...
 0295                  $cache->destroy('_diff_files');
 0296   
 0297                  $this->page_title = 'STAGE_FILE_CHECK';
 0298   
 0299                  // Now make sure our update list is correct if the admin refreshes
 0300                  $action = request_var('action', '');
 0301   
 0302                  // We are directly within an update. To make sure our update list is correct we check its status.
 0303                  $update_list = (!empty($_POST['check_again'])) ? false : $cache->get('_update_list');
 0304                  $modified = ($update_list !== false) ? @filemtime($cache->cache_dir . 'data_update_list.' . $phpEx) : 0;
 0305   
 0306                  // Make sure the list is up-to-date
 0307                  if ($update_list !== false)
 0308                  {
 0309                      $get_new_list = false;
 0310                      foreach ($this->update_info['files'] as $file)
 0311                      {
 0312                          if (file_exists($phpbb_root_path . $file) && filemtime($phpbb_root_path . $file) > $modified)
 0313                          {
 0314                              $get_new_list = true;
 0315                              break;
 0316                          }
 0317                      }
 0318                  }
 0319                  else
 0320                  {
 0321                      $get_new_list = true;
 0322                  }
 0323   
 0324                  if (!$get_new_list && $update_list['status'] != -1)
 0325                  {
 0326                      $get_new_list = true;
 0327                  }
 0328   
 0329                  if ($get_new_list)
 0330                  {
 0331                      $this->get_update_structure($update_list);
 0332                      $cache->put('_update_list', $update_list);
 0333   
 0334                      // Refresh the page if we are still not finished...
 0335                      if ($update_list['status'] != -1)
 0336                      {
 0337                          $refresh_url = append_sid($this->p_master->module_url, "mode=$mode&amp;sub=file_check");
 0338                          meta_refresh(2, $refresh_url);
 0339   
 0340                          $template->assign_vars(array(
 0341                              'S_IN_PROGRESS'        => true,
 0342                              'S_COLLECTED'        => (int) $update_list['status'],
 0343                              'S_TO_COLLECT'        => sizeof($this->update_info['files']),
 0344                              'L_IN_PROGRESS'                => $user->lang['COLLECTING_FILE_DIFFS'],
 0345                              'L_IN_PROGRESS_EXPLAIN'        => sprintf($user->lang['NUMBER_OF_FILES_COLLECTED'], (int) $update_list['status'], sizeof($this->update_info['files'])),
 0346                          ));
 0347   
 0348                          return;
 0349                      }
 0350                  }
 0351   
 0352                  if ($action == 'diff')
 0353                  {
 0354                      $this->show_diff($update_list);
 0355                      return;
 0356                  }
 0357   
 0358                  if (sizeof($update_list['no_update']))
 0359                  {
 0360                      $template->assign_vars(array(
 0361                          'S_NO_UPDATE_FILES'        => true,
 0362                          'NO_UPDATE_FILES'        => implode(', ', array_map('htmlspecialchars', $update_list['no_update'])))
 0363                      );
 0364                  }
 0365   
 0366                  // Now assign the list to the template
 0367                  foreach ($update_list as $status => $filelist)
 0368                  {
 0369                      if ($status == 'no_update' || !sizeof($filelist) || $status == 'status')
 0370                      {
 0371                          continue;
 0372                      }
 0373   
 0374                      $template->assign_block_vars('files', array(
 0375                          'S_STATUS'        => true,
 0376                          'STATUS'        => $status,
 0377                          'L_STATUS'        => $user->lang['STATUS_' . strtoupper($status)],
 0378                          'TITLE'            => $user->lang['FILES_' . strtoupper($status)],
 0379                          'EXPLAIN'        => $user->lang['FILES_' . strtoupper($status) . '_EXPLAIN'],
 0380                          )
 0381                      );
 0382   
 0383                      foreach ($filelist as $file_struct)
 0384                      {
 0385                          $s_binary = (!empty($this->update_info['binary']) && in_array($file_struct['filename'], $this->update_info['binary'])) ? true : false;
 0386   
 0387                          $filename = htmlspecialchars($file_struct['filename']);
 0388                          if (strrpos($filename, '/') !== false)
 0389                          {
 0390                              $dir_part = substr($filename, 0, strrpos($filename, '/') + 1);
 0391                              $file_part = substr($filename, strrpos($filename, '/') + 1);
 0392                          }
 0393                          else
 0394                          {
 0395                              $dir_part = '';
 0396                              $file_part = $filename;
 0397                          }
 0398   
 0399                          $diff_url = append_sid($this->p_master->module_url, "mode=$mode&amp;sub=file_check&amp;action=diff&amp;status=$status&amp;file=" . urlencode($file_struct['filename']));
 0400   
 0401                          $template->assign_block_vars('files', array(
 0402                              'STATUS'            => $status,
 0403   
 0404                              'FILENAME'            => $filename,
 0405                              'DIR_PART'            => $dir_part,
 0406                              'FILE_PART'            => $file_part,
 0407                              'NUM_CONFLICTS'        => (isset($file_struct['conflicts'])) ? $file_struct['conflicts'] : 0,
 0408   
 0409                              'S_CUSTOM'            => ($file_struct['custom']) ? true : false,
 0410                              'S_BINARY'            => $s_binary,
 0411                              'CUSTOM_ORIGINAL'    => ($file_struct['custom']) ? $file_struct['original'] : '',
 0412   
 0413                              'U_SHOW_DIFF'        => $diff_url,
 0414                              'L_SHOW_DIFF'        => ($status != 'up_to_date') ? $user->lang['SHOW_DIFF_' . strtoupper($status)] : '',
 0415   
 0416                              'U_VIEW_MOD_FILE'        => $diff_url . '&amp;op=' . MERGE_MOD_FILE,
 0417                              'U_VIEW_NEW_FILE'        => $diff_url . '&amp;op=' . MERGE_NEW_FILE,
 0418                              'U_VIEW_NO_MERGE_MOD'    => $diff_url . '&amp;op=' . MERGE_NO_MERGE_MOD,
 0419                              'U_VIEW_NO_MERGE_NEW'    => $diff_url . '&amp;op=' . MERGE_NO_MERGE_NEW,
 0420                          ));
 0421                      }
 0422                  }
 0423   
 0424                  $all_up_to_date = true;
 0425                  foreach ($update_list as $status => $filelist)
 0426                  {
 0427                      if ($status != 'up_to_date' && $status != 'custom' && $status != 'status' && sizeof($filelist))
 0428                      {
 0429                          $all_up_to_date = false;
 0430                          break;
 0431                      }
 0432                  }
 0433   
 0434                  $template->assign_vars(array(
 0435                      'S_FILE_CHECK'            => true,
 0436                      'S_ALL_UP_TO_DATE'        => $all_up_to_date,
 0437                      'S_VERSION_UP_TO_DATE'    => $up_to_date,
 0438                      'U_ACTION'                => append_sid($this->p_master->module_url, "mode=$mode&amp;sub=file_check"),
 0439                      'U_UPDATE_ACTION'        => append_sid($this->p_master->module_url, "mode=$mode&amp;sub=update_files"),
 0440                      'U_DB_UPDATE_ACTION'    => append_sid($this->p_master->module_url, "mode=$mode&amp;sub=update_db"),
 0441                  ));
 0442   
 0443                  if ($all_up_to_date)
 0444                  {
 0445                      // Add database update to log
 0446                      add_log('admin', 'LOG_UPDATE_PHPBB', $this->current_version, $this->latest_version);
 0447   
 0448                      // Refresh prosilver css data - this may cause some unhappy users, but
 0449                      $sql = 'SELECT *
 0450                          FROM ' . STYLES_THEME_TABLE . "
 0451                          WHERE theme_name = 'prosilver'";
 0452                      $result = $db->sql_query($sql);
 0453                      $theme = $db->sql_fetchrow($result);
 0454                      $db->sql_freeresult($result);
 0455   
 0456                      if ($theme)
 0457                      {
 0458                          $recache = (empty($theme['theme_data'])) ? true : false;
 0459                          $update_time = time();
 0460   
 0461                          // We test for stylesheet.css because it is faster and most likely the only file changed on common themes
 0462                          if (!$recache && $theme['theme_mtime'] < @filemtime("{$phpbb_root_path}styles/" . $theme['theme_path'] . '/theme/stylesheet.css'))
 0463                          {
 0464                              $recache = true;
 0465                              $update_time = @filemtime("{$phpbb_root_path}styles/" . $theme['theme_path'] . '/theme/stylesheet.css');
 0466                          }
 0467                          else if (!$recache)
 0468                          {
 0469                              $last_change = $theme['theme_mtime'];
 0470                              $dir = @opendir("{$phpbb_root_path}styles/{$theme['theme_path']}/theme");
 0471   
 0472                              if ($dir)
 0473                              {
 0474                                  while (($entry = readdir($dir)) !== false)
 0475                                  {
 0476                                      if (substr(strrchr($entry, '.'), 1) == 'css' && $last_change < @filemtime("{$phpbb_root_path}styles/{$theme['theme_path']}/theme/{$entry}"))
 0477                                      {
 0478                                          $recache = true;
 0479                                          break;
 0480                                      }
 0481                                  }
 0482                                  closedir($dir);
 0483                              }
 0484                          }
 0485   
 0486                          if ($recache)
 0487                          {
 0488                              include_once($phpbb_root_path . 'includes/acp/acp_styles.' . $phpEx);
 0489   
 0490                              $theme['theme_data'] = acp_styles::db_theme_data($theme);
 0491                              $theme['theme_mtime'] = $update_time;
 0492   
 0493                              // Save CSS contents
 0494                              $sql_ary = array(
 0495                                  'theme_mtime'    => $theme['theme_mtime'],
 0496                                  'theme_data'    => $theme['theme_data']
 0497                              );
 0498   
 0499                              $sql = 'UPDATE ' . STYLES_THEME_TABLE . ' SET ' . $db->sql_build_array('UPDATE', $sql_ary) . '
 0500                                  WHERE theme_id = ' . $theme['theme_id'];
 0501                              $db->sql_query($sql);
 0502   
 0503                              $cache->destroy('sql', STYLES_THEME_TABLE);
 0504                          }
 0505                      }
 0506   
 0507                      $db->sql_return_on_error(true);
 0508                      $db->sql_query('DELETE FROM ' . CONFIG_TABLE . " WHERE config_name = 'version_update_from'");
 0509                      $db->sql_return_on_error(false);
 0510   
 0511                      $cache->purge();
 0512                  }
 0513   
 0514              break;
 0515   
 0516              case 'update_files':
 0517   
 0518                  $this->page_title = 'STAGE_UPDATE_FILES';
 0519   
 0520                  $s_hidden_fields = '';
 0521                  $params = array();
 0522                  $conflicts = request_var('conflict', array('' => 0));
 0523                  $modified = request_var('modified', array('' => 0));
 0524   
 0525                  foreach ($conflicts as $filename => $merge_option)
 0526                  {
 0527                      $s_hidden_fields .= '<input type="hidden" name="conflict[' . htmlspecialchars($filename) . ']" value="' . $merge_option . '" />';
 0528                      $params[] = 'conflict[' . urlencode($filename) . ']=' . urlencode($merge_option);
 0529                  }
 0530   
 0531                  foreach ($modified as $filename => $merge_option)
 0532                  {
 0533                      if (!$merge_option)
 0534                      {
 0535                          continue;
 0536                      }
 0537                      $s_hidden_fields .= '<input type="hidden" name="modified[' . htmlspecialchars($filename) . ']" value="' . $merge_option . '" />';
 0538                      $params[] = 'modified[' . urlencode($filename) . ']=' . urlencode($merge_option);
 0539                  }
 0540   
 0541                  $no_update = request_var('no_update', array(0 => ''));
 0542   
 0543                  foreach ($no_update as $index => $filename)
 0544                  {
 0545                      $s_hidden_fields .= '<input type="hidden" name="no_update[]" value="' . htmlspecialchars($filename) . '" />';
 0546                      $params[] = 'no_update[]=' . urlencode($filename);
 0547                  }
 0548   
 0549                  // Before the user is choosing his preferred method, let's create the content list...
 0550                  $update_list = $cache->get('_update_list');
 0551   
 0552                  if ($update_list === false)
 0553                  {
 0554                      trigger_error($user->lang['NO_UPDATE_INFO'], E_USER_ERROR);
 0555                  }
 0556   
 0557                  // Check if the conflicts data is valid
 0558                  if (sizeof($conflicts))
 0559                  {
 0560                      $conflict_filenames = array();
 0561                      foreach ($update_list['conflict'] as $files)
 0562                      {
 0563                          $conflict_filenames[] = $files['filename'];
 0564                      }
 0565   
 0566                      $new_conflicts = array();
 0567                      foreach ($conflicts as $filename => $diff_method)
 0568                      {
 0569                          if (in_array($filename, $conflict_filenames))
 0570                          {
 0571                              $new_conflicts[$filename] = $diff_method;
 0572                          }
 0573                      }
 0574   
 0575                      $conflicts = $new_conflicts;
 0576                  }
 0577   
 0578                  // Build list for modifications
 0579                  if (sizeof($modified))
 0580                  {
 0581                      $modified_filenames = array();
 0582                      foreach ($update_list['modified'] as $files)
 0583                      {
 0584                          $modified_filenames[] = $files['filename'];
 0585                      }
 0586   
 0587                      $new_modified = array();
 0588                      foreach ($modified as $filename => $diff_method)
 0589                      {
 0590                          if (in_array($filename, $modified_filenames))
 0591                          {
 0592                              $new_modified[$filename] = $diff_method;
 0593                          }
 0594                      }
 0595   
 0596                      $modified = $new_modified;
 0597                  }
 0598   
 0599                  // Check number of conflicting files, they need to be equal. For modified files the number can differ
 0600                  if (sizeof($update_list['conflict']) != sizeof($conflicts))
 0601                  {
 0602                      trigger_error($user->lang['MERGE_SELECT_ERROR'], E_USER_ERROR);
 0603                  }
 0604   
 0605                  // Before we do anything, let us diff the files and store the raw file information "somewhere"
 0606                  $get_files = false;
 0607                  $file_list = $cache->get('_diff_files');
 0608   
 0609                  if ($file_list === false || $file_list['status'] != -1)
 0610                  {
 0611                      $get_files = true;
 0612                  }
 0613   
 0614                  if ($get_files)
 0615                  {
 0616                      if ($file_list === false)
 0617                      {
 0618                          $file_list = array(
 0619                              'status'    => 0,
 0620                          );
 0621                      }
 0622   
 0623                      $processed = 0;
 0624                      foreach ($update_list as $status => $files)
 0625                      {
 0626                          if (!is_array($files))
 0627                          {
 0628                              continue;
 0629                          }
 0630   
 0631                          foreach ($files as $file_struct)
 0632                          {
 0633                              // Skip this file if the user selected to not update it
 0634                              if (in_array($file_struct['filename'], $no_update))
 0635                              {
 0636                                  continue;
 0637                              }
 0638   
 0639                              // Already handled... then skip of course...
 0640                              if (isset($file_list[$file_struct['filename']]))
 0641                              {
 0642                                  continue;
 0643                              }
 0644   
 0645                              // Refresh if we reach 5 diffs...
 0646                              if ($processed >= 5)
 0647                              {
 0648                                  $cache->put('_diff_files', $file_list);
 0649   
 0650                                  if (!empty($_REQUEST['download']))
 0651                                  {
 0652                                      $params[] = 'download=1';
 0653                                  }
 0654   
 0655                                  $redirect_url = append_sid($this->p_master->module_url, "mode=$mode&amp;sub=update_files&amp;" . implode('&amp;', $params));
 0656                                  meta_refresh(3, $redirect_url);
 0657   
 0658                                  $template->assign_vars(array(
 0659                                      'S_IN_PROGRESS'            => true,
 0660                                      'L_IN_PROGRESS'            => $user->lang['MERGING_FILES'],
 0661                                      'L_IN_PROGRESS_EXPLAIN'    => $user->lang['MERGING_FILES_EXPLAIN'],
 0662                                  ));
 0663   
 0664                                  return;
 0665                              }
 0666   
 0667                              $original_filename = ($file_struct['custom']) ? $file_struct['original'] : $file_struct['filename'];
 0668   
 0669                              switch ($status)
 0670                              {
 0671                                  case 'modified':
 0672   
 0673                                      $option = (isset($modified[$file_struct['filename']])) ? $modified[$file_struct['filename']] : 0;
 0674   
 0675                                      switch ($option)
 0676                                      {
 0677                                          case MERGE_NO_MERGE_NEW:
 0678                                              $contents = file_get_contents($this->new_location . $original_filename);
 0679                                          break;
 0680   
 0681                                          case MERGE_NO_MERGE_MOD:
 0682                                              $contents = file_get_contents($phpbb_root_path . $file_struct['filename']);
 0683                                          break;
 0684   
 0685                                          default:
 0686                                              $diff = $this->return_diff($this->old_location . $original_filename, $phpbb_root_path . $file_struct['filename'], $this->new_location . $original_filename);
 0687   
 0688                                              $contents = implode("\n", $diff->merged_output());
 0689                                              unset($diff);
 0690                                          break;
 0691                                      }
 0692   
 0693                                      $file_list[$file_struct['filename']] = '_file_' . md5($file_struct['filename']);
 0694                                      $cache->put($file_list[$file_struct['filename']], base64_encode($contents));
 0695   
 0696                                      $file_list['status']++;
 0697                                      $processed++;
 0698   
 0699                                  break;
 0700   
 0701                                  case 'conflict':
 0702   
 0703                                      $option = $conflicts[$file_struct['filename']];
 0704                                      $contents = '';
 0705   
 0706                                      switch ($option)
 0707                                      {
 0708                                          case MERGE_NO_MERGE_NEW:
 0709                                              $contents = file_get_contents($this->new_location . $original_filename);
 0710                                          break;
 0711   
 0712                                          case MERGE_NO_MERGE_MOD:
 0713                                              $contents = file_get_contents($phpbb_root_path . $file_struct['filename']);
 0714                                          break;
 0715   
 0716                                          default:
 0717   
 0718                                              $diff = $this->return_diff($this->old_location . $original_filename, $phpbb_root_path . $file_struct['filename'], $this->new_location . $original_filename);
 0719   
 0720                                              if ($option == MERGE_NEW_FILE)
 0721                                              {
 0722                                                  $contents = implode("\n", $diff->merged_new_output());
 0723                                              }
 0724                                              else if ($option == MERGE_MOD_FILE)
 0725                                              {
 0726                                                  $contents = implode("\n", $diff->merged_orig_output());
 0727                                              }
 0728                                              else
 0729                                              {
 0730                                                  unset($diff);
 0731                                                  break 2;
 0732                                              }
 0733   
 0734                                              unset($diff);
 0735                                          break;
 0736                                      }
 0737   
 0738                                      $file_list[$file_struct['filename']] = '_file_' . md5($file_struct['filename']);
 0739                                      $cache->put($file_list[$file_struct['filename']], base64_encode($contents));
 0740   
 0741                                      $file_list['status']++;
 0742                                      $processed++;
 0743   
 0744                                  break;
 0745                              }
 0746                          }
 0747                      }
 0748                  }
 0749   
 0750                  $file_list['status'] = -1;
 0751                  $cache->put('_diff_files', $file_list);
 0752   
 0753                  if (!empty($_REQUEST['download']))
 0754                  {
 0755                      $this->include_file('includes/functions_compress.' . $phpEx);
 0756   
 0757                      $use_method = request_var('use_method', '');
 0758                      $methods = array('.tar');
 0759   
 0760                      $available_methods = array('.tar.gz' => 'zlib', '.tar.bz2' => 'bz2', '.zip' => 'zlib');
 0761                      foreach ($available_methods as $type => $module)
 0762                      {
 0763                          if (!@extension_loaded($module))
 0764                          {
 0765                              continue;
 0766                          }
 0767          
 0768                          $methods[] = $type;
 0769                      }
 0770   
 0771                      // Let the user decide in which format he wants to have the pack
 0772                      if (!$use_method)
 0773                      {
 0774                          $this->page_title = 'SELECT_DOWNLOAD_FORMAT';
 0775   
 0776                          $radio_buttons = '';
 0777                          foreach ($methods as $method)
 0778                          {
 0779                              $radio_buttons .= '<label><input type="radio"' . ((!$radio_buttons) ? ' id="use_method"' : '') . ' class="radio" value="' . $method . '" name="use_method" /> ' . $method . '</label>';
 0780                          }
 0781   
 0782                          $template->assign_vars(array(
 0783                              'S_DOWNLOAD_FILES'        => true,
 0784                              'U_ACTION'                => append_sid($this->p_master->module_url, "mode=$mode&amp;sub=update_files"),
 0785                              'RADIO_BUTTONS'            => $radio_buttons,
 0786                              'S_HIDDEN_FIELDS'        => $s_hidden_fields)
 0787                          );
 0788   
 0789                          // To ease the update process create a file location map
 0790                          $update_list = $cache->get('_update_list');
 0791                          $script_path = ($config['force_server_vars']) ? (($config['script_path'] == '/') ? '/' : $config['script_path'] . '/') : $user->page['root_script_path'];
 0792   
 0793                          foreach ($update_list as $status => $files)
 0794                          {
 0795                              if ($status == 'up_to_date' || $status == 'no_update' || $status == 'status')
 0796                              {
 0797                                  continue;
 0798                              }
 0799   
 0800                              foreach ($files as $file_struct)
 0801                              {
 0802                                  if (in_array($file_struct['filename'], $no_update))
 0803                                  {
 0804                                      continue;
 0805                                  }
 0806   
 0807                                  $template->assign_block_vars('location', array(
 0808                                      'SOURCE'        => htmlspecialchars($file_struct['filename']),
 0809                                      'DESTINATION'    => $script_path . htmlspecialchars($file_struct['filename']),
 0810                                  ));
 0811                              }
 0812                          }
 0813                          return;
 0814                      }
 0815   
 0816                      if (!in_array($use_method, $methods))
 0817                      {
 0818                          $use_method = '.tar';
 0819                      }
 0820   
 0821                      $update_mode = 'download';
 0822                  }
 0823                  else
 0824                  {
 0825                      $this->include_file('includes/functions_transfer.' . $phpEx);
 0826   
 0827                      // Choose FTP, if not available use fsock...
 0828                      $method = basename(request_var('method', ''));
 0829                      $submit = (isset($_POST['submit'])) ? true : false;
 0830                      $test_ftp_connection = request_var('test_connection', '');
 0831   
 0832                      if (!$method || !class_exists($method))
 0833                      {
 0834                          $method = 'ftp';
 0835                          $methods = transfer::methods();
 0836   
 0837                          if (!in_array('ftp', $methods))
 0838                          {
 0839                              $method = $methods[0];
 0840                          }
 0841                      }
 0842   
 0843                      $test_connection = false;
 0844                      if ($test_ftp_connection || $submit)
 0845                      {
 0846                          $transfer = new $method(request_var('host', ''), request_var('username', ''), request_var('password', ''), request_var('root_path', ''), request_var('port', ''), request_var('timeout', ''));
 0847                          $test_connection = $transfer->open_session();
 0848   
 0849                          // Make sure that the directory is correct by checking for the existence of common.php
 0850                          if ($test_connection === true)
 0851                          {
 0852                              // Check for common.php file
 0853                              if (!$transfer->file_exists($phpbb_root_path, 'common.' . $phpEx))
 0854                              {
 0855                                  $test_connection = 'ERR_WRONG_PATH_TO_PHPBB';
 0856                              }
 0857                          }
 0858   
 0859                          $transfer->close_session();
 0860   
 0861                          // Make sure the login details are correct before continuing
 0862                          if ($submit && $test_connection !== true)
 0863                          {
 0864                              $submit = false;
 0865                              $test_ftp_connection = true;
 0866                          }
 0867                      }
 0868   
 0869                      $s_hidden_fields .= build_hidden_fields(array('method' => $method));
 0870   
 0871                      if (!$submit)
 0872                      {
 0873                          $this->page_title = 'SELECT_FTP_SETTINGS';
 0874   
 0875                          if (!class_exists($method))
 0876                          {
 0877                              trigger_error('Method does not exist.', E_USER_ERROR);
 0878                          }
 0879   
 0880                          $requested_data = call_user_func(array($method, 'data'));
 0881                          foreach ($requested_data as $data => $default)
 0882                          {
 0883                              $template->assign_block_vars('data', array(
 0884                                  'DATA'        => $data,
 0885                                  'NAME'        => $user->lang[strtoupper($method . '_' . $data)],
 0886                                  'EXPLAIN'    => $user->lang[strtoupper($method . '_' . $data) . '_EXPLAIN'],
 0887                                  'DEFAULT'    => (!empty($_REQUEST[$data])) ? request_var($data, '') : $default
 0888                              ));
 0889                          }
 0890   
 0891                          $template->assign_vars(array(
 0892                              'S_CONNECTION_SUCCESS'        => ($test_ftp_connection && $test_connection === true) ? true : false,
 0893                              'S_CONNECTION_FAILED'        => ($test_ftp_connection && $test_connection !== true) ? true : false,
 0894                              'ERROR_MSG'                    => ($test_ftp_connection && $test_connection !== true) ? $user->lang[$test_connection] : '',
 0895   
 0896                              'S_FTP_UPLOAD'        => true,
 0897                              'UPLOAD_METHOD'        => $method,
 0898                              'U_ACTION'            => append_sid($this->p_master->module_url, "mode=$mode&amp;sub=update_files"),
 0899                              'S_HIDDEN_FIELDS'    => $s_hidden_fields)
 0900                          );
 0901   
 0902                          return;
 0903                      }
 0904   
 0905                      $update_mode = 'upload';
 0906                  }
 0907   
 0908                  // Now update the installation or download the archive...
 0909                  $download_filename = 'update_' . $this->update_info['version']['from'] . '_to_' . $this->update_info['version']['to'];
 0910                  $archive_filename = $download_filename . '_' . time() . '_' . unique_id();
 0911   
 0912                  // Now init the connection
 0913                  if ($update_mode == 'download')
 0914                  {
 0915                      if ($use_method == '.zip')
 0916                      {
 0917                          $compress = new compress_zip('w', $phpbb_root_path . 'store/' . $archive_filename . $use_method);
 0918                      }
 0919                      else
 0920                      {
 0921                          $compress = new compress_tar('w', $phpbb_root_path . 'store/' . $archive_filename . $use_method, $use_method);
 0922                      }
 0923                  }
 0924                  else
 0925                  {
 0926                      $transfer = new $method(request_var('host', ''), request_var('username', ''), request_var('password', ''), request_var('root_path', ''), request_var('port', ''), request_var('timeout', ''));
 0927                      $transfer->open_session();
 0928                  }
 0929   
 0930                  // Ok, go through the update list and do the operations based on their status
 0931                  foreach ($update_list as $status => $files)
 0932                  {
 0933                      if (!is_array($files))
 0934                      {
 0935                          continue;
 0936                      }
 0937   
 0938                      foreach ($files as $file_struct)
 0939                      {
 0940                          // Skip this file if the user selected to not update it
 0941                          if (in_array($file_struct['filename'], $no_update))
 0942                          {
 0943                              continue;
 0944                          }
 0945   
 0946                          $original_filename = ($file_struct['custom']) ? $file_struct['original'] : $file_struct['filename'];
 0947   
 0948                          switch ($status)
 0949                          {
 0950                              case 'new':
 0951                              case 'new_conflict':
 0952                              case 'not_modified':
 0953   
 0954                                  if ($update_mode == 'download')
 0955                                  {
 0956                                      $compress->add_custom_file($this->new_location . $original_filename, $file_struct['filename']);
 0957                                  }
 0958                                  else
 0959                                  {
 0960                                      if ($status != 'new')
 0961                                      {
 0962                                          $transfer->rename($file_struct['filename'], $file_struct['filename'] . '.bak');
 0963                                      }
 0964   
 0965                                      // New directory too?
 0966                                      $dirname = dirname($file_struct['filename']);
 0967   
 0968                                      if ($dirname && !file_exists($phpbb_root_path . $dirname))
 0969                                      {
 0970                                          $transfer->make_dir($dirname);
 0971                                      }
 0972   
 0973                                      $transfer->copy_file($this->new_location . $original_filename, $file_struct['filename']);
 0974                                  }
 0975                              break;
 0976   
 0977                              case 'modified':
 0978   
 0979                                  $contents = base64_decode($cache->get($file_list[$file_struct['filename']]));
 0980   
 0981                                  if ($update_mode == 'download')
 0982                                  {
 0983                                      $compress->add_data($contents, $file_struct['filename']);
 0984                                  }
 0985                                  else
 0986                                  {
 0987                                      // @todo add option to specify if a backup file should be created?
 0988                                      $transfer->rename($file_struct['filename'], $file_struct['filename'] . '.bak');
 0989                                      $transfer->write_file($file_struct['filename'], $contents);
 0990                                  }
 0991                              break;
 0992   
 0993                              case 'conflict':
 0994   
 0995                                  $contents = base64_decode($cache->get($file_list[$file_struct['filename']]));
 0996   
 0997                                  if ($update_mode == 'download')
 0998                                  {
 0999                                      $compress->add_data($contents, $file_struct['filename']);
 1000                                  }
 1001                                  else
 1002                                  {
 1003                                      $transfer->rename($file_struct['filename'], $file_struct['filename'] . '.bak');
 1004                                      $transfer->write_file($file_struct['filename'], $contents);
 1005                                  }
 1006                              break;
 1007                          }
 1008                      }
 1009                  }
 1010   
 1011                  if ($update_mode == 'download')
 1012                  {
 1013                      $compress->close();
 1014   
 1015                      $compress->download($archive_filename, $download_filename);
 1016                      @unlink($phpbb_root_path . 'store/' . $archive_filename . $use_method);
 1017   
 1018                      exit;
 1019                  }
 1020                  else
 1021                  {
 1022                      $transfer->close_session();
 1023   
 1024                      $template->assign_vars(array(
 1025                          'S_UPLOAD_SUCCESS'    => true,
 1026                          'U_ACTION'            => append_sid($this->p_master->module_url, "mode=$mode&amp;sub=file_check"))
 1027                      );
 1028                      return;
 1029                  }
 1030   
 1031              break;
 1032   
 1033          }
 1034      }
 1035   
 1036      /**
 1037      * Show file diff
 1038      */
 1039      function show_diff(&$update_list)
 1040      {
 1041          global $phpbb_root_path, $template, $user;
 1042   
 1043          $this->tpl_name = 'install_update_diff';
 1044   
 1045          // Got the diff template itself updated? If so, we are able to directly use it
 1046          if (in_array('adm/style/install_update_diff.html', $this->update_info['files']))
 1047          {
 1048              $this->tpl_name = '../../install/update/new/adm/style/install_update_diff';
 1049          }
 1050   
 1051          $this->page_title = 'VIEWING_FILE_DIFF';
 1052   
 1053          $status = request_var('status', '');
 1054          $file = request_var('file', '');
 1055          $diff_mode = request_var('diff_mode', 'side_by_side');
 1056   
 1057          // First of all make sure the file is within our file update list with the correct status
 1058          $found_entry = array();
 1059          foreach ($update_list[$status] as $index => $file_struct)
 1060          {
 1061              if ($file_struct['filename'] === $file)
 1062              {
 1063                  $found_entry = $update_list[$status][$index];
 1064              }
 1065          }
 1066   
 1067          if (empty($found_entry))
 1068          {
 1069              trigger_error($user->lang['FILE_DIFF_NOT_ALLOWED'], E_USER_ERROR);
 1070          }
 1071   
 1072          // If the status is 'up_to_date' then we do not need to show a diff
 1073          if ($status == 'up_to_date')
 1074          {
 1075              trigger_error($user->lang['FILE_ALREADY_UP_TO_DATE'], E_USER_ERROR);
 1076          }
 1077   
 1078          $original_file = ($found_entry['custom']) ? $found_entry['original'] : $file;
 1079   
 1080          // Get the correct diff
 1081          switch ($status)
 1082          {
 1083              case 'conflict':
 1084                  $option = request_var('op', 0);
 1085   
 1086                  switch ($option)
 1087                  {
 1088                      case MERGE_NO_MERGE_NEW:
 1089                      case MERGE_NO_MERGE_MOD:
 1090   
 1091                          $diff = $this->return_diff(array(), ($option == MERGE_NO_MERGE_NEW) ? $this->new_location . $original_file : $phpbb_root_path . $file);
 1092   
 1093                          $template->assign_var('S_DIFF_NEW_FILE', true);
 1094                          $diff_mode = 'inline';
 1095                          $this->page_title = 'VIEWING_FILE_CONTENTS';
 1096   
 1097                      break;
 1098   
 1099                      case MERGE_NEW_FILE:
 1100                      case MERGE_MOD_FILE:
 1101   
 1102                          $diff = $this->return_diff($this->old_location . $original_file, $phpbb_root_path . $file, $this->new_location . $original_file);
 1103   
 1104                          $tmp = array(
 1105                              'file1'        => array(),
 1106                              'file2'        => ($option == MERGE_NEW_FILE) ? implode("\n", $diff->merged_new_output()) : implode("\n", $diff->merged_orig_output()),
 1107                          );
 1108   
 1109                          $diff = &new diff($tmp['file1'], $tmp['file2']);
 1110   
 1111                          unset($tmp);
 1112   
 1113                          $template->assign_var('S_DIFF_NEW_FILE', true);
 1114                          $diff_mode = 'inline';
 1115                          $this->page_title = 'VIEWING_FILE_CONTENTS';
 1116   
 1117                      break;
 1118   
 1119                      default:
 1120   
 1121                          $diff = $this->return_diff($this->old_location . $original_file, $phpbb_root_path . $file, $this->new_location . $original_file);
 1122   
 1123                          $template->assign_vars(array(
 1124                              'S_DIFF_CONFLICT_FILE'    => true,
 1125                              'NUM_CONFLICTS'            => $diff->merged_output(false, false, false, true))
 1126                          );
 1127   
 1128                          $diff = $this->return_diff($phpbb_root_path . $file, $diff->merged_output());
 1129                      break;
 1130                  }
 1131   
 1132              break;
 1133   
 1134              case 'modified':
 1135                  $option = request_var('op', 0);
 1136   
 1137                  switch ($option)
 1138                  {
 1139                      case MERGE_NO_MERGE_NEW:
 1140                      case MERGE_NO_MERGE_MOD:
 1141   
 1142                          $diff = $this->return_diff(array(), ($option == MERGE_NO_MERGE_NEW) ? $this->new_location . $original_file : $phpbb_root_path . $file);
 1143   
 1144                          $template->assign_var('S_DIFF_NEW_FILE', true);
 1145                          $diff_mode = 'inline';
 1146                          $this->page_title = 'VIEWING_FILE_CONTENTS';
 1147   
 1148                      break;
 1149   
 1150                      default:
 1151                          $diff = $this->return_diff($this->old_location . $original_file, $phpbb_root_path . $original_file, $this->new_location . $file);
 1152                      break;
 1153                  }
 1154              break;
 1155   
 1156              case 'not_modified':
 1157              case 'new_conflict':
 1158                  $diff = $this->return_diff($phpbb_root_path . $file, $this->new_location . $original_file);
 1159              break;
 1160   
 1161              case 'new':
 1162   
 1163                  $diff = $this->return_diff(array(), $this->new_location . $original_file);
 1164   
 1165                  $template->assign_var('S_DIFF_NEW_FILE', true);
 1166                  $diff_mode = 'inline';
 1167                  $this->page_title = 'VIEWING_FILE_CONTENTS';
 1168   
 1169              break;
 1170          }
 1171   
 1172          $diff_mode_options = '';
 1173          foreach (array('side_by_side', 'inline', 'unified', 'raw') as $option)
 1174          {
 1175              $diff_mode_options .= '<option value="' . $option . '"' . (($diff_mode == $option) ? ' selected="selected"' : '') . '>' . $user->lang['DIFF_' . strtoupper($option)] . '</option>';
 1176          }
 1177   
 1178          // Now the correct renderer
 1179          $render_class = 'diff_renderer_' . $diff_mode;
 1180   
 1181          if (!class_exists($render_class))
 1182          {
 1183              trigger_error('Chosen diff mode is not supported', E_USER_ERROR);
 1184          }
 1185   
 1186          $renderer = &new $render_class();
 1187   
 1188          $template->assign_vars(array(
 1189              'DIFF_CONTENT'            => $renderer->get_diff_content($diff),
 1190              'DIFF_MODE'                => $diff_mode,
 1191              'S_DIFF_MODE_OPTIONS'    => $diff_mode_options,
 1192              'S_SHOW_DIFF'            => true,
 1193          ));
 1194   
 1195          unset($diff, $renderer);
 1196      }
 1197   
 1198      /**
 1199      * Collect all file status infos we need for the update by diffing all files
 1200      */
 1201      function get_update_structure(&$update_list)
 1202      {
 1203          global $phpbb_root_path, $phpEx, $user;
 1204   
 1205          if ($update_list === false)
 1206          {
 1207              $update_list = array(
 1208                  'up_to_date'    => array(),
 1209                  'new'            => array(),
 1210                  'not_modified'    => array(),
 1211                  'modified'        => array(),
 1212                  'new_conflict'    => array(),
 1213                  'conflict'        => array(),
 1214                  'no_update'        => array(),
 1215                  'status'        => 0,
 1216              );
 1217          }
 1218   
 1219          /* if (!empty($this->update_info['custom']))
 1220          {
 1221              foreach ($this->update_info['custom'] as $original_file => $file_ary)
 1222              {
 1223                  foreach ($file_ary as $index => $file)
 1224                  {
 1225                      $this->make_update_diff($update_list, $original_file, $file, true);
 1226                  }
 1227              }
 1228          } */
 1229   
 1230          // Get a list of those files which are completely new by checking with file_exists...
 1231          $num_bytes_processed = 0;
 1232   
 1233          foreach ($this->update_info['files'] as $index => $file)
 1234          {
 1235              if (is_int($update_list['status']) && $index < $update_list['status'])
 1236              {
 1237                  continue;
 1238              }
 1239   
 1240              if ($num_bytes_processed >= 500 * 1024)
 1241              {
 1242                  return;
 1243              }
 1244   
 1245              if (!file_exists($phpbb_root_path . $file))
 1246              {
 1247                  // Make sure the update files are consistent by checking if the file is in new_files...
 1248                  if (!file_exists($this->new_location . $file))
 1249                  {
 1250                      trigger_error($user->lang['INCOMPLETE_UPDATE_FILES'], E_USER_ERROR);
 1251                  }
 1252   
 1253                  // If the file exists within the old directory the file got removed and we will write it back
 1254                  // not a biggie, but we might want to state this circumstance separately later.
 1255                  //    if (file_exists($this->old_location . $file))
 1256                  //    {
 1257                  //        $update_list['removed'][] = $file;
 1258                  //    }
 1259   
 1260                  /* Only include a new file as new if the underlying path exist
 1261                  // The path normally do not exist if the original style or language has been removed
 1262                  if (file_exists($phpbb_root_path . dirname($file)))
 1263                  {
 1264                      $this->get_custom_info($update_list['new'], $file);
 1265                      $update_list['new'][] = array('filename' => $file, 'custom' => false);
 1266                  }
 1267                  else
 1268                  {
 1269                      // Do not include style-related or language-related content
 1270                      if (strpos($file, 'styles/') !== 0 && strpos($file, 'language/') !== 0)
 1271                      {
 1272                          $update_list['no_update'][] = $file;
 1273                      }
 1274                  }*/
 1275   
 1276                  if (file_exists($phpbb_root_path . dirname($file)) || (strpos($file, 'styles/') !== 0 && strpos($file, 'language/') !== 0))
 1277                  {
 1278                      $this->get_custom_info($update_list['new'], $file);
 1279                      $update_list['new'][] = array('filename' => $file, 'custom' => false);
 1280                  }
 1281   
 1282                  // unset($this->update_info['files'][$index]);
 1283              }
 1284              else
 1285              {
 1286                  // not modified?
 1287                  $this->make_update_diff($update_list, $file, $file);
 1288              }
 1289   
 1290              $num_bytes_processed += (file_exists($this->new_location . $file)) ? filesize($this->new_location . $file) : 100 * 1024;
 1291              $update_list['status']++;
 1292          }
 1293   
 1294          $update_list['status'] = -1;
 1295  /*        if (!sizeof($this->update_info['files']))
 1296          {
 1297              return $update_list;
 1298          }
 1299   
 1300          // Now diff the remaining files to get information about their status (not modified/modified/up-to-date)
 1301   
 1302          // not modified?
 1303          foreach ($this->update_info['files'] as $index => $file)
 1304          {
 1305              $this->make_update_diff($update_list, $file, $file);
 1306          }
 1307   
 1308          // Now to the styles...
 1309          if (empty($this->update_info['custom']))
 1310          {
 1311              return $update_list;
 1312          }
 1313   
 1314          foreach ($this->update_info['custom'] as $original_file => $file_ary)
 1315          {
 1316              foreach ($file_ary as $index => $file)
 1317              {
 1318                  $this->make_update_diff($update_list, $original_file, $file, true);
 1319              }
 1320          }
 1321   
 1322          return $update_list;*/
 1323      }
 1324   
 1325      /**
 1326      * Compare files for storage in update_list
 1327      */
 1328      function make_update_diff(&$update_list, $original_file, $file, $custom = false)
 1329      {
 1330          global $phpbb_root_path, $user;
 1331   
 1332          $update_ary = array('filename' => $file, 'custom' => $custom);
 1333   
 1334          if ($custom)
 1335          {
 1336              $update_ary['original'] = $original_file;
 1337          }
 1338   
 1339          // On a successfull update the new location file exists but the old one does not exist.
 1340          // Check for this circumstance, the new file need to be up-to-date with the current file then...
 1341          if (!file_exists($this->old_location . $original_file) && file_exists($this->new_location . $original_file) && file_exists($phpbb_root_path . $file))
 1342          {
 1343              $tmp = array(
 1344                  'file1'        => file_get_contents($this->new_location . $original_file),
 1345                  'file2'        => file_get_contents($phpbb_root_path . $file),
 1346              );
 1347   
 1348              // We need to diff the contents here to make sure the file is really the one we expect
 1349              $diff = &new diff($tmp['file1'], $tmp['file2'], false);
 1350              $empty = $diff->is_empty();
 1351   
 1352              unset($tmp, $diff);
 1353   
 1354              // if there are no differences we have an up-to-date file...
 1355              if ($empty)
 1356              {
 1357                  $update_list['up_to_date'][] = $update_ary;
 1358                  return;
 1359              }
 1360   
 1361              // If no other status matches we have another file in the way...
 1362              $update_list['new_conflict'][] = $update_ary;
 1363              return;
 1364          }
 1365   
 1366          // Old file removed?
 1367          if (file_exists($this->old_location . $original_file) && !file_exists($this->new_location . $original_file))
 1368          {
 1369              return;
 1370          }
 1371   
 1372          // Check for existance, else abort immediately
 1373          if (!file_exists($this->old_location . $original_file) || !file_exists($this->new_location . $original_file))
 1374          {
 1375              trigger_error($user->lang['INCOMPLETE_UPDATE_FILES'], E_USER_ERROR);
 1376          }
 1377   
 1378          $tmp = array(
 1379              'file1'        => file_get_contents($this->old_location . $original_file),
 1380              'file2'        => file_get_contents($phpbb_root_path . $file),
 1381          );
 1382   
 1383          // We need to diff the contents here to make sure the file is really the one we expect
 1384          $diff = &new diff($tmp['file1'], $tmp['file2'], false);
 1385          $empty_1 = $diff->is_empty();
 1386   
 1387          unset($tmp, $diff);
 1388   
 1389          $tmp = array(
 1390              'file1'        => file_get_contents($this->new_location . $original_file),
 1391              'file2'        => file_get_contents($phpbb_root_path . $file),
 1392          );
 1393   
 1394          // We need to diff the contents here to make sure the file is really the one we expect
 1395          $diff = &new diff($tmp['file1'], $tmp['file2'], false);
 1396          $empty_2 = $diff->is_empty();
 1397   
 1398          unset($tmp, $diff);
 1399   
 1400          // If the file is not modified we are finished here...
 1401          if ($empty_1)
 1402          {
 1403              // Further check if it is already up to date - it could happen that non-modified files
 1404              // slip through
 1405              if ($empty_2)
 1406              {
 1407                  $update_list['up_to_date'][] = $update_ary;
 1408                  return;
 1409              }
 1410   
 1411              $update_list['not_modified'][] = $update_ary;
 1412              return;
 1413          }
 1414   
 1415          // If the file had been modified then we need to check if it is already up to date
 1416   
 1417          // if there are no differences we have an up-to-date file...
 1418          if ($empty_2)
 1419          {
 1420              $update_list['up_to_date'][] = $update_ary;
 1421              return;
 1422          }
 1423   
 1424          // if the file is modified we try to make sure a merge succeed
 1425          $tmp = array(
 1426              'file1'        => file_get_contents($this->old_location . $original_file),
 1427              'file2'        => file_get_contents($phpbb_root_path . $file),
 1428              'file3'        => file_get_contents($this->new_location . $original_file),
 1429          );
 1430   
 1431          $diff = &new diff3($tmp['file1'], $tmp['file2'], $tmp['file3'], false);
 1432   
 1433          unset($tmp);
 1434   
 1435          if ($diff->merged_output(false, false, false, true))
 1436          {
 1437              $update_ary['conflicts'] = $diff->_conflicting_blocks;
 1438   
 1439              // There is one special case... users having merged with a conflicting file... we need to check this
 1440              $tmp = array(
 1441                  'file1'        => file_get_contents($phpbb_root_path . $file),
 1442                  'file2'        => implode("\n", $diff->merged_orig_output()),
 1443              );
 1444   
 1445              $diff = &new diff($tmp['file1'], $tmp['file2'], false);
 1446              $empty = $diff->is_empty();
 1447   
 1448              if ($empty)
 1449              {
 1450                  unset($update_ary['conflicts']);
 1451                  unset($diff);
 1452                  $update_list['up_to_date'][] = $update_ary;
 1453                  return;
 1454              }
 1455   
 1456              $update_list['conflict'][] = $update_ary;
 1457              unset($diff);
 1458   
 1459              return;
 1460          }
 1461   
 1462          $tmp = array(
 1463              'file1'        => file_get_contents($phpbb_root_path . $file),
 1464              'file2'        => implode("\n", $diff->merged_output()),
 1465          );
 1466   
 1467          // now compare the merged output with the original file to see if the modified file is up to date
 1468          $diff = &new diff($tmp['file1'], $tmp['file2'], false);
 1469          $empty = $diff->is_empty();
 1470   
 1471          if ($empty)
 1472          {
 1473              unset($diff);
 1474   
 1475              $update_list['up_to_date'][] = $update_ary;
 1476              return;
 1477          }
 1478   
 1479          // If no other status matches we have a modified file...
 1480          $update_list['modified'][] = $update_ary;
 1481      }
 1482   
 1483      /**
 1484      * Update update_list with custom new files
 1485      */
 1486      function get_custom_info(&$update_list, $file)
 1487      {
 1488          if (empty($this->update_info['custom']))
 1489          {
 1490              return;
 1491          }
 1492   
 1493          if (in_array($file, array_keys($this->update_info['custom'])))
 1494          {
 1495              foreach ($this->update_info['custom'][$file] as $_file)
 1496              {
 1497                  $update_list[] = array('filename' => $_file, 'custom' => true, 'original' => $file);
 1498              }
 1499          }
 1500      }
 1501   
 1502      /**
 1503      * Get remote file
 1504      */
 1505      function get_file($mode)
 1506      {
 1507          global $user, $db;
 1508   
 1509          $errstr = '';
 1510          $errno = 0;
 1511   
 1512          switch ($mode)
 1513          {
 1514              case 'version_info':
 1515                  global $phpbb_root_path, $phpEx;
 1516                  $info = get_remote_file('www.phpbb.com', '/updatecheck', ((defined('PHPBB_QA')) ? '30x_qa.txt' : '30x.txt'), $errstr, $errno);
 1517   
 1518                  if ($info !== false)
 1519                  {
 1520                      $info = explode("\n", $info);
 1521                      $info = trim($info[0]);
 1522                  }
 1523   
 1524                  if ($this->test_update !== false)
 1525                  {
 1526                      $info = $this->test_update;
 1527                  }
 1528   
 1529                  // If info is false the fsockopen function may not be working. Instead get the latest version from our update file (and pray it is up-to-date)
 1530                  if ($info === false)
 1531                  {
 1532                      $update_info = array();
 1533                      include($phpbb_root_path . 'install/update/index.php');
 1534                      $info = (empty($update_info) || !is_array($update_info)) ? false : $update_info;
 1535   
 1536                      if ($info !== false)
 1537                      {
 1538                          $info = (!empty($info['version']['to'])) ? trim($info['version']['to']) : false;
 1539                      }
 1540                  }
 1541              break;
 1542   
 1543              case 'update_info':
 1544                  global $phpbb_root_path, $phpEx;
 1545   
 1546                  $update_info = array();
 1547                  include($phpbb_root_path . 'install/update/index.php');
 1548   
 1549                  $info = (empty($update_info) || !is_array($update_info)) ? false : $update_info;
 1550                  $errstr = ($info === false) ? $user->lang['WRONG_INFO_FILE_FORMAT'] : '';
 1551   
 1552                  if ($info !== false)
 1553                  {
 1554                      // Adjust the update info file to hold some specific style-related information
 1555                      $info['custom'] = array();
 1556  /*
 1557                      // Get custom installed styles...
 1558                      $sql = 'SELECT template_name, template_path
 1559                          FROM ' . STYLES_TEMPLATE_TABLE . "
 1560                          WHERE LOWER(template_name) NOT IN ('subsilver2', 'prosilver')";
 1561                      $result = $db->sql_query($sql);
 1562   
 1563                      $templates = array();
 1564                      while ($row = $db->sql_fetchrow($result))
 1565                      {
 1566                          $templates[] = $row;
 1567                      }
 1568                      $db->sql_freeresult($result);
 1569   
 1570                      if (sizeof($templates))
 1571                      {
 1572                          foreach ($info['files'] as $filename)
 1573                          {
 1574                              // Template update?
 1575                              if (strpos(strtolower($filename), 'styles/prosilver/template/') === 0)
 1576                              {
 1577                                  foreach ($templates as $row)
 1578                                  {
 1579                                      $info['custom'][$filename][] = str_replace('/prosilver/', '/' . $row['template_path'] . '/', $filename);
 1580                                  }
 1581                              }
 1582                          }
 1583                      }
 1584  */
 1585                  }
 1586              break;
 1587   
 1588              default:
 1589                  trigger_error('Mode for getting remote file not specified', E_USER_ERROR);
 1590              break;
 1591          }
 1592   
 1593          if ($info === false)
 1594          {
 1595              trigger_error($errstr, E_USER_ERROR);
 1596          }
 1597   
 1598          return $info;
 1599      }
 1600   
 1601      /**
 1602      * Function for including files...
 1603      */
 1604      function include_file($filename)
 1605      {
 1606          global $phpbb_root_path, $phpEx;
 1607   
 1608          if (!empty($this->update_info['files']) && in_array($filename, $this->update_info['files']))
 1609          {
 1610              include_once($this->new_location . $filename);
 1611          }
 1612          else
 1613          {
 1614              include_once($phpbb_root_path . $filename);
 1615          }
 1616      }
 1617   
 1618      /**
 1619      * Wrapper for returning a diff object
 1620      */
 1621      function &return_diff()
 1622      {
 1623          $args = func_get_args();
 1624          $three_way_diff = (func_num_args() > 2) ? true : false;
 1625   
 1626          $file1 = array_shift($args);
 1627          $file2 = array_shift($args);
 1628   
 1629          $tmp['file1'] = (!empty($file1) && is_string($file1)) ? file_get_contents($file1) : $file1;
 1630          $tmp['file2'] = (!empty($file2) && is_string($file2)) ? file_get_contents($file2) : $file2;
 1631   
 1632          if ($three_way_diff)
 1633          {
 1634              $file3 = array_shift($args);
 1635              $tmp['file3'] = (!empty($file3) && is_string($file3)) ? file_get_contents($file3) : $file3;
 1636   
 1637              $diff = &new diff3($tmp['file1'], $tmp['file2'], $tmp['file3']);
 1638          }
 1639          else
 1640          {
 1641              $diff = &new diff($tmp['file1'], $tmp['file2']);
 1642          }
 1643   
 1644          unset($tmp);
 1645   
 1646          return $diff;
 1647      }
 1648  }
 1649   
 1650  ?>