htdocs/install/page_dbsettings.php
<?php
/**
* Installer database configuration page
*
* See the enclosed file license.txt for licensing information.
* If you did not receive this file, get it at http://www.fsf.org/copyleft/gpl.html
*
* @copyright The XOOPS project http://www.xoops.org/
* @license http://www.fsf.org/copyleft/gpl.html GNU General Public License (GPL)
* @package installer
* @since 2.3.0
* @author Haruki Setoyama <haruki@planewave.org>
* @author Kazumi Ono <webmaster@myweb.ne.jp>
* @author Skalpa Keo <skalpa@xoops.org>
* @author Taiwen Jiang <phppp@users.sourceforge.net>
*/
/**
*
*/
require_once 'common.inc.php';
if (!defined('XOOPS_INSTALL')) {
exit ();
}
$wizard->setPage('dbsettings');
$pageHasForm = true;
$pageHasHelp = true;
$vars = & $_SESSION ['settings'];
switch ($vars['DB_TYPE']) {
case 'mysql':
$func_connect = empty($vars['DB_PCONNECT'])?"mysql_connect":"mysql_pconnect";
if (!($link = @$func_connect($vars['DB_HOST'], $vars['DB_USER'], $vars['DB_PASS'], true))) {
$error = ERR_NO_DBCONNECTION;
}
break;
case 'pdo.mysql':
try {
$link = new PDO('mysql:host=' . $vars['DB_HOST'],
$vars['DB_USER'],
$vars['DB_PASS'],
array(
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_PERSISTENT => !empty($vars['DB_PCONNECT'])
));
} catch (PDOException $ex) {
$error = ERR_NO_DBCONNECTION;
}
break;
}
if (isset($error)) {
$wizard->redirectToPage('-1', $error);
exit ();
}
// Load config values from mainfile.php constants if 1st invocation, or reload has been asked
if (!isset ($vars ['DB_NAME']) || false !== @strpos($_SERVER ['HTTP_CACHE_CONTROL'], 'max-age=0')) {
$keys = array('DB_NAME', 'DB_CHARSET', 'DB_COLLATION', 'DB_PREFIX', 'DB_SALT');
foreach ($keys as $k) {
$vars [$k] = defined("XOOPS_$k")? constant ("XOOPS_$k"):'';
}
}
function exec_query($sql, $link) {
if ($link instanceof PDO) {
return $link->query($sql);
} else {
return mysql_query($sql, $link);
}
}
function fetch_assoc($result) {
if ($result instanceof PDOStatement) {
return $result->fetch(PDO::FETCH_ASSOC);
} else {
return mysql_fetch_assoc($result);
}
}
/**
* Sanitize a database name by removing all non-alphanumerical characters
*
* @param $database_name
* @return string|string[]|null
*/
function sanitize_database($database_name) {
return preg_replace('/[^A-Za-z0-9_]+/', '', $database_name);
}
function quote_sql($sql) {
global $link;
if ($link instanceof PDO) {
return $link->quote($sql);
} else {
return '\'' . mysql_real_escape_string($sql) . '\'';
}
}
function getDbCharsets($link) {
static $charsets = array( );
if ($charsets) {
return $charsets;
}
$charsets ["utf8"] = "UTF-8 Unicode";
$ut8_available = false;
if ($result = exec_query("SHOW CHARSET", $link)) {
while ($row = fetch_assoc($result)) {
$charsets [$row ["Charset"]] = $row ["Description"];
if ($row ["Charset"] == "utf8") {
$ut8_available = true;
}
}
}
if (!$ut8_available) {
unset ($charsets ["utf8"]);
}
return $charsets;
}
/**
* Get a list of collations supported by the database engine
* @param database connection $link
* @param string $charset
* @return array Character sets supported by the db, as strings
*/
function getDbCollations($link, $charset) {
static $collations = array( );
if ($result = exec_query("SHOW COLLATION WHERE Charset=" . quote_sql($charset), $link)) {
while ($row = fetch_assoc($result)) {
$collations [$charset] [$row ["Collation"]] = $row ["Default"]?1:0;
}
}
return $collations[$charset] ?? [];
}
function validateDbCharset($link, &$charset, &$collation) {
$error = null;
if (empty ($charset)) {
$collation = "";
}
if (version_compare(getDBVersion($link), "4.1.0", "lt")) {
$charset = $collation = "";
}
if (empty ($charset) && empty ($collation)) {
return $error;
}
$charsets = getDbCharsets($link);
if (!isset ($charsets [$charset])) {
$error = sprintf(ERR_INVALID_DBCHARSET, $charset);
} else {
$collations = getDbCollations($link, $charset);
if (!isset ($collations [$collation])) {
$error = sprintf(ERR_INVALID_DBCOLLATION, $collation);
}
}
return $error;
}
function getDBVersion($link) {
if ($link instanceof PDO) {
return $link->getAttribute(PDO::ATTR_SERVER_VERSION);
}
else
{
echo 'error getting DB version';
}
}
function xoFormFieldCollation($name, $value, $label, $link, $charset, $help = '') {
if (version_compare(getDBVersion($link), "4.1.0", "lt")) {
return "";
}
if (empty ($charset) || !$collations = getDbCollations($link, $charset)) {
return "";
}
$label = htmlspecialchars($label);
$name = htmlspecialchars($name, ENT_QUOTES);
$value = htmlspecialchars($value, ENT_QUOTES);
$field = "<label for='$name'>$label</label>\n";
if ($help) {
$field .= '<div class="xoform-help">' . $help . "</div><div class='clear'> </div>\n";
}
$field .= "<select name='$name' id='$name'\">";
$collation_default = "";
$options = "";
foreach ($collations as $key => $isDefault) {
if ($isDefault) {
$collation_default = $key;
continue;
}
$options .= "<option value='{$key}'" . (($value == $key)?" selected='selected'":"") . ">{$key}</option>";
}
if ($collation_default) {
$field .= "<option value='{$collation_default}'" . (($value == $collation_default || empty ($value))?" 'selected'":"") . ">{$collation_default} (Default)</option>";
}
$field .= $options;
$field .= "</select>";
return $field;
}
function xoFormBlockCollation($name, $value, $label, $link, $charset, $help = '') {
$block = '<div id="' . $name . '_div">';
$block .= xoFormFieldCollation($name, $value, $label, $link, $charset, $help);
$block .= '</div>';
return $block;
}
function select_db($db_name, $link) {
//if ($link instanceof PDO) {
try {
$link->exec("use `" . $db_name . '`;');
return true;
} catch (PDOException $ex) {
return false;
}
//}
//else return @mysql_select_db($db_name, $link);
}
if ($_SERVER ['REQUEST_METHOD'] == 'GET' && isset ($_GET ['charset']) && @$_GET ['action'] == 'updateCollation') {
echo xoFormFieldCollation('DB_COLLATION', $vars ['DB_COLLATION'], DB_COLLATION_LABEL, $link, $_GET ['charset'],DB_COLLATION_HELP);
exit ();
}
if ($_SERVER ['REQUEST_METHOD'] == 'POST') {
$params = array('DB_NAME', 'DB_CHARSET', 'DB_COLLATION', 'DB_PREFIX', 'DB_SALT');
foreach ($params as $name) {
$vars [$name] = $_POST [$name] ?? "";
}
}
$error = '';
if ($_SERVER ['REQUEST_METHOD'] == 'POST' && !empty ($vars ['DB_NAME'])) {
$error = validateDbCharset($link, $vars ['DB_CHARSET'], $vars ['DB_COLLATION']);
$db_exist = false;
if (empty ($error)) {
if (!select_db(sanitize_database($vars ['DB_NAME']), $link)) {
// Database not here: try to create it
$result = exec_query("CREATE DATABASE " . sanitize_database( $vars ['DB_NAME'] ), $link);
if (!$result) {
$error = ERR_NO_DATABASE;
} else {
$error = sprintf(DATABASE_CREATED, sanitize_database($vars ['DB_NAME']));
$db_exist = true;
}
} else {
$db_exist = true;
}
if ($db_exist && $vars['DB_CHARSET']) {
/* Attempt to set the character set and collation to the selected */
$sql = "ALTER DATABASE " . sanitize_database( $vars ['DB_NAME']) . " DEFAULT CHARACTER SET " . quote_sql($vars ['DB_CHARSET']) . ($vars ['DB_COLLATION']?" COLLATE " . quote_sql($vars ['DB_COLLATION']):"");
if (!exec_query($sql, $link)) {
/* if the alter statement fails, set the constants to match existing */
$sql = "USE " . sanitize_database($vars["DB_NAME"]);
$result = exec_query($sql, $link);
/* get the character set variables for the current database */
$sql = "SHOW VARIABLES like 'character%'";
$result = exec_query($sql, $link);
while ($row = fetch_assoc($result)) {
$character_sets[$row["Variable_name"]] = $row["Value"];
}
$vars["DB_CHARSET"] = $character_sets["character_set_database"]
?$character_sets["character_set_database"]
: $character_sets["character_set_server"];
/* get the collation for the current database */
$sql = "SHOW VARIABLES LIKE 'collation%'";
$result = exec_query($sql, $link);
while ($row = fetch_assoc($result)) {
$collations[$row["Variable_name"]] = $row["Value"];
}
$vars["DB_COLLATION"] = $collations["collation_database"]
?$collations["collation_database"]
: $collations["collation_server"];
}
}
}
if (empty ($error)) {
$wizard->redirectToPage('+1');
exit ();
}
}
if (@empty ($vars ['DB_NAME'])) {
// Fill with default values
$vars = array_merge($vars, array('DB_NAME' => '', 'DB_CHARSET' => 'utf8', 'DB_COLLATION' => '', 'DB_PREFIX' => 'i' . substr(md5(time()), 0, 8), 'DB_SALT' => icms_core_Password::createSalt()));
}
function xoFormField($name, $value, $label, $maxlength, $help = '') {
$label = htmlspecialchars($label);
$name = htmlspecialchars($name, ENT_QUOTES);
$value = htmlspecialchars($value, ENT_QUOTES);
$maxlength = (int) ($maxlength);
$field = "<div class='dbconn_line'><label for='$name'>$label</label>\n";
if ($help) {
$field .= '<div class="xoform-help">' . $help . "</div><div class='clear'> </div>\n";
}
$field .= "<input type='text' name='$name' id='$name' value='$value' /></div>";
return $field;
}
function xoFormFieldCharset($name, $value, $label, $link, $help = '') {
if (version_compare(getDBVersion($link), "4.1.0", "lt")) {
return "";
}
if (!$chars = getDbCharsets($link)) {
return "";
}
$charsets = array( );
if (isset ($chars ["utf8"])) {
$charsets ["utf8"] = $chars ["utf8"];
unset ($chars ["utf8"]);
}
ksort($chars);
$charsets = array_merge($charsets, $chars);
$label = htmlspecialchars($label);
$name = htmlspecialchars($name, ENT_QUOTES);
$value = htmlspecialchars($value, ENT_QUOTES);
$field = "<div class='dbconn_line'><label for='$name'>$label</label>\n";
if ($help) {
$field .= '<div class="xoform-help">' . $help . "</div><div class='clear'> </div>\n";
}
$field .= "<select name='$name' id='$name' onchange=\"setFormFieldCollation('DB_COLLATION_div', this.value)\">";
$field .= "<option value=''>None</option>";
foreach ($charsets as $key => $desc) {
$field .= "<option value='{$key}'" . (($value == $key)?" selected='selected'":"") . ">{$key} - {$desc}</option>";
}
$field .= "</select></div>";
return $field;
}
ob_start();
?>
<?php
if (!empty ($error)) {
echo '<div class="x2-note error">' . htmlentities($error) . "</div>\n";
}
?>
<script type="text/javascript" src="prototype.js"></script>
<script type="text/javascript">
function setFormFieldCollation(id, val) {
if (val == '') {
document.getElementById(id).style.display='none';
} else {
document.getElementById(id).style.display='display';
}
new Ajax.Updater(
id, '<?php
echo $_SERVER ['PHP_SELF'];
?>',
{ method:'get',parameters:'action=updateCollation&charset='+val }
);
}
</script>
<div class="blokSQL">
<fieldset>
<h3><?php echo LEGEND_DATABASE; ?></h3>
<?php
echo xoFormField('DB_NAME', sanitize_database($vars ['DB_NAME']), DB_NAME_LABEL, 255, DB_NAME_HELP);
?> <?php
echo xoFormField('DB_PREFIX', $vars ['DB_PREFIX'], DB_PREFIX_LABEL, 10, DB_PREFIX_HELP);
?> <?php
echo xoFormField('DB_SALT', $vars ['DB_SALT'], DB_SALT_LABEL, 255, DB_SALT_HELP);
?> <?php
echo xoFormFieldCharset('DB_CHARSET', $vars ['DB_CHARSET'], DB_CHARSET_LABEL, $link, DB_CHARSET_HELP);
?> <?php
echo xoFormBlockCollation('DB_COLLATION', $vars ['DB_COLLATION'], DB_COLLATION_LABEL, $link, $vars ['DB_CHARSET'], DB_COLLATION_HELP, );
?></fieldset>
</div>
<?php
$content = ob_get_contents();
ob_end_clean();
include 'install_tpl.php';