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. |
|
(Beispiel Datei-Icons)
|
Auf das Icon klicken um den Quellcode anzuzeigen |
install_update.php
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&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&sub=file_check"),
0242 'U_DB_UPDATE_ACTION' => append_sid($this->p_master->module_url, "mode=$mode&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&language=' . $user->data['user_lang']),
0286 'U_DB_UPDATE_ACTION' => append_sid($this->p_master->module_url, "mode=$mode&sub=update_db"),
0287 'U_ACTION' => append_sid($this->p_master->module_url, "mode=$mode&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&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&sub=file_check&action=diff&status=$status&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 . '&op=' . MERGE_MOD_FILE,
0417 'U_VIEW_NEW_FILE' => $diff_url . '&op=' . MERGE_NEW_FILE,
0418 'U_VIEW_NO_MERGE_MOD' => $diff_url . '&op=' . MERGE_NO_MERGE_MOD,
0419 'U_VIEW_NO_MERGE_NEW' => $diff_url . '&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&sub=file_check"),
0439 'U_UPDATE_ACTION' => append_sid($this->p_master->module_url, "mode=$mode&sub=update_files"),
0440 'U_DB_UPDATE_ACTION' => append_sid($this->p_master->module_url, "mode=$mode&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&sub=update_files&" . implode('&', $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&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&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&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 ?>