3.3
This commit is contained in:
78
setup/config.php
Normal file
78
setup/config.php
Normal file
@@ -0,0 +1,78 @@
|
||||
<?php
|
||||
/**
|
||||
* Front controller for config view / download and clear
|
||||
*
|
||||
* @package phpMyAdmin-setup
|
||||
* @author Piotr Przybylski <piotrprz@gmail.com>
|
||||
* @license http://www.gnu.org/licenses/gpl.html GNU GPL 2.0
|
||||
* @version $Id$
|
||||
*/
|
||||
|
||||
/**
|
||||
* Core libraries.
|
||||
*/
|
||||
require './lib/common.inc.php';
|
||||
require_once './setup/lib/Form.class.php';
|
||||
require_once './setup/lib/FormDisplay.class.php';
|
||||
|
||||
$form_display = new FormDisplay();
|
||||
$form_display->registerForm('_config.php');
|
||||
$form_display->save('_config.php');
|
||||
$config_file_path = ConfigFile::getInstance()->getFilePath();
|
||||
|
||||
if (isset($_POST['eol'])) {
|
||||
$_SESSION['eol'] = ($_POST['eol'] == 'unix') ? 'unix' : 'win';
|
||||
}
|
||||
|
||||
if (PMA_ifSetOr($_POST['submit_clear'], '')) {
|
||||
//
|
||||
// Clear current config and return to main page
|
||||
//
|
||||
$_SESSION['ConfigFile'] = array();
|
||||
// drop post data
|
||||
header('HTTP/1.1 303 See Other');
|
||||
header('Location: index.php');
|
||||
exit;
|
||||
} elseif (PMA_ifSetOr($_POST['submit_download'], '')) {
|
||||
//
|
||||
// Output generated config file
|
||||
//
|
||||
header('Content-Type: text/plain');
|
||||
header('Content-Disposition: attachment; filename="config.inc.php"');
|
||||
echo ConfigFile::getInstance()->getConfigFile();
|
||||
exit;
|
||||
} elseif (PMA_ifSetOr($_POST['submit_save'], '')) {
|
||||
//
|
||||
// Save generated config file on the server
|
||||
//
|
||||
file_put_contents($config_file_path, ConfigFile::getInstance()->getConfigFile());
|
||||
header('HTTP/1.1 303 See Other');
|
||||
header('Location: index.php');
|
||||
exit;
|
||||
} elseif (PMA_ifSetOr($_POST['submit_load'], '')) {
|
||||
//
|
||||
// Load config file from the server
|
||||
//
|
||||
$cfg = array();
|
||||
require_once $config_file_path;
|
||||
$_SESSION['ConfigFile'] = $cfg;
|
||||
header('HTTP/1.1 303 See Other');
|
||||
header('Location: index.php');
|
||||
exit;
|
||||
} elseif (PMA_ifSetOr($_POST['submit_delete'], '')) {
|
||||
//
|
||||
// Delete config file on the server
|
||||
//
|
||||
@unlink($config_file_path);
|
||||
header('HTTP/1.1 303 See Other');
|
||||
header('Location: index.php');
|
||||
exit;
|
||||
} else {
|
||||
//
|
||||
// Show generated config file in a <textarea>
|
||||
//
|
||||
header('HTTP/1.1 303 See Other');
|
||||
header('Location: index.php?page=config');
|
||||
exit;
|
||||
}
|
||||
?>
|
46
setup/frames/config.inc.php
Normal file
46
setup/frames/config.inc.php
Normal file
@@ -0,0 +1,46 @@
|
||||
<?php
|
||||
/**
|
||||
* Config file view and save screen
|
||||
*
|
||||
* @package phpMyAdmin-setup
|
||||
* @author Piotr Przybylski <piotrprz@gmail.com>
|
||||
* @license http://www.gnu.org/licenses/gpl.html GNU GPL 2.0
|
||||
* @version $Id$
|
||||
*/
|
||||
|
||||
if (!defined('PHPMYADMIN')) {
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Core libraries.
|
||||
*/
|
||||
require_once './setup/lib/FormDisplay.class.php';
|
||||
require_once './setup/lib/index.lib.php';
|
||||
|
||||
$config_readable = false;
|
||||
$config_writable = false;
|
||||
$config_exists = false;
|
||||
check_config_rw($config_readable, $config_writable, $config_exists);
|
||||
?>
|
||||
<h2><?php echo $GLOBALS['strSetupConfigurationFile'] ?></h2>
|
||||
<?php display_form_top('config.php'); ?>
|
||||
<input type="hidden" name="eol" value="<?php echo htmlspecialchars(PMA_ifSetOr($_GET['eol'], 'unix')) ?>" />
|
||||
<?php display_fieldset_top('', '', null, array('class' => 'simple')); ?>
|
||||
<tr>
|
||||
<td>
|
||||
<textarea cols="50" rows="20" name="textconfig" id="textconfig" spellcheck="false"><?php
|
||||
echo htmlspecialchars(ConfigFile::getInstance()->getConfigFile())
|
||||
?></textarea>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="lastrow" style="text-align: left">
|
||||
<input type="submit" name="submit_download" value="<?php echo $GLOBALS['strSetupDownload'] ?>" class="green" />
|
||||
<input type="submit" name="submit_save" value="<?php echo $GLOBALS['strSave'] ?>"<?php if (!$config_writable) echo ' disabled="disabled"' ?> />
|
||||
</td>
|
||||
</tr>
|
||||
<?php
|
||||
display_fieldset_bottom_simple();
|
||||
display_form_bottom();
|
||||
?>
|
50
setup/frames/form.inc.php
Normal file
50
setup/frames/form.inc.php
Normal file
@@ -0,0 +1,50 @@
|
||||
<?php
|
||||
/**
|
||||
* Form edit view
|
||||
*
|
||||
* @package phpMyAdmin-setup
|
||||
* @author Piotr Przybylski <piotrprz@gmail.com>
|
||||
* @license http://www.gnu.org/licenses/gpl.html GNU GPL 2.0
|
||||
* @version $Id$
|
||||
*/
|
||||
|
||||
if (!defined('PHPMYADMIN')) {
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Core libraries.
|
||||
*/
|
||||
require_once './setup/lib/Form.class.php';
|
||||
require_once './setup/lib/FormDisplay.class.php';
|
||||
require_once './setup/lib/form_processing.lib.php';
|
||||
|
||||
$formsets = array(
|
||||
'features' => array(
|
||||
'forms' => array('Import_export', 'Security', 'Sql_queries', 'Other_core_settings')),
|
||||
'left_frame' => array(
|
||||
'forms' => array('Left_frame', 'Left_servers', 'Left_databases', 'Left_tables')),
|
||||
'main_frame' => array(
|
||||
'forms' => array('Startup', 'Browse', 'Edit', 'Tabs', 'Sql_box')),
|
||||
'import' => array(
|
||||
'forms' => array('Import_defaults')),
|
||||
'export' => array(
|
||||
'forms' => array('Export_defaults'))
|
||||
);
|
||||
|
||||
$formset_id = filter_input(INPUT_GET, 'formset');
|
||||
$mode = filter_input(INPUT_GET, 'mode');
|
||||
if (!isset($formsets[$formset_id])) {
|
||||
die('Incorrect formset, check $formsets array in setup/frames/form.inc.php');
|
||||
}
|
||||
|
||||
$formset = $formsets[$formset_id];
|
||||
if (isset($GLOBALS['strSetupFormset_' . $formset_id])) {
|
||||
echo '<h2>' . $GLOBALS['strSetupFormset_' . $formset_id] . '</h2>';
|
||||
}
|
||||
$form_display = new FormDisplay();
|
||||
foreach ($formset['forms'] as $form_name) {
|
||||
$form_display->registerForm($form_name);
|
||||
}
|
||||
process_formset($form_display);
|
||||
?>
|
246
setup/frames/index.inc.php
Normal file
246
setup/frames/index.inc.php
Normal file
@@ -0,0 +1,246 @@
|
||||
<?php
|
||||
/**
|
||||
* Overview (main page)
|
||||
*
|
||||
* @package phpMyAdmin-setup
|
||||
* @author Piotr Przybylski <piotrprz@gmail.com>
|
||||
* @license http://www.gnu.org/licenses/gpl.html GNU GPL 2.0
|
||||
* @version $Id$
|
||||
*/
|
||||
|
||||
if (!defined('PHPMYADMIN')) {
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Core libraries.
|
||||
*/
|
||||
require_once './libraries/display_select_lang.lib.php';
|
||||
require_once './setup/lib/FormDisplay.class.php';
|
||||
require_once './setup/lib/index.lib.php';
|
||||
|
||||
// prepare unfiltered language list
|
||||
$all_languages = PMA_langList();
|
||||
uasort($all_languages, 'PMA_language_cmp');
|
||||
|
||||
$cf = ConfigFile::getInstance();
|
||||
$separator = PMA_get_arg_separator('html');
|
||||
|
||||
// message handling
|
||||
messages_begin();
|
||||
|
||||
//
|
||||
// Check phpMyAdmin version
|
||||
//
|
||||
if (isset($_GET['version_check'])) {
|
||||
PMA_version_check();
|
||||
}
|
||||
|
||||
//
|
||||
// Perform various security, compatibility and consistency checks
|
||||
//
|
||||
perform_config_checks();
|
||||
|
||||
//
|
||||
// Check whether we can read/write configuration
|
||||
//
|
||||
$config_readable = false;
|
||||
$config_writable = false;
|
||||
$config_exists = false;
|
||||
check_config_rw($config_readable, $config_writable, $config_exists);
|
||||
if (!$config_writable || !$config_readable) {
|
||||
messages_set('error', 'config_rw', 'CannotLoadConfig', PMA_lang('CannotLoadConfigMsg'));
|
||||
}
|
||||
//
|
||||
// Check https connection
|
||||
//
|
||||
$is_https = !empty($_SERVER['HTTPS']) && strtolower($_SERVER['HTTPS']) == 'on';
|
||||
if (!$is_https) {
|
||||
$text = $GLOBALS['strSetupInsecureConnectionMsg1'];
|
||||
if (!empty($_SERVER['REQUEST_URI']) && !empty($_SERVER['HTTP_HOST'])) {
|
||||
$text .= ' ' . PMA_lang('InsecureConnectionMsg2',
|
||||
'https://' . htmlspecialchars($_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI']));
|
||||
}
|
||||
messages_set('warning', 'no_https', 'InsecureConnection', $text);
|
||||
}
|
||||
?>
|
||||
|
||||
<form id="select_lang" method="post" action="<?php echo htmlspecialchars($_SERVER['REQUEST_URI']) ?>">
|
||||
<?php echo PMA_generate_common_hidden_inputs() ?>
|
||||
<bdo xml:lang="en" dir="ltr"><label for="lang">
|
||||
<?php echo $GLOBALS['strLanguage'] . ($GLOBALS['strLanguage'] != 'Language' ? ' - Language' : '') ?>
|
||||
</label></bdo><br />
|
||||
<select id="lang" name="lang" onchange="this.form.submit();" xml:lang="en" dir="ltr">
|
||||
<?php
|
||||
// create language list
|
||||
$lang_list = array();
|
||||
foreach ($all_languages as $each_lang_key => $each_lang) {
|
||||
if (!file_exists($GLOBALS['lang_path'] . $each_lang[1] . '.inc.php')) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$lang_name = ucfirst(substr(strrchr($each_lang[0], '|'), 1));
|
||||
// Include native name if non empty
|
||||
if (!empty($each_lang[3])) {
|
||||
$lang_name = $each_lang[3] . ' - ' . $lang_name;
|
||||
}
|
||||
|
||||
//Is current one active?
|
||||
$selected = ($GLOBALS['lang'] == $each_lang_key) ? ' selected="selected"' : '';
|
||||
echo '<option value="' . $each_lang_key . '"' . $selected . '>' . $lang_name
|
||||
. '</option>' . "\n";
|
||||
}
|
||||
?>
|
||||
</select>
|
||||
</form>
|
||||
|
||||
<h2><?php echo $GLOBALS['strSetupOverview'] ?></h2>
|
||||
|
||||
<?php
|
||||
// message handling
|
||||
messages_end();
|
||||
messages_show_html();
|
||||
?>
|
||||
|
||||
<a href="#" id="show_hidden_messages" style="display:none"><?php echo $GLOBALS['strSetupShowHiddenMessages'] ?></a>
|
||||
|
||||
<h3><?php echo $GLOBALS['strServers'] ?></h3>
|
||||
<?php
|
||||
//
|
||||
// Display server list
|
||||
//
|
||||
display_form_top('index.php', 'get', array(
|
||||
'page' => 'servers',
|
||||
'mode' => 'add'
|
||||
));
|
||||
?>
|
||||
<div class="form">
|
||||
<?php if ($cf->getServerCount() > 0): ?>
|
||||
<table cellspacing="0" class="datatable" style="table-layout: fixed">
|
||||
<tr>
|
||||
<th>#</th>
|
||||
<th><?php echo $GLOBALS['strName'] ?></th>
|
||||
<th>Authentication type</th>
|
||||
<th colspan="2">DSN</th>
|
||||
</tr>
|
||||
<?php foreach ($_SESSION['ConfigFile']['Servers'] as $id => $server): ?>
|
||||
<tr>
|
||||
<td><?php echo $id ?></td>
|
||||
<td><?php echo $cf->getServerName($id) ?></td>
|
||||
<td><?php echo htmlspecialchars($cf->getValue("Servers/$id/auth_type")) ?></td>
|
||||
<td><?php echo htmlspecialchars($cf->getServerDSN($id)) ?></td>
|
||||
<td style="white-space: nowrap">
|
||||
<small>
|
||||
<a href="<?php echo "?page=servers{$separator}mode=edit{$separator}id=$id" ?>"><?php echo $GLOBALS['strEdit'] ?></a>
|
||||
| <a href="<?php echo "?page=servers{$separator}mode=remove{$separator}id=$id" ?>"><?php echo $GLOBALS['strDelete'] ?></a>
|
||||
</small>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
</table>
|
||||
<?php else: ?>
|
||||
<table width="100%">
|
||||
<tr>
|
||||
<td>
|
||||
<i><?php echo $GLOBALS['strSetupNoServers'] ?></i>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<?php endif; ?>
|
||||
<table width="100%">
|
||||
<tr>
|
||||
<td class="lastrow" style="text-align: left">
|
||||
<input type="submit" name="submit" value="<?php echo $GLOBALS['strSetupNewServer'] ?>" />
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
<?php
|
||||
display_form_bottom();
|
||||
?>
|
||||
|
||||
<h3><?php echo $GLOBALS['strSetupConfigurationFile'] ?></h3>
|
||||
<?php
|
||||
//
|
||||
// Display config file settings and load/save form
|
||||
//
|
||||
$form_display = new FormDisplay();
|
||||
|
||||
display_form_top('config.php');
|
||||
display_fieldset_top('', '', null, array('class' => 'simple'));
|
||||
|
||||
// Display language list
|
||||
$opts = array(
|
||||
'doc' => $form_display->getDocLink('DefaultLang'),
|
||||
'wiki' => $form_display->getWikiLink('DefaultLang'),
|
||||
'values' => array(),
|
||||
'values_escaped' => true);
|
||||
foreach ($all_languages as $each_lang_key => $each_lang) {
|
||||
if (!file_exists($GLOBALS['lang_path'] . $each_lang[1] . '.inc.php')) {
|
||||
continue;
|
||||
}
|
||||
$lang_name = ucfirst(substr(strrchr($each_lang[0], '|'), 1));
|
||||
// Include native name if non empty
|
||||
if (!empty($each_lang[3])) {
|
||||
$lang_name = $each_lang[3] . ' - ' . $lang_name;
|
||||
}
|
||||
$opts['values'][$each_lang_key] = $lang_name;
|
||||
}
|
||||
display_input('DefaultLang', $GLOBALS['strSetupDefaultLanguage'], '', 'select',
|
||||
$cf->getValue('DefaultLang'), true, $opts);
|
||||
|
||||
// Display server list
|
||||
$opts = array(
|
||||
'doc' => $form_display->getDocLink('ServerDefault'),
|
||||
'wiki' => $form_display->getWikiLink('ServerDefault'),
|
||||
'values' => array(),
|
||||
'values_disabled' => array());
|
||||
if ($cf->getServerCount() > 0) {
|
||||
$opts['values']['0'] = $GLOBALS['strSetupLetUserChoose'];
|
||||
$opts['values']['-'] = '------------------------------';
|
||||
if ($cf->getServerCount() == 1) {
|
||||
$opts['values_disabled'][] = '0';
|
||||
}
|
||||
$opts['values_disabled'][] = '-';
|
||||
|
||||
foreach ($_SESSION['ConfigFile']['Servers'] as $id => $server) {
|
||||
$opts['values'][(string)$id] = $cf->getServerName($id) . " [$id]";
|
||||
}
|
||||
} else {
|
||||
$opts['values']['1'] = $GLOBALS['strSetupOptionNone'];
|
||||
$opts['values_escaped'] = true;
|
||||
}
|
||||
display_input('ServerDefault', $GLOBALS['strSetupDefaultServer'], '', 'select',
|
||||
$cf->getValue('ServerDefault'), true, $opts);
|
||||
|
||||
// Display EOL list
|
||||
$opts = array(
|
||||
'values' => array(
|
||||
'unix' => 'UNIX / Linux (\n)',
|
||||
'win' => 'Windows (\r\n)'),
|
||||
'values_escaped' => true);
|
||||
$eol = PMA_ifSetOr($_SESSION['eol'], (PMA_IS_WINDOWS ? 'win' : 'unix'));
|
||||
display_input('eol', $GLOBALS['strSetupEndOfLine'], '', 'select',
|
||||
$eol, true, $opts);
|
||||
?>
|
||||
<tr>
|
||||
<td colspan="2" class="lastrow" style="text-align: left">
|
||||
<input type="submit" name="submit_display" value="<?php echo $GLOBALS['strSetupDisplay'] ?>" />
|
||||
<input type="submit" name="submit_download" value="<?php echo $GLOBALS['strSetupDownload'] ?>" />
|
||||
|
||||
<input type="submit" name="submit_save" value="<?php echo $GLOBALS['strSave'] ?>"<?php if (!$config_writable) echo ' disabled="disabled"' ?> />
|
||||
<input type="submit" name="submit_load" value="<?php echo $GLOBALS['strSetupLoad'] ?>"<?php if (!$config_exists) echo ' disabled="disabled"' ?> />
|
||||
<input type="submit" name="submit_delete" value="<?php echo $GLOBALS['strDelete'] ?>"<?php if (!$config_exists || !$config_writable) echo ' disabled="disabled"' ?> />
|
||||
|
||||
<input type="submit" name="submit_clear" value="<?php echo $GLOBALS['strSetupClear'] ?>" class="red" />
|
||||
</td>
|
||||
</tr>
|
||||
<?php
|
||||
display_fieldset_bottom_simple();
|
||||
display_form_bottom();
|
||||
?>
|
||||
<div id="footer">
|
||||
<a href="http://phpmyadmin.net"><?php echo $GLOBALS['strSetupHomepageLink'] ?></a>
|
||||
<a href="http://sourceforge.net/donate/index.php?group_id=23067"><?php echo $GLOBALS['strSetupDonateLink'] ?></a>
|
||||
<a href="?version_check=1<?php echo "{$separator}token=" . $_SESSION[' PMA_token '] ?>"><?php echo $GLOBALS['strSetupVersionCheckLink'] ?></a>
|
||||
</div>
|
24
setup/frames/menu.inc.php
Normal file
24
setup/frames/menu.inc.php
Normal file
@@ -0,0 +1,24 @@
|
||||
<?php
|
||||
/**
|
||||
* Menu items
|
||||
*
|
||||
* @package phpMyAdmin-setup
|
||||
* @author Piotr Przybylski <piotrprz@gmail.com>
|
||||
* @license http://www.gnu.org/licenses/gpl.html GNU GPL 2.0
|
||||
* @version $Id$
|
||||
*/
|
||||
|
||||
if (!defined('PHPMYADMIN')) {
|
||||
exit;
|
||||
}
|
||||
|
||||
$separator = PMA_get_arg_separator('html');
|
||||
?>
|
||||
<ul>
|
||||
<li><a href="index.php"><?php echo $GLOBALS['strSetupOverview'] ?></a></li>
|
||||
<li><a href="?page=form<?php echo $separator ?>formset=features"><?php echo $GLOBALS['strSetupFormset_features'] ?></a></li>
|
||||
<li><a href="?page=form<?php echo $separator ?>formset=left_frame"><?php echo $GLOBALS['strSetupForm_Left_frame'] ?></a></li>
|
||||
<li><a href="?page=form<?php echo $separator ?>formset=main_frame"><?php echo $GLOBALS['strSetupForm_Main_frame'] ?></a></li>
|
||||
<li><a href="?page=form<?php echo $separator ?>formset=import"><?php echo $GLOBALS['strImport'] ?></a></li>
|
||||
<li><a href="?page=form<?php echo $separator ?>formset=export"><?php echo $GLOBALS['strExport'] ?></a></li>
|
||||
</ul>
|
50
setup/frames/servers.inc.php
Normal file
50
setup/frames/servers.inc.php
Normal file
@@ -0,0 +1,50 @@
|
||||
<?php
|
||||
/**
|
||||
* Server create and edit view
|
||||
*
|
||||
* @package phpMyAdmin-setup
|
||||
* @author Piotr Przybylski <piotrprz@gmail.com>
|
||||
* @license http://www.gnu.org/licenses/gpl.html GNU GPL 2.0
|
||||
* @version $Id$
|
||||
*/
|
||||
|
||||
if (!defined('PHPMYADMIN')) {
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Core libraries.
|
||||
*/
|
||||
require_once './setup/lib/Form.class.php';
|
||||
require_once './setup/lib/FormDisplay.class.php';
|
||||
require_once './setup/lib/form_processing.lib.php';
|
||||
|
||||
$mode = filter_input(INPUT_GET, 'mode');
|
||||
$id = filter_input(INPUT_GET, 'id', FILTER_VALIDATE_INT);
|
||||
|
||||
$cf = ConfigFile::getInstance();
|
||||
$server_exists = !empty($id) && $cf->get("Servers/$id") !== null;
|
||||
|
||||
if ($mode == 'edit' && $server_exists) {
|
||||
$page_title = $GLOBALS['strSetupServersEdit']
|
||||
. ' ' . $id . ' <small>(' . $cf->getServerDSN($id) . ')</small>';
|
||||
} elseif ($mode == 'remove' && $server_exists) {
|
||||
$cf->removeServer($id);
|
||||
header('Location: index.php');
|
||||
exit;
|
||||
} elseif ($mode == 'revert' && $server_exists) {
|
||||
// handled by process_formset()
|
||||
} else {
|
||||
$page_title = $GLOBALS['strSetupServersAdd'];
|
||||
$id = 0;
|
||||
}
|
||||
?>
|
||||
<h2><?php echo $page_title ?></h2>
|
||||
<?php
|
||||
$form_display = new FormDisplay();
|
||||
$form_display->registerForm('Server', $id);
|
||||
$form_display->registerForm('Server_login_options', $id);
|
||||
$form_display->registerForm('Server_config', $id);
|
||||
$form_display->registerForm('Server_pmadb', $id);
|
||||
process_formset($form_display);
|
||||
?>
|
54
setup/index.php
Normal file
54
setup/index.php
Normal file
@@ -0,0 +1,54 @@
|
||||
<?php
|
||||
/**
|
||||
* Front controller for setup script
|
||||
*
|
||||
* @package phpMyAdmin-setup
|
||||
* @author Piotr Przybylski <piotrprz@gmail.com>
|
||||
* @copyright Copyright (c) 2008, Piotr Przybylski <piotrprz@gmail.com>
|
||||
* @license http://www.gnu.org/licenses/gpl.html GNU GPL 2.0
|
||||
* @version $Id$
|
||||
*/
|
||||
|
||||
/**
|
||||
* Core libraries.
|
||||
*/
|
||||
require './lib/common.inc.php';
|
||||
|
||||
$page = filter_input(INPUT_GET, 'page');
|
||||
$page = preg_replace('/[^a-z]/', '', $page);
|
||||
if ($page === '') {
|
||||
$page = 'index';
|
||||
}
|
||||
if (!file_exists("./setup/frames/$page.inc.php")) {
|
||||
// it will happen only when enterung URL by hand, we don't care for these cases
|
||||
die('Wrong GET file attribute value');
|
||||
}
|
||||
|
||||
// send no-cache headers
|
||||
require './libraries/header_http.inc.php';
|
||||
?>
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
|
||||
<title>phpMyAdmin <?php echo $_SESSION['PMA_Config']->get('PMA_VERSION'); ?> setup</title>
|
||||
<link href="../favicon.ico" rel="icon" type="image/x-icon" />
|
||||
<link href="../favicon.ico" rel="shortcut icon" type="image/x-icon" />
|
||||
<link href="styles.css" rel="stylesheet" type="text/css" />
|
||||
<script type="text/javascript" src="../js/mootools.js"></script>
|
||||
<script type="text/javascript" src="scripts.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<h1><span class="blue">php</span><span class="orange">MyAdmin</span> <?php echo $_SESSION['PMA_Config']->get('PMA_VERSION'); ?> setup</h1>
|
||||
<div id="menu">
|
||||
<?php
|
||||
require './setup/frames/menu.inc.php';
|
||||
?>
|
||||
</div>
|
||||
<div id="page">
|
||||
<?php
|
||||
require "./setup/frames/$page.inc.php";
|
||||
?>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
3
setup/lib/.htaccess
Normal file
3
setup/lib/.htaccess
Normal file
@@ -0,0 +1,3 @@
|
||||
# This folder does not require access over HTTP
|
||||
# (the following directive denies access by default)
|
||||
Order allow,deny
|
323
setup/lib/ConfigFile.class.php
Normal file
323
setup/lib/ConfigFile.class.php
Normal file
@@ -0,0 +1,323 @@
|
||||
<?php
|
||||
/**
|
||||
* Config file management and generation
|
||||
*
|
||||
* @author Piotr Przybylski <piotrprz@gmail.com>
|
||||
* @license http://www.gnu.org/licenses/gpl.html GNU GPL 2.0
|
||||
* @version $Id$
|
||||
* @package phpMyAdmin-setup
|
||||
*/
|
||||
|
||||
/**
|
||||
* Config file management and generation class
|
||||
*
|
||||
* @package phpMyAdmin-setup
|
||||
*/
|
||||
class ConfigFile
|
||||
{
|
||||
/**
|
||||
* Stores default PMA config from config.default.php
|
||||
* @var array
|
||||
*/
|
||||
private $cfg;
|
||||
|
||||
/**
|
||||
* Stores allowed values for non-standard fields
|
||||
* @var array
|
||||
*/
|
||||
private $cfgDb;
|
||||
|
||||
/**
|
||||
* Keys which will be always written to config file
|
||||
* @var array
|
||||
*/
|
||||
private $persistKeys;
|
||||
|
||||
/**
|
||||
* ConfigFile instance
|
||||
* @var ConfigFile
|
||||
*/
|
||||
private static $_instance;
|
||||
|
||||
/**
|
||||
* Private constructor, use {@link getInstance()}
|
||||
*/
|
||||
private function __construct()
|
||||
{
|
||||
// load default config values
|
||||
$cfg = &$this->cfg;
|
||||
require './libraries/config.default.php';
|
||||
|
||||
// load additionsl config information
|
||||
$cfg_db = &$this->cfgDb;
|
||||
$persist_keys = array();
|
||||
require './setup/lib/config_info.inc.php';
|
||||
|
||||
// apply default values overrides
|
||||
if (count($cfg_db['_overrides'])) {
|
||||
foreach ($cfg_db['_overrides'] as $path => $value) {
|
||||
array_write($path, $cfg, $value);
|
||||
}
|
||||
}
|
||||
|
||||
// checking key presence is much faster than searching so move values to keys
|
||||
$this->persistKeys = array_flip($persist_keys);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns class instance
|
||||
*
|
||||
* @return ConfigFile
|
||||
*/
|
||||
public static function getInstance()
|
||||
{
|
||||
if (is_null(self::$_instance)) {
|
||||
self::$_instance = new ConfigFile();
|
||||
}
|
||||
return self::$_instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets config value
|
||||
*
|
||||
* @param string $path
|
||||
* @param mixed $value
|
||||
* @param string $canonical_path
|
||||
*/
|
||||
public function set($path, $value, $canonical_path = null)
|
||||
{
|
||||
if ($canonical_path === null) {
|
||||
$canonical_path = $this->getCanonicalPath($path);
|
||||
}
|
||||
// remove if the path isn't protected and it's empty or has a default value
|
||||
$default_value = $this->getDefault($canonical_path);
|
||||
if (!isset($this->persistKeys[$canonical_path])
|
||||
&& (($value == $default_value) || (empty($value) && empty($default_value)))) {
|
||||
array_remove($path, $_SESSION['ConfigFile']);
|
||||
} else {
|
||||
array_write($path, $_SESSION['ConfigFile'], $value);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns config value or $default if it's not set
|
||||
*
|
||||
* @param string $path
|
||||
* @param mixed $default
|
||||
* @return mixed
|
||||
*/
|
||||
public function get($path, $default = null)
|
||||
{
|
||||
return array_read($path, $_SESSION['ConfigFile'], $default);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns default config value or $default it it's not set ie. it doesn't
|
||||
* exist in config.default.php ($cfg) and config_info.inc.php
|
||||
* ($_cfg_db['_overrides'])
|
||||
*
|
||||
* @param string $canonical_path
|
||||
* @param mixed $default
|
||||
* @return mixed
|
||||
*/
|
||||
public function getDefault($canonical_path, $default = null)
|
||||
{
|
||||
return array_read($canonical_path, $this->cfg, $default);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns config value, if it's not set uses the default one; returns
|
||||
* $default if the path isn't set and doesn't contain a default value
|
||||
*
|
||||
* @param string $path
|
||||
* @param mixed $default
|
||||
* @return mixed
|
||||
*/
|
||||
public function getValue($path, $default = null)
|
||||
{
|
||||
$v = array_read($path, $_SESSION['ConfigFile'], null);
|
||||
if ($v !== null) {
|
||||
return $v;
|
||||
}
|
||||
$path = $this->getCanonicalPath($path);
|
||||
return $this->getDefault($path, $default);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns canonical path
|
||||
*
|
||||
* @param string $path
|
||||
* @return string
|
||||
*/
|
||||
public function getCanonicalPath($path) {
|
||||
return preg_replace('#^Servers/([\d]+)/#', 'Servers/1/', $path);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns config database entry for $path ($cfg_db in config_info.php)
|
||||
*
|
||||
* @param string $path
|
||||
* @param mixed $default
|
||||
* @return mixed
|
||||
*/
|
||||
public function getDbEntry($path, $default = null)
|
||||
{
|
||||
return array_read($path, $this->cfgDb, $default);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns server count
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getServerCount()
|
||||
{
|
||||
return isset($_SESSION['ConfigFile']['Servers'])
|
||||
? count($_SESSION['ConfigFile']['Servers'])
|
||||
: 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns DSN of given server
|
||||
*
|
||||
* @param integer $server
|
||||
* @return string
|
||||
*/
|
||||
function getServerDSN($server)
|
||||
{
|
||||
if (!isset($_SESSION['ConfigFile']['Servers'][$server])) {
|
||||
return '';
|
||||
}
|
||||
|
||||
$path = 'Servers/' . $server;
|
||||
$dsn = $this->getValue("$path/extension") . '://';
|
||||
if ($this->getValue("$path/auth_type") == 'config') {
|
||||
$dsn .= $this->getValue("$path/user");
|
||||
if (!$this->getValue("$path/nopassword")) {
|
||||
$dsn .= ':***';
|
||||
}
|
||||
$dsn .= '@';
|
||||
}
|
||||
if ($this->getValue("$path/connect_type") == 'tcp') {
|
||||
$dsn .= $this->getValue("$path/host");
|
||||
$port = $this->getValue("$path/port");
|
||||
if ($port) {
|
||||
$dsn .= ':' . $port;
|
||||
}
|
||||
} else {
|
||||
$dsn .= $this->getValue("$path/socket");
|
||||
}
|
||||
return $dsn;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns server name
|
||||
*
|
||||
* @param int $id
|
||||
* @return string
|
||||
*/
|
||||
public function getServerName($id)
|
||||
{
|
||||
if (!isset($_SESSION['ConfigFile']['Servers'][$id])) {
|
||||
return '';
|
||||
}
|
||||
$verbose = $this->get("Servers/$id/verbose");
|
||||
if (!empty($verbose)) {
|
||||
return $verbose;
|
||||
}
|
||||
$host = $this->get("Servers/$id/host");
|
||||
return empty($host) ? 'localhost' : $host;
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes server
|
||||
*
|
||||
* @param int $server
|
||||
*/
|
||||
public function removeServer($server)
|
||||
{
|
||||
if (!isset($_SESSION['ConfigFile']['Servers'][$server])) {
|
||||
return;
|
||||
}
|
||||
$last_server = $this->getServerCount();
|
||||
|
||||
for ($i = $server; $i < $last_server; $i++) {
|
||||
$_SESSION['ConfigFile']['Servers'][$i] = $_SESSION['ConfigFile']['Servers'][$i+1];
|
||||
}
|
||||
unset($_SESSION['ConfigFile']['Servers'][$last_server]);
|
||||
|
||||
if (isset($_SESSION['ConfigFile']['ServerDefault'])
|
||||
&& $_SESSION['ConfigFile']['ServerDefault'] >= 0) {
|
||||
unset($_SESSION['ConfigFile']['ServerDefault']);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns config file path
|
||||
*
|
||||
* @return unknown
|
||||
*/
|
||||
public function getFilePath()
|
||||
{
|
||||
return $this->getDbEntry('_config_file_path');
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates config file
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getConfigFile()
|
||||
{
|
||||
$crlf = (isset($_SESSION['eol']) && $_SESSION['eol'] == 'win') ? "\r\n" : "\n";
|
||||
$c = $_SESSION['ConfigFile'];
|
||||
|
||||
// header
|
||||
$ret = '<?php' . $crlf
|
||||
. '/*' . $crlf
|
||||
. ' * Generated configuration file' . $crlf
|
||||
. ' * Generated by: phpMyAdmin '
|
||||
. $_SESSION['PMA_Config']->get('PMA_VERSION')
|
||||
. ' setup script by Piotr Przybylski <piotrprz@gmail.com>' . $crlf
|
||||
. ' * Date: ' . date(DATE_RFC1123) . $crlf
|
||||
. ' */' . $crlf . $crlf;
|
||||
|
||||
// servers
|
||||
if ($this->getServerCount() > 0) {
|
||||
$ret .= "/* Servers configuration */$crlf\$i = 0;" . $crlf . $crlf;
|
||||
foreach ($c['Servers'] as $id => $server) {
|
||||
$ret .= '/* Server: ' . strtr($this->getServerName($id), '*/', '-') . " [$id] */" . $crlf
|
||||
. '$i++;' . $crlf;
|
||||
foreach ($server as $k => $v) {
|
||||
$k = preg_replace('/[^A-Za-z0-9_]/', '_', $k);
|
||||
$ret .= "\$cfg['Servers'][\$i]['$k'] = "
|
||||
. var_export($v, true) . ';' . $crlf;
|
||||
}
|
||||
$ret .= $crlf;
|
||||
}
|
||||
$ret .= '/* End of servers configuration */' . $crlf . $crlf;
|
||||
}
|
||||
unset($c['Servers']);
|
||||
|
||||
// other settings
|
||||
$persistKeys = $this->persistKeys;
|
||||
foreach ($c as $k => $v) {
|
||||
$k = preg_replace('/[^A-Za-z0-9_]/', '_', $k);
|
||||
$ret .= "\$cfg['$k'] = " . var_export($v, true) . ';' . $crlf;
|
||||
if (isset($persistKeys[$k])) {
|
||||
unset($persistKeys[$k]);
|
||||
}
|
||||
}
|
||||
// keep 1d array keys which are present in $persist_keys (config_info.inc.php)
|
||||
foreach (array_keys($persistKeys) as $k) {
|
||||
if (strpos($k, '/') === false) {
|
||||
$k = preg_replace('/[^A-Za-z0-9_]/', '_', $k);
|
||||
$ret .= "\$cfg['$k'] = " . var_export($this->getDefault($k), true) . ';' . $crlf;
|
||||
}
|
||||
}
|
||||
$ret .= '?>';
|
||||
|
||||
return $ret;
|
||||
}
|
||||
}
|
||||
?>
|
183
setup/lib/Form.class.php
Normal file
183
setup/lib/Form.class.php
Normal file
@@ -0,0 +1,183 @@
|
||||
<?php
|
||||
/**
|
||||
* Form handling code.
|
||||
*
|
||||
* @package phpMyAdmin-setup
|
||||
* @author Piotr Przybylski <piotrprz@gmail.com>
|
||||
* @license http://www.gnu.org/licenses/gpl.html GNU GPL 2.0
|
||||
* @version $Id$
|
||||
*/
|
||||
|
||||
/**
|
||||
* Base class for forms, loads default configuration options, checks allowed
|
||||
* values etc.
|
||||
*
|
||||
* @package phpMyAdmin-setup
|
||||
*/
|
||||
class Form
|
||||
{
|
||||
/**
|
||||
* Form name
|
||||
* @var string
|
||||
*/
|
||||
public $name;
|
||||
|
||||
/**
|
||||
* Arbitrary index, doesn't affect class' behavior
|
||||
* @var int
|
||||
*/
|
||||
public $index;
|
||||
|
||||
/**
|
||||
* Form fields (paths), filled by {@link readFormPaths()}, indexed by field name
|
||||
* @var array
|
||||
*/
|
||||
public $fields;
|
||||
|
||||
/**
|
||||
* Stores default values for some fields (eg. pmadb tables)
|
||||
* @var array
|
||||
*/
|
||||
public $default;
|
||||
|
||||
/**
|
||||
* Caches field types, indexed by field names
|
||||
* @var array
|
||||
*/
|
||||
private $fieldsTypes;
|
||||
|
||||
/**
|
||||
* Cached forms
|
||||
* @var array
|
||||
*/
|
||||
private static $_forms;
|
||||
|
||||
/**
|
||||
* Constructor, reads default config values
|
||||
*
|
||||
* @param string $form_name
|
||||
* @param int $index arbitrary index, stored in Form::$index
|
||||
*/
|
||||
public function __construct($form_name, $index = null)
|
||||
{
|
||||
$this->index = $index;
|
||||
$this->loadForm($form_name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns type of given option
|
||||
*
|
||||
* @param string $option_name path or field name
|
||||
* @return string|null one of: boolean, integer, double, string, select, array
|
||||
*/
|
||||
public function getOptionType($option_name)
|
||||
{
|
||||
$key = ltrim(substr($option_name, strrpos($option_name, '/')), '/');
|
||||
return isset($this->fieldsTypes[$key])
|
||||
? $this->fieldsTypes[$key]
|
||||
: null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns allowed values for select fields
|
||||
*
|
||||
* @param string $option_path
|
||||
* @return array
|
||||
*/
|
||||
public function getOptionValueList($option_path)
|
||||
{
|
||||
$value = ConfigFile::getInstance()->getDbEntry($option_path);
|
||||
if ($value === null) {
|
||||
trigger_error("$option_path - select options not defined", E_USER_ERROR);
|
||||
return array();
|
||||
}
|
||||
if (!is_array($value)) {
|
||||
trigger_error("$option_path - not a static value list", E_USER_ERROR);
|
||||
return array();
|
||||
}
|
||||
return $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* array_walk callback function, reads path of form fields from
|
||||
* array (see file comment in forms.inc.php)
|
||||
*
|
||||
* @param mixed $value
|
||||
* @param mixed $key
|
||||
* @param mixed $prefix
|
||||
*/
|
||||
private function _readFormPathsCallback($value, $key, $prefix)
|
||||
{
|
||||
if (is_array($value)) {
|
||||
$prefix .= (empty($prefix) ? '' : '/') . $key;
|
||||
array_walk($value, array($this, '_readFormPathsCallback'), $prefix);
|
||||
} else {
|
||||
if (!is_int($key)) {
|
||||
$this->default[$prefix . '/' . $key] = $value;
|
||||
$value = $key;
|
||||
}
|
||||
$this->fields[] = $prefix . '/' . $value;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads form paths to {@link $fields}
|
||||
*/
|
||||
protected function readFormPaths()
|
||||
{
|
||||
if (is_null(self::$_forms)) {
|
||||
$forms =& self::$_forms;
|
||||
require './setup/lib/forms.inc.php';
|
||||
}
|
||||
|
||||
if (!isset(self::$_forms[$this->name])) {
|
||||
return;
|
||||
}
|
||||
|
||||
// flatten form fields' paths and save them to $fields
|
||||
$this->fields = array();
|
||||
array_walk(self::$_forms[$this->name], array($this, '_readFormPathsCallback'), '');
|
||||
|
||||
// $this->fields is an array of the form: [0..n] => 'field path'
|
||||
// change numeric indexes to contain field names (last part of the path)
|
||||
$paths = $this->fields;
|
||||
$this->fields = array();
|
||||
foreach ($paths as $path) {
|
||||
$path = ltrim($path, '/');
|
||||
$key = ltrim(substr($path, strrpos($path, '/')), '/');
|
||||
$this->fields[$key] = $path;
|
||||
}
|
||||
// now $this->fields is an array of the form: 'field name' => 'field path'
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads fields' types to $this->fieldsTypes
|
||||
*/
|
||||
protected function readTypes()
|
||||
{
|
||||
$cf = ConfigFile::getInstance();
|
||||
foreach ($this->fields as $name => $path) {
|
||||
$v = $cf->getDbEntry($path);
|
||||
if ($v !== null) {
|
||||
$type = is_array($v) ? 'select' : $v;
|
||||
} else {
|
||||
$type = gettype($cf->getDefault($path));
|
||||
}
|
||||
$this->fieldsTypes[$name] = $type;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads form settings and prepares class to work with given subset of
|
||||
* config file
|
||||
*
|
||||
* @param string $form_name
|
||||
*/
|
||||
public function loadForm($form_name)
|
||||
{
|
||||
$this->name = $form_name;
|
||||
$this->readFormPaths();
|
||||
$this->readTypes();
|
||||
}
|
||||
}
|
||||
?>
|
586
setup/lib/FormDisplay.class.php
Normal file
586
setup/lib/FormDisplay.class.php
Normal file
@@ -0,0 +1,586 @@
|
||||
<?php
|
||||
/**
|
||||
* Form management class, displays and processes forms
|
||||
*
|
||||
* Explanation of used terms:
|
||||
* o work_path - original field path, eg. Servers/4/verbose
|
||||
* o system_path - work_path modified so that it points to the first server, eg. Servers/1/verbose
|
||||
* o translated_path - work_path modified for HTML field name, a path with
|
||||
* slashes changed to hyphens, eg. Servers-4-verbose
|
||||
*
|
||||
* @package phpMyAdmin-setup
|
||||
* @author Piotr Przybylski <piotrprz@gmail.com>
|
||||
* @license http://www.gnu.org/licenses/gpl.html GNU GPL 2.0
|
||||
* @version $Id$
|
||||
*/
|
||||
|
||||
/**
|
||||
* Core libraries.
|
||||
*/
|
||||
require_once './setup/lib/FormDisplay.tpl.php';
|
||||
require_once './setup/lib/validate.lib.php';
|
||||
require_once './libraries/js_escape.lib.php';
|
||||
|
||||
/**
|
||||
* Form management class, displays and processes forms
|
||||
* @package phpMyAdmin-setup
|
||||
*/
|
||||
class FormDisplay
|
||||
{
|
||||
/**
|
||||
* Form list
|
||||
* @var array
|
||||
*/
|
||||
private $forms = array();
|
||||
|
||||
/**
|
||||
* Stores validation errors, indexed by paths
|
||||
* [ Form_name ] is an array of form errors
|
||||
* [path] is a string storing error associated with single field
|
||||
* @var array
|
||||
*/
|
||||
private $errors = array();
|
||||
|
||||
/**
|
||||
* Paths changed so that they can be used as HTML ids, indexed by paths
|
||||
* @var array
|
||||
*/
|
||||
private $translated_paths = array();
|
||||
|
||||
/**
|
||||
* Server paths change indexes so we define maps from current server
|
||||
* path to the first one, indexed by work path
|
||||
* @var array
|
||||
*/
|
||||
private $system_paths = array();
|
||||
|
||||
/**
|
||||
* Language strings which will be sent to PMA_messages JS variable
|
||||
* Will be looked up in $GLOBALS: str{value} or strSetup{value}
|
||||
* @var array
|
||||
*/
|
||||
private $js_lang_strings = array('error_nan_p', 'error_nan_nneg',
|
||||
'error_incorrect_port');
|
||||
|
||||
/**
|
||||
* Tells whether forms have been validated
|
||||
* @var bool
|
||||
*/
|
||||
private $is_valdiated = true;
|
||||
|
||||
/**
|
||||
* Registers form in form manager
|
||||
*
|
||||
* @param string $form_name
|
||||
* @param int $server_id 0 if new server, validation; >= 1 if editing a server
|
||||
*/
|
||||
public function registerForm($form_name, $server_id = null)
|
||||
{
|
||||
$this->forms[$form_name] = new Form($form_name, $server_id);
|
||||
$this->is_valdiated = false;
|
||||
foreach ($this->forms[$form_name]->fields as $path) {
|
||||
$work_path = $server_id === null
|
||||
? $path
|
||||
: str_replace('Servers/1/', "Servers/$server_id/", $path);
|
||||
$this->system_paths[$work_path] = $path;
|
||||
$this->translated_paths[$work_path] = str_replace('/', '-', $work_path);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Processes forms, returns true on successful save
|
||||
*
|
||||
* @param bool $allow_partial_save allows for partial form saving on failed validation
|
||||
* @return boolean
|
||||
*/
|
||||
public function process($allow_partial_save = true)
|
||||
{
|
||||
// gather list of forms to save
|
||||
if (!isset($_POST['submit_save'])) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// save forms
|
||||
if (count($this->forms) > 0) {
|
||||
return $this->save(array_keys($this->forms), $allow_partial_save);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Runs validation for all registered forms
|
||||
*/
|
||||
private function _validate()
|
||||
{
|
||||
if ($this->is_valdiated) {
|
||||
return;
|
||||
}
|
||||
|
||||
$cf = ConfigFile::getInstance();
|
||||
$paths = array();
|
||||
$values = array();
|
||||
foreach ($this->forms as $form) {
|
||||
/* @var $form Form */
|
||||
$paths[] = $form->name;
|
||||
// collect values and paths
|
||||
foreach ($form->fields as $path) {
|
||||
$work_path = array_search($path, $this->system_paths);
|
||||
$values[$path] = $cf->getValue($work_path);
|
||||
$paths[] = $path;
|
||||
}
|
||||
}
|
||||
|
||||
// run validation
|
||||
$errors = validate($paths, $values, false);
|
||||
|
||||
// change error keys from canonical paths to work paths
|
||||
if (is_array($errors) && count($errors) > 0) {
|
||||
$this->errors = array();
|
||||
foreach ($errors as $path => $error_list) {
|
||||
$work_path = array_search($path, $this->system_paths);
|
||||
// field error
|
||||
if (!$work_path) {
|
||||
// form error, fix path
|
||||
$work_path = $path;
|
||||
}
|
||||
$this->errors[$work_path] = $error_list;
|
||||
}
|
||||
}
|
||||
$this->is_valdiated = true;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Outputs HTML for forms
|
||||
*
|
||||
* @param bool $tabbed_form
|
||||
* @param bool $show_restore_default whether show "restore default" button besides the input field
|
||||
*/
|
||||
public function display($tabbed_form = false, $show_restore_default = false)
|
||||
{
|
||||
static $js_lang_sent = false;
|
||||
|
||||
$js = array();
|
||||
$js_default = array();
|
||||
$tabbed_form = $tabbed_form && (count($this->forms) > 1);
|
||||
$validators = ConfigFile::getInstance()->getDbEntry('_validators');
|
||||
|
||||
display_form_top();
|
||||
|
||||
if ($tabbed_form) {
|
||||
$tabs = array();
|
||||
foreach ($this->forms as $form) {
|
||||
$tabs[$form->name] = PMA_lang("Form_$form->name");
|
||||
}
|
||||
display_tabs_top($tabs);
|
||||
}
|
||||
|
||||
// valdiate only when we aren't displaying a "new server" form
|
||||
$is_new_server = false;
|
||||
foreach ($this->forms as $form) {
|
||||
/* @var $form Form */
|
||||
if ($form->index === 0) {
|
||||
$is_new_server = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!$is_new_server) {
|
||||
$this->_validate();
|
||||
}
|
||||
|
||||
// display forms
|
||||
foreach ($this->forms as $form) {
|
||||
/* @var $form Form */
|
||||
$form_desc = isset($GLOBALS["strSetupForm_{$form->name}_desc"])
|
||||
? PMA_lang("Form_{$form->name}_desc")
|
||||
: '';
|
||||
$form_errors = isset($this->errors[$form->name])
|
||||
? $this->errors[$form->name] : null;
|
||||
display_fieldset_top(PMA_lang("Form_$form->name"),
|
||||
$form_desc, $form_errors, array('id' => $form->name));
|
||||
|
||||
foreach ($form->fields as $field => $path) {
|
||||
$work_path = array_search($path, $this->system_paths);
|
||||
$translated_path = $this->translated_paths[$work_path];
|
||||
// display input
|
||||
$this->_displayFieldInput($form, $field, $path, $work_path,
|
||||
$translated_path, $show_restore_default, $js_default);
|
||||
// register JS validators for this field
|
||||
if (isset($validators[$path])) {
|
||||
js_validate($translated_path, $validators[$path], $js);
|
||||
}
|
||||
}
|
||||
display_fieldset_bottom();
|
||||
}
|
||||
|
||||
if ($tabbed_form) {
|
||||
display_tabs_bottom();
|
||||
}
|
||||
display_form_bottom();
|
||||
|
||||
// if not already done, send strings used for valdiation to JavaScript
|
||||
if (!$js_lang_sent) {
|
||||
$js_lang_sent = true;
|
||||
$js_lang = array();
|
||||
foreach ($this->js_lang_strings as $str) {
|
||||
$lang = isset($GLOBALS["strSetup$str"])
|
||||
? $GLOBALS["strSetup$str"]
|
||||
: filter_input($GLOBALS["str$str"]); // null if not set
|
||||
$js_lang[] = "'$str': '" . PMA_jsFormat($lang, false) . '\'';
|
||||
}
|
||||
$js[] = '$extend(PMA_messages, {' . implode(",\n\t", $js_lang) . '})';
|
||||
}
|
||||
|
||||
$js[] = '$extend(defaultValues, {' . implode(",\n\t", $js_default) . '})';
|
||||
display_js($js);
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepares data for input field display and outputs HTML code
|
||||
*
|
||||
* @param Form $form
|
||||
* @param string $field field name as it appears in $form
|
||||
* @param string $system_path field path, eg. Servers/1/verbose
|
||||
* @param string $work_path work path, eg. Servers/4/verbose
|
||||
* @param string $translated_path work path changed so that it can be used as XHTML id
|
||||
* @param bool $show_restore_default whether show "restore default" button besides the input field
|
||||
* @param array &$js_default array which stores JavaScript code to be displayed
|
||||
*/
|
||||
private function _displayFieldInput(Form $form, $field, $system_path, $work_path,
|
||||
$translated_path, $show_restore_default, array &$js_default)
|
||||
{
|
||||
$name = PMA_lang_name($system_path);
|
||||
$description = PMA_lang_desc($system_path);
|
||||
|
||||
$cf = ConfigFile::getInstance();
|
||||
$value = $cf->get($work_path);
|
||||
$value_default = $cf->getDefault($system_path);
|
||||
$value_is_default = false;
|
||||
if ($value === null || $value === $value_default) {
|
||||
$value = $value_default;
|
||||
$value_is_default = true;
|
||||
}
|
||||
|
||||
$opts = array(
|
||||
'doc' => $this->getDocLink($system_path),
|
||||
'wiki' => $this->getWikiLink($system_path),
|
||||
'show_restore_default' => $show_restore_default);
|
||||
if (isset($form->default[$system_path])) {
|
||||
$opts['setvalue'] = $form->default[$system_path];
|
||||
}
|
||||
|
||||
if (isset($this->errors[$work_path])) {
|
||||
$opts['errors'] = $this->errors[$work_path];
|
||||
}
|
||||
switch ($form->getOptionType($field)) {
|
||||
case 'string':
|
||||
$type = 'text';
|
||||
break;
|
||||
case 'double':
|
||||
$type = 'text';
|
||||
break;
|
||||
case 'integer':
|
||||
$type = 'text';
|
||||
break;
|
||||
case 'boolean':
|
||||
$type = 'checkbox';
|
||||
break;
|
||||
case 'select':
|
||||
$type = 'select';
|
||||
$opts['values'] = array();
|
||||
$values = $form->getOptionValueList($form->fields[$field]);
|
||||
foreach ($values as $v) {
|
||||
$opts['values'][$v] = $v;
|
||||
}
|
||||
break;
|
||||
case 'array':
|
||||
$type = 'list';
|
||||
$value = (array) $value;
|
||||
$value_default = (array) $value_default;
|
||||
break;
|
||||
case 'NULL':
|
||||
trigger_error("Field $system_path has no type", E_USER_WARNING);
|
||||
return;
|
||||
}
|
||||
|
||||
// TrustedProxies requires changes before displaying
|
||||
if ($system_path == 'TrustedProxies') {
|
||||
foreach ($value as $ip => &$v) {
|
||||
if (!preg_match('/^-\d+$/', $ip)) {
|
||||
$v = $ip . ': ' . $v;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// send default value to form's JS
|
||||
$js_line = '\'' . $translated_path . '\': ';
|
||||
switch ($type) {
|
||||
case 'text':
|
||||
$js_line .= '\'' . PMA_escapeJsString($value_default) . '\'';
|
||||
break;
|
||||
case 'checkbox':
|
||||
$js_line .= $value_default ? 'true' : 'false';
|
||||
break;
|
||||
case 'select':
|
||||
$value_default_js = is_bool($value_default)
|
||||
? (int) $value_default
|
||||
: $value_default;
|
||||
$js_line .= '[\'' . PMA_escapeJsString($value_default_js) . '\']';
|
||||
break;
|
||||
case 'list':
|
||||
$js_line .= '\'' . PMA_escapeJsString(implode("\n", $value_default)) . '\'';
|
||||
break;
|
||||
}
|
||||
$js_default[] = $js_line;
|
||||
|
||||
display_input($translated_path, $name, $description, $type,
|
||||
$value, $value_is_default, $opts);
|
||||
}
|
||||
|
||||
/**
|
||||
* Displays errors
|
||||
*/
|
||||
public function displayErrors()
|
||||
{
|
||||
$this->_validate();
|
||||
if (count($this->errors) == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
foreach ($this->errors as $system_path => $error_list) {
|
||||
if (isset($this->system_paths[$system_path])) {
|
||||
$path = $this->system_paths[$system_path];
|
||||
$name = PMA_lang_name($path);
|
||||
} else {
|
||||
$name = $GLOBALS["strSetupForm_$system_path"];
|
||||
}
|
||||
display_errors($name, $error_list);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverts erroneous fields to their default values
|
||||
*/
|
||||
public function fixErrors()
|
||||
{
|
||||
$this->_validate();
|
||||
if (count($this->errors) == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
$cf = ConfigFile::getInstance();
|
||||
foreach (array_keys($this->errors) as $work_path) {
|
||||
if (!isset($this->system_paths[$work_path])) {
|
||||
continue;
|
||||
}
|
||||
$canonical_path = $this->system_paths[$work_path];
|
||||
$cf->set($work_path, $cf->getDefault($canonical_path));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates select field and casts $value to correct type
|
||||
*
|
||||
* @param string $value
|
||||
* @param array $allowed
|
||||
* @return bool
|
||||
*/
|
||||
private function _validateSelect(&$value, array $allowed)
|
||||
{
|
||||
foreach ($allowed as $v) {
|
||||
if ($value == $v) {
|
||||
settype($value, gettype($v));
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates and saves form data to session
|
||||
*
|
||||
* @param array|string $forms array of form names
|
||||
* @param bool $allow_partial_save allows for partial form saving on failed validation
|
||||
* @return boolean true on success (no errors and all saved)
|
||||
*/
|
||||
public function save($forms, $allow_partial_save = true)
|
||||
{
|
||||
$result = true;
|
||||
$cf = ConfigFile::getInstance();
|
||||
$forms = (array) $forms;
|
||||
|
||||
$values = array();
|
||||
$to_save = array();
|
||||
$this->errors = array();
|
||||
foreach ($forms as $form) {
|
||||
/* @var $form Form */
|
||||
if (isset($this->forms[$form])) {
|
||||
$form = $this->forms[$form];
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
// get current server id
|
||||
$change_index = $form->index === 0
|
||||
? $cf->getServerCount() + 1
|
||||
: false;
|
||||
// grab POST values
|
||||
foreach ($form->fields as $field => $system_path) {
|
||||
$work_path = array_search($system_path, $this->system_paths);
|
||||
$key = $this->translated_paths[$work_path];
|
||||
|
||||
// ensure the value is set
|
||||
if (!isset($_POST[$key])) {
|
||||
// checkboxes aren't set by browsers if they're off
|
||||
if ($form->getOptionType($field) == 'boolean') {
|
||||
$_POST[$key] = false;
|
||||
} else {
|
||||
$this->errors[$form->name][] = PMA_lang(
|
||||
'error_missing_field_data',
|
||||
'<i>' . PMA_lang_name($system_path) . '</i>');
|
||||
$result = false;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
// cast variables to correct type
|
||||
$type = $form->getOptionType($field);
|
||||
switch ($type) {
|
||||
case 'double':
|
||||
settype($_POST[$key], 'float');
|
||||
break;
|
||||
case 'boolean':
|
||||
case 'integer':
|
||||
if ($_POST[$key] !== '') {
|
||||
settype($_POST[$key], $type);
|
||||
}
|
||||
break;
|
||||
case 'select':
|
||||
if (!$this->_validateSelect($_POST[$key], $form->getOptionValueList($system_path))) {
|
||||
$this->errors[$work_path][] = $GLOBALS["strstrSetuperror_incorrect_value"];
|
||||
$result = false;
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
case 'string':
|
||||
$_POST[$key] = trim($_POST[$key]);
|
||||
break;
|
||||
case 'array':
|
||||
// eliminate empty values and ensure we have an array
|
||||
$post_values = explode("\n", $_POST[$key]);
|
||||
$_POST[$key] = array();
|
||||
foreach ($post_values as $v) {
|
||||
$v = trim($v);
|
||||
if ($v !== '') {
|
||||
$_POST[$key][] = $v;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
// now we have value with proper type
|
||||
$values[$system_path] = $_POST[$key];
|
||||
if ($change_index !== false) {
|
||||
$work_path = str_replace("Servers/$form->index/",
|
||||
"Servers/$change_index/", $work_path);
|
||||
}
|
||||
$to_save[$work_path] = $system_path;
|
||||
}
|
||||
}
|
||||
|
||||
// save forms
|
||||
if ($allow_partial_save || empty($this->errors)) {
|
||||
foreach ($to_save as $work_path => $path) {
|
||||
// TrustedProxies requires changes before saving
|
||||
if ($path == 'TrustedProxies') {
|
||||
$proxies = array();
|
||||
$i = 0;
|
||||
foreach ($values[$path] as $value) {
|
||||
$matches = array();
|
||||
if (preg_match("/^(.+):(?:[ ]?)(\\w+)$/", $value, $matches)) {
|
||||
// correct 'IP: HTTP header' pair
|
||||
$ip = trim($matches[1]);
|
||||
$proxies[$ip] = trim($matches[2]);
|
||||
} else {
|
||||
// save also incorrect values
|
||||
$proxies["-$i"] = $value;
|
||||
$i++;
|
||||
}
|
||||
}
|
||||
$values[$path] = $proxies;
|
||||
}
|
||||
$cf->set($work_path, $values[$path], $path);
|
||||
}
|
||||
}
|
||||
|
||||
// don't look for non-critical errors
|
||||
$this->_validate();
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tells whether form validation failed
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function hasErrors()
|
||||
{
|
||||
return count($this->errors) > 0;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns link to documentation
|
||||
*
|
||||
* @param string $path
|
||||
* @return string
|
||||
*/
|
||||
public function getDocLink($path)
|
||||
{
|
||||
$test = substr($path, 0, 6);
|
||||
if ($test == 'Import' || $test == 'Export') {
|
||||
return '';
|
||||
}
|
||||
return '../Documentation.html#cfg_' . self::_getOptName($path);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns link to wiki
|
||||
*
|
||||
* @param string $path
|
||||
* @return string
|
||||
*/
|
||||
public function getWikiLink($path)
|
||||
{
|
||||
$opt_name = self::_getOptName($path);
|
||||
if (substr($opt_name, 0, 7) == 'Servers') {
|
||||
$opt_name = substr($opt_name, 8);
|
||||
if (strpos($opt_name, 'AllowDeny') === 0) {
|
||||
$opt_name = str_replace('_', '_.28', $opt_name) . '.29';
|
||||
}
|
||||
}
|
||||
$test = substr($path, 0, 6);
|
||||
if ($test == 'Import') {
|
||||
$opt_name = substr($opt_name, 7);
|
||||
if ($opt_name == 'format') {
|
||||
$opt_name = 'format_2';
|
||||
}
|
||||
}
|
||||
if ($test == 'Export') {
|
||||
$opt_name = substr($opt_name, 7);
|
||||
}
|
||||
return 'http://wiki.phpmyadmin.net/pma/Config#' . $opt_name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Changes path so it can be used in URLs
|
||||
*
|
||||
* @param string $path
|
||||
* @return string
|
||||
*/
|
||||
private static function _getOptName($path)
|
||||
{
|
||||
return str_replace(array('Servers/1/', '/'), array('Servers/', '_'), $path);
|
||||
}
|
||||
}
|
||||
?>
|
294
setup/lib/FormDisplay.tpl.php
Normal file
294
setup/lib/FormDisplay.tpl.php
Normal file
@@ -0,0 +1,294 @@
|
||||
<?php
|
||||
/**
|
||||
* Form templates
|
||||
*
|
||||
* @package phpMyAdmin-setup
|
||||
* @author Piotr Przybylski <piotrprz@gmail.com>
|
||||
* @license http://www.gnu.org/licenses/gpl.html GNU GPL 2.0
|
||||
* @version $Id$
|
||||
*/
|
||||
|
||||
/**
|
||||
* Displays top part of the form
|
||||
*
|
||||
* @param string $action default: $_SERVER['REQUEST_URI']
|
||||
* @param string $method 'post' or 'get'
|
||||
* @param array $hidden_fields array of form hidden fields (key: field name)
|
||||
*/
|
||||
function display_form_top($action = null, $method = 'post', $hidden_fields = null)
|
||||
{
|
||||
static $has_check_page_refresh = false;
|
||||
|
||||
if ($action === null) {
|
||||
$action = $_SERVER['REQUEST_URI'];
|
||||
}
|
||||
if ($method != 'post') {
|
||||
$method = 'get';
|
||||
}
|
||||
?>
|
||||
<form method="<?php echo $method ?>" action="<?php echo htmlspecialchars($action) ?>">
|
||||
<?php
|
||||
// we do validation on page refresh when browser remembers field values,
|
||||
// add a field with known value which will be used for checks
|
||||
if (!$has_check_page_refresh) {
|
||||
$has_check_page_refresh = true;
|
||||
echo '<input type="hidden" name="check_page_refresh" id="check_page_refresh"'
|
||||
. ' value="" />' . "\n";
|
||||
}
|
||||
echo PMA_generate_common_hidden_inputs() . "\n";
|
||||
echo PMA_getHiddenFields((array)$hidden_fields);
|
||||
}
|
||||
|
||||
/**
|
||||
* Displays form tabs which are given by an array indexed by fieldset id
|
||||
* ({@link display_fieldset_top}), with values being tab titles.
|
||||
*
|
||||
* @param array $tabs
|
||||
*/
|
||||
function display_tabs_top($tabs) {
|
||||
?>
|
||||
<ul class="tabs">
|
||||
<?php foreach ($tabs as $tab_id => $tab_name): ?>
|
||||
<li><a href="#<?php echo $tab_id ?>"><?php echo $tab_name ?></a></li>
|
||||
<?php endforeach; ?>
|
||||
</ul>
|
||||
<br clear="right" />
|
||||
<div class="tabs_contents">
|
||||
<?php
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Displays top part of a fieldset
|
||||
*
|
||||
* @param string $title
|
||||
* @param string $description
|
||||
* @param array $errors
|
||||
* @param array $attributes
|
||||
*/
|
||||
function display_fieldset_top($title = '', $description = '', $errors = null, $attributes = array())
|
||||
{
|
||||
$attributes = array_merge(array('class' => 'optbox'), $attributes);
|
||||
foreach ($attributes as $k => &$attr) {
|
||||
$attr = $k . '="' . htmlspecialchars($attr) . '"';
|
||||
}
|
||||
|
||||
echo '<fieldset ' . implode(' ', $attributes) . '>';
|
||||
echo '<legend>' . $title . '</legend>';
|
||||
if (!empty($description)) {
|
||||
echo '<p>' . $description . '</p>';
|
||||
}
|
||||
// this must match with displayErrors() in scripts.js
|
||||
if (is_array($errors) && count($errors) > 0) {
|
||||
echo '<dl class="errors">';
|
||||
foreach ($errors as $error) {
|
||||
echo '<dd>' . $error . '</dd>';
|
||||
}
|
||||
echo '</dl>';
|
||||
}
|
||||
?>
|
||||
<table width="100%" cellspacing="0">
|
||||
<?php
|
||||
}
|
||||
|
||||
/**
|
||||
* Displays input field
|
||||
*
|
||||
* $opts keys:
|
||||
* o doc - (string) documentation link
|
||||
* o errors - error array
|
||||
* o setvalue - (string) shows button allowing to set poredefined value
|
||||
* o show_restore_default - (boolean) whether show "restore default" button
|
||||
* o values - key - value paris for <select> fields
|
||||
* o values_escaped - (boolean) tells whether values array is already escaped (defaults to false)
|
||||
* o values_disabled - (array)list of disabled values (keys from values)
|
||||
* o wiki - (string) wiki link
|
||||
*
|
||||
* @param string $path
|
||||
* @param string $name
|
||||
* @param string $description
|
||||
* @param string $type
|
||||
* @param mixed $value
|
||||
* @param bool $value_is_default
|
||||
* @param array $opts
|
||||
*/
|
||||
function display_input($path, $name, $description = '', $type, $value, $value_is_default = true, $opts = null)
|
||||
{
|
||||
$field_class = $value_is_default ? '' : ' class="custom"';
|
||||
$name_id = 'name="' . $path . '" id="' . $path . '"';
|
||||
?>
|
||||
<tr>
|
||||
<th>
|
||||
<label for="<?php echo htmlspecialchars($path) ?>"><?php echo $name ?></label>
|
||||
<?php if (!empty($opts['doc']) || !empty($opts['wiki'])): ?>
|
||||
<span class="doc">
|
||||
<?php if (!empty($opts['doc'])) { ?><a href="<?php echo $opts['doc'] ?>" target="documentation"><img class="icon" src="../<?php echo $GLOBALS['cfg']['ThemePath'] ?>/original/img/b_help.png" width="11" height="11" alt="Doc" title="<?php echo $GLOBALS['strDocu'] ?>" /></a><?php } ?>
|
||||
<?php if (!empty($opts['wiki'])){ ?><a href="<?php echo $opts['wiki'] ?>" target="wiki"><img class="icon" src="../<?php echo $GLOBALS['cfg']['ThemePath'] ?>/original/img/b_info.png" width="11" height="11" alt="Wiki" title="Wiki" /></a><?php } ?>
|
||||
</span>
|
||||
<?php endif; ?>
|
||||
<?php if (!empty($description)) { ?><small><?php echo $description ?></small><?php } ?>
|
||||
|
||||
</th>
|
||||
<td>
|
||||
<?php
|
||||
switch ($type) {
|
||||
case 'text':
|
||||
echo '<input type="text" size="50" ' . $name_id . $field_class
|
||||
. ' value="' . htmlspecialchars($value) . '" />';
|
||||
break;
|
||||
case 'checkbox':
|
||||
echo '<span class="checkbox' . ($value_is_default ? '' : ' custom')
|
||||
. '"><input type="checkbox" ' . $name_id
|
||||
. ($value ? ' checked="checked"' : '') . ' /></span>';
|
||||
break;
|
||||
case 'select':
|
||||
echo '<select ' . $name_id . $field_class . '>';
|
||||
$escape = !(isset($opts['values_escaped']) && $opts['values_escaped']);
|
||||
$values_disabled = isset($opts['values_disabled'])
|
||||
? array_flip($opts['values_disabled']) : array();
|
||||
foreach ($opts['values'] as $opt_value => $opt_name) {
|
||||
// set names for boolean values
|
||||
if (is_bool($opt_name)) {
|
||||
$opt_name = $GLOBALS['strSetup' . ($opt_value ? 'True' : 'False')];
|
||||
}
|
||||
// cast boolean values to integers
|
||||
$display_value = is_bool($opt_value) ? (int) $opt_value : $opt_value;
|
||||
// escape if necessary
|
||||
if ($escape) {
|
||||
$display = htmlspecialchars($opt_name);
|
||||
$display_value = htmlspecialchars($display_value);
|
||||
} else {
|
||||
$display = $opt_name;
|
||||
}
|
||||
// compare with selected value
|
||||
// boolean values are cast to integers when used as array keys
|
||||
$selected = is_bool($value)
|
||||
? (int) $value === $opt_value
|
||||
: $opt_value === $value;
|
||||
echo '<option value="' . $display_value . '"'
|
||||
. ($selected ? ' selected="selected"' : '')
|
||||
. (isset($values_disabled[$opt_value]) ? ' disabled="disabled"' : '')
|
||||
. '>' . $display . '</option>';
|
||||
}
|
||||
echo '</select>';
|
||||
break;
|
||||
case 'list':
|
||||
echo '<textarea cols="40" rows="5" ' . $name_id . $field_class . '>'
|
||||
. htmlspecialchars(implode("\n", $value))
|
||||
. '</textarea>';
|
||||
break;
|
||||
}
|
||||
if (isset($opts['setvalue']) && $opts['setvalue']) {
|
||||
?>
|
||||
<a class="set-value" href="#<?php echo "$path={$opts['setvalue']}" ?>" title="<?php echo sprintf($GLOBALS['strSetupSetValue'], htmlspecialchars($opts['setvalue'])) ?>" style="display:none"><img alt="set-value" src="../<?php echo $GLOBALS['cfg']['ThemePath'] ?>/original/img/b_edit.png" width="16" height="16" /></a>
|
||||
<?php
|
||||
}
|
||||
if (isset($opts['show_restore_default']) && $opts['show_restore_default']) {
|
||||
?>
|
||||
<a class="restore-default" href="#<?php echo $path ?>" title="<?php echo $GLOBALS['strSetupRestoreDefaultValue'] ?>" style="display:none"><img alt="restore-default" src="../<?php echo $GLOBALS['cfg']['ThemePath'] ?>/original/img/s_reload.png" width="16" height="16" /></a>
|
||||
<?php
|
||||
}
|
||||
// this must match with displayErrors() in scripts.js
|
||||
if (isset($opts['errors']) && !empty($opts['errors'])) {
|
||||
echo "\n <dl class=\"inline_errors\">";
|
||||
foreach ($opts['errors'] as $error) {
|
||||
echo '<dd>' . htmlspecialchars($error) . '</dd>';
|
||||
}
|
||||
echo '</dl>';
|
||||
}
|
||||
?>
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<?php
|
||||
}
|
||||
|
||||
/**
|
||||
* Displays bottom part of a fieldset
|
||||
*
|
||||
* @param array $js_array
|
||||
*/
|
||||
function display_fieldset_bottom()
|
||||
{
|
||||
?>
|
||||
<tr>
|
||||
<td colspan="2" class="lastrow">
|
||||
<input type="submit" name="submit_save" value="<?php echo $GLOBALS['strSave'] ?>" class="green" />
|
||||
<input type="button" name="submit_reset" value="<?php echo $GLOBALS['strReset'] ?>" />
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</fieldset>
|
||||
|
||||
<?php
|
||||
}
|
||||
|
||||
/**
|
||||
* Displays simple bottom part of a fieldset (without submit buttons)
|
||||
*/
|
||||
function display_fieldset_bottom_simple()
|
||||
{
|
||||
?>
|
||||
</table>
|
||||
</fieldset>
|
||||
|
||||
<?php
|
||||
}
|
||||
|
||||
/**
|
||||
* Closes form tabs
|
||||
*/
|
||||
function display_tabs_bottom() {
|
||||
echo "</div>\n";
|
||||
}
|
||||
|
||||
/**
|
||||
* Displays bottom part of the form
|
||||
*/
|
||||
function display_form_bottom()
|
||||
{
|
||||
echo "</form>\n";
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends JS validation code to $js_array
|
||||
*
|
||||
* @param string $field_id
|
||||
* @param string $validator
|
||||
* @param array $js_array
|
||||
*/
|
||||
function js_validate($field_id, $validator, &$js_array) {
|
||||
$js_array[] = "validateField('$field_id', '$validator', true)";
|
||||
}
|
||||
|
||||
/**
|
||||
* Displays JavaScript code
|
||||
*
|
||||
* @param array $js_array
|
||||
*/
|
||||
function display_js($js_array) {
|
||||
if (empty($js_array)) {
|
||||
return;
|
||||
}
|
||||
?>
|
||||
<script type="text/javascript">
|
||||
<?php echo implode(";\n", $js_array) . ";\n" ?>
|
||||
</script>
|
||||
<?php
|
||||
}
|
||||
|
||||
/**
|
||||
* Displays error list
|
||||
*
|
||||
* @param string $name
|
||||
* @param array $error_list
|
||||
*/
|
||||
function display_errors($name, $error_list) {
|
||||
echo '<dl>';
|
||||
echo '<dt>' . htmlspecialchars($name) . '</dt>';
|
||||
foreach ($error_list as $error) {
|
||||
echo '<dd>' . htmlspecialchars($error) . '</dd>';
|
||||
}
|
||||
echo '</dl>';
|
||||
}
|
||||
?>
|
226
setup/lib/common.inc.php
Normal file
226
setup/lib/common.inc.php
Normal file
@@ -0,0 +1,226 @@
|
||||
<?php
|
||||
/**
|
||||
* Loads libraries/common.inc.php and preforms some additional actions
|
||||
*
|
||||
* @package phpMyAdmin-setup
|
||||
* @author Piotr Przybylski <piotrprz@gmail.com>
|
||||
* @license http://www.gnu.org/licenses/gpl.html GNU GPL 2.0
|
||||
* @version $Id$
|
||||
*/
|
||||
|
||||
/**
|
||||
* Do not include full common.
|
||||
* @ignore
|
||||
*/
|
||||
define('PMA_MINIMUM_COMMON', TRUE);
|
||||
define('PMA_SETUP', TRUE);
|
||||
chdir('..');
|
||||
|
||||
require_once './libraries/common.inc.php';
|
||||
require_once './libraries/url_generating.lib.php';
|
||||
require_once './setup/lib/ConfigFile.class.php';
|
||||
|
||||
// use default error handler
|
||||
restore_error_handler();
|
||||
|
||||
// Save current language in a cookie, required since we use PMA_MINIMUM_COMMON
|
||||
PMA_setCookie('pma_lang', $GLOBALS['lang']);
|
||||
|
||||
if (!isset($_SESSION['ConfigFile'])) {
|
||||
$_SESSION['ConfigFile'] = array();
|
||||
}
|
||||
|
||||
// allows for redirection even after sending some data
|
||||
ob_start();
|
||||
|
||||
/**
|
||||
* Returns value of an element in $array given by $path.
|
||||
* $path is a string describing position of an element in an associative array,
|
||||
* eg. Servers/1/host refers to $array[Servers][1][host]
|
||||
*
|
||||
* @param string $path
|
||||
* @param array $array
|
||||
* @param mixed $default
|
||||
* @return mixed array element or $default
|
||||
*/
|
||||
function array_read($path, $array, $default = null)
|
||||
{
|
||||
$keys = explode('/', $path);
|
||||
$value =& $array;
|
||||
foreach ($keys as $key) {
|
||||
if (!isset($value[$key])) {
|
||||
return $default;
|
||||
}
|
||||
$value =& $value[$key];
|
||||
}
|
||||
return $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Stores value in an array
|
||||
*
|
||||
* @param string $path
|
||||
* @param array &$array
|
||||
* @param mixed $value
|
||||
*/
|
||||
function array_write($path, &$array, $value)
|
||||
{
|
||||
$keys = explode('/', $path);
|
||||
$last_key = array_pop($keys);
|
||||
$a =& $array;
|
||||
foreach ($keys as $key) {
|
||||
if (!isset($a[$key])) {
|
||||
$a[$key] = array();
|
||||
}
|
||||
$a =& $a[$key];
|
||||
}
|
||||
$a[$last_key] = $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes value from an array
|
||||
*
|
||||
* @param string $path
|
||||
* @param array &$array
|
||||
* @param mixed $value
|
||||
*/
|
||||
function array_remove($path, &$array)
|
||||
{
|
||||
$keys = explode('/', $path);
|
||||
$keys_last = array_pop($keys);
|
||||
$path = array();
|
||||
$depth = 0;
|
||||
|
||||
$path[0] =& $array;
|
||||
$found = true;
|
||||
// go as deep as required or possible
|
||||
foreach ($keys as $key) {
|
||||
if (!isset($path[$depth][$key])) {
|
||||
$found = false;
|
||||
break;
|
||||
}
|
||||
$depth++;
|
||||
$path[$depth] =& $path[$depth-1][$key];
|
||||
}
|
||||
// if element found, remove it
|
||||
if ($found) {
|
||||
unset($path[$depth][$keys_last]);
|
||||
$depth--;
|
||||
}
|
||||
|
||||
// remove empty nested arrays
|
||||
for (; $depth >= 0; $depth--) {
|
||||
if (!isset($path[$depth+1]) || count($path[$depth+1]) == 0) {
|
||||
unset($path[$depth][$keys[$depth]]);
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns sanitized language string, taking into account our special codes
|
||||
* for formatting. Takes variable number of arguments.
|
||||
* Based on PMA_sanitize from sanitize.lib.php.
|
||||
*
|
||||
* @param string $lang_key key in $GLOBALS WITHOUT 'strSetup' prefix
|
||||
* @param mixed $args arguments for sprintf
|
||||
* @return string
|
||||
*/
|
||||
function PMA_lang($lang_key)
|
||||
{
|
||||
static $search, $replace;
|
||||
|
||||
// some quick cache'ing
|
||||
if ($search === null) {
|
||||
$replace_pairs = array(
|
||||
'<' => '<',
|
||||
'>' => '>',
|
||||
'[em]' => '<em>',
|
||||
'[/em]' => '</em>',
|
||||
'[strong]' => '<strong>',
|
||||
'[/strong]' => '</strong>',
|
||||
'[code]' => '<code>',
|
||||
'[/code]' => '</code>',
|
||||
'[kbd]' => '<kbd>',
|
||||
'[/kbd]' => '</kbd>',
|
||||
'[br]' => '<br />',
|
||||
'[sup]' => '<sup>',
|
||||
'[/sup]' => '</sup>');
|
||||
$search = array_keys($replace_pairs);
|
||||
$replace = array_values($replace_pairs);
|
||||
}
|
||||
if (!isset($GLOBALS["strSetup$lang_key"])) {
|
||||
return $lang_key;
|
||||
}
|
||||
$message = str_replace($search, $replace, $GLOBALS["strSetup$lang_key"]);
|
||||
// replace [a@"$1"]$2[/a] with <a href="$1">$2</a>
|
||||
$message = preg_replace('#\[a@("?)([^\]]+)\1\]([^\[]+)\[/a\]#e',
|
||||
"PMA_lang_link_replace('$2', '$3')", $message);
|
||||
|
||||
if (func_num_args() == 1) {
|
||||
return $message;
|
||||
} else {
|
||||
$args = func_get_args();
|
||||
array_shift($args);
|
||||
return vsprintf($message, $args);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns translated field name
|
||||
*
|
||||
* @param string $canonical_path
|
||||
* @return string
|
||||
*/
|
||||
function PMA_lang_name($canonical_path)
|
||||
{
|
||||
$lang_key = str_replace(
|
||||
array('Servers/1/', '/'),
|
||||
array('Servers/', '_'),
|
||||
$canonical_path) . '_name';
|
||||
return isset($GLOBALS["strSetup$lang_key"])
|
||||
? $GLOBALS["strSetup$lang_key"]
|
||||
: $lang_key;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns translated field description
|
||||
*
|
||||
* @param string $canonical_path
|
||||
* @return string
|
||||
*/
|
||||
function PMA_lang_desc($canonical_path)
|
||||
{
|
||||
$lang_key = str_replace(
|
||||
array('Servers/1/', '/'),
|
||||
array('Servers/', '_'),
|
||||
$canonical_path) . '_desc';
|
||||
return isset($GLOBALS["strSetup$lang_key"])
|
||||
? PMA_lang($lang_key)
|
||||
: '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Wraps link in <a> tags and replaces argument separator in internal links
|
||||
* to the one returned by PMA_get_arg_separator()
|
||||
*
|
||||
* @param string $link
|
||||
* @param string $text
|
||||
* @return string
|
||||
*/
|
||||
function PMA_lang_link_replace($link, $text)
|
||||
{
|
||||
static $separator;
|
||||
|
||||
if (!isset($separator)) {
|
||||
$separator = PMA_get_arg_separator('html');
|
||||
}
|
||||
|
||||
if (!preg_match('#^http://#', $link)) {
|
||||
$link = str_replace('&', $separator, $link);
|
||||
}
|
||||
|
||||
return '<a href="' . $link . '">' . $text . '</a>';
|
||||
}
|
||||
?>
|
150
setup/lib/config_info.inc.php
Normal file
150
setup/lib/config_info.inc.php
Normal file
@@ -0,0 +1,150 @@
|
||||
<?php
|
||||
/**
|
||||
* Description of options with non-standard values, list of persistent options
|
||||
* and validator assignments.
|
||||
*
|
||||
* By default data types are taken from config.default.php, here we define
|
||||
* only allowed values for select fields and type overrides.
|
||||
*
|
||||
* @package phpMyAdmin-setup
|
||||
* @author Piotr Przybylski <piotrprz@gmail.com>
|
||||
* @license http://www.gnu.org/licenses/gpl.html GNU GPL 2.0
|
||||
* @version $Id$
|
||||
*/
|
||||
|
||||
if (!defined('PHPMYADMIN')) {
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Load paths.
|
||||
*/
|
||||
require_once('./libraries/vendor_config.php');
|
||||
|
||||
$cfg_db = array();
|
||||
|
||||
// path to config file, relative to phpMyAdmin's root path
|
||||
$cfg_db['_config_file_path'] = SETUP_CONFIG_FILE;
|
||||
|
||||
/**
|
||||
* Value meaning:
|
||||
* o array - select field, array contains allowed values
|
||||
* o string - type override
|
||||
*
|
||||
* Use normal array, paths won't be expanded
|
||||
*/
|
||||
$cfg_db['Servers'] = array(1 => array(
|
||||
'port' => 'integer',
|
||||
'connect_type' => array('tcp', 'socket'),
|
||||
'extension' => array('mysql', 'mysqli'),
|
||||
'auth_type' => array('config', 'http', 'signon', 'cookie'),
|
||||
'AllowDeny' => array(
|
||||
'order' => array('', 'deny,allow', 'allow,deny', 'explicit')),
|
||||
'only_db' => 'array'));
|
||||
$cfg_db['RecodingEngine'] = array('auto', 'iconv', 'recode');
|
||||
$cfg_db['DefaultCharset'] = $GLOBALS['cfg']['AvailableCharsets'];
|
||||
$cfg_db['OBGzip'] = array('auto', true, false);
|
||||
$cfg_db['ShowTooltipAliasTB'] = array('nested', true, false);
|
||||
$cfg_db['DisplayDatabasesList'] = array('auto', true, false);
|
||||
$cfg_db['LeftLogoLinkWindow'] = array('main', 'new');
|
||||
$cfg_db['LeftDefaultTabTable'] = array(
|
||||
'tbl_structure.php', // fields list
|
||||
'tbl_sql.php', // SQL form
|
||||
'tbl_select.php', // search page
|
||||
'tbl_change.php', // insert row page
|
||||
'sql.php'); // browse page
|
||||
$cfg_db['NavigationBarIconic'] = array(true, false, 'both');
|
||||
$cfg_db['Order'] = array('ASC', 'DESC', 'SMART');
|
||||
$cfg_db['ProtectBinary'] = array(false, 'blob', 'all');
|
||||
$cfg_db['CharEditing'] = array('input', 'textarea');
|
||||
$cfg_db['PropertiesIconic'] = array(true, false, 'both');
|
||||
$cfg_db['DefaultTabServer'] = array(
|
||||
'main.php', // the welcome page (recommended for multiuser setups)
|
||||
'server_databases.php', // list of databases
|
||||
'server_status.php', // runtime information
|
||||
'server_variables.php', // MySQL server variables
|
||||
'server_privileges.php', // user management
|
||||
'server_processlist.php'); // process list
|
||||
$cfg_db['DefaultTabDatabase'] = array(
|
||||
'db_structure.php', // tables list
|
||||
'db_sql.php', // SQL form
|
||||
'db_search.php', // search query
|
||||
'db_operations.php'); // operations on database
|
||||
$cfg_db['DefaultTabTable'] = array(
|
||||
'tbl_structure.php', // fields list
|
||||
'tbl_sql.php', // SQL form
|
||||
'tbl_select.php', // search page
|
||||
'tbl_change.php', // insert row page
|
||||
'sql.php'); // browse page
|
||||
$cfg_db['QueryWindowDefTab'] = array(
|
||||
'sql', // SQL
|
||||
'files', // Import files
|
||||
'history', // SQL history
|
||||
'full'); // All (SQL and SQL history)
|
||||
$cfg_db['Import']['format'] = array(
|
||||
'csv', // CSV
|
||||
'docsql', // DocSQL
|
||||
'ldi', // CSV using LOAD DATA
|
||||
'sql'); // SQL
|
||||
$cfg_db['Import']['sql_compatibility'] = array(
|
||||
'NONE', 'ANSI', 'DB2', 'MAXDB', 'MYSQL323', 'MYSQL40', 'MSSQL', 'ORACLE',
|
||||
// removed; in MySQL 5.0.33, this produces exports that
|
||||
// can't be read by POSTGRESQL (see our bug #1596328)
|
||||
//'POSTGRESQL',
|
||||
'TRADITIONAL');
|
||||
$cfg_db['Import']['ldi_local_option'] = array('auto', true, false);
|
||||
$cfg_db['Export']['format'] = array('codegen', 'csv', 'excel', 'htmlexcel',
|
||||
'htmlword', 'latex', 'ods', 'odt', 'pdf', 'sql', 'texytext', 'xls', 'xml',
|
||||
'yaml');
|
||||
$cfg_db['Export']['compression'] = array('none', 'zip', 'gzip', 'bzip2');
|
||||
$cfg_db['Export']['charset'] = array_merge(array(''), $GLOBALS['cfg']['AvailableCharsets']);
|
||||
|
||||
/**
|
||||
* Config options which will be placed in config file even if they are set
|
||||
* to their default values (use only full paths)
|
||||
*/
|
||||
$persist_keys = array(
|
||||
'DefaultLang',
|
||||
'ServerDefault',
|
||||
'UploadDir',
|
||||
'SaveDir',
|
||||
'Servers/1/verbose',
|
||||
'Servers/1/host',
|
||||
'Servers/1/port',
|
||||
'Servers/1/socket',
|
||||
'Servers/1/extension',
|
||||
'Servers/1/connect_type',
|
||||
'Servers/1/auth_type',
|
||||
'Servers/1/user',
|
||||
'Servers/1/password');
|
||||
|
||||
/**
|
||||
* Default values overrides
|
||||
* Use only full paths
|
||||
*/
|
||||
$cfg_db['_overrides'] = array();
|
||||
$cfg_db['_overrides']['Servers/1/extension'] = extension_loaded('mysqli')
|
||||
? 'mysqli' : 'mysql';
|
||||
|
||||
/**
|
||||
* Validator assignments (functions from validate.lib.php and 'validators'
|
||||
* object in scripts.js)
|
||||
* Use only full paths and form ids
|
||||
*/
|
||||
$cfg_db['_validators'] = array(
|
||||
'Server' => 'validate_server',
|
||||
'Server_pmadb' => 'validate_pmadb',
|
||||
'Servers/1/port' => 'validate_port_number',
|
||||
'Servers/1/hide_db' => 'validate_regex',
|
||||
'TrustedProxies' => 'validate_trusted_proxies',
|
||||
'LoginCookieValidity' => 'validate_positive_number',
|
||||
'LoginCookieStore' => 'validate_non_negative_number',
|
||||
'QueryHistoryMax' => 'validate_positive_number',
|
||||
'LeftFrameTableLevel' => 'validate_positive_number',
|
||||
'MaxRows' => 'validate_positive_number',
|
||||
'CharTextareaCols' => 'validate_positive_number',
|
||||
'CharTextareaRows' => 'validate_positive_number',
|
||||
'InsertRows' => 'validate_positive_number',
|
||||
'ForeignKeyMaxLimit' => 'validate_positive_number',
|
||||
'Import/skip_queries' => 'validate_non_negative_number');
|
||||
?>
|
61
setup/lib/form_processing.lib.php
Normal file
61
setup/lib/form_processing.lib.php
Normal file
@@ -0,0 +1,61 @@
|
||||
<?php
|
||||
/**
|
||||
* Formset processing library
|
||||
*
|
||||
* @package phpMyAdmin-setup
|
||||
* @author Piotr Przybylski <piotrprz@gmail.com>
|
||||
* @license http://www.gnu.org/licenses/gpl.html GNU GPL 2.0
|
||||
* @version $Id$
|
||||
*/
|
||||
|
||||
/**
|
||||
* Processes forms registered in $form_display, handles error correction
|
||||
*
|
||||
* @param FormDisplay $form_display
|
||||
*/
|
||||
function process_formset(FormDisplay $form_display) {
|
||||
if (filter_input(INPUT_GET, 'mode') == 'revert') {
|
||||
// revert erroneous fields to their default values
|
||||
$form_display->fixErrors();
|
||||
// drop post data
|
||||
header('HTTP/1.1 303 See Other');
|
||||
header('Location: index.php');
|
||||
exit;
|
||||
}
|
||||
if (!$form_display->process(false)) {
|
||||
// handle form view and failed POST
|
||||
$form_display->display(true, true);
|
||||
} else {
|
||||
// check for form errors
|
||||
if ($form_display->hasErrors()) {
|
||||
// form has errors, show warning
|
||||
$separator = PMA_get_arg_separator('html');
|
||||
$page = filter_input(INPUT_GET, 'page');
|
||||
$formset = filter_input(INPUT_GET, 'formset');
|
||||
$formset = $formset ? "{$separator}formset=$formset" : '';
|
||||
$id = filter_input(INPUT_GET, 'id', FILTER_VALIDATE_INT);
|
||||
if ($id === null && $page == 'servers') {
|
||||
// we've just added a new server, get it's id
|
||||
$id = ConfigFile::getInstance()->getServerCount();
|
||||
}
|
||||
$id = $id ? "{$separator}id=$id" : '';
|
||||
?>
|
||||
<div class="warning">
|
||||
<h4><?php echo $GLOBALS['strSetupWarning'] ?></h4>
|
||||
<?php echo PMA_lang('error_form') ?><br />
|
||||
<a href="?page=<?php echo $page . $formset . $id . $separator ?>mode=revert"><?php echo PMA_lang('RevertErroneousFields') ?></a>
|
||||
</div>
|
||||
<?php $form_display->displayErrors() ?>
|
||||
<a class="btn" href="index.php"><?php echo PMA_lang('IgnoreErrors') ?></a>
|
||||
|
||||
<a class="btn" href="?page=<?php echo $page . $formset . $id . $separator ?>mode=edit"><?php echo PMA_lang('ShowForm') ?></a>
|
||||
<?php
|
||||
} else {
|
||||
// drop post data
|
||||
header('HTTP/1.1 303 See Other');
|
||||
header('Location: index.php');
|
||||
exit;
|
||||
}
|
||||
}
|
||||
}
|
||||
?>
|
176
setup/lib/forms.inc.php
Normal file
176
setup/lib/forms.inc.php
Normal file
@@ -0,0 +1,176 @@
|
||||
<?php
|
||||
/**
|
||||
* List of avaible forms, each form is described as an array of fields to display.
|
||||
* Fields MUST have their counterparts in the $cfg array.
|
||||
*
|
||||
* There are two possible notations:
|
||||
* $forms['Form name'] = array('Servers' => array(1 => array('host')));
|
||||
* can be written as
|
||||
* $forms['Form name'] = array('Servers/1/host');
|
||||
*
|
||||
* You can assign default values set by special button ("set value: ..."), eg.:
|
||||
* $forms['Server_pmadb'] = array('Servers' => array(1 => array(
|
||||
* 'pmadb' => 'phpmyadmin')));
|
||||
*
|
||||
* @package phpMyAdmin-setup
|
||||
* @author Piotr Przybylski <piotrprz@gmail.com>
|
||||
* @license http://www.gnu.org/licenses/gpl.html GNU GPL 2.0
|
||||
* @version $Id$
|
||||
*/
|
||||
|
||||
$forms = array();
|
||||
$forms['_config.php'] = array(
|
||||
'DefaultLang',
|
||||
'ServerDefault');
|
||||
$forms['Server'] = array('Servers' => array(1 => array(
|
||||
'verbose',
|
||||
'host',
|
||||
'port',
|
||||
'socket',
|
||||
'ssl',
|
||||
'connect_type',
|
||||
'extension',
|
||||
'compress',
|
||||
'auth_type',
|
||||
'user',
|
||||
'password',
|
||||
'nopassword',
|
||||
'auth_swekey_config' => './swekey.conf')));
|
||||
$forms['Server_login_options'] = array('Servers' => array(1 => array(
|
||||
'SignonSession',
|
||||
'SignonURL',
|
||||
'LogoutURL')));
|
||||
$forms['Server_config'] = array('Servers' => array(1 => array(
|
||||
'only_db',
|
||||
'hide_db',
|
||||
'AllowRoot',
|
||||
'AllowNoPassword',
|
||||
'DisableIS',
|
||||
'AllowDeny/order',
|
||||
'AllowDeny/rules',
|
||||
'ShowDatabasesCommand',
|
||||
'CountTables')));
|
||||
$forms['Server_pmadb'] = array('Servers' => array(1 => array(
|
||||
'pmadb' => 'phpmyadmin',
|
||||
'controluser',
|
||||
'controlpass',
|
||||
'verbose_check',
|
||||
'bookmarktable' => 'pma_bookmark',
|
||||
'relation' => 'pma_relation',
|
||||
'table_info' => 'pma_table_info',
|
||||
'table_coords' => 'pma_table_coords',
|
||||
'pdf_pages' => 'pma_pdf_pages',
|
||||
'column_info' => 'pma_column_info',
|
||||
'history' => 'pma_history',
|
||||
'designer_coords' => 'pma_designer_coords')));
|
||||
$forms['Import_export'] = array(
|
||||
'UploadDir',
|
||||
'SaveDir',
|
||||
'AllowAnywhereRecoding',
|
||||
'DefaultCharset',
|
||||
'RecodingEngine',
|
||||
'IconvExtraParams',
|
||||
'ZipDump',
|
||||
'GZipDump',
|
||||
'BZipDump',
|
||||
'CompressOnFly');
|
||||
$forms['Security'] = array(
|
||||
'blowfish_secret',
|
||||
'ForceSSL',
|
||||
'CheckConfigurationPermissions',
|
||||
'TrustedProxies',
|
||||
'AllowUserDropDatabase',
|
||||
'AllowArbitraryServer',
|
||||
'LoginCookieRecall',
|
||||
'LoginCookieValidity',
|
||||
'LoginCookieStore',
|
||||
'LoginCookieDeleteAll');
|
||||
$forms['Sql_queries'] = array(
|
||||
'ShowSQL',
|
||||
'Confirm',
|
||||
'QueryHistoryDB',
|
||||
'QueryHistoryMax',
|
||||
'IgnoreMultiSubmitErrors',
|
||||
'VerboseMultiSubmit');
|
||||
$forms['Other_core_settings'] = array(
|
||||
'MaxDbList',
|
||||
'MaxTableList',
|
||||
'MaxCharactersInDisplayedSQL',
|
||||
'OBGzip',
|
||||
'PersistentConnections',
|
||||
'ExecTimeLimit',
|
||||
'MemoryLimit',
|
||||
'SkipLockedTables',
|
||||
'UseDbSearch');
|
||||
$forms['Left_frame'] = array(
|
||||
'LeftFrameLight',
|
||||
'LeftDisplayLogo',
|
||||
'LeftLogoLink',
|
||||
'LeftLogoLinkWindow',
|
||||
'LeftDefaultTabTable',
|
||||
'LeftPointerEnable');
|
||||
$forms['Left_servers'] = array(
|
||||
'LeftDisplayServers',
|
||||
'DisplayServersList');
|
||||
$forms['Left_databases'] = array(
|
||||
'DisplayDatabasesList',
|
||||
'LeftFrameDBTree',
|
||||
'LeftFrameDBSeparator',
|
||||
'ShowTooltipAliasDB');
|
||||
$forms['Left_tables'] = array(
|
||||
'LeftFrameTableSeparator',
|
||||
'LeftFrameTableLevel',
|
||||
'ShowTooltip',
|
||||
'ShowTooltipAliasTB');
|
||||
$forms['Startup'] = array(
|
||||
'ShowStats',
|
||||
'ShowPhpInfo',
|
||||
'ShowServerInfo',
|
||||
'ShowChgPassword',
|
||||
'ShowCreateDb',
|
||||
'SuggestDBName');
|
||||
$forms['Browse'] = array(
|
||||
'NavigationBarIconic',
|
||||
'ShowAll',
|
||||
'MaxRows',
|
||||
'Order',
|
||||
'BrowsePointerEnable',
|
||||
'BrowseMarkerEnable');
|
||||
$forms['Edit'] = array(
|
||||
'ProtectBinary',
|
||||
'ShowFunctionFields',
|
||||
'CharEditing',
|
||||
'CharTextareaCols',
|
||||
'CharTextareaRows',
|
||||
'InsertRows',
|
||||
'ForeignKeyDropdownOrder',
|
||||
'ForeignKeyMaxLimit');
|
||||
$forms['Tabs'] = array(
|
||||
'LightTabs',
|
||||
'PropertiesIconic',
|
||||
'DefaultTabServer',
|
||||
'DefaultTabDatabase',
|
||||
'DefaultTabTable',
|
||||
'QueryWindowDefTab');
|
||||
$forms['Sql_box'] = array('SQLQuery' => array(
|
||||
'Edit',
|
||||
'Explain',
|
||||
'ShowAsPHP',
|
||||
'Validate',
|
||||
'Refresh'));
|
||||
$forms['Import_defaults'] = array('Import' => array(
|
||||
'format',
|
||||
'allow_interrupt',
|
||||
'skip_queries'));
|
||||
$forms['Export_defaults'] = array('Export' => array(
|
||||
'format',
|
||||
'compression',
|
||||
'asfile',
|
||||
'charset',
|
||||
'onserver',
|
||||
'onserver_overwrite',
|
||||
'remember_file_template',
|
||||
'file_template_table',
|
||||
'file_template_database',
|
||||
'file_template_server'));
|
||||
?>
|
438
setup/lib/index.lib.php
Normal file
438
setup/lib/index.lib.php
Normal file
@@ -0,0 +1,438 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Various checks and message functions used on index page.
|
||||
*
|
||||
* Security checks are the idea of Aung Khant <aungkhant[at]yehg.net>, http://yehg.net/lab
|
||||
* Version check taken from the old setup script by Michal Čihař <michal@cihar.com>
|
||||
*
|
||||
* @package phpMyAdmin-setup
|
||||
* @author Piotr Przybylski <piotrprz@gmail.com>
|
||||
* @license http://www.gnu.org/licenses/gpl.html GNU GPL 2.0
|
||||
* @version $Id$
|
||||
*/
|
||||
|
||||
if (!defined('PHPMYADMIN')) {
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Load vendor config.
|
||||
*/
|
||||
require_once('./libraries/vendor_config.php');
|
||||
|
||||
/**
|
||||
* Initializes message list
|
||||
*/
|
||||
function messages_begin()
|
||||
{
|
||||
if (!isset($_SESSION['messages']) || !is_array($_SESSION['messages'])) {
|
||||
$_SESSION['messages'] = array('error' => array(), 'warning' => array(), 'notice' => array());
|
||||
} else {
|
||||
// reset message states
|
||||
foreach ($_SESSION['messages'] as &$messages) {
|
||||
foreach ($messages as &$msg) {
|
||||
$msg['fresh'] = false;
|
||||
$msg['active'] = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a new message to message list
|
||||
*
|
||||
* @param string $id unique message identifier
|
||||
* @param string $type one of: notice, warning, error
|
||||
* @param string $title language string id (in $str array)
|
||||
* @param string $message message text
|
||||
*/
|
||||
function messages_set($type, $id, $title, $message)
|
||||
{
|
||||
$fresh = !isset($_SESSION['messages'][$type][$id]);
|
||||
$title = PMA_lang($title);
|
||||
$_SESSION['messages'][$type][$id] = array(
|
||||
'fresh' => $fresh,
|
||||
'active' => true,
|
||||
'title' => $title,
|
||||
'message' => $message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Cleans up message list
|
||||
*/
|
||||
function messages_end()
|
||||
{
|
||||
foreach ($_SESSION['messages'] as &$messages) {
|
||||
$remove_ids = array();
|
||||
foreach ($messages as $id => &$msg) {
|
||||
if ($msg['active'] == false) {
|
||||
$remove_ids[] = $id;
|
||||
}
|
||||
}
|
||||
foreach ($remove_ids as $id) {
|
||||
unset($messages[$id]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints message list, must be called after messages_end()
|
||||
*/
|
||||
function messages_show_html()
|
||||
{
|
||||
$old_ids = array();
|
||||
foreach ($_SESSION['messages'] as $type => $messages) {
|
||||
foreach ($messages as $id => $msg) {
|
||||
echo '<div class="' . $type . '" id="' . $id . '">' . '<h4>' . $msg['title'] . '</h4>' . $msg['message'] . '</div>';
|
||||
if (!$msg['fresh'] && $type != 'error') {
|
||||
$old_ids[] = $id;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
echo "\n" . '<script type="text/javascript">';
|
||||
foreach ($old_ids as $id) {
|
||||
echo "\nhiddenMessages.push('$id');";
|
||||
}
|
||||
echo "\n</script>\n";
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks for newest phpMyAdmin version and sets result as a new notice
|
||||
*/
|
||||
function PMA_version_check()
|
||||
{
|
||||
// version check messages should always be visible so let's make
|
||||
// a unique message id each time we run it
|
||||
$message_id = uniqid('version_check');
|
||||
// wait 3s at most for server response, it's enough to get information
|
||||
// from a working server
|
||||
$connection_timeout = 3;
|
||||
|
||||
$url = 'http://phpmyadmin.net/home_page/version.php';
|
||||
$context = stream_context_create(array(
|
||||
'http' => array(
|
||||
'timeout' => $connection_timeout)));
|
||||
$data = @file_get_contents($url, null, $context);
|
||||
if ($data === false) {
|
||||
if (function_exists('curl_init')) {
|
||||
$ch = curl_init($url);
|
||||
curl_setopt($ch, CURLOPT_HEADER, false);
|
||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
||||
curl_setopt($ch, CURLOPT_TIMEOUT, $connection_timeout);
|
||||
$data = curl_exec($ch);
|
||||
curl_close($ch);
|
||||
} else {
|
||||
messages_set('error', $message_id, 'VersionCheck',
|
||||
PMA_lang('VersionCheckWrapperError'));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (empty($data)) {
|
||||
messages_set('error', $message_id, 'VersionCheck',
|
||||
PMA_lang('VersionCheckDataError'));
|
||||
return;
|
||||
}
|
||||
|
||||
/* Format: version\ndate\n(download\n)* */
|
||||
$data_list = explode("\n", $data);
|
||||
|
||||
if (count($data_list) > 1) {
|
||||
$version = $data_list[0];
|
||||
$date = $data_list[1];
|
||||
} else {
|
||||
$version = $date = '';
|
||||
}
|
||||
|
||||
$version_upstream = version_to_int($version);
|
||||
if ($version_upstream === false) {
|
||||
messages_set('error', $message_id, 'VersionCheck',
|
||||
PMA_lang('VersionCheckInvalid'));
|
||||
return;
|
||||
}
|
||||
|
||||
$version_local = version_to_int($_SESSION['PMA_Config']->get('PMA_VERSION'));
|
||||
if ($version_local === false) {
|
||||
messages_set('error', $message_id, 'VersionCheck',
|
||||
PMA_lang('VersionCheckUnparsable'));
|
||||
return;
|
||||
}
|
||||
|
||||
if ($version_upstream > $version_local) {
|
||||
$version = htmlspecialchars($version);
|
||||
$date = htmlspecialchars($date);
|
||||
messages_set('notice', $message_id, 'VersionCheck',
|
||||
PMA_lang('VersionCheckNewAvailable', $version, $date));
|
||||
} else {
|
||||
if ($version_local % 100 == 0) {
|
||||
messages_set('notice', $message_id, 'VersionCheck',
|
||||
PMA_lang('VersionCheckNewAvailableSvn', $version, $date));
|
||||
} else {
|
||||
messages_set('notice', $message_id, 'VersionCheck',
|
||||
PMA_lang('VersionCheckNone'));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates numerical equivalent of phpMyAdmin version string
|
||||
*
|
||||
* @param string version
|
||||
* @return mixed false on failure, integer on success
|
||||
*/
|
||||
function version_to_int($version)
|
||||
{
|
||||
$matches = array();
|
||||
if (!preg_match('/^(\d+)\.(\d+)\.(\d+)((\.|-(pl|rc|dev|beta|alpha))(\d+)?)?$/', $version, $matches)) {
|
||||
return false;
|
||||
}
|
||||
if (!empty($matches[6])) {
|
||||
switch ($matches[6]) {
|
||||
case 'pl':
|
||||
$added = 60;
|
||||
break;
|
||||
case 'rc':
|
||||
$added = 30;
|
||||
break;
|
||||
case 'beta':
|
||||
$added = 20;
|
||||
break;
|
||||
case 'alpha':
|
||||
$added = 10;
|
||||
break;
|
||||
case 'dev':
|
||||
$added = 0;
|
||||
break;
|
||||
default:
|
||||
messages_set('notice', 'version_match', 'VersionCheck',
|
||||
'Unknown version part: ' . htmlspecialchars($matches[6]));
|
||||
$added = 0;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
$added = 50; // for final
|
||||
}
|
||||
if (!empty($matches[7])) {
|
||||
$added = $added + $matches[7];
|
||||
}
|
||||
return $matches[1] * 1000000 + $matches[2] * 10000 + $matches[3] * 100 + $added;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether config file is readable/writable
|
||||
*
|
||||
* @param bool &$is_readable
|
||||
* @param bool &$is_writable
|
||||
* @param bool &$file_exists
|
||||
*/
|
||||
function check_config_rw(&$is_readable, &$is_writable, &$file_exists)
|
||||
{
|
||||
$file_path = ConfigFile::getInstance()->getFilePath();
|
||||
$file_dir = dirname($file_path);
|
||||
$is_readable = true;
|
||||
$is_writable = is_dir($file_dir);
|
||||
if (SETUP_DIR_WRITABLE) {
|
||||
$is_writable = $is_writable && is_writable($file_dir);
|
||||
}
|
||||
$file_exists = file_exists($file_path);
|
||||
if ($file_exists) {
|
||||
$is_readable = is_readable($file_path);
|
||||
$is_writable = $is_writable && is_writable($file_path);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs various compatibility, security and consistency checks on current config
|
||||
*
|
||||
* Outputs results to message list, must be called between messages_begin()
|
||||
* and messages_end()
|
||||
*/
|
||||
function perform_config_checks()
|
||||
{
|
||||
$cf = ConfigFile::getInstance();
|
||||
$blowfish_secret = $cf->get('blowfish_secret');
|
||||
$blowfish_secret_set = false;
|
||||
$cookie_auth_used = false;
|
||||
for ($i = 1, $server_cnt = $cf->getServerCount(); $i <= $server_cnt; $i++) {
|
||||
$cookie_auth_server = ($cf->getValue("Servers/$i/auth_type") == 'cookie');
|
||||
$cookie_auth_used |= $cookie_auth_server;
|
||||
$server_name = $cf->getServerName($i);
|
||||
if ($server_name == 'localhost') {
|
||||
$server_name .= " [$i]";
|
||||
}
|
||||
|
||||
if ($cookie_auth_server && $blowfish_secret === null) {
|
||||
$blowfish_secret = uniqid('', true);
|
||||
$blowfish_secret_set = true;
|
||||
$cf->set('blowfish_secret', $blowfish_secret);
|
||||
}
|
||||
|
||||
//
|
||||
// $cfg['Servers'][$i]['ssl']
|
||||
// should be enabled if possible
|
||||
//
|
||||
if (!$cf->getValue("Servers/$i/ssl")) {
|
||||
$title = PMA_lang_name('Servers/1/ssl') . " ($server_name)";
|
||||
messages_set('notice', "Servers/$i/ssl", $title,
|
||||
PMA_lang('ServerSslMsg'));
|
||||
}
|
||||
|
||||
//
|
||||
// $cfg['Servers'][$i]['extension']
|
||||
// warn about using 'mysql'
|
||||
//
|
||||
if ($cf->getValue("Servers/$i/extension") == 'mysql') {
|
||||
$title = PMA_lang_name('Servers/1/extension') . " ($server_name)";
|
||||
messages_set('notice', "Servers/$i/extension", $title,
|
||||
PMA_lang('ServerExtensionMsg'));
|
||||
}
|
||||
|
||||
//
|
||||
// $cfg['Servers'][$i]['auth_type']
|
||||
// warn about full user credentials if 'auth_type' is 'config'
|
||||
//
|
||||
if ($cf->getValue("Servers/$i/auth_type") == 'config'
|
||||
&& $cf->getValue("Servers/$i/user") != ''
|
||||
&& $cf->getValue("Servers/$i/password") != '') {
|
||||
$title = PMA_lang_name('Servers/1/auth_type') . " ($server_name)";
|
||||
messages_set('warning', "Servers/$i/auth_type", $title,
|
||||
PMA_lang('ServerAuthConfigMsg', $i) . ' ' .
|
||||
PMA_lang('ServerSecurityInfoMsg', $i));
|
||||
}
|
||||
|
||||
//
|
||||
// $cfg['Servers'][$i]['AllowRoot']
|
||||
// $cfg['Servers'][$i]['AllowNoPassword']
|
||||
// serious security flaw
|
||||
//
|
||||
if ($cf->getValue("Servers/$i/AllowRoot")
|
||||
&& $cf->getValue("Servers/$i/AllowNoPassword")) {
|
||||
$title = PMA_lang_name('Servers/1/AllowNoPassword') . " ($server_name)";
|
||||
messages_set('warning', "Servers/$i/AllowNoPassword", $title,
|
||||
PMA_lang('ServerNoPasswordMsg') . ' ' .
|
||||
PMA_lang('ServerSecurityInfoMsg', $i));
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// $cfg['blowfish_secret']
|
||||
// it's required for 'cookie' authentication
|
||||
//
|
||||
if ($cookie_auth_used) {
|
||||
if ($blowfish_secret_set) {
|
||||
// 'cookie' auth used, blowfish_secret was generated
|
||||
messages_set('notice', 'blowfish_secret_created', 'blowfish_secret_name',
|
||||
PMA_lang('BlowfishSecretMsg'));
|
||||
} else {
|
||||
$blowfish_warnings = array();
|
||||
// check length
|
||||
if (strlen($blowfish_secret) < 8) {
|
||||
// too short key
|
||||
$blowfish_warnings[] = PMA_lang('BlowfishSecretLengthMsg');
|
||||
}
|
||||
// check used characters
|
||||
$has_digits = (bool) preg_match('/\d/', $blowfish_secret);
|
||||
$has_chars = (bool) preg_match('/\S/', $blowfish_secret);
|
||||
$has_nonword = (bool) preg_match('/\W/', $blowfish_secret);
|
||||
if (!$has_digits || !$has_chars || !$has_nonword) {
|
||||
$blowfish_warnings[] = PMA_lang('BlowfishSecretCharsMsg');
|
||||
}
|
||||
if (!empty($blowfish_warnings)) {
|
||||
messages_set('warning', 'blowfish_warnings' . count($blowfish_warnings),
|
||||
'blowfish_secret_name', implode("<br />", $blowfish_warnings));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// $cfg['ForceSSL']
|
||||
// should be enabled if possible
|
||||
//
|
||||
if (!$cf->getValue('ForceSSL')) {
|
||||
messages_set('notice', 'ForceSSL', 'ForceSSL_name',
|
||||
PMA_lang('ForceSSLMsg'));
|
||||
}
|
||||
|
||||
//
|
||||
// $cfg['AllowArbitraryServer']
|
||||
// should be disabled
|
||||
//
|
||||
if ($cf->getValue('AllowArbitraryServer')) {
|
||||
messages_set('warning', 'AllowArbitraryServer', 'AllowArbitraryServer_name',
|
||||
PMA_lang('AllowArbitraryServerMsg'));
|
||||
}
|
||||
|
||||
//
|
||||
// $cfg['LoginCookieValidity']
|
||||
// should be at most 1800 (30 min)
|
||||
//
|
||||
if ($cf->getValue('LoginCookieValidity') > 1800) {
|
||||
messages_set('warning', 'LoginCookieValidity', 'LoginCookieValidity_name',
|
||||
PMA_lang('LoginCookieValidityMsg'));
|
||||
}
|
||||
|
||||
//
|
||||
// $cfg['SaveDir']
|
||||
// should not be world-accessible
|
||||
//
|
||||
if ($cf->getValue('SaveDir') != '') {
|
||||
messages_set('notice', 'SaveDir', 'SaveDir_name',
|
||||
PMA_lang('DirectoryNotice'));
|
||||
}
|
||||
|
||||
//
|
||||
// $cfg['TempDir']
|
||||
// should not be world-accessible
|
||||
//
|
||||
if ($cf->getValue('TempDir') != '') {
|
||||
messages_set('notice', 'TempDir', 'TempDir_name',
|
||||
PMA_lang('DirectoryNotice'));
|
||||
}
|
||||
|
||||
//
|
||||
// $cfg['GZipDump']
|
||||
// requires zlib functions
|
||||
//
|
||||
if ($cf->getValue('GZipDump')
|
||||
&& (@!function_exists('gzopen') || @!function_exists('gzencode'))) {
|
||||
messages_set('warning', 'GZipDump', 'GZipDump_name',
|
||||
PMA_lang('GZipDumpWarning', 'gzencode'));
|
||||
}
|
||||
|
||||
//
|
||||
// $cfg['BZipDump']
|
||||
// requires bzip2 functions
|
||||
//
|
||||
if ($cf->getValue('BZipDump')
|
||||
&& (!@function_exists('bzopen') || !@function_exists('bzcompress'))) {
|
||||
$functions = @function_exists('bzopen')
|
||||
? '' :
|
||||
'bzopen';
|
||||
$functions .= @function_exists('bzcompress')
|
||||
? ''
|
||||
: ($functions ? ', ' : '') . 'bzcompress';
|
||||
messages_set('warning', 'BZipDump', 'BZipDump_name',
|
||||
PMA_lang('BZipDumpWarning', $functions));
|
||||
}
|
||||
|
||||
//
|
||||
// $cfg['ZipDump']
|
||||
// requires zip_open in import
|
||||
//
|
||||
if ($cf->getValue('ZipDump') && !@function_exists('zip_open')) {
|
||||
messages_set('warning', 'ZipDump_import', 'ZipDump_name',
|
||||
PMA_lang('ZipDumpImportWarning', 'zip_open'));
|
||||
}
|
||||
|
||||
//
|
||||
// $cfg['ZipDump']
|
||||
// requires gzcompress in export
|
||||
//
|
||||
if ($cf->getValue('ZipDump') && !@function_exists('gzcompress')) {
|
||||
messages_set('warning', 'ZipDump_export', 'ZipDump_name',
|
||||
PMA_lang('ZipDumpExportWarning', 'gzcompress'));
|
||||
}
|
||||
}
|
||||
?>
|
362
setup/lib/validate.lib.php
Normal file
362
setup/lib/validate.lib.php
Normal file
@@ -0,0 +1,362 @@
|
||||
<?php
|
||||
/**
|
||||
* Various validation functions
|
||||
*
|
||||
* Validation function takes two argument: id for which it is called
|
||||
* and array of fields' values (usually values for entire formset, as defined
|
||||
* in forms.inc.php).
|
||||
* The function must always return an array with an error (or error array)
|
||||
* assigned to a form element (formset name or field path). Even if there are
|
||||
* no errors, key must be set with an empty value.
|
||||
*
|
||||
* Valdiation functions are assigned in $cfg_db['_validators'] (config_info.inc.php).
|
||||
*
|
||||
* @package phpMyAdmin-setup
|
||||
* @author Piotr Przybylski <piotrprz@gmail.com>
|
||||
* @license http://www.gnu.org/licenses/gpl.html GNU GPL 2.0
|
||||
* @version $Id$
|
||||
*/
|
||||
|
||||
/**
|
||||
* Runs validation $validator_id on values $values and returns error list.
|
||||
*
|
||||
* Return values:
|
||||
* o array, keys - field path or formset id, values - array of errors
|
||||
* when $isPostSource is true values is an empty array to allow for error list
|
||||
* cleanup in HTML documen
|
||||
* o false - when no validators match name(s) given by $validator_id
|
||||
*
|
||||
* @param string|array $validator_id
|
||||
* @param array $values
|
||||
* @param bool $isPostSource tells whether $values are directly from POST request
|
||||
* @return bool|array
|
||||
*/
|
||||
function validate($validator_id, &$values, $isPostSource)
|
||||
{
|
||||
// find validators
|
||||
$cf = ConfigFile::getInstance();
|
||||
$validator_id = (array) $validator_id;
|
||||
$validators = $cf->getDbEntry('_validators');
|
||||
$vids = array();
|
||||
foreach ($validator_id as &$vid) {
|
||||
$vid = $cf->getCanonicalPath($vid);
|
||||
if (isset($validators[$vid])) {
|
||||
$vids[] = $vid;
|
||||
}
|
||||
}
|
||||
if (empty($vids)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// create argument list with canonical paths and remember path mapping
|
||||
$arguments = array();
|
||||
$key_map = array();
|
||||
foreach ($values as $k => $v) {
|
||||
$k2 = $isPostSource ? str_replace('-', '/', $k) : $k;
|
||||
$k2 = strpos($k2, '/') ? $cf->getCanonicalPath($k2) : $k2;
|
||||
$key_map[$k2] = $k;
|
||||
$arguments[$k2] = $v;
|
||||
}
|
||||
|
||||
// validate
|
||||
$result = array();
|
||||
foreach ($vids as $vid) {
|
||||
$r = call_user_func($validators[$vid], $vid, $arguments);
|
||||
// merge results
|
||||
if (is_array($r)) {
|
||||
foreach ($r as $key => $error_list) {
|
||||
// skip empty values if $isPostSource is false
|
||||
if (!$isPostSource && empty($error_list)) {
|
||||
continue;
|
||||
}
|
||||
if (!isset($result[$key])) {
|
||||
$result[$key] = array();
|
||||
}
|
||||
$result[$key] = array_merge($result[$key], (array)$error_list);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// restore original paths
|
||||
$new_result = array();
|
||||
foreach ($result as $k => $v) {
|
||||
$k2 = isset($key_map[$k]) ? $key_map[$k] : $k;
|
||||
$new_result[$k2] = $v;
|
||||
}
|
||||
return empty($new_result) ? true : $new_result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensures that $php_errormsg variable will be registered in case of an error
|
||||
* and enables output buffering (when $start = true).
|
||||
* Called with $start = false disables output buffering end restores
|
||||
* html_errors and track_errors.
|
||||
*
|
||||
* @param boolean $start
|
||||
*/
|
||||
function test_php_errormsg($start = true)
|
||||
{
|
||||
static $old_html_errors, $old_track_errors;
|
||||
if ($start) {
|
||||
$old_html_errors = ini_get('html_errors');
|
||||
$old_track_errors = ini_get('track_errors');
|
||||
ini_set('html_errors', false);
|
||||
ini_set('track_errors', true);
|
||||
ob_start();
|
||||
} else {
|
||||
ob_end_clean();
|
||||
ini_set('html_errors', $old_html_errors);
|
||||
ini_set('track_errors', $old_track_errors);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test database connection
|
||||
*
|
||||
* @param string $extension 'mysql' or 'mysqli'
|
||||
* @param string $connect_type 'tcp' or 'socket'
|
||||
* @param string $host
|
||||
* @param string $port
|
||||
* @param string $socket
|
||||
* @param string $user
|
||||
* @param string $pass
|
||||
* @param string $error_key
|
||||
* @return bool|array
|
||||
*/
|
||||
function test_db_connection($extension, $connect_type, $host, $port, $socket, $user, $pass = null, $error_key = 'Server')
|
||||
{
|
||||
// test_php_errormsg();
|
||||
$socket = empty($socket) || $connect_type == 'tcp' ? null : ':' . $socket;
|
||||
$port = empty($port) || $connect_type == 'socket' ? null : ':' . $port;
|
||||
$error = null;
|
||||
if ($extension == 'mysql') {
|
||||
$conn = @mysql_connect($host . $socket . $port, $user, $pass);
|
||||
if (!$conn) {
|
||||
$error = PMA_lang('error_connection');
|
||||
} else {
|
||||
mysql_close($conn);
|
||||
}
|
||||
} else {
|
||||
$conn = @mysqli_connect($host, $user, $pass, null, $port, $socket);
|
||||
if (!$conn) {
|
||||
$error = PMA_lang('error_connection');
|
||||
} else {
|
||||
mysqli_close($conn);
|
||||
}
|
||||
}
|
||||
// test_php_errormsg(false);
|
||||
if (isset($php_errormsg)) {
|
||||
$error .= " - $php_errormsg";
|
||||
}
|
||||
return is_null($error) ? true : array($error_key => $error);
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate server config
|
||||
*
|
||||
* @param string $path
|
||||
* @param array $values
|
||||
* @return array
|
||||
*/
|
||||
function validate_server($path, $values)
|
||||
{
|
||||
$result = array('Server' => '', 'Servers/1/user' => '', 'Servers/1/SignonSession' => '', 'Servers/1/SignonURL' => '');
|
||||
$error = false;
|
||||
if ($values['Servers/1/auth_type'] == 'config' && empty($values['Servers/1/user'])) {
|
||||
$result['Servers/1/user'] = PMA_lang('error_empty_user_for_config_auth');
|
||||
$error = true;
|
||||
}
|
||||
if ($values['Servers/1/auth_type'] == 'signon' && empty($values['Servers/1/SignonSession'])) {
|
||||
$result['Servers/1/SignonSession'] = PMA_lang('error_empty_signon_session');
|
||||
$error = true;
|
||||
}
|
||||
if ($values['Servers/1/auth_type'] == 'signon' && empty($values['Servers/1/SignonURL'])) {
|
||||
$result['Servers/1/SignonURL'] = PMA_lang('error_empty_signon_url');
|
||||
$error = true;
|
||||
}
|
||||
|
||||
if (!$error && $values['Servers/1/auth_type'] == 'config') {
|
||||
$password = $values['Servers/1/nopassword'] ? null : $values['Servers/1/password'];
|
||||
$test = test_db_connection($values['Servers/1/extension'], $values['Servers/1/connect_type'], $values['Servers/1/host'], $values['Servers/1/port'], $values['Servers/1/socket'], $values['Servers/1/user'], $password, 'Server');
|
||||
if ($test !== true) {
|
||||
$result = array_merge($result, $test);
|
||||
}
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate pmadb config
|
||||
*
|
||||
* @param string $path
|
||||
* @param array $values
|
||||
* @return array
|
||||
*/
|
||||
function validate_pmadb($path, $values)
|
||||
{
|
||||
$tables = array('Servers/1/bookmarktable', 'Servers/1/relation', 'Servers/1/table_info', 'Servers/1/table_coords', 'Servers/1/pdf_pages', 'Servers/1/column_info', 'Servers/1/history', 'Servers/1/designer_coords');
|
||||
$result = array('Server_pmadb' => '', 'Servers/1/controluser' => '', 'Servers/1/controlpass' => '');
|
||||
$error = false;
|
||||
|
||||
if ($values['Servers/1/pmadb'] == '') {
|
||||
return $result;
|
||||
}
|
||||
|
||||
$result = array();
|
||||
if ($values['Servers/1/controluser'] == '') {
|
||||
$result['Servers/1/controluser'] = PMA_lang('error_empty_pmadb_user');
|
||||
$error = true;
|
||||
}
|
||||
if ($values['Servers/1/controlpass'] == '') {
|
||||
$result['Servers/1/controlpass'] = PMA_lang('error_empty_pmadb_password');
|
||||
$error = true;
|
||||
}
|
||||
if (!$error) {
|
||||
$test = test_db_connection($values['Servers/1/extension'], $values['Servers/1/connect_type'], $values['Servers/1/host'], $values['Servers/1/port'], $values['Servers/1/socket'], $values['Servers/1/controluser'], $values['Servers/1/controlpass'], 'Server_pmadb');
|
||||
if ($test !== true) {
|
||||
$result = array_merge($result, $test);
|
||||
}
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Validates regular expression
|
||||
*
|
||||
* @param string $path
|
||||
* @param array $values
|
||||
* @return array
|
||||
*/
|
||||
function validate_regex($path, $values)
|
||||
{
|
||||
$result = array($path => '');
|
||||
|
||||
if ($values[$path] == '') {
|
||||
return $result;
|
||||
}
|
||||
|
||||
test_php_errormsg();
|
||||
|
||||
$matches = array();
|
||||
preg_match($values[$path], '', $matches);
|
||||
ob_end_clean();
|
||||
|
||||
test_php_errormsg(false);
|
||||
|
||||
if (isset($php_errormsg)) {
|
||||
$error = preg_replace('/^preg_match\(\): /', '', $php_errormsg);
|
||||
return array($path => $error);
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates TrustedProxies field
|
||||
*
|
||||
* @param string $path
|
||||
* @param array $values
|
||||
* @return array
|
||||
*/
|
||||
function validate_trusted_proxies($path, $values)
|
||||
{
|
||||
$result = array($path => array());
|
||||
|
||||
if (empty($values[$path])) {
|
||||
return $result;
|
||||
}
|
||||
|
||||
if (is_array($values[$path])) {
|
||||
// value already processed by FormDisplay::save
|
||||
$lines = array();
|
||||
foreach ($values[$path] as $ip => $v) {
|
||||
$lines[] = preg_match('/^-\d+$/', $ip)
|
||||
? $v
|
||||
: $ip . ': ' . $v;
|
||||
}
|
||||
} else {
|
||||
// AJAX validation
|
||||
$lines = explode("\n", $values[$path]);
|
||||
}
|
||||
foreach ($lines as $line) {
|
||||
$line = trim($line);
|
||||
$matches = array();
|
||||
// we catch anything that may (or may not) be an IP
|
||||
if (!preg_match("/^(.+):(?:[ ]?)\\w+$/", $line, $matches)) {
|
||||
$result[$path][] = PMA_lang('error_incorrect_value') . ': ' . $line;
|
||||
continue;
|
||||
}
|
||||
// now let's check whether we really have an IP address
|
||||
if (filter_var($matches[1], FILTER_VALIDATE_IP, FILTER_FLAG_IPV4) === false
|
||||
&& filter_var($matches[1], FILTER_VALIDATE_IP, FILTER_FLAG_IPV6) === false) {
|
||||
$ip = htmlspecialchars(trim($matches[1]));
|
||||
$result[$path][] = PMA_lang('error_incorrect_ip_address', $ip);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Tests integer value
|
||||
*
|
||||
* @param string $path
|
||||
* @param array $values
|
||||
* @param bool $allow_neg allow negative values
|
||||
* @param bool $allow_zero allow zero
|
||||
* @param int $max_value max allowed value
|
||||
* @param string $error_lang_key error message key: $GLOBALS["strSetup$error_lang_key"]
|
||||
* @return string empty string if test is successful
|
||||
*/
|
||||
function test_number($path, $values, $allow_neg, $allow_zero, $max_value, $error_lang_key)
|
||||
{
|
||||
if ($values[$path] === '') {
|
||||
return '';
|
||||
}
|
||||
|
||||
if (intval($values[$path]) != $values[$path] || (!$allow_neg && $values[$path] < 0) || (!$allow_zero && $values[$path] == 0) || $values[$path] > $max_value) {
|
||||
return PMA_lang($error_lang_key);
|
||||
}
|
||||
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates port number
|
||||
*
|
||||
* @param string $path
|
||||
* @param array $values
|
||||
* @return array
|
||||
*/
|
||||
function validate_port_number($path, $values)
|
||||
{
|
||||
return array($path => test_number($path, $values, false, false, 65536, 'error_incorrect_port'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates positive number
|
||||
*
|
||||
* @param string $path
|
||||
* @param array $values
|
||||
* @return array
|
||||
*/
|
||||
function validate_positive_number($path, $values)
|
||||
{
|
||||
return array($path => test_number($path, $values, false, false, PHP_INT_MAX, 'error_nan_p'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates non-negative number
|
||||
*
|
||||
* @param string $path
|
||||
* @param array $values
|
||||
* @return array
|
||||
*/
|
||||
function validate_non_negative_number($path, $values)
|
||||
{
|
||||
return array($path => test_number($path, $values, false, true, PHP_INT_MAX, 'error_nan_nneg'));
|
||||
}
|
||||
?>
|
717
setup/scripts.js
Normal file
717
setup/scripts.js
Normal file
@@ -0,0 +1,717 @@
|
||||
/**
|
||||
* functions used in setup script
|
||||
*
|
||||
* @version $Id$
|
||||
*/
|
||||
|
||||
// show this window in top frame
|
||||
if (top != self) {
|
||||
window.top.location.href = location;
|
||||
}
|
||||
|
||||
// default values for fields
|
||||
var defaultValues = {};
|
||||
|
||||
// language strings
|
||||
var PMA_messages = {};
|
||||
|
||||
/**
|
||||
* Returns field type
|
||||
*
|
||||
* @param Element field
|
||||
*/
|
||||
function getFieldType(field) {
|
||||
if (field.tagName == 'INPUT') {
|
||||
return field.getProperty('type');
|
||||
} else if (field.tagName == 'SELECT') {
|
||||
return 'select';
|
||||
} else if (field.tagName == 'TEXTAREA') {
|
||||
return 'text';
|
||||
}
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets field value
|
||||
*
|
||||
* value must be of type:
|
||||
* o undefined (omitted) - restore default value (form default, not PMA default)
|
||||
* o String - if type is 'text'
|
||||
* o boolean - if type is 'checkbox'
|
||||
* o Array of values - if type is 'select'
|
||||
*
|
||||
* @param Element field
|
||||
* @param String field_type see getFieldType
|
||||
* @param mixed value
|
||||
*/
|
||||
function setFieldValue(field, field_type, value) {
|
||||
switch (field_type) {
|
||||
case 'text':
|
||||
field.value = $defined(value) ? value : field.defaultValue;
|
||||
break;
|
||||
case 'checkbox':
|
||||
field.checked = $defined(value) ? value : field.defaultChecked;
|
||||
break;
|
||||
case 'select':
|
||||
var i, imax = field.options.length;
|
||||
if (!$defined(value)) {
|
||||
for (i = 0; i < imax; i++) {
|
||||
field.options[i].selected = field.options[i].defaultSelected;
|
||||
}
|
||||
} else {
|
||||
for (i = 0; i < imax; i++) {
|
||||
field.options[i].selected = (value.indexOf(field.options[i].value) != -1);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
markField(field);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets field value
|
||||
*
|
||||
* Will return one of:
|
||||
* o String - if type is 'text'
|
||||
* o boolean - if type is 'checkbox'
|
||||
* o Array of values - if type is 'select'
|
||||
*
|
||||
* @param Element field
|
||||
* @param String field_type see getFieldType
|
||||
* @return mixed
|
||||
*/
|
||||
function getFieldValue(field, field_type) {
|
||||
switch (field_type) {
|
||||
case 'text':
|
||||
return field.value;
|
||||
case 'checkbox':
|
||||
return field.checked;
|
||||
case 'select':
|
||||
var i, imax = field.options.length, items = [];
|
||||
for (i = 0; i < imax; i++) {
|
||||
if (field.options[i].selected) {
|
||||
items.push(field.options[i].value);
|
||||
}
|
||||
}
|
||||
return items;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns values for all fields in fieldsets
|
||||
*/
|
||||
function getAllValues() {
|
||||
var elements = $$('fieldset input, fieldset select, fieldset textarea');
|
||||
var values = {}
|
||||
var type, value;
|
||||
for (var i = 0; i < elements.length; i++) {
|
||||
type = getFieldType(elements[i]);
|
||||
value = getFieldValue(elements[i], type);
|
||||
if (typeof value != 'undefined') {
|
||||
// we only have single selects, fatten array
|
||||
if (type == 'select') {
|
||||
value = value[0];
|
||||
}
|
||||
values[elements[i].name] = value;
|
||||
}
|
||||
}
|
||||
return values;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether field has its default value
|
||||
*
|
||||
* @param Element field
|
||||
* @param String type
|
||||
* @return boolean
|
||||
*/
|
||||
function checkFieldDefault(field, type) {
|
||||
if (!$defined(defaultValues[field.id])) {
|
||||
return true;
|
||||
}
|
||||
var isDefault = true
|
||||
var currentValue = getFieldValue(field, type);
|
||||
if (type != 'select') {
|
||||
isDefault = currentValue == defaultValues[field.id];
|
||||
} else {
|
||||
// compare arrays, will work for our representation of select values
|
||||
if (currentValue.length != defaultValues[field.id].length) {
|
||||
isDefault = false;
|
||||
}
|
||||
else {
|
||||
for (var i = 0; i < currentValue.length; i++) {
|
||||
if (currentValue[i] != defaultValues[field.id][i]) {
|
||||
isDefault = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return isDefault;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns element's id prefix
|
||||
* @param Element element
|
||||
*/
|
||||
function getIdPrefix(element) {
|
||||
return element.id.replace(/[^-]+$/, '');
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------
|
||||
// Messages
|
||||
//
|
||||
|
||||
// stores hidden message ids
|
||||
var hiddenMessages = [];
|
||||
|
||||
window.addEvent('domready', function() {
|
||||
var hidden = hiddenMessages.length;
|
||||
for (var i = 0; i < hidden; i++) {
|
||||
$(hiddenMessages[i]).style.display = 'none';
|
||||
}
|
||||
if (hidden > 0) {
|
||||
var link = $('show_hidden_messages');
|
||||
link.addEvent('click', function(e) {
|
||||
e.stop();
|
||||
for (var i = 0; i < hidden; i++) {
|
||||
$(hiddenMessages[i]).style.display = '';
|
||||
}
|
||||
this.dispose();
|
||||
});
|
||||
link.set('html', link.get('html').replace('#MSG_COUNT', hidden));
|
||||
link.style.display = '';
|
||||
}
|
||||
});
|
||||
|
||||
//
|
||||
// END: Messages
|
||||
// ------------------------------------------------------------------
|
||||
|
||||
// ------------------------------------------------------------------
|
||||
// Form validation and field operations
|
||||
//
|
||||
|
||||
// form validator assignments
|
||||
var validate = {};
|
||||
|
||||
// form validator list
|
||||
var validators = {
|
||||
/**
|
||||
* Validates positive number
|
||||
*
|
||||
* @param boolean isKeyUp
|
||||
*/
|
||||
validate_positive_number: function (isKeyUp) {
|
||||
var result = this.value.test('^[0-9]*$') && this.value != '0';
|
||||
return result ? true : PMA_messages['error_nan_p'];
|
||||
},
|
||||
/**
|
||||
* Validates non-negative number
|
||||
*
|
||||
* @param boolean isKeyUp
|
||||
*/
|
||||
validate_non_negative_number: function (isKeyUp) {
|
||||
var result = this.value.test('^[0-9]*$');
|
||||
return result ? true : PMA_messages['error_nan_nneg'];
|
||||
},
|
||||
/**
|
||||
* Validates port number
|
||||
*
|
||||
* @param boolean isKeyUp
|
||||
*/
|
||||
validate_port_number: function(isKeyUp) {
|
||||
var result = this.value.test('^[0-9]*$') && this.value != '0';
|
||||
if (!result || this.value > 65536) {
|
||||
result = PMA_messages['error_incorrect_port'];
|
||||
}
|
||||
return result;
|
||||
},
|
||||
// field validators
|
||||
_field: {
|
||||
/**
|
||||
* hide_db field
|
||||
*
|
||||
* @param boolean isKeyUp
|
||||
*/
|
||||
hide_db: function(isKeyUp) {
|
||||
if (!isKeyUp && this.value != '') {
|
||||
var data = {};
|
||||
data[this.id] = this.value;
|
||||
ajaxValidate(this, 'Servers/1/hide_db', data);
|
||||
}
|
||||
return true;
|
||||
},
|
||||
/**
|
||||
* TrustedProxies field
|
||||
*
|
||||
* @param boolean isKeyUp
|
||||
*/
|
||||
TrustedProxies: function(isKeyUp) {
|
||||
if (!isKeyUp && this.value != '') {
|
||||
var data = {};
|
||||
data[this.id] = this.value;
|
||||
ajaxValidate(this, 'TrustedProxies', data);
|
||||
}
|
||||
return true;
|
||||
},
|
||||
},
|
||||
// fieldset validators
|
||||
_fieldset: {
|
||||
/**
|
||||
* Validates Server fieldset
|
||||
*
|
||||
* @param boolean isKeyUp
|
||||
*/
|
||||
Server: function(isKeyUp) {
|
||||
if (!isKeyUp) {
|
||||
ajaxValidate(this, 'Server', getAllValues());
|
||||
}
|
||||
return true;
|
||||
},
|
||||
/**
|
||||
* Validates Server_login_options fieldset
|
||||
*
|
||||
* @param boolean isKeyUp
|
||||
*/
|
||||
Server_login_options: function(isKeyUp) {
|
||||
return validators._fieldset.Server.bind(this)(isKeyUp);
|
||||
},
|
||||
/**
|
||||
* Validates Server_pmadb fieldset
|
||||
*
|
||||
* @param boolean isKeyUp
|
||||
*/
|
||||
Server_pmadb: function(isKeyUp) {
|
||||
if (isKeyUp) {
|
||||
return true;
|
||||
}
|
||||
|
||||
var prefix = getIdPrefix(this.getElement('input'));
|
||||
var pmadb_active = $(prefix + 'pmadb').value != '';
|
||||
if (pmadb_active) {
|
||||
ajaxValidate(this, 'Server_pmadb', getAllValues());
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Calls server-side validation procedures
|
||||
*
|
||||
* @param Element parent input field in <fieldset> or <fieldset>
|
||||
* @param String id validator id
|
||||
* @param Object values values hash (element_id: value)
|
||||
*/
|
||||
function ajaxValidate(parent, id, values) {
|
||||
// ensure that parent is a fieldset
|
||||
if (parent.tagName != 'FIELDSET') {
|
||||
parent = parent.getParent('fieldset');
|
||||
if (!parent) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
// ensure that we have a Request object
|
||||
if (typeof parent.request == 'undefined') {
|
||||
parent.validate = {
|
||||
request: new Request.JSON({
|
||||
url: 'validate.php',
|
||||
autoCancel: true,
|
||||
onSuccess: function(response) {
|
||||
if (response == null) {
|
||||
return;
|
||||
}
|
||||
var error = {};
|
||||
if ($type(response) != 'object') {
|
||||
error[parent.id] = [response];
|
||||
} else if (typeof response['error'] != 'undefined') {
|
||||
error[parent.id] = [response['error']];
|
||||
} else {
|
||||
$each(response, function(value, key) {
|
||||
error[key] = $type(value) == 'array' ? value : [value];
|
||||
});
|
||||
}
|
||||
displayErrors(error);
|
||||
}}),
|
||||
token: parent.getParent('form').token.value
|
||||
};
|
||||
}
|
||||
|
||||
parent.validate.request.send({
|
||||
data: {
|
||||
token: parent.validate.token,
|
||||
id: id,
|
||||
values: JSON.encode(values)}
|
||||
});
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers validator for given field
|
||||
*
|
||||
* @param String id field id
|
||||
* @param String type validator (key in validators object)
|
||||
* @param boolean onKeyUp whether fire on key up
|
||||
* @param mixed params validation function parameters
|
||||
*/
|
||||
function validateField(id, type, onKeyUp, params) {
|
||||
if (typeof validators[type] == 'undefined') {
|
||||
return;
|
||||
}
|
||||
if (typeof validate[id] == 'undefined') {
|
||||
validate[id] = [];
|
||||
}
|
||||
validate[id].push([type, params, onKeyUp]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns valdiation functions associated with form field
|
||||
*
|
||||
* @param String field_id form field id
|
||||
* @param boolean onKeyUpOnly see validateField
|
||||
* @return Array array of [function, paramseters to be passed to function]
|
||||
*/
|
||||
function getFieldValidators(field_id, onKeyUpOnly) {
|
||||
// look for field bound validator
|
||||
var name = field_id.match(/[^-]+$/)[0];
|
||||
if (typeof validators._field[name] != 'undefined') {
|
||||
return [[validators._field[name], null]];
|
||||
}
|
||||
|
||||
// look for registered validators
|
||||
var functions = [];
|
||||
if (typeof validate[field_id] != 'undefined') {
|
||||
// validate[field_id]: array of [type, params, onKeyUp]
|
||||
for (var i = 0, imax = validate[field_id].length; i < imax; i++) {
|
||||
if (onKeyUpOnly && !validate[field_id][i][2]) {
|
||||
continue;
|
||||
}
|
||||
functions.push([validators[validate[field_id][i][0]], validate[field_id][i][1]]);
|
||||
}
|
||||
}
|
||||
|
||||
return functions;
|
||||
}
|
||||
|
||||
/**
|
||||
* Displays errors for given form fields
|
||||
*
|
||||
* WARNING: created DOM elements must be identical with the ones made by
|
||||
* display_input() in FormDisplay.tpl.php!
|
||||
*
|
||||
* @param Object error list (key: field id, value: error array)
|
||||
*/
|
||||
function displayErrors(errors) {
|
||||
$each(errors, function(errors, field_id) {
|
||||
var field = $(field_id);
|
||||
var isFieldset = field.tagName == 'FIELDSET';
|
||||
var errorCnt = isFieldset
|
||||
? field.getElement('dl.errors')
|
||||
: field.getNext('.inline_errors');
|
||||
|
||||
// remove empty errors (used to clear error list)
|
||||
errors = errors.filter(function(item) {
|
||||
return item != '';
|
||||
});
|
||||
|
||||
if (errors.length) {
|
||||
// if error container doesn't exist, create it
|
||||
if (errorCnt === null) {
|
||||
if (isFieldset) {
|
||||
errorCnt = new Element('dl', {
|
||||
'class': 'errors'
|
||||
});
|
||||
errorCnt.inject(field.getElement('table'), 'before');
|
||||
} else {
|
||||
errorCnt = new Element('dl', {
|
||||
'class': 'inline_errors'
|
||||
});
|
||||
errorCnt.inject(field.getParent('td'), 'bottom');
|
||||
}
|
||||
}
|
||||
|
||||
var html = '';
|
||||
for (var i = 0, imax = errors.length; i < imax; i++) {
|
||||
html += '<dd>' + errors[i] + '</dd>';
|
||||
}
|
||||
errorCnt.set('html', html);
|
||||
} else if (errorCnt !== null) {
|
||||
// remove useless error container
|
||||
errorCnt.dispose();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates fieldset and puts errors in 'errors' object
|
||||
*
|
||||
* @param Element field
|
||||
* @param boolean isKeyUp
|
||||
* @param Object errors
|
||||
*/
|
||||
function validate_fieldset(fieldset, isKeyUp, errors) {
|
||||
if (fieldset && typeof validators._fieldset[fieldset.id] != 'undefined') {
|
||||
var fieldset_errors = validators._fieldset[fieldset.id].bind(fieldset)(isKeyUp);
|
||||
$each(fieldset_errors, function(field_errors, field_id) {
|
||||
if (typeof errors[field_id] == 'undefined') {
|
||||
errors[field_id] = [];
|
||||
}
|
||||
errors[field_id][$type(field_errors) == 'array' ? 'extend' : 'push'](field_errors);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates form field and puts errors in 'errors' object
|
||||
*
|
||||
* @param Element field
|
||||
* @param boolean isKeyUp
|
||||
* @param Object errors
|
||||
*/
|
||||
function validate_field(field, isKeyUp, errors) {
|
||||
errors[field.id] = [];
|
||||
var functions = getFieldValidators(field.id, isKeyUp);
|
||||
for (var i = 0; i < functions.length; i++) {
|
||||
var result = functions[i][0].bind(field)(isKeyUp, functions[i][1]);
|
||||
if (result !== true) {
|
||||
errors[field.id][$type(result) == 'array' ? 'extend' : 'push'](result);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates form field and parent fieldset
|
||||
*
|
||||
* @param Element field
|
||||
* @param boolean isKeyUp
|
||||
*/
|
||||
function validate_field_and_fieldset(field, isKeyUp) {
|
||||
var errors = {};
|
||||
validate_field(field, isKeyUp, errors);
|
||||
validate_fieldset(field.getParent('fieldset'), isKeyUp, errors);
|
||||
displayErrors(errors);
|
||||
}
|
||||
|
||||
/**
|
||||
* Marks field depending on its value (system default or custom)
|
||||
*
|
||||
* @param Element field
|
||||
*/
|
||||
function markField(field) {
|
||||
var type = getFieldType(field);
|
||||
var isDefault = checkFieldDefault(field, type);
|
||||
|
||||
// checkboxes uses parent <span> for marking
|
||||
var fieldMarker = (type == 'checkbox') ? field.getParent() : field;
|
||||
setRestoreDefaultBtn(field, !isDefault);
|
||||
fieldMarker[isDefault ? 'removeClass' : 'addClass']('custom');
|
||||
}
|
||||
|
||||
/**
|
||||
* Enables or disables the "restore default value" button
|
||||
*
|
||||
* @param Element field
|
||||
* @param bool display
|
||||
*/
|
||||
function setRestoreDefaultBtn(field, display) {
|
||||
var td = field.getParent('td');
|
||||
if (!td) return;
|
||||
var el = td.getElement('.restore-default');
|
||||
if (!el) return;
|
||||
el.style.display = (display ? '' : 'none');
|
||||
}
|
||||
|
||||
window.addEvent('domready', function() {
|
||||
var elements = $$('input[id], select[id], textarea[id]');
|
||||
var elements_count = elements.length;
|
||||
|
||||
// register validators and mark custom values
|
||||
for (var i = 0; i < elements_count; i++) {
|
||||
var el = elements[i];
|
||||
markField(el);
|
||||
el.addEvent('change', function(e) {
|
||||
validate_field_and_fieldset(this, false);
|
||||
markField(this);
|
||||
});
|
||||
// text fields can be validated after each change
|
||||
if (el.tagName == 'INPUT' && el.type == 'text') {
|
||||
el.addEvent('keyup', function(e) {
|
||||
validate_field_and_fieldset(this, true);
|
||||
markField(el);
|
||||
});
|
||||
}
|
||||
// disable textarea spellcheck
|
||||
if (el.tagName == 'TEXTAREA') {
|
||||
el.setProperty('spellcheck', false)
|
||||
}
|
||||
}
|
||||
|
||||
// check whether we've refreshed a page and browser remembered modified
|
||||
// form values
|
||||
var check_page_refresh = $('check_page_refresh');
|
||||
if (!check_page_refresh || check_page_refresh.value == '1') {
|
||||
// run all field validators
|
||||
var errors = {};
|
||||
for (var i = 0; i < elements_count; i++) {
|
||||
validate_field(elements[i], false, errors);
|
||||
}
|
||||
// run all fieldset validators
|
||||
$$('fieldset').each(function(el){
|
||||
validate_fieldset(el, false, errors);
|
||||
});
|
||||
|
||||
displayErrors(errors);
|
||||
} else if (check_page_refresh) {
|
||||
check_page_refresh.value = '1';
|
||||
}
|
||||
});
|
||||
|
||||
//
|
||||
// END: Form validation and field operations
|
||||
// ------------------------------------------------------------------
|
||||
|
||||
// ------------------------------------------------------------------
|
||||
// Tabbed forms
|
||||
//
|
||||
|
||||
/**
|
||||
* Sets active tab
|
||||
*
|
||||
* @param Element tab_link
|
||||
*/
|
||||
function setTab(tab_link) {
|
||||
var tabs_menu = tab_link.getParent('.tabs');
|
||||
|
||||
var links = tabs_menu.getElements('a');
|
||||
var contents;
|
||||
for (var i = 0, imax = links.length; i < imax; i++) {
|
||||
contents = $(links[i].getProperty('href').substr(1));
|
||||
if (links[i] == tab_link) {
|
||||
links[i].addClass('active');
|
||||
contents.style.display = 'block';
|
||||
} else {
|
||||
links[i].removeClass('active');
|
||||
contents.style.display = 'none';
|
||||
}
|
||||
}
|
||||
location.hash = 'tab_' + tab_link.getProperty('href').substr(1);
|
||||
}
|
||||
|
||||
window.addEvent('domready', function() {
|
||||
var tabs = $$('.tabs');
|
||||
var url_tab = location.hash.match(/^#tab_.+/)
|
||||
? $$('a[href$="' + location.hash.substr(5) + '"]') : null;
|
||||
if (url_tab) {
|
||||
url_tab = url_tab[0];
|
||||
}
|
||||
// add tabs events and activate one tab (the first one or indicated by location hash)
|
||||
for (var i = 0, imax = tabs.length; i < imax; i++) {
|
||||
var links = tabs[i].getElements('a');
|
||||
var selected_tab = links[0];
|
||||
for (var j = 0, jmax = links.length; j < jmax; j++) {
|
||||
links[j].addEvent('click', function(e) {
|
||||
e.stop();
|
||||
setTab(this);
|
||||
});
|
||||
if (links[j] == url_tab) {
|
||||
selected_tab = links[j];
|
||||
}
|
||||
}
|
||||
setTab(selected_tab);
|
||||
}
|
||||
// tab links handling, check each 200ms
|
||||
// (works with history in FF, further browser support here would be an overkill)
|
||||
var prev_hash = location.hash;
|
||||
(function() {
|
||||
if (location.hash != prev_hash) {
|
||||
prev_hash = location.hash;
|
||||
var url_tab = location.hash.match(/^#tab_.+/)
|
||||
? $$('a[href$="' + location.hash.substr(5) + '"]') : null;
|
||||
if (url_tab) {
|
||||
setTab(url_tab[0]);
|
||||
}
|
||||
}
|
||||
}).periodical(200);
|
||||
});
|
||||
|
||||
//
|
||||
// END: Tabbed forms
|
||||
// ------------------------------------------------------------------
|
||||
|
||||
// ------------------------------------------------------------------
|
||||
// Form reset buttons
|
||||
//
|
||||
|
||||
window.addEvent('domready', function() {
|
||||
var buttons = $$('input[type=button]');
|
||||
for (var i = 0, imax = buttons.length; i < imax; i++) {
|
||||
buttons[i].addEvent('click', function(e) {
|
||||
var fields = this.getParent('fieldset').getElements('input, select, textarea');
|
||||
for (var i = 0, imax = fields.length; i < imax; i++) {
|
||||
setFieldValue(fields[i], getFieldType(fields[i]));
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
//
|
||||
// END: Form reset buttons
|
||||
// ------------------------------------------------------------------
|
||||
|
||||
// ------------------------------------------------------------------
|
||||
// "Restore default" and "set value" buttons
|
||||
//
|
||||
|
||||
/**
|
||||
* Restores field's default value
|
||||
*
|
||||
* @param String field_id
|
||||
*/
|
||||
function restoreField(field_id) {
|
||||
var field = $(field_id);
|
||||
if (!field || !$defined(defaultValues[field_id])) {
|
||||
return;
|
||||
}
|
||||
setFieldValue(field, getFieldType(field), defaultValues[field_id]);
|
||||
}
|
||||
|
||||
window.addEvent('domready', function() {
|
||||
var buttons = $$('.restore-default, .set-value');
|
||||
var fixIE = Browser.Engine.name == 'trident' && Browser.Engine.version == 4;
|
||||
for (var i = 0, imax = buttons.length; i < imax; i++) {
|
||||
buttons[i].set('opacity', 0.25);
|
||||
if (!buttons[i].hasClass('restore-default')) {
|
||||
// restore-default is handled by markField
|
||||
buttons[i].style.display = '';
|
||||
}
|
||||
buttons[i].addEvents({
|
||||
mouseenter: function(e) {this.set('opacity', 1);},
|
||||
mouseleave: function(e) {this.set('opacity', 0.25);},
|
||||
click: function(e) {
|
||||
e.stop();
|
||||
var href = this.getProperty('href').substr(1);
|
||||
var field_id;
|
||||
if (this.hasClass('restore-default')) {
|
||||
field_id = href;
|
||||
restoreField(field_id);
|
||||
} else {
|
||||
field_id = href.match(/^[^=]+/)[0];
|
||||
var value = href.match(/=(.+)$/)[1];
|
||||
setFieldValue($(field_id), 'text', value);
|
||||
}
|
||||
$(field_id).fireEvent('change');
|
||||
}
|
||||
});
|
||||
// fix IE showing <img> alt text instead of link title
|
||||
if (fixIE) {
|
||||
buttons[i].getChildren('img')[0].alt = buttons[i].title;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
//
|
||||
// END: "Restore default" and "set value" buttons
|
||||
// ------------------------------------------------------------------
|
379
setup/styles.css
Normal file
379
setup/styles.css
Normal file
@@ -0,0 +1,379 @@
|
||||
/* global styles */
|
||||
|
||||
body {
|
||||
padding-bottom: 1em;
|
||||
}
|
||||
|
||||
img {
|
||||
border: 0;
|
||||
}
|
||||
|
||||
a {
|
||||
color: #004C96;
|
||||
}
|
||||
|
||||
a:hover, a:active {
|
||||
color: #000;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: 1.5em;
|
||||
font-family: Verdana, Arial, Helvetica, sans-serif;
|
||||
}
|
||||
|
||||
/* language selection box */
|
||||
|
||||
#select_lang {
|
||||
position: absolute;
|
||||
right: 1em;
|
||||
top: 1em;
|
||||
}
|
||||
|
||||
/* menu */
|
||||
|
||||
#menu {
|
||||
float: left;
|
||||
width: 200px;
|
||||
}
|
||||
|
||||
#menu ul {
|
||||
margin: 1em 1em 1em 0.5em;
|
||||
padding: 0 0.5em;
|
||||
list-style: none;
|
||||
}
|
||||
|
||||
#menu li a {
|
||||
padding: 3px;
|
||||
font-weight: bold;
|
||||
display: block;
|
||||
color: #669;
|
||||
text-decoration: none;
|
||||
zoom: 1; /* IE fix */
|
||||
}
|
||||
|
||||
#menu li a:hover, #menu li a:active {
|
||||
color: #C00;
|
||||
}
|
||||
|
||||
/* page contents and footer layout */
|
||||
|
||||
#page {
|
||||
margin-left: 200px;
|
||||
}
|
||||
|
||||
#footer {
|
||||
margin-top: 1em;
|
||||
}
|
||||
|
||||
#footer a {
|
||||
margin-right: 0.5em;
|
||||
text-decoration: none;
|
||||
font-size: small;
|
||||
}
|
||||
|
||||
/* phpMyAdmin logo colors */
|
||||
|
||||
.blue {
|
||||
color: #7584B3;
|
||||
}
|
||||
|
||||
.orange {
|
||||
color: #FFAD17;
|
||||
}
|
||||
|
||||
.red {
|
||||
color: #C00;
|
||||
}
|
||||
|
||||
/* main page messages */
|
||||
|
||||
div.notice, div.warning, div.error {
|
||||
margin: 0.5em 0;
|
||||
padding: 10px 10px 10px 36px;
|
||||
border: 1px solid #000;
|
||||
background: #FFD url(../themes/original/img/b_tipp.png) no-repeat 10px 0.8em;
|
||||
}
|
||||
|
||||
div.notice h4, div.warning h4, div.error h4 {
|
||||
font-weight: bold;
|
||||
font-size: large;
|
||||
margin: 0 0 0.2em 0;
|
||||
border-bottom: 1px solid #000;
|
||||
}
|
||||
|
||||
div.notice {
|
||||
border-color: #FFD700;
|
||||
background-color: #FFD;
|
||||
background-image: url(../themes/original/img/s_notice.png);
|
||||
}
|
||||
|
||||
div.notice h4 {
|
||||
border-color: #FFD700;
|
||||
}
|
||||
|
||||
div.warning {
|
||||
border-color: #C00;
|
||||
background-color: #FFC;
|
||||
background-image: url(../themes/original/img/s_warn.png);
|
||||
}
|
||||
|
||||
div.warning h4 {
|
||||
color: #C00;
|
||||
border-color: #C00;
|
||||
}
|
||||
|
||||
div.error {
|
||||
border-color: #D00;
|
||||
background-color: #FFC;
|
||||
background-image: url(../themes/original/img/s_error.png);
|
||||
}
|
||||
|
||||
div.error h4 {
|
||||
color: #D00;
|
||||
border-color: #D00;
|
||||
}
|
||||
|
||||
/* form tabs */
|
||||
|
||||
ul.tabs {
|
||||
margin: 0;
|
||||
padding: 0 0 7px 0;
|
||||
list-style: none;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
ul.tabs li {
|
||||
float: left;
|
||||
}
|
||||
|
||||
ul.tabs li a {
|
||||
display: block;
|
||||
margin: 2px 2px 0;
|
||||
padding: 2px 8px;
|
||||
background: #DEE1FF;
|
||||
white-space: nowrap;
|
||||
text-decoration: none;
|
||||
border: 1px #9AA4FF solid;
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
ul.tabs li a:hover, ul.tabs li a:active, ul.tabs li a.active {
|
||||
margin: 0;
|
||||
padding: 2px 10px 4px;
|
||||
background: #F7FBFF;
|
||||
}
|
||||
|
||||
ul.tabs li a:hover, ul.tabs li a:active {
|
||||
color: #C00;
|
||||
}
|
||||
|
||||
.tabs_contents {
|
||||
border-top: 2px #66B solid;
|
||||
}
|
||||
|
||||
.tabs_contents fieldset {
|
||||
margin-top: 0;
|
||||
border-top: none;
|
||||
}
|
||||
|
||||
.tabs_contents legend {
|
||||
display: none;
|
||||
}
|
||||
|
||||
/* "restore default value" and "set value: foo" buttons */
|
||||
|
||||
.restore-default img, .set-value img {
|
||||
margin-bottom: -3px;
|
||||
}
|
||||
|
||||
/* forms */
|
||||
|
||||
fieldset {
|
||||
padding: 0;
|
||||
margin-top: 1em;
|
||||
border: 2px #DEE1FF solid;
|
||||
background: #DEE1FF;
|
||||
}
|
||||
|
||||
.form {
|
||||
border: 2px #DEE1FF solid;
|
||||
}
|
||||
|
||||
fieldset legend {
|
||||
margin-left: 1em;
|
||||
padding: 2px 8px;
|
||||
font-weight: bold;
|
||||
background: #F7FBFF;
|
||||
border: 1px #9AA4FF solid;
|
||||
}
|
||||
|
||||
fieldset p {
|
||||
margin: 0;
|
||||
padding: 0.5em;
|
||||
background: #DEE1FF;
|
||||
}
|
||||
|
||||
fieldset .errors { /* form error list */
|
||||
margin: 0 -2px 1em -2px;
|
||||
padding: 0.5em 1.5em;
|
||||
background: #FBEAD9;
|
||||
border: 1px #C83838 solid;
|
||||
border-width: 1px 0;
|
||||
list-style: none;
|
||||
font-family: sans-serif;
|
||||
font-size: small;
|
||||
}
|
||||
|
||||
fieldset .inline_errors { /* field error list */
|
||||
margin: 0.3em 0.3em 0.3em 0;
|
||||
padding: 0;
|
||||
list-style: none;
|
||||
color: #9A0000;
|
||||
}
|
||||
|
||||
fieldset table {
|
||||
background: #FFF;
|
||||
}
|
||||
|
||||
fieldset th {
|
||||
width: 40%;
|
||||
min-width: 350px;
|
||||
padding: 0.3em 0.3em 0.3em 0.5em;
|
||||
text-align: left;
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
fieldset th small {
|
||||
display: block;
|
||||
}
|
||||
|
||||
fieldset .doc {
|
||||
margin-left: 1em;
|
||||
}
|
||||
|
||||
fieldset td {
|
||||
padding-top: 0.3em;
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
fieldset th small {
|
||||
font-weight: normal;
|
||||
font-family: sans-serif;
|
||||
font-size: x-small;
|
||||
color: #666;
|
||||
}
|
||||
|
||||
fieldset th, fieldset td {
|
||||
border-top: 1px #555 dotted;
|
||||
}
|
||||
|
||||
fieldset .lastrow, .form .lastrow {
|
||||
background: #F7FBFF;
|
||||
padding: 0.5em;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.form .lastrow {
|
||||
border-top: 1px #555 dotted;
|
||||
}
|
||||
|
||||
fieldset .lastrow input, .form .lastrow input {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
/* simple form, without header and legend */
|
||||
|
||||
fieldset.simple {
|
||||
border-top-color: #DEE1FF;
|
||||
}
|
||||
|
||||
fieldset.simple legend {
|
||||
display: none;
|
||||
}
|
||||
|
||||
fieldset.simple th, fieldset.simple td {
|
||||
border-top: none;
|
||||
border-bottom: 1px #555 dotted;
|
||||
}
|
||||
|
||||
fieldset.simple .lastrow {
|
||||
border: 0;
|
||||
}
|
||||
|
||||
/* form elements */
|
||||
|
||||
span.checkbox {
|
||||
padding: 2px;
|
||||
}
|
||||
|
||||
.custom { /* customized field */
|
||||
background: #FFC;
|
||||
}
|
||||
|
||||
span.checkbox.custom {
|
||||
padding: 1px;
|
||||
border: 1px #EDEC90 solid;
|
||||
background: #FFC;
|
||||
}
|
||||
|
||||
input[type="text"], select, textarea {
|
||||
border: 1px #A7A6AA solid;
|
||||
}
|
||||
|
||||
input[type="text"]:focus, select:focus, textarea:focus {
|
||||
border: 1px #6676FF solid;
|
||||
background: #F7FBFF;
|
||||
}
|
||||
|
||||
.green { /* default form button */
|
||||
color: #080;
|
||||
}
|
||||
|
||||
table.datatable {
|
||||
margin: 0.5em 0 1em;
|
||||
}
|
||||
|
||||
table.datatable th {
|
||||
padding: 0 1em 0 0.5em;
|
||||
border-bottom: 2px #66F solid;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
table.datatable td {
|
||||
padding: 1px 0.5em;
|
||||
border-bottom: 1px #DEE1FF solid;
|
||||
}
|
||||
|
||||
/* textarea with config file's contents */
|
||||
|
||||
#textconfig {
|
||||
width: 100%;
|
||||
border: 0;
|
||||
}
|
||||
|
||||
/* error list */
|
||||
|
||||
dd {
|
||||
margin-left: 0.5em;
|
||||
}
|
||||
|
||||
dd:before {
|
||||
content: "\25B8 ";
|
||||
}
|
||||
|
||||
/* links on failed validation page, when saving a form */
|
||||
|
||||
a.btn {
|
||||
padding: 1px 5px;
|
||||
text-decoration: none;
|
||||
background: #E2E8FF;
|
||||
border: 1px #A6C8FF solid;
|
||||
border-top-color: #AFD0FF;
|
||||
border-left-color: #AFD0FF;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
a.btn:hover, a.btn:active {
|
||||
background: #E6F5FF;
|
||||
color: #004C96;
|
||||
}
|
33
setup/validate.php
Normal file
33
setup/validate.php
Normal file
@@ -0,0 +1,33 @@
|
||||
<?php
|
||||
/**
|
||||
* Validation callback.
|
||||
*
|
||||
* @package phpMyAdmin-setup
|
||||
* @author Piotr Przybylski <piotrprz@gmail.com>
|
||||
* @copyright Copyright (c) 2008, Piotr Przybylski <piotrprz@gmail.com>
|
||||
* @license http://www.gnu.org/licenses/gpl.html GNU GPL 2.0
|
||||
* @version $Id$
|
||||
*/
|
||||
|
||||
/**
|
||||
* Core libraries.
|
||||
*/
|
||||
require './lib/common.inc.php';
|
||||
|
||||
$validators = array();
|
||||
require './setup/lib/validate.lib.php';
|
||||
|
||||
header('Content-type: application/json');
|
||||
|
||||
$vids = explode(',', filter_input(INPUT_POST, 'id'));
|
||||
$values = json_decode(filter_input(INPUT_POST, 'values'));
|
||||
if (!($values instanceof stdClass)) {
|
||||
die('Wrong data');
|
||||
}
|
||||
$values = (array)$values;
|
||||
$result = validate($vids, $values, true);
|
||||
if ($result === false) {
|
||||
$result = 'Wrong data or no validation for ' . $vids;
|
||||
}
|
||||
echo $result !== true ? json_encode($result) : '';
|
||||
?>
|
Reference in New Issue
Block a user