See More

. */ function setup_db($cfg = array()) { global $txpcfg, $DB, $prefs, $txp_user, $txp_groups; global $permlink_mode, $siteurl, $adminurl, $theme_name, $public_themes, $step; include_once txpath . '/lib/txplib_db.php'; include_once txpath . '/lib/admin_config.php'; $siteurl = rtrim($cfg['site']['public_url'], '/'); if (!preg_match('%^https?://%', $siteurl)) { $siteurl = 'http://' . $siteurl; } if (empty($cfg['site']['admin_url'])) { $adminurl = $siteurl . '/textpattern'; } else { $adminurl = rtrim($cfg['site']['admin_url'], '/'); if (!preg_match('%^https?://%', $adminurl)) { $adminurl = 'http://' . $adminurl; } } // Determine the mode of permanent links. ini_set('default_socket_timeout', 10); $s = md5(uniqid(rand(), true)); $permlink_mode = 'messy'; // @todo Find a way to remove the error suppression here. Custom error handler? $pretext_data = @file("{$siteurl}/{$s}/?txpcleantest=1"); if (!empty($pretext_data[0]) && trim($pretext_data[0]) == md5("/{$s}/?txpcleantest=1")) { $permlink_mode = 'section_title'; } // Variable set. if (!defined('hu')) { define('hu', $siteurl . '/'); } $siteurl = preg_replace('%^https?://%', '', $siteurl); $siteurl = str_replace(' ', '%20', $siteurl); $theme_name = empty($cfg['site']['admin_theme']) ? 'hive' : $cfg['site']['admin_theme']; $Skin = Txp::get('Textpattern\Skin\Skin'); $setup_path = txpath . DS . 'setup'; $setup_themes_path = $setup_path . DS . 'themes'; $Skin->setDirPath($setup_themes_path); $setup_public_themes = $Skin->getUploaded(); $root_themes_path = txpath . DS . '..' . DS . 'themes'; $Skin->setDirPath($root_themes_path); $root_public_themes = $Skin->getUploaded(); $public_themes = array_merge($root_public_themes, $setup_public_themes); if (empty($cfg['site']['public_theme']) || !array_key_exists($cfg['site']['public_theme'], $public_themes)) { $public_theme = current(array_keys($public_themes)); } else { $public_theme = $cfg['site']['public_theme']; } $is_from_setup = in_array($public_theme, array_keys($setup_public_themes)); if (empty($cfg['site']['content_directory'])) { /* Option 'txp-data' in manifest.json: - Import /articles and /data from setup dir txp-data == 'theme' - Import /articles and /data from theme dir txp-data == 'none' - Nothing to import. */ if (!empty($public_themes[$public_theme]['txp-data']) && $public_themes[$public_theme]['txp-data'] == 'theme') { $datadir = $is_from_setup ? $setup_themes_path . DS . $public_theme : $root_public_themes . DS . $public_theme; } elseif (!empty($public_themes[$public_theme]['txp-data']) && $public_themes[$public_theme]['txp-data'] == 'none') { $datadir = ''; } else { $datadir = $setup_path; } } else { $datadir = $cfg['site']['content_directory']; } if (numRows(safe_query("SHOW TABLES LIKE '" . PFX . "textpattern'"))) { if (! empty($step)) { $step = 'step_printConfig'; echo txp_setup_progress_meter(4) . n . '

'; } msg(gTxt('tables_exist', array('{dbname}' => (!empty($txpcfg['db']) ? $txpcfg['db'] : ''))), MSG_ERROR, true); } $setup = new \Textpattern\DB\Core(); // Create tables $setup->createAllTables(); // Initial mandatory data $setup->initData(); msg(gTxt('creating_db_tables')); setup_txp_lang($cfg['site']['language_code']); // Create core prefs $setup->initPrefs(); $prefs = get_prefs(); $txp_user = $cfg['user']['login_name']; create_user($txp_user, $cfg['user']['email'], $cfg['user']['password'], $cfg['user']['full_name'], 1); if ($datadir) { /* Load theme prefs: /data/core.prefs - Allow override some core prefs. Used only in setup theme. /data/theme.prefs - Theme global and private prefs. global - Used in setup and for AutoCreate missing prefs. private - Will be created after user login */ foreach (get_files_content($datadir . '/data', 'prefs') as $key => $data) { if (($out = json_decode($data, true)) !== null) { msg("Prefs: 'data/{$key}'"); foreach ($out as $name => $p) { if (empty($p['private'])) { set_pref($name, $p['val'], $p['event'], $p['type'], $p['html'], $p['position']); } } } } $prefs = get_prefs(); $plugin = new \Textpattern\Plugin\Plugin(); foreach (get_files_content($datadir . '/plugin', 'txt') as $key => $data) { $result = $plugin->install($data, 1); msg("Plugin: '{$key}' - " . (is_array($result) ? $result[0] : $result)); } $import = new \Textpattern\Import\TxpXML(); foreach (get_files_content($datadir . '/data', 'xml') as $key => $data) { $import->importXml($data); msg("Import: 'data/{$key}'"); } foreach (get_files_content($datadir . '/articles', 'xml') as $key => $data) { $import->importXml($data); msg("Import: 'articles/{$key}'"); } } // --- Theme setup. // Import theme assets. msg(gTxt('public_theme') . ": '{$public_theme}'"); $is_from_setup ? $Skin->setDirPath($setup_themes_path) : ''; $Skin->setNames(array($public_theme)) ->import() ->setBase('default') ->updateSections(); // --- Theme setup end // Final rebuild category trees rebuild_tree_full('article'); rebuild_tree_full('link'); rebuild_tree_full('image'); rebuild_tree_full('file'); } /** * Installing Language Files * * @param string $langs The desired language code or comma separated string */ function setup_txp_lang($langs) { global $language; Txp::getContainer()->remove('\Textpattern\L10n\Lang'); $langs = array_flip(do_list_unique($langs)); unset($langs[$language]); if (!Txp::get('\Textpattern\L10n\Lang')->installFile($language)) { // If cannot install from lang file, setup the Default lang. `language` pref changed too. $language = TEXTPATTERN_DEFAULT_LANG; Txp::get('\Textpattern\L10n\Lang')->installFile($language); unset($langs[$language]); } msg("Lang: '{$language}'"); foreach (array_flip($langs) as $lang) { Txp::get('\Textpattern\L10n\Lang')->installFile($lang); msg("Lang: '{$lang}'"); } } /** * Merge the desired lang strings with fallbacks. * * The fallback language is guaranteed to exist, so any unknown strings * will be used from that pack to fill in any gaps. * * @param string $langs The desired language code or comma separated string * @return array The language-specific name-value pairs */ function setup_load_lang($langs) { global $language; $langs = do_list($langs); $lang = $langs[0]; $lang_path = txpath . DS . 'setup' . DS . 'lang' . DS; $group = 'common, setup'; $strings = array(); // Load the desired lang strings and default strings as fallbacks. $default_textpack = Txp::get('\Textpattern\L10n\Lang', $lang_path)->getPack(TEXTPATTERN_DEFAULT_LANG, $group); $lang_textpack = Txp::get('\Textpattern\L10n\Lang', $lang_path)->getPack($lang, $group); $language = empty($lang_textpack) ? TEXTPATTERN_DEFAULT_LANG : $lang; if (!defined('LANG')) { define('LANG', $language); } $allStrings = array_merge($default_textpack, $lang_textpack); // Merge the arrays, using the default language to fill in the blanks. foreach ($allStrings as $meta) { if (empty($strings[$meta['name']])) { $strings[$meta['name']] = $meta['data']; } } Txp::get('\Textpattern\L10n\Lang')->setPack($strings) ->setPack(array('help' => gTxt('setup_help')), true); return $strings; } /** * Generate a config.php file from the known info. */ function setup_makeConfig($cfg, $doSpecial = false) { define("nl", "';\n"); define("o", '$txpcfg[\''); define("m", "'] = '"); // Escape single quotes and backslashes in literal PHP strings. foreach ($cfg['database'] as $k => $v) { $cfg['database'][$k] = addcslashes($cfg['database'][$k], "'\\"); } if ($doSpecial) { $cfg['database'] = doSpecial($cfg['database']); } $config_details = "<" . "?php\n" . o . 'db' . m . $cfg['database']['db_name'] . nl . o . 'user' . m . $cfg['database']['user'] . nl . o . 'pass' . m . $cfg['database']['password'] . nl . o . 'host' . m . $cfg['database']['host'] . nl . (empty($cfg['database']['client_flags']) ? '' : o . 'client_flags' . "'] = " . $cfg['database']['client_flags'] . ";\n") . o . 'table_prefix' . m . $cfg['database']['table_prefix'] . nl . o . 'txpath' . m . txpath . nl . o . 'dbcharset' . m . $cfg['database']['charset'] . nl; if (defined('is_multisite')) { $config_details .= o . 'multisite_root_path' . m . multisite_root_path . nl . o . 'admin_url' . m . $cfg['site']['admin_url'] . nl . o . 'cookie_domain' . m . $cfg['site']['cookie_domain'] . nl . 'if (!defined(\'txpath\')) { define(\'txpath\', $txpcfg[\'txpath\']); }' . "\n"; } $config_details .= "// For more customization options, please consult config-dist.php file."; return $config_details; } /** * Try to connect to the database. * * Check the database and the table prefix. */ function setup_connect() { global $cfg; mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT); if (strpos($cfg['database']['host'], ':') === false) { $dhost = $cfg['database']['host']; $dport = ini_get("mysqli.default_port"); } else { list($dhost, $dport) = explode(':', $cfg['database']['host'], 2); $dport = intval($dport); } $dsocket = ini_get("mysqli.default_socket"); $mylink = mysqli_init(); try { // @todo Custom error handler to catch warnings if host is mangled? if (mysqli_real_connect($mylink, $dhost, $cfg['database']['user'], $cfg['database']['password'], '', $dport, $dsocket)) { $cfg['database']['client_flags'] = 0; } elseif (mysqli_real_connect($mylink, $dhost, $cfg['database']['user'], $cfg['database']['password'], '', $dport, $dsocket, MYSQLI_CLIENT_SSL)) { $cfg['database']['client_flags'] = 'MYSQLI_CLIENT_SSL'; } else { msg(gTxt('db_cant_connect'), MSG_ERROR, true); } } catch (mysqli_sql_exception $e) { error_log($e->getMessage()); msg(gTxt('db_cant_connect'), MSG_ERROR, true); } echo msg(gTxt('db_connected')); if (!($cfg['database']['table_prefix'] == '' || preg_match('#^[a-zA-Z_][a-zA-Z0-9_]*$#', $cfg['database']['table_prefix']))) { msg( gTxt( 'prefix_bad_characters', array('{dbprefix}' => txpspecialchars($cfg['database']['table_prefix'])) ), MSG_ERROR, true ); } // On MySQL 5.5.3+ use real UTF-8 tables, if the client supports it. $cfg['database']['charset'] = "utf8mb4"; // Lower versions only support UTF-8 limited to 3 bytes per character if (mysqli_get_server_version($mylink) < 50503) { $cfg['database']['charset'] = "utf8"; } else { if (false !== strpos(mysqli_get_client_info(), 'mysqlnd')) { // mysqlnd 5.0.9+ required if (mysqli_get_client_version() < 50009) { $cfg['database']['charset'] = "utf8"; } } else { // libmysqlclient 5.5.3+ required if (mysqli_get_client_version() < 50503) { $cfg['database']['charset'] = "utf8"; } } } if (!empty($cfg['database']['create'])) { $result = mysqli_query($mylink, "CREATE DATABASE IF NOT EXISTS `" . mysqli_real_escape_string($mylink, $cfg['database']['db_name']) . "` CHARACTER SET `" . mysqli_real_escape_string($mylink, $cfg['database']['charset']) . "`"); } try { $mydb = mysqli_select_db($mylink, $cfg['database']['db_name']); } catch (mysqli_sql_exception $e) { error_log($e->getMessage()); msg( gTxt( 'db_doesnt_exist', array('{dbname}' => txpspecialchars($cfg['database']['db_name'])) ), MSG_ERROR, true ); } try { $tables_exist = mysqli_query($mylink, "DESCRIBE `" . $cfg['database']['table_prefix'] . "textpattern`"); } catch (mysqli_sql_exception $e) { // It's good if the tables don't exist! $tables_exist = false; } if ($tables_exist) { msg( gTxt( 'tables_exist', array('{dbname}' => txpspecialchars($cfg['database']['db_name'])) ), MSG_ERROR, true ); } mysqli_close($mylink); echo msg(gTxt('using_db', array( '{dbname}' => txpspecialchars($cfg['database']['db_name']), '{charset}' => txpspecialchars($cfg['database']['charset']), ))); return true; }