/** * {@inheritdoc} */ public function run() { if ($this->iohandler->get_input('submit_ftp', false)) { $this->update_helper->include_file('includes/functions_transfer.' . $this->php_ext); $method = 'ftp'; $methods = \transfer::methods(); if (!in_array($method, $methods, true)) { $method = $methods[0]; } $ftp_host = $this->iohandler->get_input('ftp_host', ''); $ftp_user = $this->iohandler->get_input('ftp_user', ''); $ftp_pass = htmlspecialchars_decode($this->iohandler->get_input('ftp_pass', '')); $ftp_path = $this->iohandler->get_input('ftp_path', ''); $ftp_port = $this->iohandler->get_input('ftp_port', 21); $ftp_time = $this->iohandler->get_input('ftp_timeout', 10); $this->installer_config->set('ftp_host', $ftp_host); $this->installer_config->set('ftp_user', $ftp_user); $this->installer_config->set('ftp_pass', $ftp_pass); $this->installer_config->set('ftp_path', $ftp_path); $this->installer_config->set('ftp_port', (int) $ftp_port); $this->installer_config->set('ftp_timeout', (int) $ftp_time); $this->installer_config->set('ftp_method', $method); } else { $this->iohandler->add_user_form_group('FTP_SETTINGS', array('ftp_host' => array('label' => 'FTP_HOST', 'description' => 'FTP_HOST_EXPLAIN', 'type' => 'text'), 'ftp_user' => array('label' => 'FTP_USERNAME', 'description' => 'FTP_USERNAME_EXPLAIN', 'type' => 'text'), 'ftp_pass' => array('label' => 'FTP_PASSWORD', 'description' => 'FTP_PASSWORD_EXPLAIN', 'type' => 'password'), 'ftp_path' => array('label' => 'FTP_ROOT_PATH', 'description' => 'FTP_ROOT_PATH_EXPLAIN', 'type' => 'text'), 'ftp_port' => array('label' => 'FTP_PORT', 'description' => 'FTP_PORT_EXPLAIN', 'type' => 'text', 'default' => 21), 'ftp_timeout' => array('label' => 'FTP_TIMEOUT', 'description' => 'FTP_TIMEOUT_EXPLAIN', 'type' => 'text', 'default' => 10), 'submit_ftp' => array('label' => 'SUBMIT', 'type' => 'submit'))); throw new user_interaction_required_exception(); } }
/** * {@inheritdoc} */ public function update_file($path_to_file_to_update, $source, $create_from_content = false) { if ($create_from_content) { $this->transfer->write_file($path_to_file_to_update, $source); } else { $this->transfer->copy_file($path_to_file_to_update, $source); } }
/** * Standard parameters for FTP session */ function ftp_fsock($host, $username, $password, $root_path, $port = 21, $timeout = 10) { $this->host = $host; $this->port = $port; $this->username = $username; $this->password = $password; $this->timeout = $timeout; // Make sure $this->root_path is layed out the same way as the $user->page['root_script_path'] value (/ at the end) $this->root_path = str_replace('\\', '/', $this->root_path); if (!empty($root_path)) { $this->root_path = ($root_path[0] != '/' ? '/' : '') . $root_path . (substr($root_path, -1, 1) == '/' ? '' : '/'); } // Init some needed values transfer::transfer(); return; }
function main($id, $mode) { global $config, $db, $user, $auth, $template, $cache; global $phpbb_root_path, $phpbb_admin_path, $phpEx, $table_prefix; global $safe_mode, $file_uploads; include_once $phpbb_root_path . 'includes/functions_user.' . $phpEx; $this->default_variables(); // Check and set some common vars $action = request_var('action', ''); $action = isset($_POST['update_details']) ? 'update_details' : $action; $action = isset($_POST['download_file']) ? 'download_file' : $action; $action = isset($_POST['upload_file']) ? 'upload_file' : $action; $action = isset($_POST['upload_data']) ? 'upload_data' : $action; $action = isset($_POST['submit_file']) ? 'submit_file' : $action; $action = isset($_POST['remove_store']) ? 'details' : $action; $lang_id = request_var('id', 0); if (isset($_POST['missing_file'])) { $missing_file = request_var('missing_file', array('' => 0)); list($_REQUEST['language_file'], ) = array_keys($missing_file); } list($this->language_directory, $this->language_file) = explode('|', request_var('language_file', '|common.' . $phpEx)); $this->language_directory = basename($this->language_directory); $this->language_file = basename($this->language_file); $user->add_lang('acp/language'); $this->tpl_name = 'acp_language'; $this->page_title = 'ACP_LANGUAGE_PACKS'; if ($action == 'upload_data' && request_var('test_connection', '')) { $test_connection = false; $action = 'upload_file'; $method = request_var('method', ''); include_once $phpbb_root_path . 'includes/functions_transfer.' . $phpEx; switch ($method) { case 'ftp': $transfer = new ftp(request_var('host', ''), request_var('username', ''), request_var('password', ''), request_var('root_path', ''), request_var('port', ''), request_var('timeout', '')); break; default: trigger_error($user->lang['INVALID_UPLOAD_METHOD']); } $test_connection = $transfer->open_session(); $transfer->close_session(); } switch ($action) { case 'upload_file': include_once $phpbb_root_path . 'includes/functions_transfer.' . $phpEx; $method = request_var('method', ''); $requested_data = call_user_func(array($method, 'data')); foreach ($requested_data as $data => $default) { $template->assign_block_vars('data', array('DATA' => $data, 'NAME' => $user->lang[strtoupper($method . '_' . $data)], 'EXPLAIN' => $user->lang[strtoupper($method . '_' . $data) . '_EXPLAIN'], 'DEFAULT' => !empty($_REQUEST[$data]) ? request_var($data, '') : $default)); } $entry = $_POST['entry']; foreach ($entry as $key => $value) { if (is_array($value)) { foreach ($value as $key2 => $data) { $entry[$key][$key2] = htmlentities($data); } } else { $entry[$key] = htmlentities($value); } } $hidden_data = build_hidden_fields(array('file' => $this->language_file, 'dir' => $this->language_directory, 'method' => $method, 'entry' => $entry)); $template->assign_vars(array('S_UPLOAD' => true, 'NAME' => $method, 'U_ACTION' => $this->u_action . "&id={$lang_id}&action=upload_data", 'HIDDEN' => $hidden_data, 'S_CONNECTION_SUCCESS' => request_var('test_connection', '') && $test_connection === true ? true : false, 'S_CONNECTION_FAILED' => request_var('test_connection', '') && $test_connection !== true ? true : false)); break; case 'update_details': if (!$lang_id) { trigger_error($user->lang['NO_LANG_ID'] . adm_back_link($this->u_action)); } $sql = 'SELECT * FROM ' . LANG_TABLE . "\n\t\t\t\t\tWHERE lang_id = {$lang_id}"; $result = $db->sql_query($sql); $row = $db->sql_fetchrow($result); $db->sql_freeresult($result); $sql_ary = array('lang_english_name' => request_var('lang_english_name', $row['lang_english_name']), 'lang_local_name' => request_var('lang_local_name', $row['lang_local_name'], true), 'lang_author' => request_var('lang_author', $row['lang_author'], true)); $db->sql_query('UPDATE ' . LANG_TABLE . ' SET ' . $db->sql_build_array('UPDATE', $sql_ary) . ' WHERE lang_id = ' . $lang_id); add_log('admin', 'LOG_LANGUAGE_PACK_UPDATED', $sql_ary['lang_english_name']); trigger_error($user->lang['LANGUAGE_DETAILS_UPDATED'] . adm_back_link($this->u_action)); break; case 'submit_file': case 'download_file': case 'upload_data': if (!$lang_id || !isset($_POST['entry']) || !is_array($_POST['entry'])) { trigger_error($user->lang['NO_LANG_ID'] . adm_back_link($this->u_action)); } if (!$this->language_file || !$this->language_directory && !in_array($this->language_file, $this->main_files)) { trigger_error($user->lang['NO_FILE_SELECTED'] . adm_back_link($this->u_action)); } $sql = 'SELECT * FROM ' . LANG_TABLE . "\n\t\t\t\t\tWHERE lang_id = {$lang_id}"; $result = $db->sql_query($sql); $row = $db->sql_fetchrow($result); $db->sql_freeresult($result); if (!$safe_mode) { $mkdir_ary = array('language', 'language/' . $row['lang_iso']); if ($this->language_directory) { $mkdir_ary[] = 'language/' . $row['lang_iso'] . '/' . $this->language_directory; } foreach ($mkdir_ary as $dir) { $dir = $phpbb_root_path . 'store/' . $dir; if (!is_dir($dir)) { if (!@mkdir($dir, 0777)) { trigger_error("Could not create directory {$dir}"); } @chmod($dir, 0777); } } } // Get target filename for storage folder $filename = $this->get_filename($row['lang_iso'], $this->language_directory, $this->language_file, true, true); $fp = fopen($phpbb_root_path . $filename, 'wb'); if (!$fp) { trigger_error($user->lang['UNABLE_TO_WRITE_FILE']); } if ($this->language_directory == 'email') { // Email Template $entry = STRIP ? stripslashes($_POST['entry']) : $_POST['entry']; $entry = preg_replace('#&(\\#[0-9]+;)#', '&\\1', $entry); fwrite($fp, $entry); } else { $name = ($this->language_directory ? $this->language_directory . '_' : '') . $this->language_file; $header = str_replace(array('{FILENAME}', '{LANG_NAME}', '{CHANGED}', '{AUTHOR}'), array($name, $row['lang_english_name'], date('Y-m-d', time()), $row['lang_author']), $this->language_file_header); if (strpos($this->language_file, 'help_') === 0) { // Help File $header .= '$help = array(' . "\n"; fwrite($fp, $header); foreach ($_POST['entry'] as $key => $value) { if (!is_array($value)) { } else { $entry = "\tarray(\n"; foreach ($value as $_key => $_value) { $_value = STRIP ? stripslashes($_value) : $_value; $_value = preg_replace('#&(\\#[0-9]+;)#', '&\\1', $_value); $entry .= "\t\t" . (int) $_key . "\t=> '" . str_replace("'", "\\'", $_value) . "',\n"; } $entry .= "\t),\n"; } fwrite($fp, $entry); } } else { // Language File $header .= $this->lang_header; fwrite($fp, $header); foreach ($_POST['entry'] as $key => $value) { if (!is_array($value)) { $value = STRIP ? stripslashes($value) : $value; $value = preg_replace('#&(\\#[0-9]+;)#', '&\\1', $value); $entry = "\t'" . $key . "'\t=> '" . str_replace("'", "\\'", $value) . "',\n"; } else { $entry = "\n\t'" . $key . "'\t=> array(\n"; foreach ($value as $_key => $_value) { $_value = STRIP ? stripslashes($_value) : $_value; $_value = preg_replace('#&(\\#[0-9]+;)#', '&\\1', $_value); $entry .= "\t\t'" . $_key . "'\t=> '" . str_replace("'", "\\'", $_value) . "',\n"; } $entry .= "\t),\n\n"; } fwrite($fp, $entry); } } $footer = "));\n\n?>"; fwrite($fp, $footer); } fclose($fp); if ($action == 'download_file') { header('Pragma: no-cache'); header('Content-Type: application/octetstream; name="' . $this->language_file . '"'); header('Content-disposition: attachment; filename=' . $this->language_file); $fp = fopen($phpbb_root_path . $filename, 'rb'); while ($buffer = fread($fp, 1024)) { echo $buffer; } fclose($fp); exit; } else { if ($action == 'upload_data') { $sql = 'SELECT lang_iso FROM ' . LANG_TABLE . "\n\t\t\t\t\t\tWHERE lang_id = {$lang_id}"; $result = $db->sql_query($sql); $row = $db->sql_fetchrow($result); $db->sql_freeresult($result); $file = request_var('file', ''); $dir = request_var('dir', ''); $old_file = '/' . $this->get_filename($row['lang_iso'], $dir, $file, false, true); $lang_path = 'language/' . $row['lang_iso'] . '/' . ($dir ? $dir . '/' : ''); include_once $phpbb_root_path . 'includes/functions_transfer.' . $phpEx; $method = request_var('method', ''); switch ($method) { case 'ftp': $transfer = new ftp(request_var('host', ''), request_var('username', ''), request_var('password', ''), request_var('root_path', ''), request_var('port', ''), request_var('timeout', '')); break; default: trigger_error($user->lang['INVALID_UPLOAD_METHOD']); } if (($result = $transfer->open_session()) !== true) { trigger_error($user->lang[$result] . adm_back_link($this->u_action)); } $transfer->rename($lang_path . $file, $lang_path . $file . '.bak'); $transfer->copy_file('store/' . $lang_path . $file, $lang_path . $file); $transfer->close_session(); add_log('admin', 'LOG_LANGUAGE_FILE_REPLACED', $file); trigger_error($user->lang['UPLOAD_COMPLETED']); } } $action = 'details'; // no break; // no break; case 'details': if (!$lang_id) { trigger_error($user->lang['NO_LANG_ID'] . adm_back_link($this->u_action)); } $this->page_title = 'LANGUAGE_PACK_DETAILS'; $sql = 'SELECT * FROM ' . LANG_TABLE . ' WHERE lang_id = ' . $lang_id; $result = $db->sql_query($sql); $lang_entries = $db->sql_fetchrow($result); $db->sql_freeresult($result); $lang_iso = $lang_entries['lang_iso']; $missing_vars = $missing_files = array(); // Get email templates $email_files = filelist($phpbb_root_path . 'language/' . $config['default_lang'], 'email', 'txt'); $email_files = $email_files['email/']; // Get acp files $acp_files = filelist($phpbb_root_path . 'language/' . $config['default_lang'], 'acp', $phpEx); $acp_files = $acp_files['acp/']; // Get mod files $mods_files = filelist($phpbb_root_path . 'language/' . $config['default_lang'], 'mods', $phpEx); $mods_files = isset($mods_files['mods/']) ? $mods_files['mods/'] : array(); // Check if our current filename matches the files switch ($this->language_directory) { case 'email': if (!in_array($this->language_file, $email_files)) { trigger_error($user->lang['WRONG_LANGUAGE_FILE'] . adm_back_link($this->u_action . '&action=details&id=' . $lang_id)); } break; case 'acp': if (!in_array($this->language_file, $acp_files)) { trigger_error($user->lang['WRONG_LANGUAGE_FILE'] . adm_back_link($this->u_action . '&action=details&id=' . $lang_id)); } break; case 'mods': if (!in_array($this->language_file, $mods_files)) { trigger_error($user->lang['WRONG_LANGUAGE_FILE'] . adm_back_link($this->u_action . '&action=details&id=' . $lang_id)); } break; default: if (!in_array($this->language_file, $this->main_files)) { trigger_error($user->lang['WRONG_LANGUAGE_FILE'] . adm_back_link($this->u_action . '&action=details&id=' . $lang_id)); } } if (isset($_POST['remove_store'])) { $store_filename = $this->get_filename($lang_iso, $this->language_directory, $this->language_file, true, true); @unlink($phpbb_root_path . $store_filename); } include_once $phpbb_root_path . 'includes/functions_transfer.' . $phpEx; $methods = transfer::methods(); foreach ($methods as $method) { $template->assign_block_vars('buttons', array('VALUE' => $method)); } $template->assign_vars(array('S_DETAILS' => true, 'U_ACTION' => $this->u_action . "&action=details&id={$lang_id}", 'U_BACK' => $this->u_action, 'LANG_LOCAL_NAME' => $lang_entries['lang_local_name'], 'LANG_ENGLISH_NAME' => $lang_entries['lang_english_name'], 'LANG_ISO' => $lang_entries['lang_iso'], 'LANG_AUTHOR' => $lang_entries['lang_author'], 'ALLOW_UPLOAD' => sizeof($methods))); // If current lang is different from the default lang, then first try to grab missing/additional vars if ($lang_iso != $config['default_lang']) { $is_missing_var = false; foreach ($this->main_files as $file) { if (file_exists($phpbb_root_path . $this->get_filename($lang_iso, '', $file))) { $missing_vars[$file] = $this->compare_language_files($config['default_lang'], $lang_iso, '', $file); if (sizeof($missing_vars[$file])) { $is_missing_var = true; } } else { $missing_files[] = $this->get_filename($lang_iso, '', $file); } } // Now go through acp/mods directories foreach ($acp_files as $file) { if (file_exists($phpbb_root_path . $this->get_filename($lang_iso, 'acp', $file))) { $missing_vars['acp/' . $file] = $this->compare_language_files($config['default_lang'], $lang_iso, 'acp', $file); if (sizeof($missing_vars['acp/' . $file])) { $is_missing_var = true; } } else { $missing_files[] = $this->get_filename($lang_iso, 'acp', $file); } } if (sizeof($mods_files)) { foreach ($mods_files as $file) { if (file_exists($phpbb_root_path . $this->get_filename($lang_iso, 'mods', $file))) { $missing_vars['mods/' . $file] = $this->compare_language_files($config['default_lang'], $lang_iso, 'mods', $file); if (sizeof($missing_vars['mods/' . $file])) { $is_missing_var = true; } } else { $missing_files[] = $this->get_filename($lang_iso, 'mods', $file); } } } // More missing files... for example email templates? foreach ($email_files as $file) { if (!file_exists($phpbb_root_path . $this->get_filename($lang_iso, 'email', $file))) { $missing_files[] = $this->get_filename($lang_iso, 'email', $file); } } if (sizeof($missing_files)) { $template->assign_vars(array('S_MISSING_FILES' => true, 'L_MISSING_FILES' => sprintf($user->lang['THOSE_MISSING_LANG_FILES'], $lang_entries['lang_local_name']), 'MISSING_FILES' => implode('<br />', $missing_files))); } if ($is_missing_var) { $template->assign_vars(array('S_MISSING_VARS' => true, 'L_MISSING_VARS_EXPLAIN' => sprintf($user->lang['THOSE_MISSING_LANG_VARIABLES'], $lang_entries['lang_local_name']), 'U_MISSING_ACTION' => $this->u_action . "&action={$action}&id={$lang_id}")); foreach ($missing_vars as $file => $vars) { if (!sizeof($vars)) { continue; } $template->assign_block_vars('missing', array('FILE' => $file, 'TPL' => $this->print_language_entries($vars, '', false), 'KEY' => strpos($file, '/') === false ? '|' . $file : str_replace('/', '|', $file))); } } } // Main language files $s_lang_options = '<option value="|common.' . $phpEx . '" class="sep">' . $user->lang['LANGUAGE_FILES'] . '</option>'; foreach ($this->main_files as $file) { if (strpos($file, 'help_') === 0) { continue; } $prefix = file_exists($phpbb_root_path . $this->get_filename($lang_iso, '', $file, true, true)) ? '* ' : ''; $selected = !$this->language_directory && $this->language_file == $file ? ' selected="selected"' : ''; $s_lang_options .= '<option value="|' . $file . '"' . $selected . '>' . $prefix . $file . '</option>'; } // Help Files $s_lang_options .= '<option value="|common.' . $phpEx . '" class="sep">' . $user->lang['HELP_FILES'] . '</option>'; foreach ($this->main_files as $file) { if (strpos($file, 'help_') !== 0) { continue; } $prefix = file_exists($phpbb_root_path . $this->get_filename($lang_iso, '', $file, true, true)) ? '* ' : ''; $selected = !$this->language_directory && $this->language_file == $file ? ' selected="selected"' : ''; $s_lang_options .= '<option value="|' . $file . '"' . $selected . '>' . $prefix . $file . '</option>'; } // Now every other language directory $check_files = array('email', 'acp', 'mods'); foreach ($check_files as $check) { if (!sizeof(${$check . '_files'})) { continue; } $s_lang_options .= '<option value="|common.' . $phpEx . '" class="sep">' . $user->lang[strtoupper($check) . '_FILES'] . '</option>'; foreach (${$check . '_files'} as $file) { $prefix = file_exists($phpbb_root_path . $this->get_filename($lang_iso, $check, $file, true, true)) ? '* ' : ''; $selected = $this->language_directory == $check && $this->language_file == $file ? ' selected="selected"' : ''; $s_lang_options .= '<option value="' . $check . '|' . $file . '"' . $selected . '>' . $prefix . $file . '</option>'; } } // Get Language Entries - if saved within store folder, we take this one (with the option to remove it) $lang = array(); $is_email_file = $this->language_directory == 'email' ? true : false; $is_help_file = strpos($this->language_file, 'help_') === 0 ? true : false; $file_from_store = file_exists($phpbb_root_path . $this->get_filename($lang_iso, $this->language_directory, $this->language_file, true, true)) ? true : false; $no_store_filename = $this->get_filename($lang_iso, $this->language_directory, $this->language_file); if (!$file_from_store && !file_exists($phpbb_root_path . $no_store_filename)) { $print_message = sprintf($user->lang['MISSING_LANGUAGE_FILE'], $no_store_filename); } else { if ($is_email_file) { $lang = file_get_contents($phpbb_root_path . $this->get_filename($lang_iso, $this->language_directory, $this->language_file, $file_from_store)); } else { $help = array(); include $phpbb_root_path . $this->get_filename($lang_iso, $this->language_directory, $this->language_file, $file_from_store); if ($is_help_file) { $lang = $help; unset($help); } } $print_message = ($this->language_directory ? $this->language_directory . '/' : '') . $this->language_file; } // Normal language pack entries $template->assign_vars(array('U_ENTRY_ACTION' => $this->u_action . "&action=details&id={$lang_id}#entries", 'S_EMAIL_FILE' => $is_email_file, 'S_FROM_STORE' => $file_from_store, 'S_LANG_OPTIONS' => $s_lang_options, 'PRINT_MESSAGE' => $print_message)); if (!$is_email_file) { $method = $is_help_file ? 'print_help_entries' : 'print_language_entries'; $tpl = ''; $name = ($this->language_directory ? $this->language_directory . '/' : '') . $this->language_file; if (isset($missing_vars[$name]) && sizeof($missing_vars[$name])) { $tpl .= $this->{$method}($missing_vars[$name], '* '); } $tpl .= $this->{$method}($lang); $template->assign_var('TPL', $tpl); unset($tpl); } else { $template->assign_vars(array('LANG' => $lang)); unset($lang); } return; break; case 'delete': if (!$lang_id) { trigger_error($user->lang['NO_LANG_ID'] . adm_back_link($this->u_action)); } $sql = 'SELECT * FROM ' . LANG_TABLE . ' WHERE lang_id = ' . $lang_id; $result = $db->sql_query($sql); $row = $db->sql_fetchrow($result); $db->sql_freeresult($result); if ($row['lang_iso'] == $config['default_lang']) { trigger_error($user->lang['NO_REMOVE_DEFAULT_LANG'] . adm_back_link($this->u_action)); } $db->sql_query('DELETE FROM ' . LANG_TABLE . ' WHERE lang_id = ' . $lang_id); $sql = 'UPDATE ' . USERS_TABLE . " \n\t\t\t\t\tSET user_lang = '{$config['default_lang']}'\n\t\t\t\t\tWHERE user_lang = '{$row['lang_iso']}'"; $db->sql_query($sql); add_log('admin', 'LOG_LANGUAGE_PACK_DELETED', $row['lang_english_name']); trigger_error(sprintf($user->lang['LANGUAGE_PACK_DELETED'], $row['lang_english_name']) . adm_back_link($this->u_action)); break; case 'install': $lang_iso = request_var('iso', ''); $lang_iso = basename($lang_iso); if (!$lang_iso || !file_exists("{$phpbb_root_path}language/{$lang_iso}/iso.txt")) { trigger_error($user->lang['LANGUAGE_PACK_NOT_EXIST'] . adm_back_link($this->u_action)); } $file = file("{$phpbb_root_path}language/{$lang_iso}/iso.txt"); $lang_pack = array('iso' => $lang_iso, 'name' => trim(htmlspecialchars($file[0])), 'local_name' => trim(htmlspecialchars($file[1])), 'author' => trim(htmlspecialchars($file[2]))); unset($file); $sql = 'SELECT lang_iso FROM ' . LANG_TABLE . "\n\t\t\t\t\tWHERE lang_iso = '" . $db->sql_escape($lang_iso) . "'"; $result = $db->sql_query($sql); if ($row = $db->sql_fetchrow($result)) { trigger_error($user->lang['LANGUAGE_PACK_ALREADY_INSTALLED'] . adm_back_link($this->u_action)); } $db->sql_freeresult($result); if (!$lang_pack['name'] || !$lang_pack['local_name']) { trigger_error($user->lang['INVALID_LANGUAGE_PACK'] . adm_back_link($this->u_action)); } // Add language pack $sql_ary = array('lang_iso' => $lang_pack['iso'], 'lang_dir' => $lang_pack['iso'], 'lang_english_name' => $lang_pack['name'], 'lang_local_name' => $lang_pack['local_name'], 'lang_author' => $lang_pack['author']); $db->sql_query('INSERT INTO ' . LANG_TABLE . ' ' . $db->sql_build_array('INSERT', $sql_ary)); add_log('admin', 'LOG_LANGUAGE_PACK_INSTALLED', $lang_pack['name']); trigger_error(sprintf($user->lang['LANGUAGE_PACK_INSTALLED'], $lang_pack['name']) . adm_back_link($this->u_action)); break; case 'download': if (!$lang_id) { trigger_error($user->lang['NO_LANG_ID'] . adm_back_link($this->u_action)); } $sql = 'SELECT * FROM ' . LANG_TABLE . ' WHERE lang_id = ' . $lang_id; $result = $db->sql_query($sql); $row = $db->sql_fetchrow($result); $db->sql_freeresult($result); $use_method = request_var('use_method', ''); $methods = array('.tar'); $available_methods = array('.tar.gz' => 'zlib', '.tar.bz2' => 'bz2', '.zip' => 'zlib'); foreach ($available_methods as $type => $module) { if (!@extension_loaded($module)) { continue; } $methods[] = $type; } // Let the user decide in which format he wants to have the pack if (!$use_method) { $this->page_title = 'SELECT_DOWNLOAD_FORMAT'; $radio_buttons = ''; foreach ($methods as $method) { $radio_buttons .= '<input type="radio"' . (!$radio_buttons ? ' id="use_method"' : '') . ' class="radio" value="' . $method . '" name="use_method" /> ' . $method . ' '; } $template->assign_vars(array('S_SELECT_METHOD' => true, 'U_BACK' => $this->u_action, 'U_ACTION' => $this->u_action . "&action={$action}&id={$lang_id}", 'RADIO_BUTTONS' => $radio_buttons)); return; } if (!in_array($use_method, $methods)) { $use_method = '.tar'; } include_once $phpbb_root_path . 'includes/functions_compress.' . $phpEx; if ($use_method == 'zip') { $compress = new compress_zip('w', $phpbb_root_path . 'store/lang_' . $row['lang_iso'] . $use_method); } else { $compress = new compress_tar('w', $phpbb_root_path . 'store/lang_' . $row['lang_iso'] . $use_method, $use_method); } // Get email templates $email_templates = filelist($phpbb_root_path . 'language/' . $row['lang_iso'], 'email', 'txt'); $email_templates = $email_templates['email/']; // Get acp files $acp_files = filelist($phpbb_root_path . 'language/' . $row['lang_iso'], 'acp', $phpEx); $acp_files = $acp_files['acp/']; // Get mod files $mod_files = filelist($phpbb_root_path . 'language/' . $row['lang_iso'], 'mods', $phpEx); $mod_files = isset($mod_files['mods/']) ? $mod_files['mods/'] : array(); // Add main files $this->add_to_archive($compress, $this->main_files, $row['lang_iso']); // Write files in folders $this->add_to_archive($compress, $email_templates, $row['lang_iso'], 'email'); $this->add_to_archive($compress, $acp_files, $row['lang_iso'], 'acp'); $this->add_to_archive($compress, $mod_files, $row['lang_iso'], 'mods'); // Write ISO File $iso_src = html_entity_decode($row['lang_english_name']) . "\n"; $iso_src .= html_entity_decode($row['lang_local_name']) . "\n"; $iso_src .= html_entity_decode($row['lang_author']); $compress->add_data($iso_src, 'language/' . $row['lang_iso'] . '/iso.txt'); // index.html files $compress->add_data('', 'language/' . $row['lang_iso'] . '/index.html'); $compress->add_data('', 'language/' . $row['lang_iso'] . '/email/index.html'); $compress->add_data('', 'language/' . $row['lang_iso'] . '/acp/index.html'); if (sizeof($mod_files)) { $compress->add_data('', 'language/' . $row['lang_iso'] . '/mods/index.html'); } $compress->close(); $compress->download('lang_' . $row['lang_iso']); @unlink($phpbb_root_path . 'store/lang_' . $row['lang_iso'] . '.' . $use_method); exit; break; } $sql = 'SELECT user_lang, COUNT(user_lang) AS lang_count FROM ' . USERS_TABLE . ' GROUP BY user_lang'; $result = $db->sql_query($sql); $lang_count = array(); while ($row = $db->sql_fetchrow($result)) { $lang_count[$row['user_lang']] = $row['lang_count']; } $db->sql_freeresult($result); $sql = 'SELECT * FROM ' . LANG_TABLE; $result = $db->sql_query($sql); $installed = array(); while ($row = $db->sql_fetchrow($result)) { $installed[] = $row['lang_iso']; $tagstyle = $row['lang_iso'] == $config['default_lang'] ? '*' : ''; $template->assign_block_vars('lang', array('U_DETAILS' => $this->u_action . "&action=details&id={$row['lang_id']}", 'U_DOWNLOAD' => $this->u_action . "&action=download&id={$row['lang_id']}", 'U_DELETE' => $this->u_action . "&action=delete&id={$row['lang_id']}", 'ENGLISH_NAME' => $row['lang_english_name'], 'TAG' => $tagstyle, 'LOCAL_NAME' => $row['lang_local_name'], 'ISO' => $row['lang_iso'], 'USED_BY' => isset($lang_count[$row['lang_iso']]) ? $lang_count[$row['lang_iso']] : 0)); } $db->sql_freeresult($result); $new_ary = $iso = array(); $dp = opendir("{$phpbb_root_path}language"); while (($file = readdir($dp)) !== false) { if ($file[0] != '.' && file_exists("{$phpbb_root_path}language/{$file}/iso.txt")) { if (!in_array($file, $installed)) { if ($iso = file("{$phpbb_root_path}language/{$file}/iso.txt")) { if (sizeof($iso) == 3) { $new_ary[$file] = array('iso' => $file, 'name' => trim($iso[0]), 'local_name' => trim($iso[1]), 'author' => trim($iso[2])); } } } } } unset($installed); @closedir($dp); if (sizeof($new_ary)) { foreach ($new_ary as $iso => $lang_ary) { $template->assign_block_vars('notinst', array('ISO' => $lang_ary['iso'], 'LOCAL_NAME' => $lang_ary['local_name'], 'NAME' => $lang_ary['name'], 'U_INSTALL' => $this->u_action . '&action=install&iso=' . urlencode($lang_ary['iso']))); } } unset($new_ary); }
function editor_ftp() { global $config, $user; $this->write_method = WRITE_FTP; $this->install_time = time(); if (!class_exists('transfer')) { global $phpbb_root_path, $phpEx; include $phpbb_root_path . 'includes/functions_transfer.' . $phpEx; } $ftp_method = request_var('ftp_method', ''); if (!$ftp_method || !class_exists($ftp_method)) { $ftp_method = 'ftp'; $ftp_methods = transfer::methods(); if (!in_array('ftp', $ftp_methods)) { $ftp_method = $ftp_methods[0]; } } $this->transfer = new $ftp_method($config['ftp_host'], $config['ftp_username'], request_var('password', ''), $config['ftp_root_path'], $config['ftp_port'], $config['ftp_timeout']); $error = $this->transfer->open_session(); // Use the permissions settings specified in the AutoMOD configuration $this->transfer->dir_perms = octdec($config['am_dir_perms']); $this->transfer->file_perms = octdec($config['am_file_perms']); if (is_string($error)) { // FTP login failed trigger_error(sprintf($user->lang['MODS_FTP_CONNECT_FAILURE'], $user->lang[$error]), E_USER_ERROR); } }
function main($id, $mode) { global $config, $db, $user, $auth, $template, $cache; global $phpbb_root_path, $phpbb_admin_path, $phpEx, $table_prefix; global $safe_mode, $file_uploads; include_once $phpbb_root_path . 'includes/functions_user.' . $phpEx; $this->default_variables(); // Check and set some common vars $action = isset($_POST['update_details']) ? 'update_details' : ''; $action = isset($_POST['download_file']) ? 'download_file' : $action; $action = isset($_POST['upload_file']) ? 'upload_file' : $action; $action = isset($_POST['upload_data']) ? 'upload_data' : $action; $action = isset($_POST['submit_file']) ? 'submit_file' : $action; $action = isset($_POST['remove_store']) ? 'details' : $action; $submit = empty($action) && !isset($_POST['update']) && !isset($_POST['test_connection']) ? false : true; $action = empty($action) ? request_var('action', '') : $action; $form_name = 'acp_lang'; add_form_key('acp_lang'); $lang_id = request_var('id', 0); if (isset($_POST['missing_file'])) { $missing_file = request_var('missing_file', array('' => 0)); list($_REQUEST['language_file'], ) = array_keys($missing_file); } $selected_lang_file = request_var('language_file', '|common.' . $phpEx); list($this->language_directory, $this->language_file) = explode('|', $selected_lang_file); $this->language_directory = basename($this->language_directory); $this->language_file = basename($this->language_file); $user->add_lang('acp/language'); $this->tpl_name = 'acp_language'; $this->page_title = 'ACP_LANGUAGE_PACKS'; if ($submit && $action == 'upload_data' && request_var('test_connection', '')) { $test_connection = false; $action = 'upload_file'; $method = request_var('method', ''); include_once $phpbb_root_path . 'includes/functions_transfer.' . $phpEx; switch ($method) { case 'ftp': $transfer = new ftp(request_var('host', ''), request_var('username', ''), request_var('password', ''), request_var('root_path', ''), request_var('port', ''), request_var('timeout', '')); break; case 'ftp_fsock': $transfer = new ftp_fsock(request_var('host', ''), request_var('username', ''), request_var('password', ''), request_var('root_path', ''), request_var('port', ''), request_var('timeout', '')); break; default: trigger_error($user->lang['INVALID_UPLOAD_METHOD'], E_USER_ERROR); break; } $test_connection = $transfer->open_session(); $transfer->close_session(); } switch ($action) { case 'upload_file': include_once $phpbb_root_path . 'includes/functions_transfer.' . $phpEx; $method = request_var('method', ''); if (!class_exists($method)) { trigger_error('Method does not exist.', E_USER_ERROR); } $requested_data = call_user_func(array($method, 'data')); foreach ($requested_data as $data => $default) { $template->assign_block_vars('data', array('DATA' => $data, 'NAME' => $user->lang[strtoupper($method . '_' . $data)], 'EXPLAIN' => $user->lang[strtoupper($method . '_' . $data) . '_EXPLAIN'], 'DEFAULT' => !empty($_REQUEST[$data]) ? request_var($data, '') : $default)); } $hidden_data = build_hidden_fields(array('file' => $this->language_file, 'dir' => $this->language_directory, 'language_file' => $selected_lang_file, 'method' => $method)); $hidden_data .= build_hidden_fields(array('entry' => $_POST['entry']), true, STRIP); $template->assign_vars(array('S_UPLOAD' => true, 'NAME' => $method, 'U_ACTION' => $this->u_action . "&id={$lang_id}&action=upload_data", 'U_BACK' => $this->u_action . "&id={$lang_id}&action=details&language_file=" . urlencode($selected_lang_file), 'HIDDEN' => $hidden_data, 'S_CONNECTION_SUCCESS' => request_var('test_connection', '') && $test_connection === true ? true : false, 'S_CONNECTION_FAILED' => request_var('test_connection', '') && $test_connection !== true ? true : false)); break; case 'update_details': if (!$submit || !check_form_key($form_name)) { trigger_error($user->lang['FORM_INVALID'] . adm_back_link($this->u_action), E_USER_WARNING); } if (!$lang_id) { trigger_error($user->lang['NO_LANG_ID'] . adm_back_link($this->u_action), E_USER_WARNING); } $sql = 'SELECT * FROM ' . LANG_TABLE . "\n\t\t\t\t\tWHERE lang_id = {$lang_id}"; $result = $db->sql_query($sql); $row = $db->sql_fetchrow($result); $db->sql_freeresult($result); $sql_ary = array('lang_english_name' => request_var('lang_english_name', $row['lang_english_name']), 'lang_local_name' => utf8_normalize_nfc(request_var('lang_local_name', $row['lang_local_name'], true)), 'lang_author' => utf8_normalize_nfc(request_var('lang_author', $row['lang_author'], true))); $db->sql_query('UPDATE ' . LANG_TABLE . ' SET ' . $db->sql_build_array('UPDATE', $sql_ary) . ' WHERE lang_id = ' . $lang_id); add_log('admin', 'LOG_LANGUAGE_PACK_UPDATED', $sql_ary['lang_english_name']); trigger_error($user->lang['LANGUAGE_DETAILS_UPDATED'] . adm_back_link($this->u_action)); break; case 'submit_file': case 'download_file': case 'upload_data': if (!$submit || !check_form_key($form_name)) { trigger_error($user->lang['FORM_INVALID'] . adm_back_link($this->u_action), E_USER_WARNING); } if (!$lang_id || empty($_POST['entry'])) { trigger_error($user->lang['NO_LANG_ID'] . adm_back_link($this->u_action), E_USER_WARNING); } if ($this->language_directory != 'email' && !is_array($_POST['entry'])) { trigger_error($user->lang['NO_LANG_ID'] . adm_back_link($this->u_action), E_USER_WARNING); } if (!$this->language_file || !$this->language_directory && !in_array($this->language_file, $this->main_files)) { trigger_error($user->lang['NO_FILE_SELECTED'] . adm_back_link($this->u_action), E_USER_WARNING); } $sql = 'SELECT * FROM ' . LANG_TABLE . "\n\t\t\t\t\tWHERE lang_id = {$lang_id}"; $result = $db->sql_query($sql); $row = $db->sql_fetchrow($result); $db->sql_freeresult($result); if (!$row) { trigger_error($user->lang['NO_LANG_ID'] . adm_back_link($this->u_action), E_USER_WARNING); } // Before we attempt to write anything let's check if the admin really chose a correct filename switch ($this->language_directory) { case 'email': // Get email templates $email_files = filelist($phpbb_root_path . 'language/' . $row['lang_iso'], 'email', 'txt'); $email_files = $email_files['email/']; if (!in_array($this->language_file, $email_files)) { trigger_error($user->lang['WRONG_LANGUAGE_FILE'] . adm_back_link($this->u_action . '&action=details&id=' . $lang_id), E_USER_WARNING); } break; case 'acp': // Get acp files $acp_files = filelist($phpbb_root_path . 'language/' . $row['lang_iso'], 'acp', $phpEx); $acp_files = $acp_files['acp/']; if (!in_array($this->language_file, $acp_files)) { trigger_error($user->lang['WRONG_LANGUAGE_FILE'] . adm_back_link($this->u_action . '&action=details&id=' . $lang_id), E_USER_WARNING); } break; case 'mods': // Get mod files $mods_files = filelist($phpbb_root_path . 'language/' . $row['lang_iso'], 'mods', $phpEx); $mods_files = isset($mods_files['mods/']) ? $mods_files['mods/'] : array(); if (!in_array($this->language_file, $mods_files)) { trigger_error($user->lang['WRONG_LANGUAGE_FILE'] . adm_back_link($this->u_action . '&action=details&id=' . $lang_id), E_USER_WARNING); } break; default: if (!in_array($this->language_file, $this->main_files)) { trigger_error($user->lang['WRONG_LANGUAGE_FILE'] . adm_back_link($this->u_action . '&action=details&id=' . $lang_id), E_USER_WARNING); } break; } if (!$safe_mode) { $mkdir_ary = array('language', 'language/' . $row['lang_iso']); if ($this->language_directory) { $mkdir_ary[] = 'language/' . $row['lang_iso'] . '/' . $this->language_directory; } foreach ($mkdir_ary as $dir) { $dir = $phpbb_root_path . 'store/' . $dir; if (!is_dir($dir)) { if (!@mkdir($dir, 0777)) { trigger_error("Could not create directory {$dir}", E_USER_ERROR); } @chmod($dir, 0777); } } } // Get target filename for storage folder $filename = $this->get_filename($row['lang_iso'], $this->language_directory, $this->language_file, true, true); $fp = @fopen($phpbb_root_path . $filename, 'wb'); if (!$fp) { trigger_error(sprintf($user->lang['UNABLE_TO_WRITE_FILE'], $filename) . adm_back_link($this->u_action . '&id=' . $lang_id . '&action=details&language_file=' . urlencode($selected_lang_file)), E_USER_WARNING); } if ($this->language_directory == 'email') { // Email Template $entry = $this->prepare_lang_entry($_POST['entry'], false); fwrite($fp, $entry); } else { $name = ($this->language_directory ? $this->language_directory . '_' : '') . $this->language_file; $header = str_replace(array('{FILENAME}', '{LANG_NAME}', '{CHANGED}', '{AUTHOR}'), array($name, $row['lang_english_name'], date('Y-m-d', time()), $row['lang_author']), $this->language_file_header); if (strpos($this->language_file, 'help_') === 0) { // Help File $header .= '$help = array(' . "\n"; fwrite($fp, $header); foreach ($_POST['entry'] as $key => $value) { if (!is_array($value)) { continue; } $entry = "\tarray(\n"; foreach ($value as $_key => $_value) { $entry .= "\t\t" . (int) $_key . "\t=> '" . $this->prepare_lang_entry($_value) . "',\n"; } $entry .= "\t),\n"; fwrite($fp, $entry); } $footer = ");\n\n?>"; fwrite($fp, $footer); } else { // Language File $header .= $this->lang_header; fwrite($fp, $header); foreach ($_POST['entry'] as $key => $value) { $entry = $this->format_lang_array($key, $value); fwrite($fp, $entry); } $footer = "));\n\n?>"; fwrite($fp, $footer); } } fclose($fp); if ($action == 'download_file') { header('Pragma: no-cache'); header('Content-Type: application/octetstream; name="' . $this->language_file . '"'); header('Content-disposition: attachment; filename=' . $this->language_file); $fp = @fopen($phpbb_root_path . $filename, 'rb'); while ($buffer = fread($fp, 1024)) { echo $buffer; } fclose($fp); add_log('admin', 'LOG_LANGUAGE_FILE_SUBMITTED', $this->language_file); exit; } else { if ($action == 'upload_data') { $sql = 'SELECT lang_iso FROM ' . LANG_TABLE . "\n\t\t\t\t\t\tWHERE lang_id = {$lang_id}"; $result = $db->sql_query($sql); $row = $db->sql_fetchrow($result); $db->sql_freeresult($result); $file = request_var('file', ''); $dir = request_var('dir', ''); $selected_lang_file = $dir . '|' . $file; $old_file = '/' . $this->get_filename($row['lang_iso'], $dir, $file, false, true); $lang_path = 'language/' . $row['lang_iso'] . '/' . ($dir ? $dir . '/' : ''); include_once $phpbb_root_path . 'includes/functions_transfer.' . $phpEx; $method = request_var('method', ''); if ($method != 'ftp' && $method != 'ftp_fsock') { trigger_error($user->lang['INVALID_UPLOAD_METHOD'], E_USER_ERROR); } $transfer = new $method(request_var('host', ''), request_var('username', ''), request_var('password', ''), request_var('root_path', ''), request_var('port', ''), request_var('timeout', '')); if (($result = $transfer->open_session()) !== true) { trigger_error($user->lang[$result] . adm_back_link($this->u_action . '&action=details&id=' . $lang_id . '&language_file=' . urlencode($selected_lang_file)), E_USER_WARNING); } $transfer->rename($lang_path . $file, $lang_path . $file . '.bak'); $result = $transfer->copy_file('store/' . $lang_path . $file, $lang_path . $file); if ($result === false) { // If failed, try to rename again and print error out... $transfer->delete_file($lang_path . $file); $transfer->rename($lang_path . $file . '.bak', $lang_path . $file); trigger_error($user->lang['UPLOAD_FAILED'] . adm_back_link($this->u_action . '&action=details&id=' . $lang_id . '&language_file=' . urlencode($selected_lang_file)), E_USER_WARNING); } $transfer->close_session(); // Remove from storage folder if (file_exists($phpbb_root_path . 'store/' . $lang_path . $file)) { @unlink($phpbb_root_path . 'store/' . $lang_path . $file); } add_log('admin', 'LOG_LANGUAGE_FILE_REPLACED', $file); trigger_error($user->lang['UPLOAD_COMPLETED'] . adm_back_link($this->u_action . '&action=details&id=' . $lang_id . '&language_file=' . urlencode($selected_lang_file))); } } add_log('admin', 'LOG_LANGUAGE_FILE_SUBMITTED', $this->language_file); $action = 'details'; // no break; // no break; case 'details': if (!$lang_id) { trigger_error($user->lang['NO_LANG_ID'] . adm_back_link($this->u_action), E_USER_WARNING); } $this->page_title = 'LANGUAGE_PACK_DETAILS'; $sql = 'SELECT * FROM ' . LANG_TABLE . ' WHERE lang_id = ' . $lang_id; $result = $db->sql_query($sql); $lang_entries = $db->sql_fetchrow($result); $db->sql_freeresult($result); $lang_iso = $lang_entries['lang_iso']; $missing_vars = $missing_files = array(); // Get email templates $email_files = filelist($phpbb_root_path . 'language/' . $config['default_lang'], 'email', 'txt'); $email_files = $email_files['email/']; // Get acp files $acp_files = filelist($phpbb_root_path . 'language/' . $config['default_lang'], 'acp', $phpEx); $acp_files = $acp_files['acp/']; // Get mod files $mods_files = filelist($phpbb_root_path . 'language/' . $config['default_lang'], 'mods', $phpEx); $mods_files = isset($mods_files['mods/']) ? $mods_files['mods/'] : array(); // Check if our current filename matches the files switch ($this->language_directory) { case 'email': if (!in_array($this->language_file, $email_files)) { trigger_error($user->lang['WRONG_LANGUAGE_FILE'] . adm_back_link($this->u_action . '&action=details&id=' . $lang_id), E_USER_WARNING); } break; case 'acp': if (!in_array($this->language_file, $acp_files)) { trigger_error($user->lang['WRONG_LANGUAGE_FILE'] . adm_back_link($this->u_action . '&action=details&id=' . $lang_id), E_USER_WARNING); } break; case 'mods': if (!in_array($this->language_file, $mods_files)) { trigger_error($user->lang['WRONG_LANGUAGE_FILE'] . adm_back_link($this->u_action . '&action=details&id=' . $lang_id), E_USER_WARNING); } break; default: if (!in_array($this->language_file, $this->main_files)) { trigger_error($user->lang['WRONG_LANGUAGE_FILE'] . adm_back_link($this->u_action . '&action=details&id=' . $lang_id), E_USER_WARNING); } } if (isset($_POST['remove_store'])) { $store_filename = $this->get_filename($lang_iso, $this->language_directory, $this->language_file, true, true); if (file_exists($phpbb_root_path . $store_filename)) { @unlink($phpbb_root_path . $store_filename); } } include_once $phpbb_root_path . 'includes/functions_transfer.' . $phpEx; $methods = transfer::methods(); foreach ($methods as $method) { $template->assign_block_vars('buttons', array('VALUE' => $method)); } $template->assign_vars(array('S_DETAILS' => true, 'U_ACTION' => $this->u_action . "&action=details&id={$lang_id}", 'U_BACK' => $this->u_action, 'LANG_LOCAL_NAME' => $lang_entries['lang_local_name'], 'LANG_ENGLISH_NAME' => $lang_entries['lang_english_name'], 'LANG_ISO' => $lang_entries['lang_iso'], 'LANG_AUTHOR' => $lang_entries['lang_author'], 'ALLOW_UPLOAD' => sizeof($methods))); // If current lang is different from the default lang, then first try to grab missing/additional vars if ($lang_iso != $config['default_lang']) { $is_missing_var = false; foreach ($this->main_files as $file) { if (file_exists($phpbb_root_path . $this->get_filename($lang_iso, '', $file))) { $missing_vars[$file] = $this->compare_language_files($config['default_lang'], $lang_iso, '', $file); if (sizeof($missing_vars[$file])) { $is_missing_var = true; } } else { $missing_files[] = $this->get_filename($lang_iso, '', $file); } } // Now go through acp/mods directories foreach ($acp_files as $file) { if (file_exists($phpbb_root_path . $this->get_filename($lang_iso, 'acp', $file))) { $missing_vars['acp/' . $file] = $this->compare_language_files($config['default_lang'], $lang_iso, 'acp', $file); if (sizeof($missing_vars['acp/' . $file])) { $is_missing_var = true; } } else { $missing_files[] = $this->get_filename($lang_iso, 'acp', $file); } } if (sizeof($mods_files)) { foreach ($mods_files as $file) { if (file_exists($phpbb_root_path . $this->get_filename($lang_iso, 'mods', $file))) { $missing_vars['mods/' . $file] = $this->compare_language_files($config['default_lang'], $lang_iso, 'mods', $file); if (sizeof($missing_vars['mods/' . $file])) { $is_missing_var = true; } } else { $missing_files[] = $this->get_filename($lang_iso, 'mods', $file); } } } // More missing files... for example email templates? foreach ($email_files as $file) { if (!file_exists($phpbb_root_path . $this->get_filename($lang_iso, 'email', $file))) { $missing_files[] = $this->get_filename($lang_iso, 'email', $file); } } if (sizeof($missing_files)) { $template->assign_vars(array('S_MISSING_FILES' => true, 'L_MISSING_FILES' => sprintf($user->lang['THOSE_MISSING_LANG_FILES'], $lang_entries['lang_local_name']), 'MISSING_FILES' => implode('<br />', $missing_files))); } if ($is_missing_var) { $template->assign_vars(array('S_MISSING_VARS' => true, 'L_MISSING_VARS_EXPLAIN' => sprintf($user->lang['THOSE_MISSING_LANG_VARIABLES'], $lang_entries['lang_local_name']), 'U_MISSING_ACTION' => $this->u_action . "&action={$action}&id={$lang_id}")); foreach ($missing_vars as $file => $vars) { if (!sizeof($vars)) { continue; } $template->assign_block_vars('missing', array('FILE' => $file, 'TPL' => $this->print_language_entries($vars, '', false), 'KEY' => strpos($file, '/') === false ? '|' . $file : str_replace('/', '|', $file))); } } } // Main language files $s_lang_options = '<option value="|common.' . $phpEx . '" class="sep">' . $user->lang['LANGUAGE_FILES'] . '</option>'; foreach ($this->main_files as $file) { if (strpos($file, 'help_') === 0) { continue; } $prefix = file_exists($phpbb_root_path . $this->get_filename($lang_iso, '', $file, true, true)) ? '* ' : ''; $selected = !$this->language_directory && $this->language_file == $file ? ' selected="selected"' : ''; $s_lang_options .= '<option value="|' . $file . '"' . $selected . '>' . $prefix . $file . '</option>'; } // Help Files $s_lang_options .= '<option value="|common.' . $phpEx . '" class="sep">' . $user->lang['HELP_FILES'] . '</option>'; foreach ($this->main_files as $file) { if (strpos($file, 'help_') !== 0) { continue; } $prefix = file_exists($phpbb_root_path . $this->get_filename($lang_iso, '', $file, true, true)) ? '* ' : ''; $selected = !$this->language_directory && $this->language_file == $file ? ' selected="selected"' : ''; $s_lang_options .= '<option value="|' . $file . '"' . $selected . '>' . $prefix . $file . '</option>'; } // Now every other language directory $check_files = array('email', 'acp', 'mods'); foreach ($check_files as $check) { if (!sizeof(${$check . '_files'})) { continue; } $s_lang_options .= '<option value="|common.' . $phpEx . '" class="sep">' . $user->lang[strtoupper($check) . '_FILES'] . '</option>'; foreach (${$check . '_files'} as $file) { $prefix = file_exists($phpbb_root_path . $this->get_filename($lang_iso, $check, $file, true, true)) ? '* ' : ''; $selected = $this->language_directory == $check && $this->language_file == $file ? ' selected="selected"' : ''; $s_lang_options .= '<option value="' . $check . '|' . $file . '"' . $selected . '>' . $prefix . $file . '</option>'; } } // Get Language Entries - if saved within store folder, we take this one (with the option to remove it) $lang = array(); $is_email_file = $this->language_directory == 'email' ? true : false; $is_help_file = strpos($this->language_file, 'help_') === 0 ? true : false; $file_from_store = file_exists($phpbb_root_path . $this->get_filename($lang_iso, $this->language_directory, $this->language_file, true, true)) ? true : false; $no_store_filename = $this->get_filename($lang_iso, $this->language_directory, $this->language_file); if (!$file_from_store && !file_exists($phpbb_root_path . $no_store_filename)) { $print_message = sprintf($user->lang['MISSING_LANGUAGE_FILE'], $no_store_filename); } else { if ($is_email_file) { $lang = file_get_contents($phpbb_root_path . $this->get_filename($lang_iso, $this->language_directory, $this->language_file, $file_from_store)); } else { $help = array(); include $phpbb_root_path . $this->get_filename($lang_iso, $this->language_directory, $this->language_file, $file_from_store); if ($is_help_file) { $lang = $help; unset($help); } } $print_message = ($this->language_directory ? $this->language_directory . '/' : '') . $this->language_file; } // Normal language pack entries $template->assign_vars(array('U_ENTRY_ACTION' => $this->u_action . "&action=details&id={$lang_id}#entries", 'S_EMAIL_FILE' => $is_email_file, 'S_FROM_STORE' => $file_from_store, 'S_LANG_OPTIONS' => $s_lang_options, 'PRINT_MESSAGE' => $print_message)); if (!$is_email_file) { $tpl = ''; $name = ($this->language_directory ? $this->language_directory . '/' : '') . $this->language_file; if (isset($missing_vars[$name]) && sizeof($missing_vars[$name])) { $tpl .= $this->print_language_entries($missing_vars[$name], '* '); } $tpl .= $this->print_language_entries($lang); $template->assign_var('TPL', $tpl); unset($tpl); } else { $template->assign_vars(array('LANG' => $lang)); unset($lang); } return; break; case 'delete': if (!$lang_id) { trigger_error($user->lang['NO_LANG_ID'] . adm_back_link($this->u_action), E_USER_WARNING); } $sql = 'SELECT * FROM ' . LANG_TABLE . ' WHERE lang_id = ' . $lang_id; $result = $db->sql_query($sql); $row = $db->sql_fetchrow($result); $db->sql_freeresult($result); if ($row['lang_iso'] == $config['default_lang']) { trigger_error($user->lang['NO_REMOVE_DEFAULT_LANG'] . adm_back_link($this->u_action), E_USER_WARNING); } if (confirm_box(true)) { $db->sql_query('DELETE FROM ' . LANG_TABLE . ' WHERE lang_id = ' . $lang_id); $sql = 'UPDATE ' . USERS_TABLE . "\n\t\t\t\t\t\tSET user_lang = '" . $db->sql_escape($config['default_lang']) . "'\n\t\t\t\t\t\tWHERE user_lang = '" . $db->sql_escape($row['lang_iso']) . "'"; $db->sql_query($sql); // We also need to remove the translated entries for custom profile fields - we want clean tables, don't we? $sql = 'DELETE FROM ' . PROFILE_LANG_TABLE . ' WHERE lang_id = ' . $lang_id; $db->sql_query($sql); $sql = 'DELETE FROM ' . PROFILE_FIELDS_LANG_TABLE . ' WHERE lang_id = ' . $lang_id; $db->sql_query($sql); $sql = 'DELETE FROM ' . STYLES_IMAGESET_DATA_TABLE . " WHERE image_lang = '" . $db->sql_escape($row['lang_iso']) . "'"; $result = $db->sql_query($sql); $cache->destroy('sql', STYLES_IMAGESET_DATA_TABLE); add_log('admin', 'LOG_LANGUAGE_PACK_DELETED', $row['lang_english_name']); trigger_error(sprintf($user->lang['LANGUAGE_PACK_DELETED'], $row['lang_english_name']) . adm_back_link($this->u_action)); } else { $s_hidden_fields = array('i' => $id, 'mode' => $mode, 'action' => $action, 'id' => $lang_id); confirm_box(false, $user->lang['CONFIRM_OPERATION'], build_hidden_fields($s_hidden_fields)); } break; case 'install': $lang_iso = request_var('iso', ''); $lang_iso = basename($lang_iso); if (!$lang_iso || !file_exists("{$phpbb_root_path}language/{$lang_iso}/iso.txt")) { trigger_error($user->lang['LANGUAGE_PACK_NOT_EXIST'] . adm_back_link($this->u_action), E_USER_WARNING); } $file = file("{$phpbb_root_path}language/{$lang_iso}/iso.txt"); $lang_pack = array('iso' => $lang_iso, 'name' => trim(htmlspecialchars($file[0])), 'local_name' => trim(htmlspecialchars($file[1], ENT_COMPAT, 'UTF-8')), 'author' => trim(htmlspecialchars($file[2], ENT_COMPAT, 'UTF-8'))); unset($file); $sql = 'SELECT lang_iso FROM ' . LANG_TABLE . "\n\t\t\t\t\tWHERE lang_iso = '" . $db->sql_escape($lang_iso) . "'"; $result = $db->sql_query($sql); $row = $db->sql_fetchrow($result); $db->sql_freeresult($result); if ($row) { trigger_error($user->lang['LANGUAGE_PACK_ALREADY_INSTALLED'] . adm_back_link($this->u_action), E_USER_WARNING); } if (!$lang_pack['name'] || !$lang_pack['local_name']) { trigger_error($user->lang['INVALID_LANGUAGE_PACK'] . adm_back_link($this->u_action), E_USER_WARNING); } // Add language pack $sql_ary = array('lang_iso' => $lang_pack['iso'], 'lang_dir' => $lang_pack['iso'], 'lang_english_name' => $lang_pack['name'], 'lang_local_name' => $lang_pack['local_name'], 'lang_author' => $lang_pack['author']); $db->sql_query('INSERT INTO ' . LANG_TABLE . ' ' . $db->sql_build_array('INSERT', $sql_ary)); $lang_id = $db->sql_nextid(); $valid_localized = array('icon_back_top', 'icon_contact_aim', 'icon_contact_email', 'icon_contact_icq', 'icon_contact_jabber', 'icon_contact_msnm', 'icon_contact_pm', 'icon_contact_yahoo', 'icon_contact_www', 'icon_post_delete', 'icon_post_edit', 'icon_post_info', 'icon_post_quote', 'icon_post_report', 'icon_user_online', 'icon_user_offline', 'icon_user_profile', 'icon_user_search', 'icon_user_warn', 'button_pm_forward', 'button_pm_new', 'button_pm_reply', 'button_topic_locked', 'button_topic_new', 'button_topic_reply'); $sql_ary = array(); $sql = 'SELECT * FROM ' . STYLES_IMAGESET_TABLE; $result = $db->sql_query($sql); while ($imageset_row = $db->sql_fetchrow($result)) { if (@file_exists("{$phpbb_root_path}styles/{$imageset_row['imageset_path']}/imageset/{$lang_pack['iso']}/imageset.cfg")) { $cfg_data_imageset_data = parse_cfg_file("{$phpbb_root_path}styles/{$imageset_row['imageset_path']}/imageset/{$lang_pack['iso']}/imageset.cfg"); foreach ($cfg_data_imageset_data as $image_name => $value) { if (strpos($value, '*') !== false) { if (substr($value, -1, 1) === '*') { list($image_filename, $image_height) = explode('*', $value); $image_width = 0; } else { list($image_filename, $image_height, $image_width) = explode('*', $value); } } else { $image_filename = $value; $image_height = $image_width = 0; } if (strpos($image_name, 'img_') === 0 && $image_filename) { $image_name = substr($image_name, 4); if (in_array($image_name, $valid_localized)) { $sql_ary[] = array('image_name' => (string) $image_name, 'image_filename' => (string) $image_filename, 'image_height' => (int) $image_height, 'image_width' => (int) $image_width, 'imageset_id' => (int) $imageset_row['imageset_id'], 'image_lang' => (string) $lang_pack['iso']); } } } } } $db->sql_freeresult($result); if (sizeof($sql_ary)) { $db->sql_multi_insert(STYLES_IMAGESET_DATA_TABLE, $sql_ary); $cache->destroy('sql', STYLES_IMAGESET_DATA_TABLE); } // Now let's copy the default language entries for custom profile fields for this new language - makes admin's life easier. $sql = 'SELECT lang_id FROM ' . LANG_TABLE . "\n\t\t\t\t\tWHERE lang_iso = '" . $db->sql_escape($config['default_lang']) . "'"; $result = $db->sql_query($sql); $default_lang_id = (int) $db->sql_fetchfield('lang_id'); $db->sql_freeresult($result); // From the mysql documentation: // Prior to MySQL 4.0.14, the target table of the INSERT statement cannot appear in the FROM clause of the SELECT part of the query. This limitation is lifted in 4.0.14. // Due to this we stay on the safe side if we do the insertion "the manual way" $sql = 'SELECT field_id, lang_name, lang_explain, lang_default_value FROM ' . PROFILE_LANG_TABLE . ' WHERE lang_id = ' . $default_lang_id; $result = $db->sql_query($sql); while ($row = $db->sql_fetchrow($result)) { $row['lang_id'] = $lang_id; $db->sql_query('INSERT INTO ' . PROFILE_LANG_TABLE . ' ' . $db->sql_build_array('INSERT', $row)); } $db->sql_freeresult($result); $sql = 'SELECT field_id, option_id, field_type, lang_value FROM ' . PROFILE_FIELDS_LANG_TABLE . ' WHERE lang_id = ' . $default_lang_id; $result = $db->sql_query($sql); while ($row = $db->sql_fetchrow($result)) { $row['lang_id'] = $lang_id; $db->sql_query('INSERT INTO ' . PROFILE_FIELDS_LANG_TABLE . ' ' . $db->sql_build_array('INSERT', $row)); } $db->sql_freeresult($result); add_log('admin', 'LOG_LANGUAGE_PACK_INSTALLED', $lang_pack['name']); trigger_error(sprintf($user->lang['LANGUAGE_PACK_INSTALLED'], $lang_pack['name']) . adm_back_link($this->u_action)); break; case 'download': if (!$lang_id) { trigger_error($user->lang['NO_LANG_ID'] . adm_back_link($this->u_action), E_USER_WARNING); } $sql = 'SELECT * FROM ' . LANG_TABLE . ' WHERE lang_id = ' . $lang_id; $result = $db->sql_query($sql); $row = $db->sql_fetchrow($result); $db->sql_freeresult($result); $use_method = request_var('use_method', ''); $methods = array('.tar'); $available_methods = array('.tar.gz' => 'zlib', '.tar.bz2' => 'bz2', '.zip' => 'zlib'); foreach ($available_methods as $type => $module) { if (!@extension_loaded($module)) { continue; } $methods[] = $type; } // Let the user decide in which format he wants to have the pack if (!$use_method) { $this->page_title = 'SELECT_DOWNLOAD_FORMAT'; $radio_buttons = ''; foreach ($methods as $method) { $radio_buttons .= '<label><input type="radio"' . (!$radio_buttons ? ' id="use_method"' : '') . ' class="radio" value="' . $method . '" name="use_method" /> ' . $method . '</label>'; } $template->assign_vars(array('S_SELECT_METHOD' => true, 'U_BACK' => $this->u_action, 'U_ACTION' => $this->u_action . "&action={$action}&id={$lang_id}", 'RADIO_BUTTONS' => $radio_buttons)); return; } if (!in_array($use_method, $methods)) { $use_method = '.tar'; } include_once $phpbb_root_path . 'includes/functions_compress.' . $phpEx; if ($use_method == '.zip') { $compress = new compress_zip('w', $phpbb_root_path . 'store/lang_' . $row['lang_iso'] . $use_method); } else { $compress = new compress_tar('w', $phpbb_root_path . 'store/lang_' . $row['lang_iso'] . $use_method, $use_method); } // Get email templates $email_templates = filelist($phpbb_root_path . 'language/' . $row['lang_iso'], 'email', 'txt'); $email_templates = $email_templates['email/']; // Get acp files $acp_files = filelist($phpbb_root_path . 'language/' . $row['lang_iso'], 'acp', $phpEx); $acp_files = $acp_files['acp/']; // Get mod files $mod_files = filelist($phpbb_root_path . 'language/' . $row['lang_iso'], 'mods', $phpEx); $mod_files = isset($mod_files['mods/']) ? $mod_files['mods/'] : array(); // Add main files $this->add_to_archive($compress, $this->main_files, $row['lang_iso']); // Add search files if they exist... if (file_exists($phpbb_root_path . 'language/' . $row['lang_iso'] . '/search_ignore_words.' . $phpEx)) { $this->add_to_archive($compress, array("search_ignore_words.{$phpEx}"), $row['lang_iso']); } if (file_exists($phpbb_root_path . 'language/' . $row['lang_iso'] . '/search_synonyms.' . $phpEx)) { $this->add_to_archive($compress, array("search_synonyms.{$phpEx}"), $row['lang_iso']); } // Write files in folders $this->add_to_archive($compress, $email_templates, $row['lang_iso'], 'email'); $this->add_to_archive($compress, $acp_files, $row['lang_iso'], 'acp'); $this->add_to_archive($compress, $mod_files, $row['lang_iso'], 'mods'); // Write ISO File $iso_src = htmlspecialchars_decode($row['lang_english_name']) . "\n"; $iso_src .= htmlspecialchars_decode($row['lang_local_name']) . "\n"; $iso_src .= htmlspecialchars_decode($row['lang_author']); $compress->add_data($iso_src, 'language/' . $row['lang_iso'] . '/iso.txt'); // index.html files $compress->add_data('', 'language/' . $row['lang_iso'] . '/index.html'); $compress->add_data('', 'language/' . $row['lang_iso'] . '/email/index.html'); $compress->add_data('', 'language/' . $row['lang_iso'] . '/acp/index.html'); if (sizeof($mod_files)) { $compress->add_data('', 'language/' . $row['lang_iso'] . '/mods/index.html'); } $compress->close(); $compress->download('lang_' . $row['lang_iso']); @unlink($phpbb_root_path . 'store/lang_' . $row['lang_iso'] . $use_method); exit; break; } $sql = 'SELECT user_lang, COUNT(user_lang) AS lang_count FROM ' . USERS_TABLE . ' GROUP BY user_lang'; $result = $db->sql_query($sql); $lang_count = array(); while ($row = $db->sql_fetchrow($result)) { $lang_count[$row['user_lang']] = $row['lang_count']; } $db->sql_freeresult($result); $sql = 'SELECT * FROM ' . LANG_TABLE . ' ORDER BY lang_english_name'; $result = $db->sql_query($sql); $installed = array(); while ($row = $db->sql_fetchrow($result)) { $installed[] = $row['lang_iso']; $tagstyle = $row['lang_iso'] == $config['default_lang'] ? '*' : ''; $template->assign_block_vars('lang', array('U_DETAILS' => $this->u_action . "&action=details&id={$row['lang_id']}", 'U_DOWNLOAD' => $this->u_action . "&action=download&id={$row['lang_id']}", 'U_DELETE' => $this->u_action . "&action=delete&id={$row['lang_id']}", 'ENGLISH_NAME' => $row['lang_english_name'], 'TAG' => $tagstyle, 'LOCAL_NAME' => $row['lang_local_name'], 'ISO' => $row['lang_iso'], 'USED_BY' => isset($lang_count[$row['lang_iso']]) ? $lang_count[$row['lang_iso']] : 0)); } $db->sql_freeresult($result); $new_ary = $iso = array(); $dp = @opendir("{$phpbb_root_path}language"); if ($dp) { while (($file = readdir($dp)) !== false) { if ($file[0] != '.' && file_exists("{$phpbb_root_path}language/{$file}/iso.txt")) { if (!in_array($file, $installed)) { if ($iso = file("{$phpbb_root_path}language/{$file}/iso.txt")) { if (sizeof($iso) == 3) { $new_ary[$file] = array('iso' => $file, 'name' => trim($iso[0]), 'local_name' => trim($iso[1]), 'author' => trim($iso[2])); } } } } } closedir($dp); } unset($installed); if (sizeof($new_ary)) { foreach ($new_ary as $iso => $lang_ary) { $template->assign_block_vars('notinst', array('ISO' => htmlspecialchars($lang_ary['iso']), 'LOCAL_NAME' => htmlspecialchars($lang_ary['local_name'], ENT_COMPAT, 'UTF-8'), 'NAME' => htmlspecialchars($lang_ary['name'], ENT_COMPAT, 'UTF-8'), 'U_INSTALL' => $this->u_action . '&action=install&iso=' . urlencode($lang_ary['iso']))); } } unset($new_ary); }
set_time_limit(0); error_reporting(E_ALL ^ E_NOTICE); include_once "../config/config.php"; $link = mysql_connect(DB_HOST, DB_USER, DB_PASSWORD); mysql_select_db(DB_NAME); mysql_query("set names utf8"); ?> <html> <head> <title>ShopEx数据转换程序</title> <META HTTP-EQUIV="content-type" CONTENT="text/html; charset=UTF-8"> </head> <body style="font-size:16px;"> <?php $do = new transfer(); // $do->goodsCategory(); $do->goodsBrand(); $do->goodsDetail(); $do->relaGoods(); $do->goodsImage(); $do->goodsComment(); // $do->memberLevel(); $do->memberDetail(); class transfer { function goodsCategory() { //情况商品分类表
function main($mode, $sub) { global $template, $phpEx, $phpbb_root_path, $user, $db, $config, $cache, $auth; $this->tpl_name = 'install_update'; $this->page_title = 'UPDATE_INSTALLATION'; $this->unequal_version = false; $this->old_location = $phpbb_root_path . 'install/update/old/'; $this->new_location = $phpbb_root_path . 'install/update/new/'; // Init DB require($phpbb_root_path . 'config.' . $phpEx); require($phpbb_root_path . 'includes/db/' . $dbms . '.' . $phpEx); require($phpbb_root_path . 'includes/constants.' . $phpEx); // Special options for conflicts/modified files define('MERGE_NO_MERGE_NEW', 1); define('MERGE_NO_MERGE_MOD', 2); define('MERGE_NEW_FILE', 3); define('MERGE_MOD_FILE', 4); $db = new $sql_db(); // Connect to DB $db->sql_connect($dbhost, $dbuser, $dbpasswd, $dbname, $dbport, false, false); // We do not need this any longer, unset for safety purposes unset($dbpasswd); $config = array(); $sql = 'SELECT config_name, config_value FROM ' . CONFIG_TABLE; $result = $db->sql_query($sql); while ($row = $db->sql_fetchrow($result)) { $config[$row['config_name']] = $row['config_value']; } $db->sql_freeresult($result); // Force template recompile $config['load_tplcompile'] = 1; // First of all, init the user session $user->session_begin(); $auth->acl($user->data); $user->setup('install'); // If we are within the intro page we need to make sure we get up-to-date version info if ($sub == 'intro') { $cache->destroy('_version_info'); } // Set custom template again. ;) $template->set_custom_template('../adm/style', 'admin'); // still, the acp template is never stored in the database $user->theme['template_storedb'] = false; // Get current and latest version if (($latest_version = $cache->get('_version_info')) === false) { $this->latest_version = $this->get_file('version_info'); $cache->put('_version_info', $this->latest_version); } else { $this->latest_version = $latest_version; } // For the current version we trick a bit. ;) $this->current_version = (!empty($config['version_update_from'])) ? $config['version_update_from'] : $config['version']; $up_to_date = (version_compare(str_replace('rc', 'RC', strtolower($this->current_version)), str_replace('rc', 'RC', strtolower($this->latest_version)), '<')) ? false : true; // Check for a valid update directory, else point the user to the phpbb.com website 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)) { $template->assign_vars(array( 'S_ERROR' => true, '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)) ); return; } $this->update_info = $this->get_file('update_info'); // Make sure the update directory holds the correct information // 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. if (version_compare(str_replace('rc', 'RC', strtolower($this->current_version)), str_replace('rc', 'RC', strtolower($this->update_info['version']['to'])), '>')) { $template->assign_vars(array( 'S_ERROR' => true, 'ERROR_MSG' => sprintf($user->lang['INCOMPATIBLE_UPDATE_FILES'], $config['version'], $this->update_info['version']['from'], $this->update_info['version']['to'])) ); return; } // Check if the update files stored are for the latest version... if ($this->latest_version != $this->update_info['version']['to']) { $this->unequal_version = true; $template->assign_vars(array( 'S_WARNING' => true, 'WARNING_MSG' => sprintf($user->lang['OLD_UPDATE_FILES'], $this->update_info['version']['from'], $this->update_info['version']['to'], $this->latest_version)) ); } if ($this->test_update === false) { // Got the updater template itself updated? If so, we are able to directly use it - but only if all three files are present if (in_array('adm/style/install_update.html', $this->update_info['files'])) { $this->tpl_name = '../../install/update/new/adm/style/install_update'; } // What about the language file? Got it updated? if (in_array('language/en/install.php', $this->update_info['files'])) { $lang = array(); include($this->new_location . 'language/en/install.php'); // only add new keys to user's language in english $new_keys = array_diff(array_keys($lang), array_keys($user->lang)); foreach ($new_keys as $i => $new_key) { $user->lang[$new_key] = $lang[$new_key]; } } } // Include renderer and engine $this->include_file('includes/diff/diff.' . $phpEx); $this->include_file('includes/diff/engine.' . $phpEx); $this->include_file('includes/diff/renderer.' . $phpEx); // Make sure we stay at the file check if checking the files again if (!empty($_POST['check_again'])) { $sub = $this->p_master->sub = 'file_check'; } switch ($sub) { case 'intro': $this->page_title = 'UPDATE_INSTALLATION'; $template->assign_vars(array( 'S_INTRO' => true, 'U_ACTION' => append_sid($this->p_master->module_url, "mode=$mode&sub=version_check"), )); // Make sure the update list is destroyed. $cache->destroy('_update_list'); $cache->destroy('_diff_files'); break; case 'version_check': $this->page_title = 'STAGE_VERSION_CHECK'; $template->assign_vars(array( 'S_UP_TO_DATE' => $up_to_date, 'S_VERSION_CHECK' => true, 'U_ACTION' => append_sid($this->p_master->module_url, "mode=$mode&sub=file_check"), 'U_DB_UPDATE_ACTION' => append_sid($this->p_master->module_url, "mode=$mode&sub=update_db"), 'LATEST_VERSION' => $this->latest_version, 'CURRENT_VERSION' => $this->current_version) ); // Print out version the update package updates to if ($this->unequal_version) { $template->assign_var('PACKAGE_VERSION', $this->update_info['version']['to']); } break; case 'update_db': // Make sure the database update is valid for the latest version $valid = false; $updates_to_version = ''; if (file_exists($phpbb_root_path . 'install/database_update.' . $phpEx)) { include_once($phpbb_root_path . 'install/database_update.' . $phpEx); if ($updates_to_version === $this->update_info['version']['to']) { $valid = true; } } // Should not happen at all if (!$valid) { trigger_error($user->lang['DATABASE_UPDATE_INFO_OLD'], E_USER_ERROR); } // Just a precaution $cache->purge(); // Redirect the user to the database update script with some explanations... $template->assign_vars(array( 'S_DB_UPDATE' => true, 'S_DB_UPDATE_FINISHED' => ($config['version'] == $this->update_info['version']['to']) ? true : false, 'U_DB_UPDATE' => append_sid($phpbb_root_path . 'install/database_update.' . $phpEx, 'type=1&language=' . $user->data['user_lang']), 'U_DB_UPDATE_ACTION' => append_sid($this->p_master->module_url, "mode=$mode&sub=update_db"), 'U_ACTION' => append_sid($this->p_master->module_url, "mode=$mode&sub=file_check"), )); break; case 'file_check': // Make sure the previous file collection is no longer valid... $cache->destroy('_diff_files'); $this->page_title = 'STAGE_FILE_CHECK'; // Now make sure our update list is correct if the admin refreshes $action = request_var('action', ''); // We are directly within an update. To make sure our update list is correct we check its status. $update_list = (!empty($_POST['check_again'])) ? false : $cache->get('_update_list'); $modified = ($update_list !== false) ? @filemtime($cache->cache_dir . 'data_update_list.' . $phpEx) : 0; // Make sure the list is up-to-date if ($update_list !== false) { $get_new_list = false; foreach ($this->update_info['files'] as $file) { if (file_exists($phpbb_root_path . $file) && filemtime($phpbb_root_path . $file) > $modified) { $get_new_list = true; break; } } } else { $get_new_list = true; } if (!$get_new_list && $update_list['status'] != -1) { $get_new_list = true; } if ($get_new_list) { $this->get_update_structure($update_list); $cache->put('_update_list', $update_list); // Refresh the page if we are still not finished... if ($update_list['status'] != -1) { $refresh_url = append_sid($this->p_master->module_url, "mode=$mode&sub=file_check"); meta_refresh(2, $refresh_url); $template->assign_vars(array( 'S_IN_PROGRESS' => true, 'S_COLLECTED' => (int) $update_list['status'], 'S_TO_COLLECT' => sizeof($this->update_info['files']), 'L_IN_PROGRESS' => $user->lang['COLLECTING_FILE_DIFFS'], 'L_IN_PROGRESS_EXPLAIN' => sprintf($user->lang['NUMBER_OF_FILES_COLLECTED'], (int) $update_list['status'], sizeof($this->update_info['files'])), )); return; } } if ($action == 'diff') { $this->show_diff($update_list); return; } if (sizeof($update_list['no_update'])) { $template->assign_vars(array( 'S_NO_UPDATE_FILES' => true, 'NO_UPDATE_FILES' => implode(', ', array_map('htmlspecialchars', $update_list['no_update']))) ); } // Now assign the list to the template foreach ($update_list as $status => $filelist) { if ($status == 'no_update' || !sizeof($filelist) || $status == 'status') { continue; } $template->assign_block_vars('files', array( 'S_STATUS' => true, 'STATUS' => $status, 'L_STATUS' => $user->lang['STATUS_' . strtoupper($status)], 'TITLE' => $user->lang['FILES_' . strtoupper($status)], 'EXPLAIN' => $user->lang['FILES_' . strtoupper($status) . '_EXPLAIN'], ) ); foreach ($filelist as $file_struct) { $s_binary = (!empty($this->update_info['binary']) && in_array($file_struct['filename'], $this->update_info['binary'])) ? true : false; $filename = htmlspecialchars($file_struct['filename']); if (strrpos($filename, '/') !== false) { $dir_part = substr($filename, 0, strrpos($filename, '/') + 1); $file_part = substr($filename, strrpos($filename, '/') + 1); } else { $dir_part = ''; $file_part = $filename; } $diff_url = append_sid($this->p_master->module_url, "mode=$mode&sub=file_check&action=diff&status=$status&file=" . urlencode($file_struct['filename'])); $template->assign_block_vars('files', array( 'STATUS' => $status, 'FILENAME' => $filename, 'DIR_PART' => $dir_part, 'FILE_PART' => $file_part, 'NUM_CONFLICTS' => (isset($file_struct['conflicts'])) ? $file_struct['conflicts'] : 0, 'S_CUSTOM' => ($file_struct['custom']) ? true : false, 'S_BINARY' => $s_binary, 'CUSTOM_ORIGINAL' => ($file_struct['custom']) ? $file_struct['original'] : '', 'U_SHOW_DIFF' => $diff_url, 'L_SHOW_DIFF' => ($status != 'up_to_date') ? $user->lang['SHOW_DIFF_' . strtoupper($status)] : '', 'U_VIEW_MOD_FILE' => $diff_url . '&op=' . MERGE_MOD_FILE, 'U_VIEW_NEW_FILE' => $diff_url . '&op=' . MERGE_NEW_FILE, 'U_VIEW_NO_MERGE_MOD' => $diff_url . '&op=' . MERGE_NO_MERGE_MOD, 'U_VIEW_NO_MERGE_NEW' => $diff_url . '&op=' . MERGE_NO_MERGE_NEW, )); } } $all_up_to_date = true; foreach ($update_list as $status => $filelist) { if ($status != 'up_to_date' && $status != 'custom' && $status != 'status' && sizeof($filelist)) { $all_up_to_date = false; break; } } $template->assign_vars(array( 'S_FILE_CHECK' => true, 'S_ALL_UP_TO_DATE' => $all_up_to_date, 'S_VERSION_UP_TO_DATE' => $up_to_date, 'U_ACTION' => append_sid($this->p_master->module_url, "mode=$mode&sub=file_check"), 'U_UPDATE_ACTION' => append_sid($this->p_master->module_url, "mode=$mode&sub=update_files"), 'U_DB_UPDATE_ACTION' => append_sid($this->p_master->module_url, "mode=$mode&sub=update_db"), )); if ($all_up_to_date) { // Add database update to log add_log('admin', 'LOG_UPDATE_PHPBB', $this->current_version, $this->latest_version); // Refresh prosilver css data - this may cause some unhappy users, but $sql = 'SELECT * FROM ' . STYLES_THEME_TABLE . " WHERE theme_name = 'prosilver'"; $result = $db->sql_query($sql); $theme = $db->sql_fetchrow($result); $db->sql_freeresult($result); if ($theme) { $recache = (empty($theme['theme_data'])) ? true : false; $update_time = time(); // We test for stylesheet.css because it is faster and most likely the only file changed on common themes if (!$recache && $theme['theme_mtime'] < @filemtime("{$phpbb_root_path}styles/" . $theme['theme_path'] . '/theme/stylesheet.css')) { $recache = true; $update_time = @filemtime("{$phpbb_root_path}styles/" . $theme['theme_path'] . '/theme/stylesheet.css'); } else if (!$recache) { $last_change = $theme['theme_mtime']; $dir = @opendir("{$phpbb_root_path}styles/{$theme['theme_path']}/theme"); if ($dir) { while (($entry = readdir($dir)) !== false) { if (substr(strrchr($entry, '.'), 1) == 'css' && $last_change < @filemtime("{$phpbb_root_path}styles/{$theme['theme_path']}/theme/{$entry}")) { $recache = true; break; } } closedir($dir); } } if ($recache) { include_once($phpbb_root_path . 'includes/acp/acp_styles.' . $phpEx); $theme['theme_data'] = acp_styles::db_theme_data($theme); $theme['theme_mtime'] = $update_time; // Save CSS contents $sql_ary = array( 'theme_mtime' => $theme['theme_mtime'], 'theme_data' => $theme['theme_data'] ); $sql = 'UPDATE ' . STYLES_THEME_TABLE . ' SET ' . $db->sql_build_array('UPDATE', $sql_ary) . ' WHERE theme_id = ' . $theme['theme_id']; $db->sql_query($sql); $cache->destroy('sql', STYLES_THEME_TABLE); } } $db->sql_return_on_error(true); $db->sql_query('DELETE FROM ' . CONFIG_TABLE . " WHERE config_name = 'version_update_from'"); $db->sql_return_on_error(false); $cache->purge(); } break; case 'update_files': $this->page_title = 'STAGE_UPDATE_FILES'; $s_hidden_fields = ''; $params = array(); $conflicts = request_var('conflict', array('' => 0)); $modified = request_var('modified', array('' => 0)); foreach ($conflicts as $filename => $merge_option) { $s_hidden_fields .= '<input type="hidden" name="conflict[' . htmlspecialchars($filename) . ']" value="' . $merge_option . '" />'; $params[] = 'conflict[' . urlencode($filename) . ']=' . urlencode($merge_option); } foreach ($modified as $filename => $merge_option) { if (!$merge_option) { continue; } $s_hidden_fields .= '<input type="hidden" name="modified[' . htmlspecialchars($filename) . ']" value="' . $merge_option . '" />'; $params[] = 'modified[' . urlencode($filename) . ']=' . urlencode($merge_option); } $no_update = request_var('no_update', array(0 => '')); foreach ($no_update as $index => $filename) { $s_hidden_fields .= '<input type="hidden" name="no_update[]" value="' . htmlspecialchars($filename) . '" />'; $params[] = 'no_update[]=' . urlencode($filename); } // Before the user is choosing his preferred method, let's create the content list... $update_list = $cache->get('_update_list'); if ($update_list === false) { trigger_error($user->lang['NO_UPDATE_INFO'], E_USER_ERROR); } // Check if the conflicts data is valid if (sizeof($conflicts)) { $conflict_filenames = array(); foreach ($update_list['conflict'] as $files) { $conflict_filenames[] = $files['filename']; } $new_conflicts = array(); foreach ($conflicts as $filename => $diff_method) { if (in_array($filename, $conflict_filenames)) { $new_conflicts[$filename] = $diff_method; } } $conflicts = $new_conflicts; } // Build list for modifications if (sizeof($modified)) { $modified_filenames = array(); foreach ($update_list['modified'] as $files) { $modified_filenames[] = $files['filename']; } $new_modified = array(); foreach ($modified as $filename => $diff_method) { if (in_array($filename, $modified_filenames)) { $new_modified[$filename] = $diff_method; } } $modified = $new_modified; } // Check number of conflicting files, they need to be equal. For modified files the number can differ if (sizeof($update_list['conflict']) != sizeof($conflicts)) { trigger_error($user->lang['MERGE_SELECT_ERROR'], E_USER_ERROR); } // Before we do anything, let us diff the files and store the raw file information "somewhere" $get_files = false; $file_list = $cache->get('_diff_files'); if ($file_list === false || $file_list['status'] != -1) { $get_files = true; } if ($get_files) { if ($file_list === false) { $file_list = array( 'status' => 0, ); } $processed = 0; foreach ($update_list as $status => $files) { if (!is_array($files)) { continue; } foreach ($files as $file_struct) { // Skip this file if the user selected to not update it if (in_array($file_struct['filename'], $no_update)) { continue; } // Already handled... then skip of course... if (isset($file_list[$file_struct['filename']])) { continue; } // Refresh if we reach 5 diffs... if ($processed >= 5) { $cache->put('_diff_files', $file_list); if (!empty($_REQUEST['download'])) { $params[] = 'download=1'; } $redirect_url = append_sid($this->p_master->module_url, "mode=$mode&sub=update_files&" . implode('&', $params)); meta_refresh(3, $redirect_url); $template->assign_vars(array( 'S_IN_PROGRESS' => true, 'L_IN_PROGRESS' => $user->lang['MERGING_FILES'], 'L_IN_PROGRESS_EXPLAIN' => $user->lang['MERGING_FILES_EXPLAIN'], )); return; } $original_filename = ($file_struct['custom']) ? $file_struct['original'] : $file_struct['filename']; switch ($status) { case 'modified': $option = (isset($modified[$file_struct['filename']])) ? $modified[$file_struct['filename']] : 0; switch ($option) { case MERGE_NO_MERGE_NEW: $contents = file_get_contents($this->new_location . $original_filename); break; case MERGE_NO_MERGE_MOD: $contents = file_get_contents($phpbb_root_path . $file_struct['filename']); break; default: $diff = $this->return_diff($this->old_location . $original_filename, $phpbb_root_path . $file_struct['filename'], $this->new_location . $original_filename); $contents = implode("\n", $diff->merged_output()); unset($diff); break; } $file_list[$file_struct['filename']] = '_file_' . md5($file_struct['filename']); $cache->put($file_list[$file_struct['filename']], base64_encode($contents)); $file_list['status']++; $processed++; break; case 'conflict': $option = $conflicts[$file_struct['filename']]; $contents = ''; switch ($option) { case MERGE_NO_MERGE_NEW: $contents = file_get_contents($this->new_location . $original_filename); break; case MERGE_NO_MERGE_MOD: $contents = file_get_contents($phpbb_root_path . $file_struct['filename']); break; default: $diff = $this->return_diff($this->old_location . $original_filename, $phpbb_root_path . $file_struct['filename'], $this->new_location . $original_filename); if ($option == MERGE_NEW_FILE) { $contents = implode("\n", $diff->merged_new_output()); } else if ($option == MERGE_MOD_FILE) { $contents = implode("\n", $diff->merged_orig_output()); } else { unset($diff); break 2; } unset($diff); break; } $file_list[$file_struct['filename']] = '_file_' . md5($file_struct['filename']); $cache->put($file_list[$file_struct['filename']], base64_encode($contents)); $file_list['status']++; $processed++; break; } } } } $file_list['status'] = -1; $cache->put('_diff_files', $file_list); if (!empty($_REQUEST['download'])) { $this->include_file('includes/functions_compress.' . $phpEx); $use_method = request_var('use_method', ''); $methods = array('.tar'); $available_methods = array('.tar.gz' => 'zlib', '.tar.bz2' => 'bz2', '.zip' => 'zlib'); foreach ($available_methods as $type => $module) { if (!@extension_loaded($module)) { continue; } $methods[] = $type; } // Let the user decide in which format he wants to have the pack if (!$use_method) { $this->page_title = 'SELECT_DOWNLOAD_FORMAT'; $radio_buttons = ''; foreach ($methods as $method) { $radio_buttons .= '<label><input type="radio"' . ((!$radio_buttons) ? ' id="use_method"' : '') . ' class="radio" value="' . $method . '" name="use_method" /> ' . $method . '</label>'; } $template->assign_vars(array( 'S_DOWNLOAD_FILES' => true, 'U_ACTION' => append_sid($this->p_master->module_url, "mode=$mode&sub=update_files"), 'RADIO_BUTTONS' => $radio_buttons, 'S_HIDDEN_FIELDS' => $s_hidden_fields) ); // To ease the update process create a file location map $update_list = $cache->get('_update_list'); $script_path = ($config['force_server_vars']) ? (($config['script_path'] == '/') ? '/' : $config['script_path'] . '/') : $user->page['root_script_path']; foreach ($update_list as $status => $files) { if ($status == 'up_to_date' || $status == 'no_update' || $status == 'status') { continue; } foreach ($files as $file_struct) { if (in_array($file_struct['filename'], $no_update)) { continue; } $template->assign_block_vars('location', array( 'SOURCE' => htmlspecialchars($file_struct['filename']), 'DESTINATION' => $script_path . htmlspecialchars($file_struct['filename']), )); } } return; } if (!in_array($use_method, $methods)) { $use_method = '.tar'; } $update_mode = 'download'; } else { $this->include_file('includes/functions_transfer.' . $phpEx); // Choose FTP, if not available use fsock... $method = basename(request_var('method', '')); $submit = (isset($_POST['submit'])) ? true : false; $test_ftp_connection = request_var('test_connection', ''); if (!$method || !class_exists($method)) { $method = 'ftp'; $methods = transfer::methods(); if (!in_array('ftp', $methods)) { $method = $methods[0]; } } $test_connection = false; if ($test_ftp_connection || $submit) { $transfer = new $method(request_var('host', ''), request_var('username', ''), request_var('password', ''), request_var('root_path', ''), request_var('port', ''), request_var('timeout', '')); $test_connection = $transfer->open_session(); // Make sure that the directory is correct by checking for the existence of common.php if ($test_connection === true) { // Check for common.php file if (!$transfer->file_exists($phpbb_root_path, 'common.' . $phpEx)) { $test_connection = 'ERR_WRONG_PATH_TO_PHPBB'; } } $transfer->close_session(); // Make sure the login details are correct before continuing if ($submit && $test_connection !== true) { $submit = false; $test_ftp_connection = true; } } $s_hidden_fields .= build_hidden_fields(array('method' => $method)); if (!$submit) { $this->page_title = 'SELECT_FTP_SETTINGS'; if (!class_exists($method)) { trigger_error('Method does not exist.', E_USER_ERROR); } $requested_data = call_user_func(array($method, 'data')); foreach ($requested_data as $data => $default) { $template->assign_block_vars('data', array( 'DATA' => $data, 'NAME' => $user->lang[strtoupper($method . '_' . $data)], 'EXPLAIN' => $user->lang[strtoupper($method . '_' . $data) . '_EXPLAIN'], 'DEFAULT' => (!empty($_REQUEST[$data])) ? request_var($data, '') : $default )); } $template->assign_vars(array( 'S_CONNECTION_SUCCESS' => ($test_ftp_connection && $test_connection === true) ? true : false, 'S_CONNECTION_FAILED' => ($test_ftp_connection && $test_connection !== true) ? true : false, 'ERROR_MSG' => ($test_ftp_connection && $test_connection !== true) ? $user->lang[$test_connection] : '', 'S_FTP_UPLOAD' => true, 'UPLOAD_METHOD' => $method, 'U_ACTION' => append_sid($this->p_master->module_url, "mode=$mode&sub=update_files"), 'U_DOWNLOAD_METHOD' => append_sid($this->p_master->module_url, "mode=$mode&sub=update_files&download=1"), 'S_HIDDEN_FIELDS' => $s_hidden_fields, )); return; } $update_mode = 'upload'; } // Now update the installation or download the archive... $download_filename = 'update_' . $this->update_info['version']['from'] . '_to_' . $this->update_info['version']['to']; $archive_filename = $download_filename . '_' . time() . '_' . unique_id(); // Now init the connection if ($update_mode == 'download') { if ($use_method == '.zip') { $compress = new compress_zip('w', $phpbb_root_path . 'store/' . $archive_filename . $use_method); } else { $compress = new compress_tar('w', $phpbb_root_path . 'store/' . $archive_filename . $use_method, $use_method); } } else { $transfer = new $method(request_var('host', ''), request_var('username', ''), request_var('password', ''), request_var('root_path', ''), request_var('port', ''), request_var('timeout', '')); $transfer->open_session(); } // Ok, go through the update list and do the operations based on their status foreach ($update_list as $status => $files) { if (!is_array($files)) { continue; } foreach ($files as $file_struct) { // Skip this file if the user selected to not update it if (in_array($file_struct['filename'], $no_update)) { continue; } $original_filename = ($file_struct['custom']) ? $file_struct['original'] : $file_struct['filename']; switch ($status) { case 'new': case 'new_conflict': case 'not_modified': if ($update_mode == 'download') { $compress->add_custom_file($this->new_location . $original_filename, $file_struct['filename']); } else { if ($status != 'new') { $transfer->rename($file_struct['filename'], $file_struct['filename'] . '.bak'); } // New directory too? $dirname = dirname($file_struct['filename']); if ($dirname && !file_exists($phpbb_root_path . $dirname)) { $transfer->make_dir($dirname); } $transfer->copy_file($this->new_location . $original_filename, $file_struct['filename']); } break; case 'modified': $contents = base64_decode($cache->get($file_list[$file_struct['filename']])); if ($update_mode == 'download') { $compress->add_data($contents, $file_struct['filename']); } else { // @todo add option to specify if a backup file should be created? $transfer->rename($file_struct['filename'], $file_struct['filename'] . '.bak'); $transfer->write_file($file_struct['filename'], $contents); } break; case 'conflict': $contents = base64_decode($cache->get($file_list[$file_struct['filename']])); if ($update_mode == 'download') { $compress->add_data($contents, $file_struct['filename']); } else { $transfer->rename($file_struct['filename'], $file_struct['filename'] . '.bak'); $transfer->write_file($file_struct['filename'], $contents); } break; } } } if ($update_mode == 'download') { $compress->close(); $compress->download($archive_filename, $download_filename); @unlink($phpbb_root_path . 'store/' . $archive_filename . $use_method); exit; } else { $transfer->close_session(); $template->assign_vars(array( 'S_UPLOAD_SUCCESS' => true, 'U_ACTION' => append_sid($this->p_master->module_url, "mode=$mode&sub=file_check")) ); return; } break; } }
function main($id, $mode) { global $config, $db, $user, $auth, $template, $cache; global $phpbb_root_path, $phpEx; global $method, $test_ftp_connection, $test_connection; include "{$phpbb_root_path}includes/functions_transfer.{$phpEx}"; include "{$phpbb_root_path}includes/editor.{$phpEx}"; include "{$phpbb_root_path}includes/functions_mods.{$phpEx}"; include "{$phpbb_root_path}includes/mod_parser.{$phpEx}"; // start the page $user->add_lang(array('install', 'acp/mods')); $this->tpl_name = 'acp_mods'; $this->page_title = 'ACP_CAT_MODS'; $this->mods_dir = $phpbb_root_path . 'store/mods'; // get any url vars $action = request_var('action', ''); $mod_id = request_var('mod_id', 0); $mod_url = request_var('mod_url', ''); $parent = request_var('parent', 0); $mod_path = request_var('mod_path', ''); if ($mod_path) { $mod_path = urldecode($mod_path); $mod_dir = substr($mod_path, 1, strpos($mod_path, '/', 1)); $this->mod_root = $this->mods_dir . '/' . $mod_dir; $this->backup_root = $this->mod_root . '_backups/'; } switch ($mode) { case 'config': $ftp_method = request_var('ftp_method', ''); if (!$ftp_method || !class_exists($ftp_method)) { $ftp_method = 'ftp'; $ftp_methods = transfer::methods(); if (!in_array('ftp', $ftp_methods)) { $ftp_method = $ftp_methods[0]; } } if (isset($_POST['submit']) && check_form_key('acp_mods')) { $ftp_host = request_var('host', ''); $ftp_username = request_var('username', ''); $ftp_password = request_var('password', ''); // not stored, used to test connection $ftp_root_path = request_var('root_path', ''); $ftp_port = request_var('port', 21); $ftp_timeout = request_var('timeout', 10); $write_method = request_var('write_method', 0); $file_perms = request_var('file_perms', '0644'); $dir_perms = request_var('dir_perms', '0755'); $compress_method = request_var('compress_method', ''); $preview_changes = request_var('preview_changes', 0); $error = ''; if ($write_method == WRITE_DIRECT) { // the very best method would be to check every file for is_writable if (!is_writable("{$phpbb_root_path}common.{$phpEx}") || !is_writable("{$phpbb_root_path}adm/style/acp_groups.html")) { $error = 'FILESYSTEM_NOT_WRITABLE'; } } else { if ($write_method == WRITE_FTP) { // check the correctness of FTP infos $test_ftp_connection = true; $test_connection = false; test_ftp_connection($ftp_method, $test_ftp_connection, $test_connection); if ($test_connection !== true) { $error = $test_connection; } } else { if ($write_method == WRITE_MANUAL) { // the compress class requires write access to the /store/ dir if (!is_writable("{$phpbb_root_path}store/")) { $error = 'STORE_NOT_WRITABLE'; } } } } if (empty($error)) { set_config('ftp_method', $ftp_method); set_config('ftp_host', $ftp_host); set_config('ftp_username', $ftp_username); set_config('ftp_root_path', $ftp_root_path); set_config('ftp_port', $ftp_port); set_config('ftp_timeout', $ftp_timeout); set_config('write_method', $write_method); set_config('compress_method', $compress_method); set_config('preview_changes', $preview_changes); set_config('am_file_perms', $file_perms); set_config('am_dir_perms', $dir_perms); trigger_error($user->lang['MOD_CONFIG_UPDATED'] . adm_back_link($this->u_action)); } else { $template->assign_var('ERROR', $user->lang[$error]); } } else { if (isset($_POST['submit']) && !check_form_key('acp_mods')) { trigger_error($user->lang['FORM_INVALID'] . adm_back_link($this->u_action), E_USER_WARNING); } } add_form_key('acp_mods'); // implicit else include "{$phpbb_root_path}includes/functions_compress.{$phpEx}"; foreach (compress::methods() as $method) { $template->assign_block_vars('compress', array('METHOD' => $method)); } $requested_data = call_user_func(array($ftp_method, 'data')); foreach ($requested_data as $data => $default) { $default = !empty($config['ftp_' . $data]) ? $config['ftp_' . $data] : $default; $template->assign_block_vars('data', array('DATA' => $data, 'NAME' => $user->lang[strtoupper($ftp_method . '_' . $data)], 'EXPLAIN' => $user->lang[strtoupper($ftp_method . '_' . $data) . '_EXPLAIN'], 'DEFAULT' => !empty($_REQUEST[$data]) ? request_var($data, '') : $default)); } $template->assign_vars(array('S_CONFIG' => true, 'U_CONFIG' => $this->u_action . '&mode=config', 'UPLOAD_METHOD' => $ftp_method, 'WRITE_DIRECT' => $config['write_method'] == WRITE_DIRECT ? ' checked="checked"' : '', 'WRITE_FTP' => $config['write_method'] == WRITE_FTP ? ' checked="checked"' : '', 'WRITE_MANUAL' => $config['write_method'] == WRITE_MANUAL ? ' checked="checked"' : '', 'WRITE_METHOD_DIRECT' => WRITE_DIRECT, 'WRITE_METHOD_FTP' => WRITE_FTP, 'WRITE_METHOD_MANUAL' => WRITE_MANUAL, 'COMPRESS_METHOD' => $config['compress_method'], 'DIR_PERMS' => $config['am_dir_perms'], 'FILE_PERMS' => $config['am_file_perms'], 'PREVIEW_CHANGES_YES' => $config['preview_changes'] ? ' checked="checked"' : '', 'PREVIEW_CHANGES_NO' => !$config['preview_changes'] ? ' checked="checked"' : '', 'S_HIDE_FTP' => $config['write_method'] == WRITE_FTP ? false : true)); break; case 'frontend': if ($config['write_method'] == WRITE_FTP) { $method = basename(request_var('method', '')); if (!$method || !class_exists($method)) { $method = 'ftp'; $methods = transfer::methods(); if (!in_array('ftp', $methods)) { $method = $methods[0]; } } $test_connection = false; $test_ftp_connection = request_var('test_connection', ''); if (!empty($test_ftp_connection) || $action == 'install') { test_ftp_connection($method, $test_ftp_connection, $test_connection); // Make sure the login details are correct before continuing if ($test_connection !== true || !empty($test_ftp_connection)) { $action = 'pre_install'; $test_ftp_connection = true; } } } switch ($action) { case 'pre_install': $this->pre_install($mod_path); break; case 'install': $this->install($mod_path, $parent); break; case 'pre_uninstall': case 'uninstall': $this->uninstall($action, $mod_id); break; case 'details': $mod_ident = $mod_id ? $mod_id : $mod_path; $this->list_details($mod_ident); break; default: $template->assign_vars(array('S_FRONTEND' => true)); $this->list_installed(); $this->list_uninstalled(); break; } return; break; } }
function main($mode, $sub) { global $lang, $template, $language, $phpbb_root_path, $phpEx, $config, $db, $table_prefix, $db, $auth, $cache, $user; $this->old_location = $phpbb_root_path . 'garage/install/install/old/'; $this->new_location = $phpbb_root_path . 'garage/install/install/new/'; // Special options for conflicts/modified files define('MERGE_NO_MERGE_NEW', 1); define('MERGE_NO_MERGE_MOD', 2); define('MERGE_NEW_FILE', 3); define('MERGE_MOD_FILE', 4); $this->install_info = $this->get_file('install_info'); // Include renderer and engine $this->include_file('includes/diff/diff.' . $phpEx); $this->include_file('includes/diff/engine.' . $phpEx); $this->include_file('includes/diff/renderer.' . $phpEx); // Make sure we stay at the file check if checking the files again if (!empty($_POST['check_again'])) { $sub = $this->p_master->sub = 'file_check'; } $this->tpl_name = 'garage_install_install'; switch ($sub) { case 'intro': $this->page_title = $lang['SUB_INTRO']; $template->assign_vars(array('TITLE' => $lang['INSTALL_INTRO'], 'BODY' => $lang['INSTALL_INTRO_BODY'], 'L_SUBMIT' => $lang['NEXT_STEP'], 'U_ACTION' => $this->p_master->module_url . "?mode={$mode}&sub=requirements&language={$language}")); break; case 'requirements': $this->check_server_requirements($mode, $sub); break; case 'optional': $this->obtain_optional_settings($mode, $sub); break; case 'create_table': $this->load_schema($mode, $sub); break; case 'create_permissions': $this->add_permissions($mode, $sub); $this->update_group_permissions($mode, $sub); $this->update_role_permissions($mode, $sub); $submit = $lang['NEXT_STEP']; $url = $this->p_master->module_url . "?mode={$mode}&sub=install_modules"; $template->assign_vars(array('BODY' => $lang['STAGE_CREATE_PERMISSIONS_EXPLAIN'], 'L_SUBMIT' => $submit, 'U_ACTION' => $url)); break; case 'install_modules': $this->add_modules($mode, $sub); $submit = $lang['NEXT_STEP']; $url = $this->p_master->module_url . "?mode={$mode}&sub=file_check"; $template->assign_vars(array('BODY' => $lang['STAGE_INSTALL_MODULES_EXPLAIN'], 'L_SUBMIT' => $submit, 'U_ACTION' => $url)); break; // Last step is just a re-check of files... // Last step is just a re-check of files... case 'final': case 'file_check': $this->tpl_name = 'garage_install_update'; $this->page_title = 'STAGE_FILE_CHECK'; // Now make sure our install list is correct if the admin refreshes $action = request_var('action', ''); // We are directly within an update. To make sure our install list is correct we check its status. $install_list = !empty($_POST['check_again']) ? false : $cache->get('_install_list'); $modified = $install_list !== false ? @filemtime($cache->cache_dir . 'data_install_list.' . $phpEx) : 0; // Make sure the list is up-to-date if ($install_list !== false) { $get_new_list = false; foreach ($this->install_info['files'] as $file) { if (file_exists($phpbb_root_path . $file) && filemtime($phpbb_root_path . $file) > $modified) { $get_new_list = true; break; } } } else { $get_new_list = true; } if ($get_new_list) { $install_list = $this->get_install_structure(); $cache->put('_install_list', $install_list); } if ($action == 'diff') { $this->show_diff($install_list); return; } // Now assign the list to the template foreach ($install_list as $status => $filelist) { if ($status == 'no_update' || !sizeof($filelist)) { continue; } $template->assign_block_vars('files', array('S_STATUS' => true, 'STATUS' => $status, 'L_STATUS' => $user->lang['STATUS_' . strtoupper($status)], 'TITLE' => $user->lang['FILES_' . strtoupper($status)], 'EXPLAIN' => $user->lang['FILES_' . strtoupper($status) . '_EXPLAIN'])); foreach ($filelist as $file_struct) { $filename = htmlspecialchars($file_struct['filename']); if (strrpos($filename, '/') !== false) { $dir_part = substr($filename, 0, strrpos($filename, '/') + 1); $file_part = substr($filename, strrpos($filename, '/') + 1); } else { $dir_part = ''; $file_part = $filename; } $diff_url = append_sid($this->p_master->module_url, "mode={$mode}&sub=file_check&action=diff&status={$status}&file=" . urlencode($file_struct['filename'])); $template->assign_block_vars('files', array('STATUS' => $status, 'FILENAME' => $filename, 'DIR_PART' => $dir_part, 'FILE_PART' => $file_part, 'NUM_CONFLICTS' => isset($file_struct['conflicts']) ? $file_struct['conflicts'] : 0, 'S_CUSTOM' => $file_struct['custom'] ? true : false, 'CUSTOM_ORIGINAL' => $file_struct['custom'] ? $file_struct['original'] : '', 'U_SHOW_DIFF' => $diff_url, 'L_SHOW_DIFF' => $status != 'up_to_date' ? $user->lang['SHOW_DIFF_' . strtoupper($status)] : '', 'U_VIEW_MOD_FILE' => $diff_url . '&op=' . MERGE_MOD_FILE, 'U_VIEW_NEW_FILE' => $diff_url . '&op=' . MERGE_NEW_FILE, 'U_VIEW_NO_MERGE_MOD' => $diff_url . '&op=' . MERGE_NO_MERGE_MOD, 'U_VIEW_NO_MERGE_NEW' => $diff_url . '&op=' . MERGE_NO_MERGE_NEW)); } } $all_up_to_date = true; foreach ($install_list as $status => $filelist) { if ($status != 'up_to_date' && $status != 'custom' && sizeof($filelist)) { $all_up_to_date = false; break; } } $template->assign_vars(array('S_FILE_CHECK' => true, 'S_ALL_UP_TO_DATE' => $all_up_to_date, 'U_ACTION' => append_sid($this->p_master->module_url, "mode={$mode}&sub=file_check"), 'U_UPDATE_ACTION' => append_sid($this->p_master->module_url, "mode={$mode}&sub=update_files"))); if ($all_up_to_date and $sub == 'final') { // Remove the lock file @unlink($phpbb_root_path . 'cache/install_lock'); } // Make sure we stay at the final if we checked_again and all is now up to date if (!empty($_POST['check_again']) && $all_up_to_date) { $sub = $this->p_master->sub = 'final'; } if ($all_up_to_date) { // Refresh any style css data we updated - this may cause some unhappy users, but $sql = 'SELECT * FROM ' . STYLES_THEME_TABLE; $result = $db->sql_query($sql); while ($theme = $db->sql_fetchrow($result)) { //Check For Themes Updated By Installer if (file_exists($phpbb_root_path . "garage/install/install/styles/{$theme['theme_name']}/theme/index." . $phpEx)) { $recache = empty($theme['theme_data']) ? true : false; $update_time = time(); // We test for stylesheet.css because it is faster and most likely the only file changed on common themes if (!$recache && $theme['theme_mtime'] < @filemtime("{$phpbb_root_path}styles/" . $theme['theme_path'] . '/theme/stylesheet.css')) { $recache = true; $update_time = @filemtime("{$phpbb_root_path}styles/" . $theme['theme_path'] . '/theme/stylesheet.css'); } else { if (!$recache) { $last_change = $theme['theme_mtime']; $dir = @opendir("{$phpbb_root_path}styles/{$theme['theme_path']}/theme"); if ($dir) { while (($entry = readdir($dir)) !== false) { if (substr(strrchr($entry, '.'), 1) == 'css' && $last_change < @filemtime("{$phpbb_root_path}styles/{$theme['theme_path']}/theme/{$entry}")) { $recache = true; break; } } closedir($dir); } } } if ($recache) { include_once $phpbb_root_path . 'includes/acp/acp_styles.' . $phpEx; $theme['theme_data'] = acp_styles::db_theme_data($theme); $theme['theme_mtime'] = $update_time; // Save CSS contents $sql_ary = array('theme_mtime' => $theme['theme_mtime'], 'theme_data' => $theme['theme_data']); $sql = 'UPDATE ' . STYLES_THEME_TABLE . ' SET ' . $db->sql_build_array('UPDATE', $sql_ary) . ' WHERE theme_id = ' . $theme['theme_id']; $db->sql_query($sql); $cache->destroy('sql', STYLES_THEME_TABLE); } } } $db->sql_freeresult($result); // Refresh any imageset data we updated - but only for garage images $sql = 'SELECT * FROM ' . STYLES_IMAGESET_TABLE; $result = $db->sql_query($sql); while ($imageset = $db->sql_fetchrow($result)) { $sql_ary = array(); $db->sql_transaction('begin'); if (!class_exists('garage_template')) { include $phpbb_root_path . 'includes/mods/class_garage_template.' . $phpEx; $garage_template = new garage_template(); } //We need to build the imageset_keys now only for garage keys $imageset_keys = array(); $imageset_keys['buttons'] = array(); $imageset_keys = $garage_template->update_imageset_keys($imageset_keys); $imageset_definitions = array(); foreach ($imageset_keys as $topic => $key_array) { $imageset_definitions = array_merge($imageset_definitions, $key_array); } //Check For Imageset Updated By Installer if (file_exists($phpbb_root_path . "garage/install/install/new/styles/{$imageset['imageset_path']}/imageset/imageset.cfg")) { $cfg_data_imageset = parse_cfg_file("{$phpbb_root_path}styles/{$imageset['imageset_path']}/imageset/imageset.cfg"); $sql = 'DELETE FROM ' . STYLES_IMAGESET_DATA_TABLE . ' WHERE imageset_id = ' . $imageset['imageset_id'] . ' AND ' . $db->sql_in_set('image_name', $imageset_keys['garage']); $db->sql_query($sql); foreach ($cfg_data_imageset as $image_name => $value) { //Lets cut to the chase and make sure we only work with garage images $image_wanted = substr($image_name, 4); if (!in_array($image_wanted, $imageset_keys['garage'])) { continue; } if (strpos($value, '*') !== false) { if (substr($value, -1, 1) === '*') { list($image_filename, $image_height) = explode('*', $value); $image_width = 0; } else { list($image_filename, $image_height, $image_width) = explode('*', $value); } } else { $image_filename = $value; $image_height = $image_width = 0; } if (strpos($image_name, 'img_') === 0 && $image_filename) { $image_name = substr($image_name, 4); if (in_array($image_name, $imageset_definitions)) { $sql_ary[] = array('image_name' => (string) $image_name, 'image_filename' => (string) $image_filename, 'image_height' => (int) $image_height, 'image_width' => (int) $image_width, 'imageset_id' => (int) $imageset['imageset_id'], 'image_lang' => ''); } } } } $sql2 = 'SELECT lang_dir FROM ' . LANG_TABLE; $result2 = $db->sql_query($sql2); while ($language = $db->sql_fetchrow($result2)) { //Check For Language Imageset Updated By Installer if (file_exists($phpbb_root_path . "garage/install/install/new/styles/{$imageset['imageset_path']}/imageset/{$language['lang_dir']}/imageset.cfg")) { $cfg_data_imageset_data = parse_cfg_file("{$phpbb_root_path}styles/{$imageset['imageset_path']}/imageset/{$language['lang_dir']}/imageset.cfg"); $sql = 'DELETE FROM ' . STYLES_IMAGESET_DATA_TABLE . ' WHERE imageset_id = ' . $imageset['imageset_id'] . ' AND ' . $db->sql_in_set('image_name', $imageset_keys['buttons']) . "\n\t\t\t\t\t\t\t\t\t\tAND image_lang = '{$language['lang_dir']}'"; $db->sql_query($sql); foreach ($cfg_data_imageset_data as $image_name => $value) { //Lets cut to the chase and make sure we only work with garage images $image_wanted = substr($image_name, 4); if (!in_array($image_wanted, $imageset_keys['buttons'])) { continue; } if (strpos($value, '*') !== false) { if (substr($value, -1, 1) === '*') { list($image_filename, $image_height) = explode('*', $value); $image_width = 0; } else { list($image_filename, $image_height, $image_width) = explode('*', $value); } } else { $image_filename = $value; $image_height = $image_width = 0; } if (strpos($image_name, 'img_') === 0 && $image_filename) { $image_name = substr($image_name, 4); if (in_array($image_name, $imageset_definitions)) { $sql_ary[] = array('image_name' => (string) $image_name, 'image_filename' => (string) $image_filename, 'image_height' => (int) $image_height, 'image_width' => (int) $image_width, 'imageset_id' => (int) $imageset['imageset_id'], 'image_lang' => (string) $language['lang_dir']); } } } } } $db->sql_freeresult($result2); $db->sql_multi_insert(STYLES_IMAGESET_DATA_TABLE, $sql_ary); $db->sql_transaction('commit'); } $db->sql_freeresult($result); $cache->destroy('sql', STYLES_IMAGESET_DATA_TABLE); add_log('admin', 'LOG_IMAGESET_REFRESHED', $imageset['imageset_name']); $db->sql_return_on_error(true); $db->sql_query('DELETE FROM ' . GARAGE_CONFIG_TABLE . " WHERE config_name = 'version_update_from'"); $db->sql_return_on_error(false); $cache->purge(); } break; case 'update_files': $this->tpl_name = 'garage_install_update'; $this->page_title = 'STAGE_UPDATE_FILES'; $s_hidden_fields = ''; $conflicts = request_var('conflict', array('' => 0)); $modified = request_var('modified', array('' => 0)); foreach ($conflicts as $filename => $merge_option) { $s_hidden_fields .= '<input type="hidden" name="conflict[' . htmlspecialchars($filename) . ']" value="' . $merge_option . '" />'; } foreach ($modified as $filename => $merge_option) { if (!$merge_option) { continue; } $s_hidden_fields .= '<input type="hidden" name="modified[' . htmlspecialchars($filename) . ']" value="' . $merge_option . '" />'; } $no_update = request_var('no_update', array(0 => '')); foreach ($no_update as $index => $filename) { $s_hidden_fields .= '<input type="hidden" name="no_update[]" value="' . htmlspecialchars($filename) . '" />'; } if (!empty($_POST['download'])) { $this->include_file('includes/functions_compress.' . $phpEx); $use_method = request_var('use_method', ''); $methods = array('.tar'); $available_methods = array('.tar.gz' => 'zlib', '.tar.bz2' => 'bz2', '.zip' => 'zlib'); foreach ($available_methods as $type => $module) { if (!@extension_loaded($module)) { continue; } $methods[] = $type; } // Let the user decide in which format he wants to have the pack if (!$use_method) { $this->page_title = 'SELECT_DOWNLOAD_FORMAT'; $radio_buttons = ''; foreach ($methods as $method) { $radio_buttons .= '<label><input type="radio"' . (!$radio_buttons ? ' id="use_method"' : '') . ' class="radio" value="' . $method . '" name="use_method" /> ' . $method . '</label>'; } $template->assign_vars(array('S_DOWNLOAD_FILES' => true, 'U_ACTION' => append_sid($this->p_master->module_url, "mode={$mode}&sub=update_files"), 'RADIO_BUTTONS' => $radio_buttons, 'S_HIDDEN_FIELDS' => $s_hidden_fields)); // To ease the update process create a file location map $install_list = $cache->get('_install_list'); $script_path = $config['force_server_vars'] ? $config['script_path'] == '/' ? '/' : $config['script_path'] . '/' : $user->page['root_script_path']; foreach ($install_list as $status => $files) { if ($status == 'up_to_date' || $status == 'no_update') { continue; } foreach ($files as $file_struct) { if (in_array($file_struct['filename'], $no_update)) { continue; } $template->assign_block_vars('location', array('SOURCE' => htmlspecialchars($file_struct['filename']), 'DESTINATION' => $script_path . htmlspecialchars($file_struct['filename']))); } } return; } if (!in_array($use_method, $methods)) { $use_method = '.tar'; } $update_mode = 'download'; } else { $this->include_file('includes/functions_transfer.' . $phpEx); // Choose FTP, if not available use fsock... $method = request_var('method', ''); $submit = isset($_POST['submit']) ? true : false; $test_ftp_connection = request_var('test_connection', ''); if (!$method) { $method = 'ftp'; $methods = transfer::methods(); if (!in_array('ftp', $methods)) { $method = $methods[0]; } } $test_connection = false; if ($test_ftp_connection || $submit) { $transfer = new $method(request_var('host', ''), request_var('username', ''), request_var('password', ''), request_var('root_path', ''), request_var('port', ''), request_var('timeout', '')); $test_connection = $transfer->open_session(); // Make sure that the directory is correct by checking for the existence of common.php if ($test_connection === true) { // Check for common.php file if (!$transfer->file_exists($phpbb_root_path, 'common.' . $phpEx)) { $test_connection = 'ERR_WRONG_PATH_TO_PHPBB'; } } $transfer->close_session(); // Make sure the login details are correct before continuing if ($submit && $test_connection !== true) { $submit = false; $test_ftp_connection = true; } } if (!$submit) { $this->page_title = 'SELECT_FTP_SETTINGS'; if (!class_exists($method)) { trigger_error('Method does not exist.', E_USER_ERROR); } $requested_data = call_user_func(array($method, 'data')); foreach ($requested_data as $data => $default) { $template->assign_block_vars('data', array('DATA' => $data, 'NAME' => $user->lang[strtoupper($method . '_' . $data)], 'EXPLAIN' => $user->lang[strtoupper($method . '_' . $data) . '_EXPLAIN'], 'DEFAULT' => !empty($_REQUEST[$data]) ? request_var($data, '') : $default)); } $s_hidden_fields .= build_hidden_fields(array('method' => $method)); $template->assign_vars(array('S_CONNECTION_SUCCESS' => $test_ftp_connection && $test_connection === true ? true : false, 'S_CONNECTION_FAILED' => $test_ftp_connection && $test_connection !== true ? true : false, 'ERROR_MSG' => $test_ftp_connection && $test_connection !== true ? $user->lang[$test_connection] : '', 'S_FTP_UPLOAD' => true, 'UPLOAD_METHOD' => $method, 'U_ACTION' => append_sid($this->p_master->module_url, "mode={$mode}&sub=update_files"), 'S_HIDDEN_FIELDS' => $s_hidden_fields)); return; } $update_mode = 'upload'; } // Now update the installation or download the archive... $download_filename = 'install_phpbbgarage_' . $this->install_info['version']['install']; $archive_filename = $download_filename . '_' . time() . '_' . unique_id(); $install_list = $cache->get('_install_list'); $conflicts = request_var('conflict', array('' => 0)); $modified = request_var('modified', array('' => 0)); if ($install_list === false) { trigger_error($user->lang['NO_UPDATE_INFO'], E_USER_ERROR); } // Check if the conflicts data is valid if (sizeof($conflicts)) { $conflict_filenames = array(); foreach ($install_list['conflict'] as $files) { $conflict_filenames[] = $files['filename']; } $new_conflicts = array(); foreach ($conflicts as $filename => $diff_method) { if (in_array($filename, $conflict_filenames)) { $new_conflicts[$filename] = $diff_method; } } $conflicts = $new_conflicts; } // Build list for modifications if (sizeof($modified)) { $modified_filenames = array(); foreach ($install_list['modified'] as $files) { $modified_filenames[] = $files['filename']; } $new_modified = array(); foreach ($modified as $filename => $diff_method) { if (in_array($filename, $modified_filenames)) { $new_modified[$filename] = $diff_method; } } $modified = $new_modified; } // Check number of conflicting files, they need to be equal. For modified files the number can differ if (sizeof($install_list['conflict']) != sizeof($conflicts)) { trigger_error($user->lang['MERGE_SELECT_ERROR'], E_USER_ERROR); } // Now init the connection if ($update_mode == 'download') { if ($use_method == '.zip') { $compress = new compress_zip('w', $phpbb_root_path . 'store/' . $archive_filename . $use_method); } else { $compress = new compress_tar('w', $phpbb_root_path . 'store/' . $archive_filename . $use_method, $use_method); } } else { $transfer = new $method(request_var('host', ''), request_var('username', ''), request_var('password', ''), request_var('root_path', ''), request_var('port', ''), request_var('timeout', '')); $transfer->open_session(); } // Ok, go through the update list and do the operations based on their status foreach ($install_list as $status => $files) { foreach ($files as $file_struct) { // Skip this file if the user selected to not update it if (in_array($file_struct['filename'], $no_update)) { continue; } $original_filename = $file_struct['custom'] ? $file_struct['original'] : $file_struct['filename']; switch ($status) { case 'new': case 'new_conflict': case 'not_modified': if ($update_mode == 'download') { $compress->add_custom_file($this->new_location . $original_filename, $file_struct['filename']); } else { if ($status != 'new') { $transfer->rename($file_struct['filename'], $file_struct['filename'] . '.bak'); } $transfer->copy_file($this->new_location . $original_filename, $file_struct['filename']); } break; case 'modified': $option = isset($modified[$file_struct['filename']]) ? $modified[$file_struct['filename']] : 0; switch ($option) { case MERGE_NO_MERGE_NEW: $contents = file_get_contents($this->new_location . $original_filename); break; case MERGE_NO_MERGE_MOD: $contents = file_get_contents($phpbb_root_path . $file_struct['filename']); break; default: $diff = $this->return_diff($this->old_location . $original_filename, $phpbb_root_path . $file_struct['filename'], $this->new_location . $original_filename); $contents = implode("\n", $diff->merged_output()); unset($diff); break; } if ($update_mode == 'download') { $compress->add_data($contents, $file_struct['filename']); } else { // @todo add option to specify if a backup file should be created? $transfer->rename($file_struct['filename'], $file_struct['filename'] . '.bak'); $transfer->write_file($file_struct['filename'], $contents); } break; case 'conflict': $option = $conflicts[$file_struct['filename']]; $contents = ''; switch ($option) { case MERGE_NO_MERGE_NEW: $contents = file_get_contents($this->new_location . $original_filename); break; case MERGE_NO_MERGE_MOD: $contents = file_get_contents($phpbb_root_path . $file_struct['filename']); break; default: $diff = $this->return_diff($this->old_location . $original_filename, $phpbb_root_path . $file_struct['filename'], $this->new_location . $original_filename); if ($option == MERGE_NEW_FILE) { $contents = implode("\n", $diff->merged_new_output()); } else { if ($option == MERGE_MOD_FILE) { $contents = implode("\n", $diff->merged_orig_output()); } else { unset($diff); break 2; } } unset($diff); break; } if ($update_mode == 'download') { $compress->add_data($contents, $file_struct['filename']); } else { $transfer->rename($file_struct['filename'], $file_struct['filename'] . '.bak'); $transfer->write_file($file_struct['filename'], $contents); } break; } } } if ($update_mode == 'download') { $compress->close(); $compress->download($archive_filename, $download_filename); @unlink($phpbb_root_path . 'store/' . $archive_filename . $use_method); exit; } else { $transfer->close_session(); $template->assign_vars(array('S_UPLOAD_SUCCESS' => true, 'U_ACTION' => append_sid($this->p_master->module_url, "mode={$mode}&sub=final"))); return; } break; } switch ($sub) { case 'final': $this->tpl_name = 'garage_install_install'; // Remove the lock file @unlink($phpbb_root_path . 'cache/install_lock'); $sql = $db->sql_build_query('SELECT', array('SELECT' => 'c.config_name, c.config_value', 'FROM' => array(GARAGE_CONFIG_TABLE => 'c'))); $result = $db->sql_query($sql); while ($row = $db->sql_fetchrow($result)) { $garage_config[$row['config_name']] = $row['config_value']; } $db->sql_freeresult($result); add_log('admin', 'LOG_GARAGE_INSTALL', $garage_config['version']); $template->assign_vars(array('S_FILE_CHECK' => false, 'TITLE' => $lang['INSTALL_CONGRATS'], 'BODY' => sprintf($lang['INSTALL_CONGRATS_EXPLAIN'], $garage_config['version'], append_sid($phpbb_root_path . 'garage/install/index.' . $phpEx, 'mode=convert&'), '../docs/README.html'))); $sql = 'INSERT INTO ' . GARAGE_CONFIG_TABLE . ' ' . $db->sql_build_array('INSERT', array('config_name' => 'installed', 'config_value' => 1)); $db->sql_query($sql); $cache->purge(); break; } }
function main($mode, $sub) { global $template, $phpEx, $phpbb_root_path, $user, $db, $config, $cache, $auth, $language; global $request, $phpbb_admin_path, $phpbb_adm_relative_path, $phpbb_container, $phpbb_config_php_file; // We must enable super globals, otherwise creating a new instance of the request class, // using the new container with a dbal connection will fail with the following PHP Notice: // Object of class phpbb_request_deactivated_super_global could not be converted to int $request->enable_super_globals(); // Create a normal container now $phpbb_container_builder = new \phpbb\di\container_builder($phpbb_config_php_file, $phpbb_root_path, $phpEx); $phpbb_container_builder->set_dump_container(false); $phpbb_container_builder->set_use_extensions(false); if (file_exists($phpbb_root_path . 'install/update/new/config')) { $phpbb_container_builder->set_config_path($phpbb_root_path . 'install/update/new/config'); } $phpbb_container = $phpbb_container_builder->get_container(); // Writes into global $cache $cache = $phpbb_container->get('cache'); $this->tpl_name = 'install_update'; $this->page_title = 'UPDATE_INSTALLATION'; $this->old_location = $phpbb_root_path . 'install/update/old/'; $this->new_location = $phpbb_root_path . 'install/update/new/'; // Init DB extract($phpbb_config_php_file->get_all()); require $phpbb_root_path . 'includes/constants.' . $phpEx; // Special options for conflicts/modified files define('MERGE_NO_MERGE_NEW', 1); define('MERGE_NO_MERGE_MOD', 2); define('MERGE_NEW_FILE', 3); define('MERGE_MOD_FILE', 4); $dbms = $phpbb_config_php_file->convert_30_dbms_to_31($dbms); $db = new $dbms(); // Connect to DB $db->sql_connect($dbhost, $dbuser, $dbpasswd, $dbname, $dbport, false, false); // We do not need this any longer, unset for safety purposes unset($dbpasswd); // We need to fill the config to let internal functions correctly work $config = new \phpbb\config\db($db, new \phpbb\cache\driver\null(), CONFIG_TABLE); set_config(null, null, null, $config); set_config_count(null, null, null, $config); // Force template recompile $config['load_tplcompile'] = 1; // First of all, init the user session $user->session_begin(); $auth->acl($user->data); // Overwrite user's language with the selected one. // Config needs to be changed to ensure that guests also get the selected language. $config_default_lang = $config['default_lang']; $config['default_lang'] = $language; $user->data['user_lang'] = $language; $user->add_lang(array('common', 'acp/common', 'acp/board', 'install', 'posting')); // Reset the default_lang $config['default_lang'] = $config_default_lang; unset($config_default_lang); // If we are within the intro page we need to make sure we get up-to-date version info if ($sub == 'intro') { $cache->destroy('_version_info'); } // Set custom template again. ;) $paths = array($phpbb_root_path . 'install/update/new/adm/style', $phpbb_admin_path . 'style'); $paths = array_filter($paths, 'is_dir'); $template->set_custom_style(array(array('name' => 'adm', 'ext_path' => 'adm/style/')), $paths); $template->assign_vars(array('S_USER_LANG' => $user->lang['USER_LANG'], 'S_CONTENT_DIRECTION' => $user->lang['DIRECTION'], 'S_CONTENT_ENCODING' => 'UTF-8', 'S_CONTENT_FLOW_BEGIN' => $user->lang['DIRECTION'] == 'ltr' ? 'left' : 'right', 'S_CONTENT_FLOW_END' => $user->lang['DIRECTION'] == 'ltr' ? 'right' : 'left')); // Get current and latest version $version_helper = $phpbb_container->get('version_helper'); try { $this->latest_version = $version_helper->get_latest_on_current_branch(true); } catch (\RuntimeException $e) { $this->latest_version = false; $update_info = array(); include $phpbb_root_path . 'install/update/index.' . $phpEx; $info = empty($update_info) || !is_array($update_info) ? false : $update_info; if ($info !== false) { $this->latest_version = !empty($info['version']['to']) ? trim($info['version']['to']) : false; } } // For the current version we trick a bit. ;) $this->current_version = !empty($config['version_update_from']) ? $config['version_update_from'] : $config['version']; $up_to_date = version_compare(str_replace('rc', 'RC', strtolower($this->current_version)), str_replace('rc', 'RC', strtolower($this->latest_version)), '<') ? false : true; // Check for a valid update directory, else point the user to the phpbb.com website 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)) { $template->assign_vars(array('S_ERROR' => true, '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))); return; } $this->update_info = $this->get_file('update_info'); // Make sure the update directory holds the correct information // 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. if (version_compare(str_replace('rc', 'RC', strtolower($this->current_version)), str_replace('rc', 'RC', strtolower($this->update_info['version']['to'])), '>')) { $template->assign_vars(array('S_ERROR' => true, 'ERROR_MSG' => sprintf($user->lang['INCOMPATIBLE_UPDATE_FILES'], $config['version'], $this->update_info['version']['from'], $this->update_info['version']['to']))); return; } // Check if the update files are actually meant to update from the current version if ($this->current_version != $this->update_info['version']['from']) { $template->assign_vars(array('S_ERROR' => true, 'ERROR_MSG' => sprintf($user->lang['INCOMPATIBLE_UPDATE_FILES'], $this->current_version, $this->update_info['version']['from'], $this->update_info['version']['to']))); } // Check if the update files stored are for the latest version... if (version_compare(strtolower($this->latest_version), strtolower($this->update_info['version']['to']), '>')) { $template->assign_vars(array('S_WARNING' => true, 'WARNING_MSG' => sprintf($user->lang['OLD_UPDATE_FILES'], $this->update_info['version']['from'], $this->update_info['version']['to'], $this->latest_version))); } // We store the "update to" version, because it is not always the latest. ;) $this->update_to_version = $this->update_info['version']['to']; // Fill DB version if (empty($config['dbms_version'])) { set_config('dbms_version', $db->sql_server_info(true)); } if ($this->test_update === false) { // What about the language file? Got it updated? if (in_array('language/' . $language . '/install.' . $phpEx, $this->update_info['files'])) { $lang = array(); include $this->new_location . 'language/' . $language . '/install.' . $phpEx; // this is the user's language.. just merge it $user->lang = array_merge($user->lang, $lang); } if ($language != 'en' && in_array('language/en/install.' . $phpEx, $this->update_info['files'])) { $lang = array(); include $this->new_location . 'language/en/install.' . $phpEx; // only add new keys to user's language in english $new_keys = array_diff(array_keys($lang), array_keys($user->lang)); foreach ($new_keys as $i => $new_key) { $user->lang[$new_key] = $lang[$new_key]; } } } // Include renderer and engine $this->include_file('includes/diff/diff.' . $phpEx); $this->include_file('includes/diff/engine.' . $phpEx); $this->include_file('includes/diff/renderer.' . $phpEx); // Make sure we stay at the file check if checking the files again if ($request->variable('check_again', false, false, \phpbb\request\request_interface::POST)) { $sub = $this->p_master->sub = 'file_check'; } switch ($sub) { case 'intro': $this->page_title = 'UPDATE_INSTALLATION'; $template->assign_vars(array('S_INTRO' => true, 'U_ACTION' => append_sid($this->p_master->module_url, "language={$language}&mode={$mode}&sub=version_check"))); // Make sure the update list is destroyed. $cache->destroy('_update_list'); $cache->destroy('_diff_files'); $cache->destroy('_expected_files'); break; case 'version_check': $this->page_title = 'STAGE_VERSION_CHECK'; $template->assign_vars(array('S_VERSION_CHECK' => true, 'U_ACTION' => append_sid($this->p_master->module_url, "language={$language}&mode={$mode}&sub=file_check"), 'S_UP_TO_DATE' => $up_to_date, 'LATEST_VERSION' => $this->latest_version, 'CURRENT_VERSION' => $this->current_version)); // Print out version the update package updates to if ($this->latest_version != $this->update_info['version']['to']) { $template->assign_var('PACKAGE_VERSION', $this->update_info['version']['to']); } // Since some people try to update to RC releases, but phpBB.com tells them the last version is the version they currently run // we are faced with the updater thinking the database schema is up-to-date; which it is, but should be updated none-the-less // We now try to cope with this by triggering the update process if (version_compare(str_replace('rc', 'RC', strtolower($this->current_version)), str_replace('rc', 'RC', strtolower($this->update_info['version']['to'])), '<')) { $template->assign_vars(array('S_UP_TO_DATE' => false)); } break; case 'update_db': // Redirect the user to the database update script with some explanations... $template->assign_vars(array('S_DB_UPDATE' => true, 'S_DB_UPDATE_FINISHED' => $config['version'] == $this->update_info['version']['to'] ? true : false, 'U_DB_UPDATE' => append_sid($phpbb_root_path . 'install/database_update.' . $phpEx, 'type=1&language=' . $user->data['user_lang']), 'U_DB_UPDATE_ACTION' => append_sid($this->p_master->module_url, "language={$language}&mode={$mode}&sub=update_db"), 'U_ACTION' => append_sid($this->p_master->module_url, "language={$language}&mode={$mode}&sub=file_check"), 'L_EVERYTHING_UP_TO_DATE' => $user->lang('EVERYTHING_UP_TO_DATE', append_sid("{$phpbb_root_path}ucp.{$phpEx}", 'mode=login'), append_sid("{$phpbb_root_path}ucp.{$phpEx}", 'mode=login&redirect=' . $phpbb_adm_relative_path . 'index.php%3Fi=send_statistics%26mode=send_statistics')))); // Do not display incompatible package note after successful update if ($config['version'] == $this->update_info['version']['to']) { $template->assign_var('S_ERROR', false); } break; case 'file_check': // retrieve info on what changes should have already been made to the files. $expected_files = $cache->get('_expected_files'); if (!$expected_files) { $expected_files = array(); } // Now make sure the previous file collection is no longer valid... $cache->destroy('_diff_files'); $this->page_title = 'STAGE_FILE_CHECK'; // Now make sure our update list is correct if the admin refreshes $action = request_var('action', ''); // We are directly within an update. To make sure our update list is correct we check its status. $update_list = $request->variable('check_again', false, false, \phpbb\request\request_interface::POST) ? false : $cache->get('_update_list'); $modified = $update_list !== false ? @filemtime($cache->get_driver()->cache_dir . 'data_update_list.' . $phpEx) : 0; // Make sure the list is up-to-date if ($update_list !== false) { $get_new_list = false; foreach ($this->update_info['files'] as $file) { if (file_exists($phpbb_root_path . $file) && filemtime($phpbb_root_path . $file) > $modified) { $get_new_list = true; break; } } } else { $get_new_list = true; } if (!$get_new_list && $update_list['status'] != -1) { $get_new_list = true; } if ($get_new_list) { $this->get_update_structure($update_list, $expected_files); $cache->put('_update_list', $update_list); // Refresh the page if we are still not finished... if ($update_list['status'] != -1) { $refresh_url = append_sid($this->p_master->module_url, "language={$language}&mode={$mode}&sub=file_check"); meta_refresh(2, $refresh_url); $template->assign_vars(array('S_IN_PROGRESS' => true, 'S_COLLECTED' => (int) $update_list['status'], 'S_TO_COLLECT' => sizeof($this->update_info['files']), 'L_IN_PROGRESS' => $user->lang['COLLECTING_FILE_DIFFS'], 'L_IN_PROGRESS_EXPLAIN' => sprintf($user->lang['NUMBER_OF_FILES_COLLECTED'], (int) $update_list['status'], sizeof($this->update_info['files']) + sizeof($this->update_info['deleted'])))); return; } } if ($action == 'diff') { $this->show_diff($update_list); return; } if (sizeof($update_list['no_update'])) { $template->assign_vars(array('S_NO_UPDATE_FILES' => true, 'NO_UPDATE_FILES' => implode(', ', array_map('htmlspecialchars', $update_list['no_update'])))); } $new_expected_files = array(); // Now assign the list to the template foreach ($update_list as $status => $filelist) { if ($status == 'no_update' || !sizeof($filelist) || $status == 'status' || $status == 'status_deleted') { continue; } /* $template->assign_block_vars('files', array( 'S_STATUS' => true, 'STATUS' => $status, 'L_STATUS' => $user->lang['STATUS_' . strtoupper($status)], 'TITLE' => $user->lang['FILES_' . strtoupper($status)], 'EXPLAIN' => $user->lang['FILES_' . strtoupper($status) . '_EXPLAIN'], ) );*/ foreach ($filelist as $file_struct) { $s_binary = !empty($this->update_info['binary']) && in_array($file_struct['filename'], $this->update_info['binary']) ? true : false; $filename = htmlspecialchars($file_struct['filename']); if (strrpos($filename, '/') !== false) { $dir_part = substr($filename, 0, strrpos($filename, '/') + 1); $file_part = substr($filename, strrpos($filename, '/') + 1); } else { $dir_part = ''; $file_part = $filename; } $diff_url = append_sid($this->p_master->module_url, "language={$language}&mode={$mode}&sub=file_check&action=diff&status={$status}&file=" . urlencode($file_struct['filename'])); if (isset($file_struct['as_expected']) && $file_struct['as_expected']) { $new_expected_files[$file_struct['filename']] = $expected_files[$file_struct['filename']]; } else { $template->assign_block_vars($status, array('STATUS' => $status, 'FILENAME' => $filename, 'DIR_PART' => $dir_part, 'FILE_PART' => $file_part, 'NUM_CONFLICTS' => isset($file_struct['conflicts']) ? $file_struct['conflicts'] : 0, 'S_CUSTOM' => $file_struct['custom'] ? true : false, 'S_BINARY' => $s_binary, 'CUSTOM_ORIGINAL' => $file_struct['custom'] ? $file_struct['original'] : '', 'U_SHOW_DIFF' => $diff_url, 'L_SHOW_DIFF' => $status != 'up_to_date' ? $user->lang['SHOW_DIFF_' . strtoupper($status)] : '', 'U_VIEW_MOD_FILE' => $diff_url . '&op=' . MERGE_MOD_FILE, 'U_VIEW_NEW_FILE' => $diff_url . '&op=' . MERGE_NEW_FILE, 'U_VIEW_NO_MERGE_MOD' => $diff_url . '&op=' . MERGE_NO_MERGE_MOD, 'U_VIEW_NO_MERGE_NEW' => $diff_url . '&op=' . MERGE_NO_MERGE_NEW)); } } } $cache->put('_expected_files', $new_expected_files); $all_up_to_date = true; foreach ($update_list as $status => $filelist) { if ($status != 'up_to_date' && $status != 'custom' && $status != 'status' && $status != 'status_deleted' && sizeof($filelist)) { $all_up_to_date = false; break; } } $template->assign_vars(array('S_FILE_CHECK' => true, 'S_ALL_UP_TO_DATE' => $all_up_to_date, 'S_VERSION_UP_TO_DATE' => $up_to_date, 'S_UP_TO_DATE' => $up_to_date, 'U_ACTION' => append_sid($this->p_master->module_url, "language={$language}&mode={$mode}&sub=file_check"), 'U_UPDATE_ACTION' => append_sid($this->p_master->module_url, "language={$language}&mode={$mode}&sub=update_files"), 'U_DB_UPDATE_ACTION' => append_sid($this->p_master->module_url, "language={$language}&mode={$mode}&sub=update_db"))); // Since some people try to update to RC releases, but phpBB.com tells them the last version is the version they currently run // we are faced with the updater thinking the database schema is up-to-date; which it is, but should be updated none-the-less // We now try to cope with this by triggering the update process if (version_compare(str_replace('rc', 'RC', strtolower($this->current_version)), str_replace('rc', 'RC', strtolower($this->update_info['version']['to'])), '<')) { $template->assign_vars(array('S_UP_TO_DATE' => false)); } if ($all_up_to_date) { global $phpbb_container; $phpbb_log = $phpbb_container->get('log'); // Add database update to log $phpbb_log->add('admin', $user->data['user_id'], $user->ip, 'LOG_UPDATE_PHPBB', time(), array($this->current_version, $this->update_to_version)); $db->sql_return_on_error(true); $db->sql_query('DELETE FROM ' . CONFIG_TABLE . " WHERE config_name = 'version_update_from'"); $db->sql_return_on_error(false); $cache->purge(); } break; case 'update_files': $this->page_title = 'STAGE_UPDATE_FILES'; $s_hidden_fields = ''; $params = array(); $conflicts = request_var('conflict', array('' => 0)); $modified = request_var('modified', array('' => 0)); foreach ($conflicts as $filename => $merge_option) { $s_hidden_fields .= '<input type="hidden" name="conflict[' . htmlspecialchars($filename) . ']" value="' . $merge_option . '" />'; $params[] = 'conflict[' . urlencode($filename) . ']=' . urlencode($merge_option); } foreach ($modified as $filename => $merge_option) { if (!$merge_option) { continue; } $s_hidden_fields .= '<input type="hidden" name="modified[' . htmlspecialchars($filename) . ']" value="' . $merge_option . '" />'; $params[] = 'modified[' . urlencode($filename) . ']=' . urlencode($merge_option); } $no_update = request_var('no_update', array(0 => '')); foreach ($no_update as $index => $filename) { $s_hidden_fields .= '<input type="hidden" name="no_update[]" value="' . htmlspecialchars($filename) . '" />'; $params[] = 'no_update[]=' . urlencode($filename); } // Before the user is choosing his preferred method, let's create the content list... $update_list = $cache->get('_update_list'); if ($update_list === false) { trigger_error($user->lang['NO_UPDATE_INFO'], E_USER_ERROR); } // Check if the conflicts data is valid if (sizeof($conflicts)) { $conflict_filenames = array(); foreach ($update_list['conflict'] as $files) { $conflict_filenames[] = $files['filename']; } $new_conflicts = array(); foreach ($conflicts as $filename => $diff_method) { if (in_array($filename, $conflict_filenames)) { $new_conflicts[$filename] = $diff_method; } } $conflicts = $new_conflicts; } // Build list for modifications if (sizeof($modified)) { $modified_filenames = array(); foreach ($update_list['modified'] as $files) { $modified_filenames[] = $files['filename']; } $new_modified = array(); foreach ($modified as $filename => $diff_method) { if (in_array($filename, $modified_filenames)) { $new_modified[$filename] = $diff_method; } } $modified = $new_modified; } // Check number of conflicting files, they need to be equal. For modified files the number can differ if (sizeof($update_list['conflict']) != sizeof($conflicts)) { trigger_error($user->lang['MERGE_SELECT_ERROR'], E_USER_ERROR); } // Before we do anything, let us diff the files and store the raw file information "somewhere" $get_files = false; $file_list = $cache->get('_diff_files'); $expected_files = $cache->get('_expected_files'); if ($file_list === false || $file_list['status'] != -1) { $get_files = true; } if ($get_files) { if ($file_list === false) { $file_list = array('status' => 0); } if (!isset($expected_files) || $expected_files === false) { $expected_files = array(); } $processed = 0; foreach ($update_list as $status => $files) { if (!is_array($files)) { continue; } foreach ($files as $file_struct) { // Skip this file if the user selected to not update it if (in_array($file_struct['filename'], $no_update)) { $expected_files[$file_struct['filename']] = false; continue; } // Already handled... then skip of course... if (isset($file_list[$file_struct['filename']])) { continue; } // Refresh if we reach 5 diffs... if ($processed >= 5) { $cache->put('_diff_files', $file_list); if ($request->variable('download', false)) { $params[] = 'download=1'; } $redirect_url = append_sid($this->p_master->module_url, "language={$language}&mode={$mode}&sub=update_files&" . implode('&', $params)); meta_refresh(3, $redirect_url); $template->assign_vars(array('S_IN_PROGRESS' => true, 'L_IN_PROGRESS' => $user->lang['MERGING_FILES'], 'L_IN_PROGRESS_EXPLAIN' => $user->lang['MERGING_FILES_EXPLAIN'])); return; } if (file_exists($phpbb_root_path . $file_struct['filename'])) { $contents = file_get_contents($phpbb_root_path . $file_struct['filename']); if (isset($expected_files[$file_struct['filename']]) && md5($contents) == $expected_files[$file_struct['filename']]) { continue; } } $original_filename = $file_struct['custom'] ? $file_struct['original'] : $file_struct['filename']; switch ($status) { case 'modified': $option = isset($modified[$file_struct['filename']]) ? $modified[$file_struct['filename']] : 0; switch ($option) { case MERGE_NO_MERGE_NEW: $contents = file_get_contents($this->new_location . $original_filename); break; case MERGE_NO_MERGE_MOD: $contents = file_get_contents($phpbb_root_path . $file_struct['filename']); break; default: $diff = $this->return_diff($this->old_location . $original_filename, $phpbb_root_path . $file_struct['filename'], $this->new_location . $original_filename); $contents = implode("\n", $diff->merged_output()); unset($diff); break; } $expected_files[$file_struct['filename']] = md5($contents); $file_list[$file_struct['filename']] = '_file_' . md5($file_struct['filename']); $cache->put($file_list[$file_struct['filename']], base64_encode($contents)); $file_list['status']++; $processed++; break; case 'conflict': $option = $conflicts[$file_struct['filename']]; $contents = ''; switch ($option) { case MERGE_NO_MERGE_NEW: $contents = file_get_contents($this->new_location . $original_filename); break; case MERGE_NO_MERGE_MOD: $contents = file_get_contents($phpbb_root_path . $file_struct['filename']); break; default: $diff = $this->return_diff($this->old_location . $original_filename, $phpbb_root_path . $file_struct['filename'], $this->new_location . $original_filename); if ($option == MERGE_NEW_FILE) { $contents = implode("\n", $diff->merged_new_output()); } else { if ($option == MERGE_MOD_FILE) { $contents = implode("\n", $diff->merged_orig_output()); } else { unset($diff); break 2; } } unset($diff); break; } $expected_files[$file_struct['filename']] = md5($contents); $file_list[$file_struct['filename']] = '_file_' . md5($file_struct['filename']); $cache->put($file_list[$file_struct['filename']], base64_encode($contents)); $file_list['status']++; $processed++; break; } } } $cache->put('_expected_files', $expected_files); } $file_list['status'] = -1; $cache->put('_diff_files', $file_list); if ($request->variable('download', false)) { $this->include_file('includes/functions_compress.' . $phpEx); $use_method = request_var('use_method', ''); $methods = array('.tar'); $available_methods = array('.tar.gz' => 'zlib', '.tar.bz2' => 'bz2', '.zip' => 'zlib'); foreach ($available_methods as $type => $module) { if (!@extension_loaded($module)) { continue; } $methods[] = $type; } // Let the user decide in which format he wants to have the pack if (!$use_method) { $this->page_title = 'SELECT_DOWNLOAD_FORMAT'; $radio_buttons = ''; foreach ($methods as $method) { $radio_buttons .= '<label><input type="radio"' . (!$radio_buttons ? ' id="use_method"' : '') . ' class="radio" value="' . $method . '" name="use_method" /> ' . $method . '</label>'; } $template->assign_vars(array('S_DOWNLOAD_FILES' => true, 'U_ACTION' => append_sid($this->p_master->module_url, "language={$language}&mode={$mode}&sub=update_files"), 'RADIO_BUTTONS' => $radio_buttons, 'S_HIDDEN_FIELDS' => $s_hidden_fields)); // To ease the update process create a file location map $update_list = $cache->get('_update_list'); $script_path = $config['force_server_vars'] ? $config['script_path'] == '/' ? '/' : $config['script_path'] . '/' : $user->page['root_script_path']; foreach ($update_list as $status => $files) { if ($status == 'up_to_date' || $status == 'no_update' || $status == 'status' || $status == 'status_deleted') { continue; } foreach ($files as $file_struct) { if (in_array($file_struct['filename'], $no_update)) { continue; } $template->assign_block_vars('location', array('SOURCE' => htmlspecialchars($file_struct['filename']), 'DESTINATION' => $script_path . htmlspecialchars($file_struct['filename']))); } } return; } if (!in_array($use_method, $methods)) { $use_method = '.tar'; } $update_mode = 'download'; } else { $this->include_file('includes/functions_transfer.' . $phpEx); // Choose FTP, if not available use fsock... $method = basename(request_var('method', '')); $submit = isset($_POST['submit']) ? true : false; $test_ftp_connection = request_var('test_connection', ''); if (!$method || !class_exists($method)) { $method = 'ftp'; $methods = transfer::methods(); if (!in_array('ftp', $methods)) { $method = $methods[0]; } } $test_connection = false; if ($test_ftp_connection || $submit) { $transfer = new $method(request_var('host', ''), request_var('username', ''), htmlspecialchars_decode($request->untrimmed_variable('password', '')), request_var('root_path', ''), request_var('port', ''), request_var('timeout', '')); $test_connection = $transfer->open_session(); // Make sure that the directory is correct by checking for the existence of common.php if ($test_connection === true) { // Check for common.php file if (!$transfer->file_exists($phpbb_root_path, 'common.' . $phpEx)) { $test_connection = 'ERR_WRONG_PATH_TO_PHPBB'; } } $transfer->close_session(); // Make sure the login details are correct before continuing if ($submit && $test_connection !== true) { $submit = false; $test_ftp_connection = true; } } $s_hidden_fields .= build_hidden_fields(array('method' => $method)); if (!$submit) { $this->page_title = 'SELECT_FTP_SETTINGS'; if (!class_exists($method)) { trigger_error('Method does not exist.', E_USER_ERROR); } $requested_data = call_user_func(array($method, 'data')); foreach ($requested_data as $data => $default) { $template->assign_block_vars('data', array('DATA' => $data, 'NAME' => $user->lang[strtoupper($method . '_' . $data)], 'EXPLAIN' => $user->lang[strtoupper($method . '_' . $data) . '_EXPLAIN'], 'DEFAULT' => $request->variable($data, (string) $default))); } $template->assign_vars(array('S_CONNECTION_SUCCESS' => $test_ftp_connection && $test_connection === true ? true : false, 'S_CONNECTION_FAILED' => $test_ftp_connection && $test_connection !== true ? true : false, 'ERROR_MSG' => $test_ftp_connection && $test_connection !== true ? $user->lang[$test_connection] : '', 'S_FTP_UPLOAD' => true, 'UPLOAD_METHOD' => $method, 'U_ACTION' => append_sid($this->p_master->module_url, "language={$language}&mode={$mode}&sub=update_files"), 'U_DOWNLOAD_METHOD' => append_sid($this->p_master->module_url, "language={$language}&mode={$mode}&sub=update_files&download=1"), 'S_HIDDEN_FIELDS' => $s_hidden_fields)); return; } $update_mode = 'upload'; } // Now update the installation or download the archive... $download_filename = 'update_' . $this->update_info['version']['from'] . '_to_' . $this->update_info['version']['to']; $archive_filename = $download_filename . '_' . time() . '_' . unique_id(); // Now init the connection if ($update_mode == 'download') { if (function_exists('phpbb_is_writable') && !phpbb_is_writable($phpbb_root_path . 'store/')) { trigger_error(sprintf('The directory “%s” is not writable.', $phpbb_root_path . 'store/'), E_USER_ERROR); } if ($use_method == '.zip') { $compress = new compress_zip('w', $phpbb_root_path . 'store/' . $archive_filename . $use_method); } else { $compress = new compress_tar('w', $phpbb_root_path . 'store/' . $archive_filename . $use_method, $use_method); } } else { $transfer = new $method(request_var('host', ''), request_var('username', ''), htmlspecialchars_decode($request->untrimmed_variable('password', '')), request_var('root_path', ''), request_var('port', ''), request_var('timeout', '')); $transfer->open_session(); } // Ok, go through the update list and do the operations based on their status foreach ($update_list as $status => $files) { if (!is_array($files)) { continue; } foreach ($files as $file_struct) { // Skip this file if the user selected to not update it if (in_array($file_struct['filename'], $no_update)) { continue; } $original_filename = $file_struct['custom'] ? $file_struct['original'] : $file_struct['filename']; switch ($status) { case 'new': case 'new_conflict': case 'not_modified': if ($update_mode == 'download') { $compress->add_custom_file($this->new_location . $original_filename, $file_struct['filename']); } else { if ($status != 'new') { $transfer->rename($file_struct['filename'], $file_struct['filename'] . '.bak'); } // New directory too? $dirname = dirname($file_struct['filename']); if ($dirname && !file_exists($phpbb_root_path . $dirname)) { $transfer->make_dir($dirname); } $transfer->copy_file($this->new_location . $original_filename, $file_struct['filename']); } break; case 'modified': $contents = base64_decode($cache->get($file_list[$file_struct['filename']])); if ($update_mode == 'download') { $compress->add_data($contents, $file_struct['filename']); } else { // @todo add option to specify if a backup file should be created? $transfer->rename($file_struct['filename'], $file_struct['filename'] . '.bak'); $transfer->write_file($file_struct['filename'], $contents); } break; case 'conflict': $contents = base64_decode($cache->get($file_list[$file_struct['filename']])); if ($update_mode == 'download') { $compress->add_data($contents, $file_struct['filename']); } else { $transfer->rename($file_struct['filename'], $file_struct['filename'] . '.bak'); $transfer->write_file($file_struct['filename'], $contents); } break; case 'deleted': if ($update_mode != 'download') { $transfer->rename($file_struct['filename'], $file_struct['filename'] . '.bak'); } break; } } } if ($update_mode == 'download') { $compress->close(); $compress->download($archive_filename, $download_filename); @unlink($phpbb_root_path . 'store/' . $archive_filename . $use_method); exit; } else { $transfer->close_session(); $template->assign_vars(array('S_UPLOAD_SUCCESS' => true, 'U_ACTION' => append_sid($this->p_master->module_url, "language={$language}&mode={$mode}&sub=file_check"))); return; } break; } }
set_time_limit(0); error_reporting(E_ALL ^ E_NOTICE); include_once "../config/config.php"; $link = mysql_connect(DB_HOST, DB_USER, DB_PASSWORD); mysql_select_db(DB_NAME); mysql_query("set names utf8"); ?> <html> <head> <title>ShopEx数据转换程序</title> <META HTTP-EQUIV="content-type" CONTENT="text/html; charset=UTF-8"> </head> <body style="font-size:16px;"> <?php $do = new transfer(); $do->orderDetail(); $do->orderItems(); $do->memberLevel(); $do->memberDetail(); class transfer { var $dbPrefix = DB_PREFIX; function orderDetail() { //清空会员等级相关表 $aTable = array($this->dbPrefix . 'orders', $this->dbPrefix . 'order_items', $this->dbPrefix . 'order_log', $this->dbPrefix . 'order_pmt'); $this->truncate($aTable); //////////////////////////////////////////////////// $aMap = array('order_id' => 'orderid', 'member_id' => 'userid', 'confirm' => '', 'status' => '', 'pay_status' => 'ifsk', 'ship_status' => '', 'user_status' => '', 'is_delivery' => '', 'shipping_id' => 'ttype', 'shipping' => '', 'shipping_area' => '', 'payment' => 'ptype', 'weight' => 'weight', 'tostr' => '', 'itemnum' => '', 'acttime' => 'paytime', 'createtime' => 'ordertime', 'refer_id' => '', 'refer_url' => '', 'ip' => 'ip', 'ship_name' => 'name', 'ship_area' => '', 'ship_addr' => 'addr', 'ship_zip' => 'zip', 'ship_tel' => 'tel', 'ship_email' => 'email', 'ship_time' => 'sendtime', 'ship_mobile' => 'mobile', 'cost_item' => 'item_amount', 'is_tax' => '', 'cost_tax' => '', 'tax_company' => '', 'cost_freight' => 'freight', 'is_protect' => '', 'cost_protect' => '', 'cost_payment' => '', 'currency' => 'paycur', 'cur_rate' => '', 'score_u' => 'orderpoint', 'score_g' => 'getpoint', 'advance' => '', 'discount' => '', 'use_pmt' => '', 'total_amount' => 'total_amount', 'final_amount' => 'total_amount', 'pmt_amount' => '', 'payed' => 'paymoney', 'markstar' => '', 'memo' => 'memo', 'print_status' => '', 'mark_text' => '', 'disabled' => '', 'last_change_time' => '', 'use_registerinfo' => '', 'mark_type' => ''); $to = $this->dbPrefix . 'orders';
function main($id, $mode) { global $config, $db, $user, $auth, $template, $cache; global $phpbb_root_path, $phpEx; global $ftp_method, $test_ftp_connection, $test_connection, $sort_key, $sort_dir; include "{$phpbb_root_path}includes/functions_transfer.{$phpEx}"; include "{$phpbb_root_path}includes/editor.{$phpEx}"; include "{$phpbb_root_path}includes/functions_mods.{$phpEx}"; include "{$phpbb_root_path}includes/mod_parser.{$phpEx}"; // start the page $user->add_lang(array('install', 'acp/mods')); $this->tpl_name = 'acp_mods'; $this->page_title = 'ACP_CAT_MODS'; $this->store_dir = $phpbb_root_path . 'store'; $this->mods_dir = $phpbb_root_path . 'store/mods'; // get any url vars $action = request_var('action', ''); $mod_id = request_var('mod_id', 0); $mod_url = request_var('mod_url', ''); $parent = request_var('parent', 0); //sort keys $sort_key = request_var('sk', 't'); $sort_dir = request_var('sd', 'a'); $mod_path = request_var('mod_path', ''); if ($mod_path) { $mod_path = htmlspecialchars_decode($mod_path); // "/my_mod/install.xml" or "/./contrib/blah.xml" $mod_dir = substr($mod_path, 1, strpos($mod_path, '/', 1)); // "my_mod/" $this->mod_root = $this->mods_dir . '/' . $mod_dir; // "./../store/mods/my_mod/" $this->backup_root = "{$this->mod_root}_backups/"; // "./../store/mods/my_mod/_backups/" $this->edited_root = "{$this->mod_root}_edited/"; // "./../store/mods/my_mod/_edited/" } switch ($mode) { case 'config': $ftp_method = request_var('ftp_method', $config['ftp_method']); if (!$ftp_method || !class_exists($ftp_method)) { $ftp_method = 'ftp'; $ftp_methods = transfer::methods(); if (!in_array('ftp', $ftp_methods)) { $ftp_method = $ftp_methods[0]; } } if (isset($_POST['submit']) && check_form_key('acp_mods')) { $ftp_host = request_var('host', ''); $ftp_username = request_var('username', ''); $ftp_password = request_var('password', ''); // not stored, used to test connection $ftp_root_path = request_var('root_path', ''); $ftp_port = request_var('port', 21); $ftp_timeout = request_var('timeout', 10); $write_method = request_var('write_method', 0); $file_perms = request_var('file_perms', '0644'); $dir_perms = request_var('dir_perms', '0755'); $compress_method = request_var('compress_method', ''); $preview_changes = request_var('preview_changes', 0); $error = ''; if ($write_method == WRITE_DIRECT) { // the very best method would be to check every file for is_writable if (!is_writable("{$phpbb_root_path}common.{$phpEx}") || !is_writable("{$phpbb_root_path}adm/style/acp_groups.html")) { $error = 'FILESYSTEM_NOT_WRITABLE'; } } else { if ($write_method == WRITE_FTP) { // check the correctness of FTP infos $test_ftp_connection = true; $test_connection = false; test_ftp_connection($ftp_method, $test_ftp_connection, $test_connection); if ($test_connection !== true) { $error = $test_connection; } } else { if ($write_method == WRITE_MANUAL) { // the compress class requires write access to the store/ dir if (!is_writable($this->store_dir)) { $error = 'STORE_NOT_WRITABLE'; } } } } if (empty($error)) { set_config('ftp_method', $ftp_method); set_config('ftp_host', $ftp_host); set_config('ftp_username', $ftp_username); set_config('ftp_root_path', $ftp_root_path); set_config('ftp_port', $ftp_port); set_config('ftp_timeout', $ftp_timeout); set_config('write_method', $write_method); set_config('compress_method', $compress_method); set_config('preview_changes', $preview_changes); set_config('am_file_perms', $file_perms); set_config('am_dir_perms', $dir_perms); trigger_error($user->lang['MOD_CONFIG_UPDATED'] . adm_back_link($this->u_action)); } else { $template->assign_var('ERROR', $user->lang[$error]); } } else { if (isset($_POST['submit']) && !check_form_key('acp_mods')) { trigger_error($user->lang['FORM_INVALID'] . adm_back_link($this->u_action), E_USER_WARNING); } } add_form_key('acp_mods'); // implicit else include "{$phpbb_root_path}includes/functions_compress.{$phpEx}"; foreach (compress::methods() as $compress_method) { $template->assign_block_vars('compress', array('METHOD' => $compress_method)); } $requested_data = call_user_func(array($ftp_method, 'data')); foreach ($requested_data as $data => $default) { $default = !empty($config['ftp_' . $data]) ? $config['ftp_' . $data] : $default; $template->assign_block_vars('data', array('DATA' => $data, 'NAME' => $user->lang[strtoupper($ftp_method . '_' . $data)], 'EXPLAIN' => $user->lang[strtoupper($ftp_method . '_' . $data) . '_EXPLAIN'], 'DEFAULT' => !empty($_REQUEST[$data]) ? request_var($data, '') : $default)); } $template->assign_vars(array('S_CONFIG' => true, 'U_CONFIG' => $this->u_action . '&mode=config', 'UPLOAD_METHOD_FTP' => $config['ftp_method'] == 'ftp' ? ' checked="checked"' : '', 'UPLOAD_METHOD_FSOCK' => $config['ftp_method'] == 'ftp_fsock' ? ' checked="checked"' : '', 'WRITE_DIRECT' => $config['write_method'] == WRITE_DIRECT ? ' checked="checked"' : '', 'WRITE_FTP' => $config['write_method'] == WRITE_FTP ? ' checked="checked"' : '', 'WRITE_MANUAL' => $config['write_method'] == WRITE_MANUAL ? ' checked="checked"' : '', 'WRITE_METHOD_DIRECT' => WRITE_DIRECT, 'WRITE_METHOD_FTP' => WRITE_FTP, 'WRITE_METHOD_MANUAL' => WRITE_MANUAL, 'AUTOMOD_VERSION' => $config['automod_version'], 'COMPRESS_METHOD' => $config['compress_method'], 'DIR_PERMS' => $config['am_dir_perms'], 'FILE_PERMS' => $config['am_file_perms'], 'PREVIEW_CHANGES_YES' => $config['preview_changes'] ? ' checked="checked"' : '', 'PREVIEW_CHANGES_NO' => !$config['preview_changes'] ? ' checked="checked"' : '', 'S_HIDE_FTP' => $config['write_method'] == WRITE_FTP ? false : true)); break; case 'frontend': if ($config['write_method'] == WRITE_FTP) { $ftp_method = basename(request_var('method', $config['ftp_method'])); if (!$ftp_method || !class_exists($ftp_method)) { $ftp_method = 'ftp'; $ftp_methods = transfer::methods(); if (!in_array('ftp', $ftp_methods)) { $ftp_method = $ftp_methods[0]; } } $test_connection = false; $test_ftp_connection = request_var('test_connection', ''); if (!empty($test_ftp_connection) || in_array($action, array('install', 'uninstall', 'upload_mod', 'delete_mod'))) { test_ftp_connection($ftp_method, $test_ftp_connection, $test_connection); // Make sure the login details are correct before continuing if ($test_connection !== true || !empty($test_ftp_connection)) { $action = 'pre_' . $action; } } } // store/ needs to be world-writable even when FTP is the write method, // for extracting uploaded mod zip files if (!is_writable($this->store_dir)) { $template->assign_var('S_STORE_WRITABLE_WARN', true); } else { if ($config['write_method'] != WRITE_FTP && !is_writable($this->mods_dir)) { $template->assign_var('S_MODS_WRITABLE_WARN', true); } } switch ($action) { case 'pre_install': case 'install': $this->install($action, $mod_path, $parent); break; case 'pre_uninstall': case 'uninstall': $this->uninstall($action, $mod_id, $parent); break; case 'details': $mod_ident = $mod_id ? $mod_id : $mod_path; $this->list_details($mod_ident); break; case 'pre_delete_mod': case 'delete_mod': $this->delete_mod($action, $mod_path); break; case 'pre_upload_mod': case 'upload_mod': default: $action = isset($action) ? $action : ''; if (!$this->upload_mod($action)) { $this->list_installed(); $this->list_uninstalled(); } break; case 'download': include $phpbb_root_path . "includes/functions_compress.{$phpEx}"; $editor = new editor_manual(); $time = request_var('time', 0); // if for some reason the MOD isn't found in the DB... $download_name = 'mod_' . $time; $sql = 'SELECT mod_name FROM ' . MODS_TABLE . ' WHERE mod_time = ' . $time; $result = $db->sql_query($sql); if ($row = $db->sql_fetchrow($result)) { // Always use the English name except for showing the user. $mod_name = localize_title($row['mod_name'], 'en'); $download_name = str_replace(' ', '_', $mod_name); } $editor->compress->download("{$this->store_dir}/mod_{$time}", $download_name); exit; break; } return; break; } }