drop_table_if_exists('import_id_remap'); $GLOBALS['SITE_DB']->drop_table_if_exists('import_session'); $GLOBALS['SITE_DB']->drop_table_if_exists('import_parts_done'); $GLOBALS['SITE_DB']->query_delete('group_page_access', array('page_name' => 'admin_import')); } /** * Install the module. * * @param ?integer $upgrade_from What version we're upgrading from (null: new install) * @param ?integer $upgrade_from_hack What hack version we're upgrading from (null: new-install/not-upgrading-from-a-hacked-version) */ public function install($upgrade_from = null, $upgrade_from_hack = null) { if ((!is_null($upgrade_from)) && ($upgrade_from < 7)) { $GLOBALS['SITE_DB']->alter_table_field('import_id_remap', 'id_session', '*ID_TEXT'); $GLOBALS['SITE_DB']->alter_table_field('import_session', 'imp_session', '*ID_TEXT'); $GLOBALS['SITE_DB']->add_auto_key('import_parts_done'); $GLOBALS['SITE_DB']->alter_table_field('import_parts_done', 'imp_session', 'ID_TEXT'); if ((strpos(get_db_type(), 'mysql') !== false) && (get_charset() == 'utf-8')) { // Could not be made utf8mb4 in advance but can be now because 'id' fields was added as the key $GLOBALS['SITE_DB']->query('ALTER TABLE ' . get_table_prefix() . 'import_parts_done CONVERT TO CHARACTER SET utf8mb4'); } } if ((!is_null($upgrade_from)) && ($upgrade_from < 6)) { $GLOBALS['SITE_DB']->add_table_field('import_session', 'imp_db_host', 'ID_TEXT'); } if ((!is_null($upgrade_from)) && ($upgrade_from < 5)) { $GLOBALS['SITE_DB']->alter_table_field('import_id_remap', 'id_old', 'ID_TEXT'); } if ((is_null($upgrade_from)) || ($upgrade_from < 4)) { $GLOBALS['SITE_DB']->create_table('import_parts_done', array( 'id' => '*AUTO', 'imp_id' => 'SHORT_TEXT', 'imp_session' => 'ID_TEXT', )); $GLOBALS['SITE_DB']->create_table('import_session', array( 'imp_session' => '*ID_TEXT', 'imp_old_base_dir' => 'SHORT_TEXT', 'imp_db_host' => 'ID_TEXT', 'imp_db_name' => 'ID_TEXT', 'imp_db_user' => 'ID_TEXT', 'imp_db_table_prefix' => 'ID_TEXT', 'imp_hook' => 'ID_TEXT', 'imp_refresh_time' => 'INTEGER', )); $usergroups = $GLOBALS['FORUM_DRIVER']->get_usergroup_list(false, true); foreach (array_keys($usergroups) as $id) { $GLOBALS['SITE_DB']->query_insert('group_page_access', array('page_name' => 'admin_import', 'zone_name' => 'adminzone', 'group_id' => $id)); // Import very dangerous } $GLOBALS['SITE_DB']->create_table('import_id_remap', array( 'id_old' => '*ID_TEXT', 'id_new' => 'AUTO_LINK', 'id_type' => '*ID_TEXT', 'id_session' => '*ID_TEXT' )); } } /** * Find entry-points available within this module. * * @param boolean $check_perms Whether to check permissions. * @param ?MEMBER $member_id The member to check permissions as (null: current user). * @param boolean $support_crosslinks Whether to allow cross links to other modules (identifiable via a full-page-link rather than a screen-name). * @param boolean $be_deferential Whether to avoid any entry-point (or even return null to disable the page in the Sitemap) if we know another module, or page_group, is going to link to that entry-point. Note that "!" and "browse" entry points are automatically merged with container page nodes (likely called by page-groupings) as appropriate. * @return ?array A map of entry points (screen-name=>language-code/string or screen-name=>[language-code/string, icon-theme-image]) (null: disabled). */ public function get_entry_points($check_perms = true, $member_id = null, $support_crosslinks = true, $be_deferential = false) { return array( 'browse' => array('IMPORT', 'menu/_generic_admin/import'), ); } public $title; /** * Module pre-run function. Allows us to know metadata for before we start streaming output. * * @return ?Tempcode Tempcode indicating some kind of exceptional output (null: none). */ public function pre_run() { $type = get_param_string('type', 'browse'); require_lang('import'); set_helper_panel_tutorial('tut_importer'); if ($type == 'browse') { breadcrumb_set_self(do_lang_tempcode('IMPORT')); } if ($type == 'session') { breadcrumb_set_parents(array(array('_SELF:_SELF:browse', do_lang_tempcode('IMPORT')))); breadcrumb_set_self(do_lang_tempcode('IMPORT_SESSION')); } if ($type == 'session2') { breadcrumb_set_parents(array(array('_SELF:_SELF:browse', do_lang_tempcode('IMPORT')), array('_SELF:_SELF:session:session=' . get_session_id(), do_lang_tempcode('IMPORT_SESSION')))); } if ($type == 'hook') { $importer = filter_naughty(get_param_string('importer')); breadcrumb_set_parents(array(array('_SELF:_SELF:browse', do_lang_tempcode('IMPORT')), array('_SELF:_SELF:session:session=' . get_session_id() . ':importer=' . $importer, do_lang_tempcode('IMPORT_SESSION')))); } if ($type == 'import') { $importer = filter_naughty(get_param_string('importer')); breadcrumb_set_parents(array(array('_SELF:_SELF:browse', do_lang_tempcode('IMPORT')), array('_SELF:_SELF:session:session=' . get_session_id() . ':importer=' . $importer, do_lang_tempcode('IMPORT_SESSION')))); breadcrumb_set_self(do_lang_tempcode('ACTIONS')); } $this->title = get_screen_title('IMPORT'); return null; } /** * Execute the module. * * @return Tempcode The result of execution. */ public function run() { if (!is_null($GLOBALS['CURRENT_SHARE_USER'])) { warn_exit(do_lang_tempcode('SHARED_INSTALL_PROHIBIT')); } disable_php_memory_limit(); require_code('import'); load_import_deps(); $GLOBALS['LAX_COMCODE'] = true; set_mass_import_mode(); // Decide what we're doing $type = get_param_string('type', 'browse'); if ($type == 'browse') { return $this->choose_importer(); } if ($type == 'session') { return $this->choose_session(); } if ($type == 'session2') { return $this->choose_session2(); } if ($type == 'hook') { return $this->choose_actions(); } if ($type == 'import') { return $this->do_import(); } return new Tempcode(); } /** * The UI to choose an importer. * * @return Tempcode The UI */ public function choose_importer() { $hooks = new Tempcode(); $_hooks = find_all_hooks('modules', 'admin_import'); $__hooks = array(); require_code('form_templates'); foreach (array_keys($_hooks) as $hook) { require_code('hooks/modules/admin_import/' . filter_naughty_harsh($hook)); if (class_exists('Hook_' . filter_naughty_harsh($hook))) { $object = object_factory('Hook_' . filter_naughty_harsh($hook), true); if (is_null($object)) { continue; } $info = $object->info(); $__hooks[$hook] = $info['product']; } } uasort($__hooks, 'strnatcmp'); foreach ($__hooks as $hook => $hook_title) { $hooks->attach(form_input_list_entry($hook, false, $hook_title)); } if ($hooks->is_empty()) { warn_exit(do_lang_tempcode('NO_CATEGORIES')); } $fields = form_input_huge_list(do_lang_tempcode('IMPORTER'), do_lang_tempcode('DESCRIPTION_IMPORTER'), 'importer', $hooks, null, true); $post_url = build_url(array('page' => '_SELF', 'type' => 'session'), '_SELF'); return do_template('FORM_SCREEN', array('_GUID' => '02416e5e9d6cb64248adeb9d2e6f2402', 'GET' => true, 'HIDDEN' => '', 'SKIP_WEBSTANDARDS' => true, 'SUBMIT_ICON' => 'buttons__proceed', 'SUBMIT_NAME' => do_lang_tempcode('PROCEED'), 'TITLE' => $this->title, 'FIELDS' => $fields, 'URL' => $post_url, 'TEXT' => '')); } /** * The UI to choose an import session. * * @return Tempcode The UI */ public function choose_session() { // Get importer details $importer = filter_naughty(get_param_string('importer')); require_code('hooks/modules/admin_import/' . filter_naughty_harsh($importer)); $object = object_factory('Hook_' . filter_naughty_harsh($importer)); $info = $object->info(); // Code to detect redirect hooks for import if (array_key_exists('hook_type', $info)) { // Right - not a real importer, just a link over to some module's native import implementation $redirect_url = build_url(array('page' => $info['import_module'], 'type' => $info['import_method_name']), get_module_zone($info['import_module'])); return redirect_screen($this->title, $redirect_url, do_lang_tempcode('REDIRECTED_TO_CACHE_MODULES')); } // List of sessions $sessions = new Tempcode(); $_sessions = $GLOBALS['SITE_DB']->query_select('import_session', array('*')); require_code('form_templates'); foreach ($_sessions as $session) { if ($session['imp_session'] == get_session_id()) { $text = do_lang_tempcode('IMPORT_SESSION_CURRENT', escape_html($session['imp_db_name'] . ', ' . $session['imp_session'])); } else { $text = do_lang_tempcode('IMPORT_SESSION_EXISTING_REMAP', escape_html($session['imp_db_name'] . ', ' . $session['imp_session'])); } $sessions->attach(form_input_list_entry($session['imp_session'], false, $text)); } $text = do_lang_tempcode((count($_sessions) == 0) ? 'IMPORT_SESSION_NEW' : 'IMPORT_SESSION_NEW_DELETE'); $sessions->attach(form_input_list_entry(strval(-1), false, $text)); if ($importer == 'cms_merge') { $text = do_lang_tempcode('IMPORT_SESSION_NEW_DELETE_CNS_SATELLITE'); $sessions->attach(form_input_list_entry(strval(-2), false, $text)); } $fields = form_input_list(do_lang_tempcode('IMPORT_SESSION'), do_lang_tempcode('DESCRIPTION_IMPORT_SESSION'), 'session', $sessions, null, true); $post_url = build_url(array('page' => '_SELF', 'type' => 'session2', 'importer' => get_param_string('importer')), '_SELF'); return do_template('FORM_SCREEN', array( '_GUID' => 'f474980f7263f2def2ff75e7ee40be33', 'SKIP_WEBSTANDARDS' => true, 'HIDDEN' => form_input_hidden('importer', get_param_string('importer')), 'SUBMIT_ICON' => 'buttons__proceed', 'SUBMIT_NAME' => do_lang_tempcode('CHOOSE'), 'TITLE' => $this->title, 'FIELDS' => $fields, 'URL' => $post_url, 'TEXT' => '', )); } /** * The UI to choose session details (database access details, for example). * * @return Tempcode The UI */ public function choose_session2() { // Handle selected session /* These cases: 1) We are continuing (therefore do nothing) 2) We are resuming a prior session, after our session changed (therefore remap old session-data to current session) 3) We are starting afresh (therefore delete all previous import sessions) 4) As per '3', except Conversr imports are maintained as we're now importing a satellite site */ $session = either_param_string('session', get_session_id()); if (($session == '-1') || ($session == '-2')) { // New session, with delete option for prior // Delete all others $GLOBALS['SITE_DB']->query_delete('import_session'); if ($session == '-1') { $GLOBALS['SITE_DB']->query_delete('import_parts_done'); $GLOBALS['SITE_DB']->query_delete('import_id_remap'); } else { $GLOBALS['SITE_DB']->query('DELETE FROM ' . get_table_prefix() . 'import_parts_done WHERE imp_id NOT LIKE \'' . db_encode_like('cns\_%') . '\''); $GLOBALS['SITE_DB']->query('DELETE FROM ' . get_table_prefix() . 'import_id_remap WHERE (id_type NOT LIKE \'' . db_encode_like('cns\_%') . '\'' . ') AND ' . db_string_not_equal_to('id_type', 'category') . ' AND ' . db_string_not_equal_to('id_type', 'forum') . ' AND ' . db_string_not_equal_to('id_type', 'topic') . ' AND ' . db_string_not_equal_to('id_type', 'post') . ' AND ' . db_string_not_equal_to('id_type', 'f_poll') . ' AND ' . db_string_not_equal_to('id_type', 'group') . ' AND ' . db_string_not_equal_to('id_type', 'member')); } } $this->appropriate_import_session_to_current($session); // Get importer details $importer = filter_naughty(get_param_string('importer')); require_code('hooks/modules/admin_import/' . filter_naughty_harsh($importer)); $object = object_factory('Hook_' . filter_naughty_harsh($importer)); $info = $object->info(); // Load in preexisting settings, or defaults (although if probing is supported we'll never use these) $session_row = $GLOBALS['SITE_DB']->query_select('import_session', array('*'), array('imp_session' => get_session_id()), '', 1); if (array_key_exists(0, $session_row)) { $old_base_dir = $session_row[0]['imp_old_base_dir']; $db_host = $session_row[0]['imp_db_host']; $db_name = $session_row[0]['imp_db_name']; $db_user = $session_row[0]['imp_db_user']; $db_table_prefix = $session_row[0]['imp_db_table_prefix']; $refresh_time = $session_row[0]['imp_refresh_time']; } else { $old_base_dir = get_file_base() . '/old'; $db_host = 'localhost'; $db_name = get_db_site(); $db_user = get_db_site_user(); $db_table_prefix = array_key_exists('prefix', $info) ? $info['prefix'] : $GLOBALS['SITE_DB']->get_table_prefix(); $refresh_time = 45; } // Build the form $fields = new Tempcode(); require_code('form_templates'); if ((!method_exists($object, 'probe_db_access')) || (get_param_integer('keep_manual_import_config', 0) == 1)) { // Probing either not supported or not desired, so make a proper input form $fields->attach(form_input_line(do_lang_tempcode('installer:DATABASE_HOST'), do_lang_tempcode('_FROM_IMPORTING_SYSTEM'), 'db_host', $db_host, true)); $fields->attach(form_input_line(do_lang_tempcode('installer:DATABASE_NAME'), do_lang_tempcode('_FROM_IMPORTING_SYSTEM'), 'db_name', $db_name, true)); $fields->attach(form_input_line(do_lang_tempcode('installer:DATABASE_USERNAME'), do_lang_tempcode('_FROM_IMPORTING_SYSTEM'), 'db_user', $db_user, true)); $fields->attach(form_input_password(do_lang_tempcode('installer:DATABASE_PASSWORD'), do_lang_tempcode('_FROM_IMPORTING_SYSTEM'), 'db_password', false)); // Not required as there may be a blank password $fields->attach(form_input_line(do_lang_tempcode('TABLE_PREFIX'), do_lang_tempcode('_FROM_IMPORTING_SYSTEM'), 'db_table_prefix', $db_table_prefix, false)); } $fields->attach(form_input_line(do_lang_tempcode('FILE_BASE'), do_lang_tempcode('FROM_IMPORTING_SYSTEM'), 'old_base_dir', $old_base_dir, true)); // This guides where probing will happen from if (intval(ini_get('safe_mode')) == 0) { $fields->attach(form_input_integer(do_lang_tempcode('REFRESH_TIME'), do_lang_tempcode('DESCRIPTION_REFRESH_TIME'), 'refresh_time', ($refresh_time == 0) ? null : $refresh_time, false)); } if (method_exists($object, 'get_extra_fields')) { $fields->attach($object->get_extra_fields()); } $url = build_url(array('page' => '_SELF', 'type' => 'hook', 'session' => $session, 'importer' => $importer), '_SELF'); $message = array_key_exists('message', $info) ? $info['message'] : ''; return do_template('FORM_SCREEN', array('_GUID' => '15f2c855acf0d365a2e6329bec692dc8', 'MODSECURITY_WORKAROUND' => true, 'TEXT' => $message, 'TITLE' => $this->title, 'FIELDS' => $fields, 'URL' => $url, 'HIDDEN' => '', 'SUBMIT_ICON' => 'buttons__proceed', 'SUBMIT_NAME' => do_lang_tempcode('PROCEED'))); } /** * Saves settings from choose_session2 step and/or does probing for settings. * Then shows the UI to choose what to import. * * @param mixed $extra Output to show from last action (blank: none) * @return Tempcode The UI */ public function choose_actions($extra = '') { require_code('input_filter_2'); modsecurity_workaround_enable(); $session = either_param_string('session', get_session_id()); $this->appropriate_import_session_to_current($session); // Get importer details $importer = filter_naughty(get_param_string('importer')); require_code('hooks/modules/admin_import/' . filter_naughty_harsh($importer)); $object = object_factory('Hook_' . filter_naughty_harsh($importer)); $info = $object->info(); // Get source path, and try and fix if it is incorrect $old_base_dir = either_param_string('old_base_dir'); if (!file_exists($old_base_dir)) { if ((substr($old_base_dir, 0, 1) != '/') && (file_exists('/' . $old_base_dir))) { $old_base_dir = '/' . $old_base_dir; } elseif ((substr($old_base_dir, 0, 1) != '/') && (file_exists(get_file_base() . '/' . $old_base_dir))) { $old_base_dir = get_file_base() . '/' . $old_base_dir; } elseif (file_exists(get_file_base() . $old_base_dir)) { $old_base_dir = get_file_base() . $old_base_dir; } } // Load/probe DB details $db_host = get_db_site_host(); if ((method_exists($object, 'probe_db_access')) && (get_param_integer('keep_manual_import_config', 0) == 0)) { $probe = $object->probe_db_access($old_base_dir); if (array_key_exists(4, $probe)) { $db_host = $probe[4]; if ($db_host === null) { $db_host = ''; } } list($db_name, $db_user, $db_password, $db_table_prefix) = $probe; if ($db_name === null) { $db_name = ''; } if ($db_user === null) { $db_user = ''; } if ($db_table_prefix === null) { $db_table_prefix = ''; } } else { $db_host = either_param_string('db_host', $db_host); $db_name = either_param_string('db_name'); $db_user = either_param_string('db_user'); $db_password = either_param_string('db_password'); $db_table_prefix = either_param_string('db_table_prefix'); } // Special case: Error if merging into self if (($db_name == get_db_site()) && ($importer == 'cms_merge') && ($db_table_prefix == $GLOBALS['SITE_DB']->get_table_prefix())) { warn_exit(do_lang_tempcode('IMPORT_SELF_NO')); } // Test import source is good $import_source = ($db_name === null) ? null : new DatabaseConnector($db_name, $db_host, $db_user, $db_password, $db_table_prefix); unset($import_source); // Save data from choose_session2 step $refresh_time = either_param_integer('refresh_time', 0); // Shouldn't default, but reported on some systems to do so $GLOBALS['SITE_DB']->query_delete('import_session', array('imp_session' => get_session_id()), '', 1); $GLOBALS['SITE_DB']->query_insert('import_session', array( 'imp_hook' => $importer, 'imp_old_base_dir' => $old_base_dir, 'imp_db_host' => $db_host, 'imp_db_name' => $db_name, 'imp_db_user' => $db_user, 'imp_db_table_prefix' => $db_table_prefix, 'imp_refresh_time' => $refresh_time, 'imp_session' => get_session_id() )); // Build master list of input types to select from $lang_array = array(); $hooks = find_all_hooks('modules', 'admin_import_types'); foreach (array_keys($hooks) as $hook) { require_code('hooks/modules/admin_import_types/' . filter_naughty_harsh($hook)); $_hook = object_factory('Hook_admin_import_types_' . filter_naughty_harsh($hook)); $lang_array += $_hook->run(); } // Build importer-specific list of input types to select from $_import_list = $info['import']; $_import_list_2 = array(); foreach ($_import_list as $import) { if (is_null($import)) { continue; } if (!array_key_exists($import, $lang_array)) { continue; } if (is_null($lang_array[$import])) { continue; } $text = do_lang_tempcode((strtolower($lang_array[$import]) != $lang_array[$import]) ? $lang_array[$import] : strtoupper($lang_array[$import])); $_import_list_2[$import] = $text; } if ((array_key_exists('cns_members', $_import_list_2)) && (get_forum_type() == $importer) && ($db_name == get_db_forums()) && ($db_table_prefix == $GLOBALS['FORUM_DB']->get_table_prefix())) { $_import_list_2['cns_switch'] = do_lang_tempcode('SWITCH_TO_CNS'); } $import_list = new Tempcode(); //asort($_import_list_2); Let's preserve order here $just = get_param_string('just', null); $first = true; $skip_hidden = array(); $parts_done = collapse_2d_complexity('imp_id', 'imp_session', $GLOBALS['SITE_DB']->query_select('import_parts_done', array('imp_id', 'imp_session'), array('imp_session' => get_session_id()))); foreach ($_import_list_2 as $import => $text) { if (array_key_exists($import, $parts_done)) { $import_list->attach(do_template('IMPORT_ACTION_LINE', array( '_GUID' => '887770aad4269b74fdf11d09f4ab4fa3', 'CHECKED' => false, 'DISABLED' => true, 'NAME' => 'import_' . $import, 'TEXT' => $text, 'ADVANCED_URL' => $info['supports_advanced_import'] ? build_url(array('page' => '_SELF', 'type' => 'advanced_hook', 'session' => $session, 'content_type' => $import, 'importer' => $importer), '_SELF') : new Tempcode(), ))); } else { $checked = (is_null($just)) && ($first); $import_list->attach(do_template('IMPORT_ACTION_LINE', array( '_GUID' => 'f2215115f920200a0a1ba6bc776ad945', 'CHECKED' => $checked, 'NAME' => 'import_' . $import, 'TEXT' => $text, 'ADVANCED_URL' => $info['supports_advanced_import'] ? build_url(array('page' => '_SELF', 'type' => 'advanced_hook', 'session' => $session, 'content_type' => $import, 'importer' => $importer), '_SELF') : new Tempcode() ))); } if ($just == $import) { $first = true; $just = null; } else { $first = false; } $skip_hidden[] = 'import_' . $import; } $message = array_key_exists('message', $info) ? $info['message'] : ''; if (count($parts_done) == count($_import_list_2)) { inform_exit(do_lang_tempcode(($message === '') ? '_IMPORT_ALL_FINISHED' : 'IMPORT_ALL_FINISHED', $message)); } $url = build_url(array('page' => '_SELF', 'type' => 'import', 'session' => $session, 'importer' => $importer), '_SELF'); $hidden = new Tempcode(); $hidden->attach(build_keep_post_fields($skip_hidden)); $hidden->attach(build_keep_form_fields('', true, array('type', 'label_for__old_base_dir', 'require__old_base_dir', 'label_for__refresh_time', 'require__refresh_time'))); $hidden->attach(form_input_hidden('db_password', $db_password)); return do_template('IMPORT_ACTION_SCREEN', array('_GUID' => 'a3a69637e541923ad76e9e7e6ec7e1af', 'EXTRA' => $extra, 'MESSAGE' => $message, 'TITLE' => $this->title, 'FIELDS' => '', 'HIDDEN' => $hidden, 'IMPORTER' => $importer, 'IMPORT_LIST' => $import_list, 'URL' => $url)); } /** * The actualiser to do an import. Import the chosen import types. * * @return Tempcode The UI */ public function do_import() { $session = either_param_string('session', get_session_id()); $this->appropriate_import_session_to_current($session); // Get importer details $importer = get_param_string('importer'); require_code('hooks/modules/admin_import/' . filter_naughty_harsh($importer)); $object = object_factory('Hook_' . filter_naughty_harsh($importer)); $info = $object->info(); // Protection from if things take too long $refresh_url = get_self_url(true, false, array('type' => 'import'), false, true); $refresh_time = either_param_integer('refresh_time', 0); // Shouldn't default, but reported on some systems to do so if (php_function_allowed('set_time_limit')) { @set_time_limit($refresh_time); // We cannot rely on this as the timer doesn't count DB activity etc on most PHP platforms but something like a CGI timeout will; hence register_tick_function also below safe_ini_set('display_errors', '0'); // So that the timeout message does not show, which made the user not think the refresh was going to happen automatically, and could thus result in double-requests } send_http_output_ping(); safe_ini_set('log_errors', '0'); global $I_REFRESH_URL, $I_REFRESH_TIME; $I_REFRESH_URL = $refresh_url; $I_REFRESH_TIME = $refresh_time; $GLOBALS['NO_QUERY_LIMIT'] = true; if ($I_REFRESH_TIME != 0) { register_tick_function('i_timed_refresh'); } // Get data from session $session_row = $GLOBALS['SITE_DB']->query_select('import_session', array('*'), array('imp_session' => get_session_id()), '', 1); if (!array_key_exists(0, $session_row)) { warn_exit(do_lang_tempcode('INTERNAL_ERROR')); } $old_base_dir = $session_row[0]['imp_old_base_dir']; $db_host = $session_row[0]['imp_db_host']; $db_name = $session_row[0]['imp_db_name']; $db_user = $session_row[0]['imp_db_user']; $db_password = post_param_string('db_password', ''); $db_table_prefix = $session_row[0]['imp_db_table_prefix']; $parts_done = collapse_2d_complexity('imp_id', 'imp_session', $GLOBALS['SITE_DB']->query_select('import_parts_done', array('imp_id', 'imp_session'), array('imp_session' => get_session_id()))); // Load database connection $import_source = ($db_name === null) ? null : new DatabaseConnector($db_name, $db_host, $db_user, $db_password, $db_table_prefix); // Some preliminary tests $happy = get_param_integer('happy', 0); if ((method_exists($object, 'pre_import_tests')) && ($happy == 0)) { $ui = $object->pre_import_tests($import_source, $db_table_prefix, $old_base_dir); if (!is_null($ui)) { return $ui; } } // Put Conversr to SITE_DB, as we'll import Conversr to that if (get_forum_type() != 'cns') { require_code('forum/cns'); $GLOBALS['CNS_DRIVER'] = new Forum_driver_cns(); $GLOBALS['CNS_DRIVER']->connection = $GLOBALS['SITE_DB']; $GLOBALS['CNS_DRIVER']->MEMBER_ROWS_CACHED = array(); } // Build master list of input types selected from $lang_array = array(); $hooks = find_all_hooks('modules', 'admin_import_types'); foreach (array_keys($hooks) as $hook) { require_code('hooks/modules/admin_import_types/' . filter_naughty_harsh($hook)); $_hook = object_factory('Hook_admin_import_types_' . filter_naughty_harsh($hook)); $lang_array += $_hook->run(); } // Work through import actions, handling each one that was selected $out = new Tempcode(); $import_last = '-1'; $all_skipped = true; $_import_list = $info['import']; $_import_list[] = 'cns_switch'; foreach ($_import_list as $import) { $import_this = either_param_integer('import_' . $import, 0); if ($import_this == 1) { // Try to do import of $import action... // Check dependencies $dependency = null; if ((array_key_exists('dependencies', $info)) && (array_key_exists($import, $info['dependencies']))) { foreach ($info['dependencies'][$import] as $_dependency) { if ((!array_key_exists($_dependency, $parts_done)) && (isset($lang_array[$_dependency]))) { $dependency = $_dependency; } } } if ($dependency !== null) { $out->attach(do_template('IMPORT_MESSAGE', array('_GUID' => 'b2a853f5fb93beada51a3eb8fbd1575f', 'MESSAGE' => do_lang_tempcode('IMPORT_OF_SKIPPED', escape_html($import), escape_html($dependency))))); continue; } // Do import if ($import == 'cns_switch') { $out->attach($this->cns_switch()); } else { $function_name = 'import_' . $import; cns_over_local(); $func_output = call_user_func_array(array($object, $function_name), array($import_source, $db_table_prefix, $old_base_dir)); if (!is_null($func_output)) { $out->attach($func_output); } cns_over_msn(); } $parts_done[$import] = get_session_id(); // Something was done $import_last = $import; $all_skipped = false; // Mark done $GLOBALS['SITE_DB']->query_delete('import_parts_done', array('imp_id' => $import, 'imp_session' => get_session_id()), '', 1); $GLOBALS['SITE_DB']->query_insert('import_parts_done', array('imp_id' => $import, 'imp_session' => get_session_id())); // Logging log_it('IMPORT', $import); } } // If something was done, say so - and if there were errors if (!$all_skipped) { $lang_code = 'SUCCESS'; foreach ($GLOBALS['ATTACHED_MESSAGES_RAW'] as $message) { if ($message[1] == 'warn') { $lang_code = 'SOME_ERRORS_OCCURRED'; } } $out->attach(do_template('IMPORT_MESSAGE', array('_GUID' => '4c4860d021814ffd1df6e21e712c7b44', 'MESSAGE' => do_lang_tempcode($lang_code)))); } // Cleanup post_import_cleanup(); //$back_url = build_url(array('page' => '_SELF', 'type' => 'hook', 'importer' => get_param_string('importer'), 'just' => $import_last, 'session' => $session), '_SELF'); Actually we won't do this, as we want to be able to see any PHP errors that had been spit out // Instead we will just go back to choose_actions $_GET['just'] = $import_last; return $this->choose_actions($out); } /** * Special import-esque function to aid switching to Conversr after importing forum previously served by a forum driver. * * @return Tempcode Information about progress */ public function cns_switch() { $out = new Tempcode(); $todos = array('MEMBER' => array('member', db_get_first_id(), null), 'GROUP' => array('group', null, 'group_id')); foreach ($todos as $db_abstraction => $definition) { list($import_code, $default_id, $field_name_also) = $definition; $count = 0; $extra = is_null($field_name_also) ? '' : (' OR ' . db_string_equal_to('m_name', $field_name_also)); $fields = $GLOBALS['SITE_DB']->query('SELECT m_table,m_name FROM ' . $GLOBALS['SITE_DB']->get_table_prefix() . 'db_meta WHERE (NOT (m_table LIKE \'' . db_encode_like('f\_%') . '\')) AND (' . db_string_equal_to('m_type', $db_abstraction) . ' OR ' . db_string_equal_to('m_type', '*' . $db_abstraction) . ' OR ' . db_string_equal_to('m_type', '?' . $db_abstraction) . $extra . ')'); foreach ($fields as $field) { if ($field['m_table'] == 'stats') { continue; // Lots of data and it's not important } //echo '(working) ' . $field['m_table'] . '/' . $field['m_name'] . '
'; $values = $GLOBALS['SITE_DB']->query_select($field['m_table'], array('*')); foreach ($values as $value) { $current = $value[$field['m_name']]; $remapped = import_id_remap_get($import_code, $current, true); if (is_null($remapped)) { $remapped = $default_id; } if (!is_null($remapped)) { $value2 = $value; $value2[$field['m_name']] = -$remapped; $c = $GLOBALS['SITE_DB']->query_update($field['m_table'], $value2, $value, '', null, null, true, true); if (is_null($c)) { // Something went wrong apparently- but we still need to clean up $GLOBALS['SITE_DB']->query_delete($field['m_table'], $value); } else { $count += $c; } } else { $GLOBALS['SITE_DB']->query_delete($field['m_table'], $value); } } $GLOBALS['SITE_DB']->query('UPDATE ' . $GLOBALS['SITE_DB']->get_table_prefix() . $field['m_table'] . ' SET ' . $field['m_name'] . '=-' . $field['m_name'] . ' WHERE ' . $field['m_name'] . '<0'); } $out->attach(paragraph(do_lang_tempcode('CNS_CONVERTED_' . $db_abstraction, ($count == 0) ? '?' : strval($count)))); } // _config.php global $FILE_BASE; require_code('files'); $config_file = '_config.php'; $config_contents = ''; $config_contents .= "<" . "?php\n"; global $SITE_INFO; $SITE_INFO['forum_type'] = 'cns'; $SITE_INFO['cns_table_prefix'] = $SITE_INFO['table_prefix']; $SITE_INFO['db_forums'] = $SITE_INFO['db_site']; $SITE_INFO['db_forums_host'] = array_key_exists('db_site_host', $SITE_INFO) ? $SITE_INFO['db_site_host'] : 'localhost'; $SITE_INFO['db_forums_user'] = $SITE_INFO['db_site_user']; $SITE_INFO['db_forums_password'] = $SITE_INFO['db_site_password']; $SITE_INFO['board_prefix'] = get_base_url(); foreach ($SITE_INFO as $key => $val) { $_val = str_replace('\\', '\\\\', $val); $config_contents .= '$SITE_INFO[\'' . $key . '\']=\'' . $_val . "';\n"; } cms_file_put_contents_safe($FILE_BASE . '/' . $config_file, $config_contents, FILE_WRITE_FIX_PERMISSIONS | FILE_WRITE_SYNC_FILE); $out->attach(paragraph(do_lang_tempcode('CNS_CONVERTED_INFO'))); // Add zone formally $map = array( 'zone_name' => 'forum', 'zone_default_page' => 'forumview', 'zone_theme' => '-1', 'zone_require_session' => 0, ); $map += insert_lang('zone_title', do_lang('SECTION_FORUMS'), 1); $map += insert_lang('zone_header_text', do_lang('FORUM'), 1); $GLOBALS['SITE_DB']->query_insert('zones', $map); return $out; } /** * Move old import session over to current user session. * * @param string $session Import session */ protected function appropriate_import_session_to_current(&$session) { if ($session != get_session_id()) { // Remap given to current $GLOBALS['SITE_DB']->query_delete('import_session', array('imp_session' => get_session_id()), '', 1); $GLOBALS['SITE_DB']->query_delete('import_parts_done', array('imp_session' => get_session_id())); $GLOBALS['SITE_DB']->query_delete('import_id_remap', array('id_session' => get_session_id())); $GLOBALS['SITE_DB']->query_update('import_session', array('imp_session' => get_session_id()), array('imp_session' => $session), '', 1); $GLOBALS['SITE_DB']->query_update('import_parts_done', array('imp_session' => get_session_id()), array('imp_session' => $session)); $GLOBALS['SITE_DB']->query_update('import_id_remap', array('id_session' => get_session_id()), array('id_session' => $session)); $session = get_session_id(); } } }