Adminer class

git-svn-id: https://adminer.svn.sourceforge.net/svnroot/adminer/trunk@913 7c3ca157-0c34-0410-bff1-cbf682f78f5c
This commit is contained in:
jakubvrana 2009-07-27 11:25:37 +00:00
parent 90a6bd8d4b
commit c64c4fd14d
11 changed files with 492 additions and 485 deletions

View file

@ -3,7 +3,7 @@ $where = (isset($_GET["select"]) ? (count($_POST["check"]) == 1 ? where_check($_
$update = ($where && !$_POST["clone"]);
$fields = fields($_GET["edit"]);
foreach ($fields as $name => $field) {
if ((isset($_GET["default"]) ? $field["auto_increment"] || ereg('text|blob', $field["type"]) : !isset($field["privileges"][$update ? "update" : "insert"])) || !strlen(adminer_field_name($field))) {
if ((isset($_GET["default"]) ? $field["auto_increment"] || ereg('text|blob', $field["type"]) : !isset($field["privileges"][$update ? "update" : "insert"])) || !strlen($adminer->fieldName($field))) {
unset($fields[$name]);
}
}
@ -36,7 +36,7 @@ if ($_POST && !$error && !isset($_GET["select"])) {
}
}
$table_name = adminer_table_name(table_status($_GET["edit"]));
$table_name = $adminer->tableName(table_status($_GET["edit"]));
page_header(
(isset($_GET["default"]) ? lang('Default values') : ($_GET["where"] || (isset($_GET["select"]) && !$_POST["clone"]) ? lang('Edit') : lang('Insert'))),
$error,
@ -69,7 +69,7 @@ if ($fields) {
unset($create);
echo "<table cellspacing='0'>\n";
foreach ($fields as $name => $field) {
echo "<tr><th>" . adminer_field_name($field);
echo "<tr><th>" . $adminer->fieldName($field);
$value = (isset($row)
? (strlen($row[$name]) && ($field["type"] == "enum" || $field["type"] == "set") ? intval($row[$name]) : $row[$name])
: ($_POST["clone"] && $field["auto_increment"] ? "" : (isset($_GET["select"]) ? false : $field["default"]))

View file

@ -1,32 +1,33 @@
<?php
/** Name in title and navigation
* @return string
*/
function adminer_name() {
return call_adminer('name', lang('Adminer'));
}
/** Connection parameters
* @return array ($server, $username, $password)
*/
function adminer_credentials() {
return call_adminer('credentials', array($_GET["server"], $_SESSION["usernames"][$_GET["server"]], $_SESSION["passwords"][$_GET["server"]]));
}
/** Identifier of selected database
* @return string
*/
function adminer_database() {
// should be used everywhere instead of $_GET["db"]
return call_adminer('database', $_GET["db"]);
}
/** Print login form
* @param string
* @return bool whether to display default login form
*/
function adminer_login_form($username) {
if (call_adminer('login_form', true, $username)) {
class Adminer {
/** Name in title and navigation
* @return string
*/
function name() {
return lang('Adminer');
}
/** Connection parameters
* @return array ($server, $username, $password)
*/
function credentials() {
return array($_GET["server"], $_SESSION["usernames"][$_GET["server"]], $_SESSION["passwords"][$_GET["server"]]);
}
/** Identifier of selected database
* @return string
*/
function database() {
// should be used everywhere instead of $_GET["db"]
return $_GET["db"];
}
/** Print login form
* @param string
* @return null
*/
function loginForm($username) {
?>
<table cellspacing="0">
<tr><th><?php echo lang('Server'); ?><td><input name="server" value="<?php echo htmlspecialchars($_GET["server"]); ?>">
@ -35,196 +36,194 @@ function adminer_login_form($username) {
</table>
<?php
}
}
/** Authorize the user
* @param string
* @param string
* @return bool
*/
function adminer_login($login, $password) {
return call_adminer('login', true, $login, $password);
}
/** Table caption used in navigation and headings
* @param array result of SHOW TABLE STATUS
* @return string
*/
function adminer_table_name($table_status) {
return call_adminer('table_name', htmlspecialchars($table_status["Name"]), $table_status);
}
/** Field caption used in select and edit
* @param array single field returned from fields()
* @return string
*/
function adminer_field_name($field) {
return call_adminer('field_name', '<span title="' . htmlspecialchars($field["full_type"]) . '">' . htmlspecialchars($field["field"]) . '</span>', $field);
}
/** Links after select heading
* @param array result of SHOW TABLE STATUS
* @return string
*/
function adminer_select_links($table_status) {
global $SELF;
return call_adminer('select_links', '<a href="' . htmlspecialchars($SELF) . 'table=' . urlencode($_GET['select']) . '">' . lang('Table structure') . '</a>', $table_status);
}
/** Find backward keys for table
* @param string
* @return array $return[$target_table][$key_name][$target_column] = $source_column;
*/
function adminer_backward_keys($table) {
return call_adminer('backward_keys', array(), $table);
}
/** Query printed in select before execution
* @param string query to be executed
* @return string
*/
function adminer_select_query($query) {
global $SELF;
// it would be nice if $query can be passed by reference and printed value would be returned but call_user() doesn't allow reference parameters
return call_adminer('select_query', "<p><code class='jush-sql'>" . htmlspecialchars($query) . "</code> <a href='" . htmlspecialchars($SELF) . "sql=" . urlencode($query) . "'>" . lang('Edit') . "</a>\n", $query);
}
/** Description of a row in a table
* @param string
* @return string SQL expression, empty string for no description
*/
function adminer_row_description($table) {
return call_adminer('row_description', "", $table);
}
/** Get descriptions of selected data
* @param array all data to print
* @param array
* @return array
*/
function adminer_row_descriptions($rows, $foreign_keys) {
return call_adminer('row_descriptions', $rows, $rows, $foreign_keys);
}
/** Value printed in select table
* @param string escaped value to print
* @param string link to foreign key
* @param array single field returned from fields()
* @return string
*/
function adminer_select_val($val, $link, $field) {
$return = ($field["type"] == "char" ? "<code>$val</code>" : $val);
if (ereg('blob|binary', $field["type"]) && !is_utf8($val)) {
$return = lang('%d byte(s)', strlen($val));
/** Authorize the user
* @param string
* @param string
* @return bool
*/
function login($login, $password) {
return true;
}
return call_adminer('select_val', ($link ? "<a href=\"$link\">$return</a>" : $return), $val, $link);
}
/** Print extra text in the end of a select form
* @param array fields holding e-mails
* @return bool whether to print default extra
*/
function adminer_select_extra_display($email_fields) {
call_adminer('select_extra_display', false, $email_fields);
}
/** Process extras in select form
* @param array AND conditions
* @return bool true if processed, false to process other parts of form
*/
function adminer_select_extra_process($where) {
return call_adminer('select_extra_process', false, $where);
}
/** Query printed after execution in the message
* @param string executed query
* @return string
*/
function adminer_message_query($query) {
global $SELF;
$id = "sql-" . count($_SESSION["messages"]);
$_SESSION["history"][$_GET["server"]][$_GET["db"]][] = $query;
return call_adminer('message_query', " <a href='#$id' onclick=\"return !toggle('$id');\">" . lang('SQL command') . "</a><div id='$id' class='hidden'><pre class='jush-sql'>" . htmlspecialchars($query) . '</pre><a href="' . htmlspecialchars($SELF . 'sql=&history=' . (count($_SESSION["history"][$_GET["server"]][$_GET["db"]]) - 1)) . '">' . lang('Edit') . '</a></div>', $query);
}
/** Functions displayed in edit form
* @param array single field from fields()
* @return array
*/
function adminer_edit_functions($field) {
$return = array("");
if (!isset($_GET["default"])) {
if (ereg('char|date|time', $field["type"])) {
$return = (ereg('char', $field["type"]) ? array("", "md5", "sha1", "password", "uuid") : array("", "now")); //! JavaScript for disabling maxlength
/** Table caption used in navigation and headings
* @param array result of SHOW TABLE STATUS
* @return string
*/
function tableName($tableStatus) {
return htmlspecialchars($tableStatus["Name"]);
}
/** Field caption used in select and edit
* @param array single field returned from fields()
* @return string
*/
function fieldName($field) {
return '<span title="' . htmlspecialchars($field["full_type"]) . '">' . htmlspecialchars($field["field"]) . '</span>';
}
/** Links after select heading
* @param array result of SHOW TABLE STATUS
* @return string
*/
function selectLinks($tableStatus) {
global $SELF;
return '<a href="' . htmlspecialchars($SELF) . 'table=' . urlencode($_GET['select']) . '">' . lang('Table structure') . '</a>';
}
/** Find backward keys for table
* @param string
* @return array $return[$target_table][$key_name][$target_column] = $source_column;
*/
function backwardKeys($table) {
return array();
}
/** Query printed in select before execution
* @param string query to be executed
* @return string
*/
function selectQuery($query) {
global $SELF;
// it would be nice if $query can be passed by reference and printed value would be returned but call_user() doesn't allow reference parameters
return "<p><code class='jush-sql'>" . htmlspecialchars($query) . "</code> <a href='" . htmlspecialchars($SELF) . "sql=" . urlencode($query) . "'>" . lang('Edit') . "</a>\n";
}
/** Description of a row in a table
* @param string
* @return string SQL expression, empty string for no description
*/
function rowDescription($table) {
return "";
}
/** Get descriptions of selected data
* @param array all data to print
* @param array
* @return array
*/
function rowDescriptions($rows, $foreignKeys) {
return $rows;
}
/** Value printed in select table
* @param string escaped value to print
* @param string link to foreign key
* @param array single field returned from fields()
* @return string
*/
function selectVal($val, $link, $field) {
$return = ($field["type"] == "char" ? "<code>$val</code>" : $val);
if (ereg('blob|binary', $field["type"]) && !is_utf8($val)) {
$return = lang('%d byte(s)', strlen($val));
}
if (!isset($_GET["call"]) && (isset($_GET["select"]) || where($_GET))) {
// relative functions
if (ereg('int|float|double|decimal', $field["type"])) {
$return = array("", "+", "-");
return ($link ? "<a href=\"$link\">$return</a>" : $return);
}
/** Print extra text in the end of a select form
* @param array fields holding e-mails
* @return null
*/
function selectExtraDisplay($emailFields) {
}
/** Process extras in select form
* @param array AND conditions
* @return bool true if processed, false to process other parts of form
*/
function selectExtraProcess($where) {
return false;
}
/** Query printed after execution in the message
* @param string executed query
* @return string
*/
function messageQuery($query) {
global $SELF;
$id = "sql-" . count($_SESSION["messages"]);
$_SESSION["history"][$_GET["server"]][$_GET["db"]][] = $query;
return " <a href='#$id' onclick=\"return !toggle('$id');\">" . lang('SQL command') . "</a><div id='$id' class='hidden'><pre class='jush-sql'>" . htmlspecialchars($query) . '</pre><a href="' . htmlspecialchars($SELF . 'sql=&history=' . (count($_SESSION["history"][$_GET["server"]][$_GET["db"]]) - 1)) . '">' . lang('Edit') . '</a></div>';
}
/** Functions displayed in edit form
* @param array single field from fields()
* @return array
*/
function editFunctions($field) {
$return = array("");
if (!isset($_GET["default"])) {
if (ereg('char|date|time', $field["type"])) {
$return = (ereg('char', $field["type"]) ? array("", "md5", "sha1", "password", "uuid") : array("", "now")); //! JavaScript for disabling maxlength
}
if (ereg('date', $field["type"])) {
$return[] = "+ interval";
$return[] = "- interval";
}
if (ereg('time', $field["type"])) {
$return[] = "addtime";
$return[] = "subtime";
if (!isset($_GET["call"]) && (isset($_GET["select"]) || where($_GET))) {
// relative functions
if (ereg('int|float|double|decimal', $field["type"])) {
$return = array("", "+", "-");
}
if (ereg('date', $field["type"])) {
$return[] = "+ interval";
$return[] = "- interval";
}
if (ereg('time', $field["type"])) {
$return[] = "addtime";
$return[] = "subtime";
}
}
}
if ($field["null"] || isset($_GET["default"])) {
array_unshift($return, "NULL");
}
return (isset($_GET["select"]) ? array("orig" => lang('original')) : array()) + $return;
}
if ($field["null"] || isset($_GET["default"])) {
array_unshift($return, "NULL");
/** Get options to display edit field
* @param string table name
* @param array single field from fields()
* @return array options for <select> or empty to display <input>
*/
function editInput($table, $field) {
return false;
}
return call_adminer('edit_functions', (isset($_GET["select"]) ? array("orig" => lang('original')) : array()) + $return, $field);
}
/** Get options to display edit field
* @param string table name
* @param array single field from fields()
* @return array options for <select> or empty to display <input>
*/
function adminer_edit_input($table, $field) {
return call_adminer('edit_input', false, $table, $field);
}
/** Process sent input
* @param string field name
* @param array single field from fields()
* @return string expression to use in a query
*/
function adminer_process_input($name, $field) {
global $dbh;
$idf = bracket_escape($name);
$function = $_POST["function"][$idf];
$value = $_POST["fields"][$idf];
$return = $dbh->quote($value);
if (ereg('^(now|uuid)$', $function)) {
$return = "$function()";
} elseif (ereg('^[+-]$', $function)) {
$return = idf_escape($name) . " $function $return";
} elseif (ereg('^[+-] interval$', $function)) {
$return = idf_escape($name) . " $function " . (preg_match("~^([0-9]+|'[0-9.: -]') [A-Z_]+$~i", $value) ? $value : $return);
} elseif (ereg('^(addtime|subtime)$', $function)) {
$return = "$function(" . idf_escape($name) . ", $return)";
} elseif (ereg('^(md5|sha1|password)$', $function)) {
$return = "$function($return)";
} elseif (ereg('date|time', $field["type"]) && $value == "CURRENT_TIMESTAMP") {
$return = $value;
/** Process sent input
* @param string field name
* @param array single field from fields()
* @return string expression to use in a query
*/
function processInput($name, $field) {
global $dbh;
$idf = bracket_escape($name);
$function = $_POST["function"][$idf];
$value = $_POST["fields"][$idf];
$return = $dbh->quote($value);
if (ereg('^(now|uuid)$', $function)) {
$return = "$function()";
} elseif (ereg('^[+-]$', $function)) {
$return = idf_escape($name) . " $function $return";
} elseif (ereg('^[+-] interval$', $function)) {
$return = idf_escape($name) . " $function " . (preg_match("~^([0-9]+|'[0-9.: -]') [A-Z_]+$~i", $value) ? $value : $return);
} elseif (ereg('^(addtime|subtime)$', $function)) {
$return = "$function(" . idf_escape($name) . ", $return)";
} elseif (ereg('^(md5|sha1|password)$', $function)) {
$return = "$function($return)";
} elseif (ereg('date|time', $field["type"]) && $value == "CURRENT_TIMESTAMP") {
$return = $value;
}
return $return;
}
return call_adminer('process_input', $return, $name, $field);
}
/** Prints navigation after Adminer title
* @param string can be "auth" if there is no database connection or "db" if there is no database selected
* @return bool true if default navigation should be printed
*/
function adminer_navigation($missing) {
global $SELF, $dbh;
if (call_adminer('navigation', true, $missing) && $missing != "auth") {
ob_flush();
flush();
$databases = get_databases();
?>
/** Prints navigation after Adminer title
* @param string can be "auth" if there is no database connection or "db" if there is no database selected
* @return null
*/
function navigation($missing) {
global $SELF, $dbh;
if ($missing != "auth") {
ob_flush();
flush();
$databases = get_databases();
?>
<form action="" method="post">
<p>
<a href="<?php echo htmlspecialchars($SELF); ?>sql="><?php echo lang('SQL command'); ?></a>
@ -247,19 +246,21 @@ function adminer_navigation($missing) {
</p>
</form>
<?php
if ($missing != "db" && strlen($_GET["db"])) {
$result = $dbh->query("SHOW TABLES");
if (!$result->num_rows) {
echo "<p class='message'>" . lang('No tables.') . "\n";
} else {
echo "<p>\n";
while ($row = $result->fetch_row()) {
echo '<a href="' . htmlspecialchars($SELF) . 'select=' . urlencode($row[0]) . '">' . lang('select') . '</a> ';
echo '<a href="' . htmlspecialchars($SELF) . 'table=' . urlencode($row[0]) . '">' . adminer_table_name(array("Name" => $row[0])) . "</a><br>\n"; //! Adminer::table_name may work with full table status
if ($missing != "db" && strlen($_GET["db"])) {
$result = $dbh->query("SHOW TABLES");
if (!$result->num_rows) {
echo "<p class='message'>" . lang('No tables.') . "\n";
} else {
echo "<p>\n";
while ($row = $result->fetch_row()) {
echo '<a href="' . htmlspecialchars($SELF) . 'select=' . urlencode($row[0]) . '">' . lang('select') . '</a> ';
echo '<a href="' . htmlspecialchars($SELF) . 'table=' . urlencode($row[0]) . '">' . $this->tableName(array("Name" => $row[0])) . "</a><br>\n"; //! Adminer::table_name may work with full table status
}
}
$result->free();
echo '<p><a href="' . htmlspecialchars($SELF) . 'create=">' . lang('Create new table') . "</a>\n";
}
$result->free();
echo '<p><a href="' . htmlspecialchars($SELF) . 'create=">' . lang('Create new table') . "</a>\n";
}
}
}

View file

@ -37,12 +37,12 @@ if (isset($_POST["server"])) {
}
function auth_error($exception = null) {
global $ignore, $dbh;
global $ignore, $dbh, $adminer;
$username = $_SESSION["usernames"][$_GET["server"]];
unset($_SESSION["usernames"][$_GET["server"]]);
page_header(lang('Login'), (isset($username) ? htmlspecialchars($exception ? $exception->getMessage() : (is_string($dbh) ? $dbh : lang('Invalid credentials.'))) : (isset($_POST["server"]) ? lang('Sessions must be enabled.') : ($_POST ? lang('Session expired, please login again.') : ""))), null);
echo "<form action='' method='post'>\n";
adminer_login_form($login);
$adminer->loginForm($login);
echo "<p>\n";
hidden_fields($_POST, $ignore); // expired session
foreach ($_FILES as $key => $val) {
@ -57,7 +57,7 @@ if (!isset($username)) {
$username = $_GET["username"]; // default username can be passed in URL
}
$dbh = (isset($username) ? connect() : '');
if (is_string($dbh) || !adminer_login($username, $_SESSION["passwords"][$_GET["server"]])) {
if (is_string($dbh) || !$adminer->login($username, $_SESSION["passwords"][$_GET["server"]])) {
auth_error();
exit;
}

View file

@ -72,6 +72,7 @@ include "../adminer/include/functions.inc.php";
include "../adminer/include/lang.inc.php";
include "../adminer/lang/$LANG.inc.php";
include "./include/adminer.inc.php";
$adminer = (function_exists('adminer_object') ? adminer_object() : new Adminer);
include "../adminer/include/design.inc.php";
include "../adminer/include/pdo.inc.php";
include "../adminer/include/mysql.inc.php";

View file

@ -1,6 +1,6 @@
<?php
function page_header($title, $error = "", $breadcrumb = array(), $title2 = "") {
global $SELF, $LANG, $VERSION;
global $SELF, $LANG, $VERSION, $adminer;
header("Content-Type: text/html; charset=utf-8");
?>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">
@ -8,7 +8,7 @@ function page_header($title, $error = "", $breadcrumb = array(), $title2 = "") {
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta http-equiv="Content-Script-Type" content="text/javascript">
<meta name="robots" content="noindex">
<title><?php echo $title . (strlen($title2) ? ": " . htmlspecialchars($title2) : "") . (strlen($_GET["server"]) && $_GET["server"] != "localhost" ? htmlspecialchars("- $_GET[server]") : "") . " - " . adminer_name(); ?></title>
<title><?php echo $title . (strlen($title2) ? ": " . htmlspecialchars($title2) : "") . (strlen($_GET["server"]) && $_GET["server"] != "localhost" ? htmlspecialchars("- $_GET[server]") : "") . " - " . $adminer->name(); ?></title>
<link rel="shortcut icon" type="image/x-icon" href="../adminer/favicon.ico">
<link rel="stylesheet" type="text/css" href="../adminer/default.css<?php // Ondrej Valka, http://valka.info ?>">
<?php if (file_exists("adminer.css")) { ?>
@ -56,16 +56,16 @@ function page_header($title, $error = "", $breadcrumb = array(), $title2 = "") {
}
function page_footer($missing = false) {
global $VERSION;
global $VERSION, $adminer;
?>
</div>
<?php switch_lang(); ?>
<div id="menu">
<h1><a href="http://www.adminer.org/" class="h1"><?php echo adminer_name(); ?></a> &nbsp; <?php echo $VERSION; ?> &nbsp;
<h1><a href="http://www.adminer.org/" class="h1"><?php echo $adminer->name(); ?></a> &nbsp; <?php echo $VERSION; ?> &nbsp;
<a href='http://www.adminer.org/#download' id="version"><?php echo (version_compare($VERSION, $_COOKIE["adminer_version"]) < 0 ? htmlspecialchars($_COOKIE["adminer_version"]) : ""); ?></a>
</h1>
<?php adminer_navigation($missing); ?>
<?php $adminer->navigation($missing); ?>
</div>
<?php
}

View file

@ -1,4 +1,10 @@
<?php
function get_dbh() {
// can be used in customization, $dbh is minified
global $dbh;
return $dbh;
}
function idf_escape($idf) {
return "`" . str_replace("`", "``", $idf) . "`";
}
@ -103,10 +109,10 @@ function redirect($location, $message = null) {
}
function query_redirect($query, $location, $message, $redirect = true, $execute = true, $failed = false) {
global $dbh, $error, $SELF;
global $dbh, $error, $SELF, $adminer;
$sql = "";
if ($query) {
$sql = adminer_message_query($query);
$sql = $adminer->messageQuery($query);
}
if ($execute) {
$failed = !$dbh->query($query);
@ -276,7 +282,7 @@ function column_foreign_keys($table) {
}
function input($field, $value, $function) {
global $types;
global $types, $adminer;
$name = htmlspecialchars(bracket_escape($field["field"]));
echo "<td class='function'>";
if ($field["type"] == "enum") {
@ -294,11 +300,11 @@ function input($field, $value, $function) {
echo ' <label><input type="radio" name="fields[' . $name . ']" value="' . (isset($_GET["default"]) ? (strlen($val) ? htmlspecialchars($val) : " ") : $i+1) . '"' . ($checked ? ' checked="checked"' : '') . '>' . htmlspecialchars($val) . '</label>';
}
} else {
$functions = adminer_edit_functions($field);
$functions = $adminer->editFunctions($field);
$first = array_search("", $functions);
$onchange = ($first ? ' onchange="var f = this.form[\'function[' . addcslashes($name, "\r\n'\\") . ']\']; if (' . $first . ' > f.selectedIndex) f.selectedIndex = ' . $first . ';"' : '');
echo (count($functions) > 1 ? '<select name="function[' . $name . ']">' . optionlist($functions, $function) . '</select>' : "&nbsp;") . '<td>';
$options = adminer_edit_input($_GET["edit"], $field); // usage in call is without a table
$options = $adminer->editInput($_GET["edit"], $field); // usage in call is without a table
if (is_array($options)) {
echo '<select name="fields[' . $name . ']"' . $onchange . '>' . optionlist(($options ? $options : array("" => "")), $value, true) . '</select>';
} elseif ($field["type"] == "set") { //! 64 bits
@ -321,7 +327,7 @@ function input($field, $value, $function) {
}
function process_input($name, $field) {
global $dbh;
global $dbh, $adminer;
$idf = bracket_escape($name);
$function = $_POST["function"][$idf];
$value = $_POST["fields"][$idf];
@ -340,7 +346,7 @@ function process_input($name, $field) {
}
return "_binary" . $dbh->quote($file);
} else {
return adminer_process_input($name, $field);
return $adminer->processInput($name, $field);
}
}
@ -363,11 +369,3 @@ function email_header($header) {
// iconv_mime_encode requires PHP 5, imap_8bit requires IMAP extension
return "=?UTF-8?B?" . base64_encode($header) . "?="; //! split long lines
}
function call_adminer($method, $default, $arg1 = null, $arg2 = null, $arg3 = null) {
if (method_exists('Adminer', $method)) { // user defined class
// can use func_get_args() and call_user_func_array()
return Adminer::$method($arg1, $arg2, $arg3);
}
return $default; //! $default is evaluated even if not neccessary
}

View file

@ -141,8 +141,9 @@ if (extension_loaded("mysqli")) {
}
function connect() {
global $adminer;
$dbh = new Min_DB;
$credentials = adminer_credentials();
$credentials = $adminer->credentials();
if ($dbh->connect($credentials[0], $credentials[1], $credentials[2])) {
$dbh->query("SET SQL_QUOTE_SHOW_CREATE=1");
$dbh->query("SET NAMES utf8");

View file

@ -18,7 +18,7 @@ $rights = array(); // privilege => 0
$columns = array(); // selectable columns
unset($text_length);
foreach ($fields as $key => $field) {
$name = adminer_field_name($field);
$name = $adminer->fieldName($field);
if (isset($field["privileges"]["select"]) && strlen($name)) {
$columns[$key] = html_entity_decode(strip_tags($name));
if (ereg('text|blob', $field["type"])) {
@ -109,7 +109,7 @@ if ($_POST && !$error) {
}
exit;
}
if (!adminer_select_extra_process($where)) {
if (!$adminer->selectExtraProcess($where)) {
if (!$_POST["import"]) { // edit
$result = true;
$affected = 0;
@ -169,14 +169,14 @@ if ($_POST && !$error) {
}
}
page_header(lang('Select') . ": " . adminer_table_name($table_status), $error);
page_header(lang('Select') . ": " . $adminer->tableName($table_status), $error);
echo "<p>";
if (isset($rights["insert"])) {
//! pass search values forth and back
echo '<a href="' . htmlspecialchars($SELF) . 'edit=' . urlencode($_GET['select']) . '">' . lang('New item') . '</a> ';
}
echo adminer_select_links($table_status);
echo $adminer->selectLinks($table_status);
if (!$columns) {
echo "<p class='error'>" . lang('Unable to select the table') . ($fields ? "" : ": " . htmlspecialchars($dbh->error)) . ".\n";
@ -253,7 +253,7 @@ if (!$columns) {
echo "</form>\n";
$query = "SELECT " . (intval($limit) && count($group) < count($select) ? "SQL_CALC_FOUND_ROWS " : "") . $from . $group_by . (strlen($limit) ? " LIMIT " . intval($limit) . (intval($_GET["page"]) ? " OFFSET " . ($limit * $_GET["page"]) : "") : "");
echo adminer_select_query($query);
echo $adminer->selectQuery($query);
$result = $dbh->query($query);
if (!$result) {
@ -276,12 +276,12 @@ if (!$columns) {
);
$foreign_keys = column_foreign_keys($_GET["select"]);
$descriptions = adminer_row_descriptions($rows, $foreign_keys);
$descriptions = $adminer->rowDescriptions($rows, $foreign_keys);
$backward_keys = adminer_backward_keys($_GET["select"]);
$backward_keys = $adminer->backwardKeys($_GET["select"]);
$table_names = array_keys($backward_keys);
if ($table_names) {
$table_names = array_combine($table_names, array_map('adminer_table_name', array_map('table_status', $table_names)));
$table_names = array_combine($table_names, array_map(array($adminer, 'tableName'), array_map('table_status', $table_names)));
}
echo "<table cellspacing='0' class='nowrap'>\n";
@ -291,7 +291,7 @@ if (!$columns) {
foreach ($rows[0] as $key => $val) {
$val = $_GET["columns"][key($select)];
$field = $fields[$select ? $val["col"] : $key];
$name = ($field ? adminer_field_name($field) : "*");
$name = ($field ? $adminer->fieldName($field) : "*");
if (strlen($name)) {
$names[$key] = $name;
echo '<th><a href="' . htmlspecialchars(remove_from_uri('(order|desc)[^=]*') . '&order%5B0%5D=' . urlencode($key) . ($_GET["order"] == array($key) && !$_GET["desc"][0] ? '&desc%5B0%5D=1' : '')) . '">' . apply_sql_function($val["fun"], $name) . "</a>";
@ -336,7 +336,7 @@ if (!$columns) {
if (!$link && is_email($val)) {
$link = "mailto:$val";
}
$val = adminer_select_val($val, $link, $fields[$key]);
$val = $adminer->selectVal($val, $link, $fields[$key]);
echo "<td>$val";
}
}
@ -381,7 +381,7 @@ if (!$columns) {
}
echo "<fieldset><legend>" . lang('CSV Import') . "</legend><div><input type='hidden' name='token' value='$token'><input type='file' name='csv_file'> <input type='submit' name='import' value='" . lang('Import') . "'></div></fieldset>\n";
adminer_select_extra_display(array_filter($email_fields, 'strlen'));
$adminer->selectExtraDisplay(array_filter($email_fields, 'strlen'));
echo "</form>\n";
}

View file

@ -1,36 +1,41 @@
<?php
class Adminer {
function adminer_object() {
function name() {
// custom name in title and heading
return 'CDs';
}
function credentials() {
// ODBC user without password on localhost
return array('localhost', 'ODBC', '');
}
function database() {
// will be escaped by Adminer
return 'adminer_test';
}
function login($login, $password) {
// username: admin, password: anything
return ($login == 'admin');
}
function table_name($row) {
// tables without comments would return empty string and will be ignored by Adminer
return htmlspecialchars($row["Comment"]);
}
function field_name($field) {
// fields without comments will be ignored
return ($field ? htmlspecialchars($field["comment"]) : "*");
class AdminerCds extends Adminer {
function name() {
// custom name in title and heading
return 'CDs';
}
function credentials() {
// ODBC user without password on localhost
return array('localhost', 'ODBC', '');
}
function database() {
// will be escaped by Adminer
return 'adminer_test';
}
function login($login, $password) {
// username: 'admin', password: anything
return ($login == 'admin');
}
function tableName($row) {
// tables without comments would return empty string and will be ignored by Adminer
return htmlspecialchars($row["Comment"]);
}
function fieldName($field) {
// fields without comments will be ignored
return ($field ? htmlspecialchars($field["comment"]) : "*");
}
}
return new AdminerCds;
}
include "./index.php";

View file

@ -1,19 +1,20 @@
<?php
function adminer_name() {
return call_adminer('name', lang('Editor'));
}
function adminer_credentials() {
return call_adminer('credentials', array()); // default INI settings
}
function adminer_database() {
$dbs = get_databases();
return call_adminer('database', (count($dbs) == 1 ? $dbs[0] : (count($dbs) == 2 && information_schema($dbs[0]) ? $dbs[1] : 'test')));
}
function adminer_login_form($username) {
if (call_adminer('login_form', true, $username)) {
class Adminer {
function name() {
return lang('Editor');
}
function credentials() {
return array(); // default INI settings
}
function database() {
$dbs = get_databases();
return (count($dbs) == 1 ? $dbs[0] : (count($dbs) == 2 && information_schema($dbs[0]) ? $dbs[1] : 'test'));
}
function loginForm($username) {
?>
<table cellspacing="0">
<tr><th><?php echo lang('Username'); ?><td><input type="hidden" name="server" value="" /><input name="username" value="<?php echo htmlspecialchars($username); ?>">
@ -21,197 +22,195 @@ function adminer_login_form($username) {
</table>
<?php
}
}
function adminer_login($login, $password) {
return call_adminer('login', true, $login, $password);
}
function adminer_table_name($table_status) {
table_comment($table_status);
return call_adminer('table_name', htmlspecialchars(strlen($table_status["Comment"]) ? $table_status["Comment"] : $table_status["Name"]), $table_status);
}
function adminer_field_name($field) {
return call_adminer('field_name', htmlspecialchars(strlen($field["comment"]) ? $field["comment"] : $field["field"]), $field);
}
function adminer_select_links($table_status) {
return call_adminer('select_links', "", $table_status);
}
function adminer_backward_keys($table) {
global $dbh;
$return = array();
$result = $dbh->query("SELECT TABLE_NAME, CONSTRAINT_NAME, COLUMN_NAME, REFERENCED_COLUMN_NAME
function login($login, $password) {
return true;
}
function tableName($tableStatus) {
table_comment($tableStatus);
return htmlspecialchars(strlen($tableStatus["Comment"]) ? $tableStatus["Comment"] : $tableStatus["Name"]);
}
function fieldName($field) {
return htmlspecialchars(strlen($field["comment"]) ? $field["comment"] : $field["field"]);
}
function selectLinks($tableStatus) {
return "";
}
function backwardKeys($table) {
global $dbh;
$return = array();
$result = $dbh->query("SELECT TABLE_NAME, CONSTRAINT_NAME, COLUMN_NAME, REFERENCED_COLUMN_NAME
FROM information_schema.KEY_COLUMN_USAGE
WHERE TABLE_SCHEMA = " . $dbh->quote(adminer_database()) . "
AND REFERENCED_TABLE_SCHEMA = " . $dbh->quote(adminer_database()) . "
WHERE TABLE_SCHEMA = " . $dbh->quote($this->database()) . "
AND REFERENCED_TABLE_SCHEMA = " . $dbh->quote($this->database()) . "
AND REFERENCED_TABLE_NAME = " . $dbh->quote($table) . "
ORDER BY ORDINAL_POSITION"); //! requires MySQL 5
if ($result) {
while ($row = $result->fetch_assoc()) {
$return[$row["TABLE_NAME"]][$row["CONSTRAINT_NAME"]][$row["COLUMN_NAME"]] = $row["REFERENCED_COLUMN_NAME"];
if ($result) {
while ($row = $result->fetch_assoc()) {
$return[$row["TABLE_NAME"]][$row["CONSTRAINT_NAME"]][$row["COLUMN_NAME"]] = $row["REFERENCED_COLUMN_NAME"];
}
$result->free();
}
$result->free();
return $return;
}
return call_adminer('backward_keys', $return, $table);
}
function adminer_select_query($query) {
return call_adminer('select_query', "<!-- " . str_replace("--", "--><!--", $query) . " -->\n", $query);
}
function adminer_row_description($table) {
$return = "";
// first varchar column
foreach (fields($table) as $field) {
if ($field["type"] == "varchar") {
$return = idf_escape($field["field"]);
break;
function selectQuery($query) {
return "<!-- " . str_replace("--", "--><!--", $query) . " -->\n";
}
function rowDescription($table) {
$return = "";
// first varchar column
foreach (fields($table) as $field) {
if ($field["type"] == "varchar") {
$return = idf_escape($field["field"]);
break;
}
}
return $return;
}
function rowDescriptions($rows, $foreignKeys) {
global $dbh;
$return = $rows;
foreach ($rows[0] as $key => $val) {
foreach ((array) $foreignKeys[$key] as $foreignKey) {
if (count($foreignKey["source"]) == 1) {
$id = idf_escape($foreignKey["target"][0]);
$name = $this->rowDescription($foreignKey["table"]);
if (strlen($name)) {
// find all used ids
$ids = array();
foreach ($rows as $row) {
$ids[$row[$key]] = $dbh->quote($row[$key]);
}
// uses constant number of queries to get the descriptions, join would be complex, multiple queries would be slow
$descriptions = array();
$result = $dbh->query("SELECT $id, $name FROM " . idf_escape($foreignKey["table"]) . " WHERE $id IN (" . implode(", ", $ids) . ")");
while ($row = $result->fetch_row()) {
$descriptions[$row[0]] = $row[1];
}
$result->free();
// use the descriptions
foreach ($rows as $n => $row) {
$return[$n][$key] = $descriptions[$row[$key]];
}
break;
}
}
}
}
return $return;
}
function selectVal($val, $link, $field) {
$return = ($val == "<i>NULL</i>" ? "&nbsp;" : $val);
if (ereg('blob|binary', $field["type"]) && !is_utf8($val)) {
$return = lang('%d byte(s)', strlen($val));
if (ereg("^(GIF|\xFF\xD8\xFF|\x89\x50\x4E\x47\x0D\x0A\x1A\x0A)", $val)) { // GIF|JPG|PNG, getimagetype() works with filename
$return = "<img src=\"$link\" alt='$return'>";
}
}
return ($link ? "<a href=\"$link\">$return</a>" : $return);
}
function selectExtraDisplay($emailFields) {
global $confirm;
if ($emailFields) {
echo '<fieldset><legend><a href="#fieldset-email" onclick="return !toggle(\'fieldset-email\');">' . lang('E-mail') . "</a></legend><div id='fieldset-email' class='hidden'>\n";
echo "<p>" . lang('From') . ": <input name='email_from'>\n";
echo lang('Subject') . ": <input name='email_subject'>\n";
echo "<p><textarea name='email_message' rows='15' cols='60'></textarea>\n";
echo "<p>" . (count($emailFields) == 1 ? '<input type="hidden" name="email_field" value="' . htmlspecialchars(key($emailFields)) . '">' : '<select name="email_field">' . optionlist($emailFields) . '</select> ');
echo "<input type='submit' name='email' value='" . lang('Send') . "'$confirm>\n";
echo "</div></fieldset>\n";
}
}
return call_adminer('row_description', $return, $table);
}
function adminer_row_descriptions($rows, $foreign_keys) {
global $dbh;
$return = $rows;
foreach ($rows[0] as $key => $val) {
foreach ((array) $foreign_keys[$key] as $foreign_key) {
function selectExtraProcess($where) {
global $dbh;
if ($_POST["email"]) {
$sent = 0;
if ($_POST["all"] || $_POST["check"]) {
$field = idf_escape($_POST["email_field"]);
$result = $dbh->query("SELECT DISTINCT $field FROM " . idf_escape($_GET["select"])
. " WHERE $field IS NOT NULL AND $field != ''"
. ($where ? " AND " . implode(" AND ", $where) : "")
. ($_POST["all"] ? "" : " AND ((" . implode(") OR (", array_map('where_check', (array) $_POST["check"])) . "))")
);
while ($row = $result->fetch_row()) {
if (is_email($row[0]) && mail($row[0], email_header($_POST["email_subject"]), $_POST["email_message"],
"MIME-Version: 1.0\nContent-Type: text/plain; charset=utf-8\nContent-Transfer-Encoding: 8bit"
. (is_email($_POST["email_from"]) ? "\nFrom: $_POST[email_from]" : "") //! should allow address with a name but simple application of email_header() adds the default server domain
)) {
$sent++;
}
}
$result->free();
}
redirect(remove_from_uri(), lang('%d e-mail(s) have been sent.', $sent));
}
return false;
}
function messageQuery($query) {
return "<!--\n" . str_replace("--", "--><!--", $query) . "\n-->";
}
function editFunctions($field) {
return (isset($_GET["select"]) ? array("orig" => lang('original')) : array()) + array("");
}
function editInput($table, $field) {
global $dbh;
$return = null;
$foreign_keys = column_foreign_keys($table);
foreach ((array) $foreign_keys[$field["field"]] as $foreign_key) {
if (count($foreign_key["source"]) == 1) {
$id = idf_escape($foreign_key["target"][0]);
$name = adminer_row_description($foreign_key["table"]);
if (strlen($name)) {
// find all used ids
$ids = array();
foreach ($rows as $row) {
$ids[$row[$key]] = $dbh->quote($row[$key]);
$name = $this->rowDescription($foreign_key["table"]);
if (strlen($name) && $dbh->result($dbh->query("SELECT COUNT(*) FROM " . idf_escape($foreign_key["table"]))) <= 1000) { // optionlist with more than 1000 options would be too big
if ($field["null"]) {
$return[""] = "";
}
// uses constant number of queries to get the descriptions, join would be complex, multiple queries would be slow
$descriptions = array();
$result = $dbh->query("SELECT $id, $name FROM " . idf_escape($foreign_key["table"]) . " WHERE $id IN (" . implode(", ", $ids) . ")");
$result = $dbh->query("SELECT $id, $name FROM " . idf_escape($foreign_key["table"]) . " ORDER BY 2");
while ($row = $result->fetch_row()) {
$descriptions[$row[0]] = $row[1];
$return[$row[0]] = $row[1];
}
$result->free();
// use the descriptions
foreach ($rows as $n => $row) {
$return[$n][$key] = $descriptions[$row[$key]];
}
break;
}
}
}
return $return;
}
return call_adminer('row_descriptions', $return, $rows, $foreign_keys);
}
function adminer_select_val($val, $link, $field) {
$return = ($val == "<i>NULL</i>" ? "&nbsp;" : $val);
if (ereg('blob|binary', $field["type"]) && !is_utf8($val)) {
$return = lang('%d byte(s)', strlen($val));
if (ereg("^(GIF|\xFF\xD8\xFF|\x89\x50\x4E\x47\x0D\x0A\x1A\x0A)", $val)) { // GIF|JPG|PNG, getimagetype() works with filename
$return = "<img src=\"$link\" alt='$return'>";
/** Process sent input
* @param string field name
* @param array single field from fields()
* @return string expression to use in a query
*/
function processInput($name, $field) {
global $dbh;
$idf = bracket_escape($name);
$value = $_POST["fields"][$idf];
$return = $dbh->quote($value);
if (!ereg('varchar|text', $field["type"]) && !strlen($value)) {
$return = "NULL";
} elseif (ereg('date|time', $field["type"]) && $value == "CURRENT_TIMESTAMP") {
$return = $value;
}
return $return;
}
return call_adminer('select_val', ($link ? "<a href=\"$link\">$return</a>" : $return), $val, $link);
}
function adminer_select_extra_display($email_fields) {
global $confirm;
if (call_adminer('select_extra_display', true, $email_fields) && $email_fields) {
echo '<fieldset><legend><a href="#fieldset-email" onclick="return !toggle(\'fieldset-email\');">' . lang('E-mail') . "</a></legend><div id='fieldset-email' class='hidden'>\n";
echo "<p>" . lang('From') . ": <input name='email_from'>\n";
echo lang('Subject') . ": <input name='email_subject'>\n";
echo "<p><textarea name='email_message' rows='15' cols='60'></textarea>\n";
echo "<p>" . (count($email_fields) == 1 ? '<input type="hidden" name="email_field" value="' . htmlspecialchars(key($email_fields)) . '">' : '<select name="email_field">' . optionlist($email_fields) . '</select> ');
echo "<input type='submit' name='email' value='" . lang('Send') . "'$confirm>\n";
echo "</div></fieldset>\n";
}
}
function adminer_select_extra_process($where) {
global $dbh;
if ($_POST["email"]) {
$sent = 0;
if ($_POST["all"] || $_POST["check"]) {
$field = idf_escape($_POST["email_field"]);
$result = $dbh->query("SELECT DISTINCT $field FROM " . idf_escape($_GET["select"])
. " WHERE $field IS NOT NULL AND $field != ''"
. ($where ? " AND " . implode(" AND ", $where) : "")
. ($_POST["all"] ? "" : " AND ((" . implode(") OR (", array_map('where_check', (array) $_POST["check"])) . "))")
);
while ($row = $result->fetch_row()) {
if (is_email($row[0]) && mail($row[0], email_header($_POST["email_subject"]), $_POST["email_message"],
"MIME-Version: 1.0\nContent-Type: text/plain; charset=utf-8\nContent-Transfer-Encoding: 8bit"
. (is_email($_POST["email_from"]) ? "\nFrom: $_POST[email_from]" : "") //! should allow address with a name but simple application of email_header() adds the default server domain
)) {
$sent++;
}
}
$result->free();
}
redirect(remove_from_uri(), lang('%d e-mail(s) have been sent.', $sent));
}
return call_adminer('select_extra_process', false, $where);
}
function adminer_message_query($query) {
return call_adminer('message_query', "<!--\n" . str_replace("--", "--><!--", $query) . "\n-->", $query);
}
function adminer_edit_functions($field) {
return call_adminer('edit_functions', (isset($_GET["select"]) ? array("orig" => lang('original')) : array()) + array(""), $field);
}
function adminer_edit_input($table, $field) {
global $dbh;
$return = null;
$foreign_keys = column_foreign_keys($table);
foreach ((array) $foreign_keys[$field["field"]] as $foreign_key) {
if (count($foreign_key["source"]) == 1) {
$id = idf_escape($foreign_key["target"][0]);
$name = adminer_row_description($foreign_key["table"]);
if (strlen($name) && $dbh->result($dbh->query("SELECT COUNT(*) FROM " . idf_escape($foreign_key["table"]))) <= 1000) { // optionlist with more than 1000 options would be too big
if ($field["null"]) {
$return[""] = "";
}
$result = $dbh->query("SELECT $id, $name FROM " . idf_escape($foreign_key["table"]) . " ORDER BY 2");
while ($row = $result->fetch_row()) {
$return[$row[0]] = $row[1];
}
$result->free();
break;
}
}
}
return call_adminer('edit_input', $return, $table, $field);
}
/** Process sent input
* @param string field name
* @param array single field from fields()
* @return string expression to use in a query
*/
function adminer_process_input($name, $field) {
global $dbh;
$idf = bracket_escape($name);
$function = $_POST["function"][$idf];
$value = $_POST["fields"][$idf];
$return = $dbh->quote($value);
if (!ereg('varchar|text', $field["type"]) && !strlen($value)) {
$return = "NULL";
} elseif (ereg('date|time', $field["type"]) && $value == "CURRENT_TIMESTAMP") {
$return = $value;
}
return call_adminer('process_input', $return, $name, $field);
}
function adminer_navigation($missing) {
global $SELF;
if (call_adminer('navigation', true, $missing) && $missing != "auth") {
?>
function navigation($missing) {
global $SELF;
if ($missing != "auth") {
?>
<form action="" method="post">
<p>
<input type="hidden" name="token" value="<?php echo $_SESSION["tokens"][$_GET["server"]]; ?>">
@ -219,19 +218,21 @@ function adminer_navigation($missing) {
</p>
</form>
<?php
if ($missing != "db") {
$table_status = table_status();
if (!$table_status) {
echo "<p class='message'>" . lang('No tables.') . "\n";
} else {
echo "<p>\n";
foreach ($table_status as $row) {
$name = adminer_table_name($row);
if (isset($row["Engine"]) && strlen($name)) { // ignore views and tables without name
echo '<a href="' . htmlspecialchars($SELF) . 'select=' . urlencode($row["Name"]) . "\">$name</a><br>\n";
if ($missing != "db") {
$table_status = table_status();
if (!$table_status) {
echo "<p class='message'>" . lang('No tables.') . "\n";
} else {
echo "<p>\n";
foreach ($table_status as $row) {
$name = $this->tableName($row);
if (isset($row["Engine"]) && strlen($name)) { // ignore views and tables without name
echo '<a href="' . htmlspecialchars($SELF) . 'select=' . urlencode($row["Name"]) . "\">$name</a><br>\n";
}
}
}
}
}
}
}

View file

@ -1,3 +1,3 @@
<?php
$_GET["db"] = ""; // used here and there by Adminer
$dbh->select_db(adminer_database());
$dbh->select_db($adminer->database());