Compare commits

...

44 Commits

Author SHA1 Message Date
Jakub Vrana
9ef9b8646e Release 2011-08-08 16:26:10 +02:00
Jakub Vrana
709ef12a88 Improve test 2011-08-08 16:19:23 +02:00
Jakub Vrana
593e071dbf Credits only in commit log 2011-08-08 10:38:41 +02:00
Jakub Vrana
0e2438c98e Comment 2011-08-05 17:53:40 +02:00
Jakub Vrana
52c15bf251 Fix Stop on error
Broken since commit 5576d84980
2011-08-05 17:47:33 +02:00
Jakub Vrana
388c21a0f9 Database name is LIKE pattern 2011-08-05 10:42:11 +02:00
Jakub Vrana
55223eb10c Avoid infinite loop 2011-08-05 09:01:36 +02:00
Jakub Vrana
f0d0bdbf39 Parse 'a\';' on webserver file separation 2011-08-04 23:49:38 +02:00
Jakub Vrana
323f4ab34c MySQL specific characters 2011-08-04 23:18:50 +02:00
Jakub Vrana
ad45a666cc Adminer 3.3.0 compatibility (bug #3383184) 2011-08-03 16:03:42 +02:00
Jakub Vrana
c99c11648d Display schema in title 2011-08-03 10:54:31 +02:00
Jakub Vrana
3efcd4d5b7 Comment 2011-08-03 10:54:29 +02:00
Jakub Vrana
fd65b4c9b9 Comment 2011-08-02 23:30:52 +02:00
Jakub Vrana
8e75d54e44 Save bytes 2011-08-02 17:46:13 +02:00
Jakub Vrana
c91185c435 Fix foreign key schema 2011-08-02 17:36:12 +02:00
Jakub Vrana
bbe46b7c0d Utilize variable 2011-08-02 17:34:21 +02:00
Jan Dolecek
a80c1d1632 Faster foreign keys 2011-08-02 17:33:00 +02:00
Jakub Vrana
2d721016d9 Display error with non-existent row 2011-08-01 21:50:57 +02:00
Jakub Vrana
0ecf84f987 Comment (bug #3380103) 2011-07-29 20:21:13 +02:00
Jakub Vrana
9dda217d55 Sort schemas in PostgreSQL 2011-07-29 17:59:14 +02:00
Jan Dolecek
21e88515c1 Sort databases in PostgreSQL 2011-07-29 17:57:30 +02:00
Jakub Vrana
b01d0cec22 Function found_rows should return null 2011-07-29 17:27:26 +02:00
Jakub Vrana
c82829942c Fast number of rows with big tables in PostgreSQL (thanks to juzna) 2011-07-29 17:08:06 +02:00
Jakub Vrana
2e1d38a920 Rename variable 2011-07-29 16:42:44 +02:00
Jakub Vrana
b1f1b03424 Comment 2011-07-29 16:41:52 +02:00
Jakub Vrana
aeae30ffb7 Don't scroll with AJAX select order and alter move column 2011-07-28 14:25:16 +02:00
Jakub Vrana
5046f71f9a Update design 2011-07-28 13:47:36 +02:00
Jakub Vrana
503034d010 Develop 2011-07-27 10:25:51 +02:00
Jakub Vrana
f4204386c7 Release 2011-07-27 10:16:57 +02:00
Jakub Vrana
f80e15f987 Typo 2011-07-27 09:08:53 +02:00
Jakub Vrana
4b4055432d Reorganize functions 2011-07-27 09:04:43 +02:00
Jakub Vrana
be4f2ef76c More thorough escaping 2011-07-27 08:58:07 +02:00
Jakub Vrana
037c547365 Fix XSS (thanks to Jigal van Hemert) 2011-07-27 08:01:51 +02:00
Jakub Vrana
71efbc545a Remove CodeMirror 2011-07-26 22:20:26 +02:00
Jakub Vrana
1c415dbcf8 WYMeditor 2011-07-26 22:10:45 +02:00
Jakub Vrana
903a0377af Lithuanian translation 2011-07-26 19:42:51 +02:00
Jakub Vrana
628a43156d Hide search for hidden enums (thanks to hever) 2011-07-25 17:20:32 +02:00
Jakub Vrana
6c1598ebaf Save bytes 2011-07-22 16:27:06 +02:00
Jan Dolecek
cde1d43e89 Fix altering of default values in PostgreSQL 2011-07-22 15:34:35 +02:00
Jan Dolecek
06aa0f842b Process list for PostgreSQL 2011-07-22 14:32:16 +02:00
Jakub Vrana
7f05e73689 Missing variable (thanks to juzna) 2011-07-22 13:41:05 +02:00
Jakub Vrana
83d82d6eee Pass $filter to remove_slashes (thanks to juzna) 2011-07-22 13:37:01 +02:00
Jakub Vrana
a3663066b0 Use $adminer->database() instead of DB (thanks to Lubor Bilek) 2011-07-19 17:58:44 +02:00
Jakub Vrana
dc4851dacd Develop 2011-07-19 15:06:16 +02:00
31 changed files with 306 additions and 152 deletions

3
.gitmodules vendored
View File

@@ -13,3 +13,6 @@
[submodule "jquery-timepicker"] [submodule "jquery-timepicker"]
path = externals/jquery-timepicker path = externals/jquery-timepicker
url = git://github.com/trentrichardson/jQuery-Timepicker-Addon.git url = git://github.com/trentrichardson/jQuery-Timepicker-Addon.git
[submodule "wymeditor"]
path = externals/wymeditor
url = git://github.com/wymeditor/wymeditor.git

View File

@@ -47,7 +47,7 @@ if ($_POST && !$error && !$_POST["add"] && !$_POST["drop_col"] && !$_POST["up"]
$fields[] = array($field["orig"], $process_field, $after); $fields[] = array($field["orig"], $process_field, $after);
} }
if (isset($foreign_key)) { if (isset($foreign_key)) {
$foreign[idf_escape($field["field"])] = ($TABLE != "" ? "ADD" : " ") . " FOREIGN KEY (" . idf_escape($field["field"]) . ") REFERENCES " . table($foreign_keys[$field["type"]]) . " (" . idf_escape($type_field["field"]) . ")" . (in_array($field["on_delete"], $on_actions) ? " ON DELETE $field[on_delete]" : ""); $foreign[idf_escape($field["field"])] = ($TABLE != "" ? "ADD" : " ") . " FOREIGN KEY (" . idf_escape($field["field"]) . ") REFERENCES " . table($foreign_keys[$field["type"]]) . " (" . idf_escape($type_field["field"]) . ")" . (ereg("^($on_actions)\$", $field["on_delete"]) ? " ON DELETE $field[on_delete]" : "");
} }
$after = "AFTER " . idf_escape($field["field"]); $after = "AFTER " . idf_escape($field["field"]);
} elseif ($field["orig"] != "") { } elseif ($field["orig"] != "") {

View File

@@ -490,6 +490,9 @@ WHERE OBJECT_NAME(i.object_id) = " . q($table)
return $return; return $return;
} }
function found_rows($table_status, $where) {
}
function foreign_keys($table) { function foreign_keys($table) {
$return = array(); $return = array();
foreach (get_rows("EXEC sp_fkeys @fktable_name = " . q($table)) as $row) { foreach (get_rows("EXEC sp_fkeys @fktable_name = " . q($table)) as $row) {

View File

@@ -335,7 +335,7 @@ if (!defined("DRIVER")) {
} }
/** Get tables list /** Get tables list
* @return array * @return array array($name => $type)
*/ */
function tables_list() { function tables_list() {
global $connection; global $connection;
@@ -356,7 +356,7 @@ if (!defined("DRIVER")) {
/** Get table status /** Get table status
* @param string * @param string
* @return array * @return array array($name => array("Name" => , "Engine" => , "Comment" => , "Oid" => , "Rows" => , "Collation" => , "Auto_increment" => , "Data_length" => , "Index_length" => , "Data_free" => )) or only inner array with $name
*/ */
function table_status($name = "") { function table_status($name = "") {
$return = array(); $return = array();
@@ -444,7 +444,7 @@ if (!defined("DRIVER")) {
$return = array(); $return = array();
$create_table = $connection->result("SHOW CREATE TABLE " . table($table), 1); $create_table = $connection->result("SHOW CREATE TABLE " . table($table), 1);
if ($create_table) { if ($create_table) {
preg_match_all("~CONSTRAINT ($pattern) FOREIGN KEY \\(((?:$pattern,? ?)+)\\) REFERENCES ($pattern)(?:\\.($pattern))? \\(((?:$pattern,? ?)+)\\)(?: ON DELETE (" . implode("|", $on_actions) . "))?(?: ON UPDATE (" . implode("|", $on_actions) . "))?~", $create_table, $matches, PREG_SET_ORDER); preg_match_all("~CONSTRAINT ($pattern) FOREIGN KEY \\(((?:$pattern,? ?)+)\\) REFERENCES ($pattern)(?:\\.($pattern))? \\(((?:$pattern,? ?)+)\\)(?: ON DELETE ($on_actions))?(?: ON UPDATE ($on_actions))?~", $create_table, $matches, PREG_SET_ORDER);
foreach ($matches as $match) { foreach ($matches as $match) {
preg_match_all("~$pattern~", $match[2], $source); preg_match_all("~$pattern~", $match[2], $source);
preg_match_all("~$pattern~", $match[5], $target); preg_match_all("~$pattern~", $match[5], $target);
@@ -822,6 +822,15 @@ if (!defined("DRIVER")) {
return $connection->query("EXPLAIN $query"); return $connection->query("EXPLAIN $query");
} }
/** Get approximate number of rows
* @param array
* @param array
* @return int or null if approximate number can't be retrieved
*/
function found_rows($table_status, $where) {
return ($where || $table_status["Engine"] != "InnoDB" ? null : $table_status["Rows"]);
}
/** Get user defined types /** Get user defined types
* @return array * @return array
*/ */
@@ -902,6 +911,13 @@ if (!defined("DRIVER")) {
return get_key_vals("SHOW VARIABLES"); return get_key_vals("SHOW VARIABLES");
} }
/** Get process list
* @return array ($row)
*/
function process_list() {
return get_rows("SHOW FULL PROCESSLIST");
}
/** Get status variables /** Get status variables
* @return array ($name => $value) * @return array ($name => $value)
*/ */
@@ -910,7 +926,7 @@ if (!defined("DRIVER")) {
} }
/** Check whether a feature is supported /** Check whether a feature is supported
* @param string "comment", "copy", "drop_col", "dump", "event", "partitioning", "privileges", "procedure", "processlist", "routine", "scheme", "sequence", "status", "trigger", "type", "variables", "view" * @param string "comment", "copy", "drop_col", "dump", "event", "kill", "partitioning", "privileges", "procedure", "processlist", "routine", "scheme", "sequence", "status", "trigger", "type", "variables", "view"
* @return bool * @return bool
*/ */
function support($feature) { function support($feature) {

View File

@@ -275,6 +275,9 @@ ORDER BY uc.constraint_type, uic.column_position", $connection2) as $row) {
return $connection->query("SELECT * FROM plan_table"); return $connection->query("SELECT * FROM plan_table");
} }
function found_rows($table_status, $where) {
}
function alter_table($table, $name, $fields, $foreign, $comment, $engine, $collation, $auto_increment, $partitioning) { function alter_table($table, $name, $fields, $foreign, $comment, $engine, $collation, $auto_increment, $partitioning) {
$alter = $drop = array(); $alter = $drop = array();
foreach ($fields as $field) { foreach ($fields as $field) {

View File

@@ -17,10 +17,12 @@ if (isset($_GET["pgsql"])) {
} }
function connect($server, $username, $password) { function connect($server, $username, $password) {
global $adminer;
$db = $adminer->database();
set_error_handler(array($this, '_error')); set_error_handler(array($this, '_error'));
$this->_string = "host='" . str_replace(":", "' port='", addcslashes($server, "'\\")) . "' user='" . addcslashes($username, "'\\") . "' password='" . addcslashes($password, "'\\") . "'"; $this->_string = "host='" . str_replace(":", "' port='", addcslashes($server, "'\\")) . "' user='" . addcslashes($username, "'\\") . "' password='" . addcslashes($password, "'\\") . "'";
$this->_link = @pg_connect($this->_string . (DB != "" ? " dbname='" . addcslashes(DB, "'\\") . "'" : " dbname='template1'"), PGSQL_CONNECT_FORCE_NEW); $this->_link = @pg_connect($this->_string . ($db != "" ? " dbname='" . addcslashes($db, "'\\") . "'" : " dbname='template1'"), PGSQL_CONNECT_FORCE_NEW);
if (!$this->_link && DB != "") { if (!$this->_link && $db != "") {
// try to connect directly with database for performance // try to connect directly with database for performance
$this->_database = false; $this->_database = false;
$this->_link = @pg_connect("$this->_string dbname='template1'", PGSQL_CONNECT_FORCE_NEW); $this->_link = @pg_connect("$this->_string dbname='template1'", PGSQL_CONNECT_FORCE_NEW);
@@ -39,7 +41,8 @@ if (isset($_GET["pgsql"])) {
} }
function select_db($database) { function select_db($database) {
if ($database == DB) { global $adminer;
if ($database == $adminer->database()) {
return $this->_database; return $this->_database;
} }
$return = @pg_connect("$this->_string dbname='" . addcslashes($database, "'\\") . "'", PGSQL_CONNECT_FORCE_NEW); $return = @pg_connect("$this->_string dbname='" . addcslashes($database, "'\\") . "'", PGSQL_CONNECT_FORCE_NEW);
@@ -126,14 +129,17 @@ if (isset($_GET["pgsql"])) {
var $extension = "PDO_PgSQL"; var $extension = "PDO_PgSQL";
function connect($server, $username, $password) { function connect($server, $username, $password) {
global $adminer;
$db = $adminer->database();
$string = "pgsql:host='" . str_replace(":", "' port='", addcslashes($server, "'\\")) . "' options='-c client_encoding=utf8'"; $string = "pgsql:host='" . str_replace(":", "' port='", addcslashes($server, "'\\")) . "' options='-c client_encoding=utf8'";
$this->dsn($string . (DB != "" ? " dbname='" . addcslashes(DB, "'\\") . "'" : ""), $username, $password); $this->dsn($string . ($db != "" ? " dbname='" . addcslashes($db, "'\\") . "'" : ""), $username, $password);
//! connect without DB in case of an error //! connect without DB in case of an error
return true; return true;
} }
function select_db($database) { function select_db($database) {
return (DB == $database); global $adminer;
return ($adminer->database() == $database);
} }
function close() { function close() {
@@ -161,7 +167,7 @@ if (isset($_GET["pgsql"])) {
} }
function get_databases() { function get_databases() {
return get_vals("SELECT datname FROM pg_database"); return get_vals("SELECT datname FROM pg_database ORDER BY datname");
} }
function limit($query, $where, $limit, $offset = 0, $separator = " ") { function limit($query, $where, $limit, $offset = 0, $separator = " ") {
@@ -235,6 +241,9 @@ ORDER BY a.attnum"
$row["null"] = ($row["attnotnull"] == "f"); $row["null"] = ($row["attnotnull"] == "f");
$row["auto_increment"] = eregi("^nextval\\(", $row["default"]); $row["auto_increment"] = eregi("^nextval\\(", $row["default"]);
$row["privileges"] = array("insert" => 1, "select" => 1, "update" => 1); $row["privileges"] = array("insert" => 1, "select" => 1, "update" => 1);
if (preg_match('~^(.*)::.+$~', $row["default"], $match)) {
$row["default"] = ($match[1][0] == "'" ? idf_unescape($match[1]) : $match[1]);
}
$return[$row["field"]] = $row; $return[$row["field"]] = $row;
} }
return $return; return $return;
@@ -260,20 +269,25 @@ ORDER BY a.attnum"
} }
function foreign_keys($table) { function foreign_keys($table) {
global $on_actions;
$return = array(); $return = array();
foreach (get_rows("SELECT tc.constraint_name, kcu.column_name, rc.update_rule AS on_update, rc.delete_rule AS on_delete, unique_constraint_schema AS ns, ccu.table_name AS table, ccu.column_name AS ref foreach (get_rows("SELECT conname, pg_get_constraintdef(oid) AS definition
FROM information_schema.table_constraints tc FROM pg_constraint
LEFT JOIN information_schema.key_column_usage kcu USING (constraint_catalog, constraint_schema, constraint_name) WHERE conrelid = (SELECT oid FROM pg_class WHERE relname = " . q($table) . ")
LEFT JOIN information_schema.referential_constraints rc USING (constraint_catalog, constraint_schema, constraint_name) AND contype = 'f'::char
LEFT JOIN information_schema.constraint_column_usage ccu ON rc.unique_constraint_catalog = ccu.constraint_catalog AND rc.unique_constraint_schema = ccu.constraint_schema AND rc.unique_constraint_name = ccu.constraint_name ORDER BY conkey, conname") as $row) {
WHERE tc.constraint_type = 'FOREIGN KEY' AND tc.constraint_schema = current_schema() AND tc.table_name = " . q($table) //! there can be more unique_constraint_name if (preg_match('~FOREIGN KEY\s*\((.+)\)\s*REFERENCES (.+)\((.+)\)(.*)$~iA', $row['definition'], $match)) {
) as $row) { $row['source'] = array_map('trim', explode(',', $match[1]));
$foreign_key = &$return[$row["constraint_name"]]; $row['table'] = $match[2];
if (!$foreign_key) { if (preg_match('~(.+)\.(.+)~', $match[2], $match2)) {
$foreign_key = $row; $row['ns'] = $match2[1];
$row['table'] = $match2[2];
}
$row['target'] = array_map('trim', explode(',', $match[3]));
$row['on_delete'] = (preg_match("~ON DELETE ($on_actions)~", $match[4], $match2) ? $match2[1] : '');
$row['on_update'] = (preg_match("~ON UPDATE ($on_actions)~", $match[4], $match2) ? $match2[1] : '');
$return[$row['conname']] = $row;
} }
$foreign_key["source"][] = $row["column_name"];
$foreign_key["target"][] = $row["ref"];
} }
return $return; return $return;
} }
@@ -502,6 +516,18 @@ ORDER BY p.proname');
return $connection->query("EXPLAIN $query"); return $connection->query("EXPLAIN $query");
} }
function found_rows($table_status, $where) {
global $connection;
if (ereg(
" rows=([0-9]+)",
$connection->result("EXPLAIN SELECT * FROM " . idf_escape($table_status["Name"]) . ($where ? " WHERE " . implode(" AND ", $where) : "")),
$regs
)) {
return $regs[1];
}
return false;
}
function types() { function types() {
return get_vals("SELECT typname return get_vals("SELECT typname
FROM pg_type FROM pg_type
@@ -512,7 +538,7 @@ AND typelem = 0"
} }
function schemas() { function schemas() {
return get_vals("SELECT nspname FROM pg_namespace"); return get_vals("SELECT nspname FROM pg_namespace ORDER BY nspname");
} }
function get_schema() { function get_schema() {
@@ -540,11 +566,15 @@ AND typelem = 0"
return get_key_vals("SHOW ALL"); return get_key_vals("SHOW ALL");
} }
function process_list() {
return get_rows("SELECT * FROM pg_stat_activity ORDER BY procpid");
}
function show_status() { function show_status() {
} }
function support($feature) { function support($feature) {
return ereg('^(comment|view|scheme|sequence|trigger|type|variables|drop_col)$', $feature); //! routine| return ereg('^(comment|view|scheme|processlist|sequence|trigger|type|variables|drop_col)$', $feature); //! routine|
} }
$jush = "pgsql"; $jush = "pgsql";

View File

@@ -503,6 +503,9 @@ if (isset($_GET["sqlite"]) || isset($_GET["sqlite2"])) {
return $connection->query("EXPLAIN $query"); return $connection->query("EXPLAIN $query");
} }
function found_rows($table_status, $where) {
}
function types() { function types() {
return array(); return array();
} }

View File

@@ -62,6 +62,10 @@ if ($_POST["save"]) {
$row = (isset($_GET["select"]) && count($rows) != 1 ? null : reset($rows)); $row = (isset($_GET["select"]) && count($rows) != 1 ? null : reset($rows));
} }
} }
if ($row === false) {
echo "<p class='error'>" . lang('No rows.') . "\n";
}
?> ?>
<form action="" method="post" enctype="multipart/form-data" id="form"> <form action="" method="post" enctype="multipart/form-data" id="form">

View File

@@ -13,8 +13,8 @@ if ($_POST && !$error && !$_POST["add"] && !$_POST["change"] && !$_POST["change-
query_redirect("ALTER TABLE " . table($TABLE) query_redirect("ALTER TABLE " . table($TABLE)
. ($_GET["name"] != "" ? "\nDROP FOREIGN KEY " . idf_escape($_GET["name"]) . "," : "") . ($_GET["name"] != "" ? "\nDROP FOREIGN KEY " . idf_escape($_GET["name"]) . "," : "")
. "\nADD FOREIGN KEY (" . implode(", ", array_map('idf_escape', $source)) . ") REFERENCES " . table($_POST["table"]) . " (" . implode(", ", array_map('idf_escape', $target)) . ")" //! reuse $_GET["name"] - check in older MySQL versions . "\nADD FOREIGN KEY (" . implode(", ", array_map('idf_escape', $source)) . ") REFERENCES " . table($_POST["table"]) . " (" . implode(", ", array_map('idf_escape', $target)) . ")" //! reuse $_GET["name"] - check in older MySQL versions
. (in_array($_POST["on_delete"], $on_actions) ? " ON DELETE $_POST[on_delete]" : "") . (ereg("^($on_actions)\$", $_POST["on_delete"]) ? " ON DELETE $_POST[on_delete]" : "")
. (in_array($_POST["on_update"], $on_actions) ? " ON UPDATE $_POST[on_update]" : "") . (ereg("^($on_actions)\$", $_POST["on_update"]) ? " ON UPDATE $_POST[on_update]" : "")
, ME . "table=" . urlencode($TABLE), ($_GET["name"] != "" ? lang('Foreign key has been altered.') : lang('Foreign key has been created.'))); , ME . "table=" . urlencode($TABLE), ($_GET["name"] != "" ? lang('Foreign key has been altered.') : lang('Foreign key has been created.')));
$error = lang('Source and target columns must have the same data type, there must be an index on the target columns and referenced data must exist.') . "<br>$error"; //! no partitioning $error = lang('Source and target columns must have the same data type, there must be an index on the target columns and referenced data must exist.') . "<br>$error"; //! no partitioning
} }
@@ -67,8 +67,8 @@ foreach ($row["source"] as $key => $val) {
?> ?>
</table> </table>
<p> <p>
<?php echo lang('ON DELETE'); ?>: <?php echo html_select("on_delete", array(-1 => "") + $on_actions, $row["on_delete"]); ?> <?php echo lang('ON DELETE'); ?>: <?php echo html_select("on_delete", array(-1 => "") + explode("|", $on_actions), $row["on_delete"]); ?>
<?php echo lang('ON UPDATE'); ?>: <?php echo html_select("on_update", array(-1 => "") + $on_actions, $row["on_update"]); ?> <?php echo lang('ON UPDATE'); ?>: <?php echo html_select("on_update", array(-1 => "") + explode("|", $on_actions), $row["on_update"]); ?>
<p> <p>
<input type="submit" value="<?php echo lang('Save'); ?>"> <input type="submit" value="<?php echo lang('Save'); ?>">
<noscript><p><input type="submit" name="add" value="<?php echo lang('Add column'); ?>"></noscript> <noscript><p><input type="submit" name="add" value="<?php echo lang('Add column'); ?>"></noscript>

View File

@@ -798,7 +798,6 @@ DROP PROCEDURE adminer_alter;
foreach (array("bac", "bra", "sqlite_quo", "mssql_bra") as $val) { foreach (array("bac", "bra", "sqlite_quo", "mssql_bra") as $val) {
echo "jushLinks.$val = jushLinks.$jush;\n"; echo "jushLinks.$val = jushLinks.$jush;\n";
} }
echo "var cmComplete = [ '" . implode("', '", array_map('js_escape', array_keys($tables))) . "' ];\n";
echo "</script>\n"; echo "</script>\n";
} }
} }

View File

@@ -4,8 +4,8 @@ error_reporting(6135); // errors and warnings
include "../adminer/include/coverage.inc.php"; include "../adminer/include/coverage.inc.php";
// disable filter.default // disable filter.default
$filter = (!ereg('^(unsafe_raw)?$', ini_get("filter.default")) || ini_get("filter.default_flags")); $filter = (!ereg('^(unsafe_raw)?$', ini_get("filter.default")));
if ($filter) { if ($filter || ini_get("filter.default_flags")) {
foreach (array('_GET', '_POST', '_COOKIE', '_SERVER') as $val) { foreach (array('_GET', '_POST', '_COOKIE', '_SERVER') as $val) {
$unsafe = filter_input_array(constant("INPUT$val"), FILTER_UNSAFE_RAW); $unsafe = filter_input_array(constant("INPUT$val"), FILTER_UNSAFE_RAW);
if ($unsafe) { if ($unsafe) {
@@ -39,7 +39,7 @@ if (!defined("SID")) {
} }
// disable magic quotes to be able to use database escaping function // disable magic quotes to be able to use database escaping function
remove_slashes(array(&$_GET, &$_POST, &$_COOKIE)); remove_slashes(array(&$_GET, &$_POST, &$_COOKIE), $filter);
if (function_exists("set_magic_quotes_runtime")) { // removed in PHP 6 if (function_exists("set_magic_quotes_runtime")) { // removed in PHP 6
set_magic_quotes_runtime(false); set_magic_quotes_runtime(false);
} }
@@ -78,4 +78,4 @@ if (!ini_bool("session.use_cookies") || @ini_set("session.use_cookies", false) !
session_write_close(); // improves concurrency if a user opens several pages at once, may be restarted later session_write_close(); // improves concurrency if a user opens several pages at once, may be restarted later
} }
$on_actions = array("RESTRICT", "CASCADE", "SET NULL", "NO ACTION"); ///< @var array used in foreign_keys() $on_actions = "RESTRICT|CASCADE|SET NULL|NO ACTION"; ///< @var string used in foreign_keys()

View File

@@ -38,7 +38,7 @@ var areYouSure = '<?php echo lang('Resend POST data?'); ?>';
<?php } ?> <?php } ?>
<?php } ?> <?php } ?>
<body class="<?php echo lang('ltr'); ?> nojs"<?php echo ($_POST ? "" : " onclick=\"return bodyClick(event, '" . js_escape(DB) . "', '" . js_escape($_GET["ns"]) . "');\""); // avoid re-post confirmation after refreshing the next page in Google Chrome ?> onkeydown="bodyKeydown(event);" onload="bodyLoad('<?php echo (is_object($connection) ? substr($connection->server_info, 0, 3) : ""); ?>');<?php echo (isset($_COOKIE["adminer_version"]) ? "" : " verifyVersion();"); ?>"> <body class="<?php echo lang('ltr'); ?> nojs"<?php echo ($_POST ? "" : " onclick=\"return bodyClick(event, '" . h(js_escape(DB) . "', '" . js_escape($_GET["ns"])) . "');\""); // avoid re-post confirmation after refreshing the next page in Google Chrome ?> onkeydown="bodyKeydown(event);" onload="bodyLoad('<?php echo (is_object($connection) ? substr($connection->server_info, 0, 3) : ""); ?>');<?php echo (isset($_COOKIE["adminer_version"]) ? "" : " verifyVersion();"); ?>">
<script type="text/javascript"> <script type="text/javascript">
document.body.className = document.body.className.replace(/(^|\s)nojs(\s|$)/, '$1js$2'); document.body.className = document.body.className.replace(/(^|\s)nojs(\s|$)/, '$1js$2');
</script> </script>

View File

@@ -145,7 +145,7 @@ function edit_type($key, $field, $collations, $foreign_keys = array()) {
<td><input name="<?php echo $key; ?>[length]" value="<?php echo h($field["length"]); ?>" size="3" onfocus="editingLengthFocus(this);"><td class="options"><?php <td><input name="<?php echo $key; ?>[length]" value="<?php echo h($field["length"]); ?>" size="3" onfocus="editingLengthFocus(this);"><td class="options"><?php
echo "<select name='$key" . "[collation]'" . (ereg('(char|text|enum|set)$', $field["type"]) ? "" : " class='hidden'") . '><option value="">(' . lang('collation') . ')' . optionlist($collations, $field["collation"]) . '</select>'; echo "<select name='$key" . "[collation]'" . (ereg('(char|text|enum|set)$', $field["type"]) ? "" : " class='hidden'") . '><option value="">(' . lang('collation') . ')' . optionlist($collations, $field["collation"]) . '</select>';
echo ($unsigned ? "<select name='$key" . "[unsigned]'" . (!$field["type"] || ereg('(int|float|double|decimal)$', $field["type"]) ? "" : " class='hidden'") . '><option>' . optionlist($unsigned, $field["unsigned"]) . '</select>' : ''); echo ($unsigned ? "<select name='$key" . "[unsigned]'" . (!$field["type"] || ereg('(int|float|double|decimal)$', $field["type"]) ? "" : " class='hidden'") . '><option>' . optionlist($unsigned, $field["unsigned"]) . '</select>' : '');
echo ($foreign_keys ? "<select name='$key" . "[on_delete]'" . (ereg("`", $field["type"]) ? "" : " class='hidden'") . "><option value=''>(" . lang('ON DELETE') . ")" . optionlist($on_actions, $field["on_delete"]) . "</select> " : " "); // space for IE echo ($foreign_keys ? "<select name='$key" . "[on_delete]'" . (ereg("`", $field["type"]) ? "" : " class='hidden'") . "><option value=''>(" . lang('ON DELETE') . ")" . optionlist(explode("|", $on_actions), $field["on_delete"]) . "</select> " : " "); // space for IE
} }
/** Filter length value including enums /** Filter length value including enums

View File

@@ -27,9 +27,10 @@ function escape_string($val) {
/** Disable magic_quotes_gpc /** Disable magic_quotes_gpc
* @param array e.g. (&$_GET, &$_POST, &$_COOKIE) * @param array e.g. (&$_GET, &$_POST, &$_COOKIE)
* @param bool whether to leave values as is
* @return null modified in place * @return null modified in place
*/ */
function remove_slashes($process) { function remove_slashes($process, $filter = false) {
if (get_magic_quotes_gpc()) { if (get_magic_quotes_gpc()) {
while (list($key, $val) = each($process)) { while (list($key, $val) = each($process)) {
foreach ($val as $k => $v) { foreach ($val as $k => $v) {
@@ -92,7 +93,7 @@ function nl_br($string) {
function checkbox($name, $value, $checked, $label = "", $onclick = "", $jsonly = false) { function checkbox($name, $value, $checked, $label = "", $onclick = "", $jsonly = false) {
static $id = 0; static $id = 0;
$id++; $id++;
$return = "<input type='checkbox' name='$name' value='" . h($value) . "'" . ($checked ? " checked" : "") . ($onclick ? " onclick=\"$onclick\"" : "") . ($jsonly ? " class='jsonly'" : "") . " id='checkbox-$id'>"; $return = "<input type='checkbox' name='$name' value='" . h($value) . "'" . ($checked ? " checked" : "") . ($onclick ? ' onclick="' . h($onclick) . '"' : '') . ($jsonly ? " class='jsonly'" : "") . " id='checkbox-$id'>";
return ($label != "" ? "<label for='checkbox-$id'>$return" . h($label) . "</label>" : $return); return ($label != "" ? "<label for='checkbox-$id'>$return" . h($label) . "</label>" : $return);
} }
@@ -129,7 +130,7 @@ function optionlist($options, $selected = null, $use_keys = false) {
*/ */
function html_select($name, $options, $value = "", $onchange = true) { function html_select($name, $options, $value = "", $onchange = true) {
if ($onchange) { if ($onchange) {
return "<select name='" . h($name) . "'" . (is_string($onchange) ? " onchange=\"$onchange\"" : "") . ">" . optionlist($options, $value) . "</select>"; return "<select name='" . h($name) . "'" . (is_string($onchange) ? ' onchange="' . h($onchange) . '"' : "") . ">" . optionlist($options, $value) . "</select>";
} }
$return = ""; $return = "";
foreach ($options as $key => $val) { foreach ($options as $key => $val) {
@@ -147,6 +148,37 @@ function confirm($count = "", $stop = false) {
return " onclick=\"" . ($stop ? "eventStop(event); " : "") . "return confirm('" . lang('Are you sure?') . ($count ? " (' + $count + ')" : "") . "');\""; return " onclick=\"" . ($stop ? "eventStop(event); " : "") . "return confirm('" . lang('Are you sure?') . ($count ? " (' + $count + ')" : "") . "');\"";
} }
/** Print header for hidden fieldset (close by </div></fieldset>)
* @param string
* @param string
* @param bool
* @param string
* @return null
*/
function print_fieldset($id, $legend, $visible = false, $onclick = "") {
echo "<fieldset><legend><a href='#fieldset-$id' onclick=\"" . h($onclick) . "return !toggle('fieldset-$id');\">$legend</a></legend><div id='fieldset-$id'" . ($visible ? "" : " class='hidden'") . ">\n";
}
/** Return class='active' if $bold is true
* @param bool
* @return string
*/
function bold($bold) {
return ($bold ? " class='active'" : "");
}
/** Generate class for odd rows
* @param string return this for odd rows, empty to reset counter
* @return string
*/
function odd($return = ' class="odd"') {
static $i = 0;
if (!$return) { // reset counter
$i = -1;
}
return ($i++ % 2 ? $return : '');
}
/** Escape string for JavaScript apostrophes /** Escape string for JavaScript apostrophes
* @param string * @param string
* @return string * @return string
@@ -155,6 +187,25 @@ function js_escape($string) {
return addcslashes($string, "\r\n'\\/"); // slash for <script> return addcslashes($string, "\r\n'\\/"); // slash for <script>
} }
/** Print one row in JSON object
* @param string or "" to close the object
* @param string
* @return null
*/
function json_row($key, $val = null) {
static $first = true;
if ($first) {
echo "{";
}
if ($key != "") {
echo ($first ? "" : ",") . "\n\t\"" . addcslashes($key, "\r\n\"\\") . '": ' . (isset($val) ? '"' . addcslashes($val, "\r\n\"\\") . '"' : 'undefined');
$first = false;
} else {
echo "\n}\n";
$first = true;
}
}
/** Get INI boolean value /** Get INI boolean value
* @param string * @param string
* @return bool * @return bool
@@ -516,35 +567,14 @@ function upload_error($error) {
return ($error ? lang('Unable to upload a file.') . ($max_size ? " " . lang('Maximum allowed file size is %sB.', $max_size) : "") : lang('File does not exist.')); return ($error ? lang('Unable to upload a file.') . ($max_size ? " " . lang('Maximum allowed file size is %sB.', $max_size) : "") : lang('File does not exist.'));
} }
/** Generate class for odd rows /** Create repeat pattern for preg
* @param string return this for odd rows, empty to reset counter * @param string
* @param int
* @return string * @return string
*/ */
function odd($return = ' class="odd"') { function repeat_pattern($pattern, $length) {
static $i = 0; // fix for Compilation failed: number too big in {} quantifier
if (!$return) { // reset counter return str_repeat("$pattern{0,65535}", $length / 65535) . "$pattern{0," . ($length % 65535) . "}"; // can create {0,0} which is OK
$i = -1;
}
return ($i++ % 2 ? $return : '');
}
/** Print one row in JSON object
* @param string or "" to close the object
* @param string
* @return null
*/
function json_row($key, $val = null) {
static $first = true;
if ($first) {
echo "{";
}
if ($key != "") {
echo ($first ? "" : ",") . "\n\t\"" . addcslashes($key, "\r\n\"\\") . '": ' . (isset($val) ? '"' . addcslashes($val, "\r\n\"\\") . '"' : 'undefined');
$first = false;
} else {
echo "\n}\n";
$first = true;
}
} }
/** Check whether the string is in UTF-8 /** Check whether the string is in UTF-8
@@ -556,16 +586,6 @@ function is_utf8($val) {
return (preg_match('~~u', $val) && !preg_match('~[\\0-\\x8\\xB\\xC\\xE-\\x1F]~', $val)); return (preg_match('~~u', $val) && !preg_match('~[\\0-\\x8\\xB\\xC\\xE-\\x1F]~', $val));
} }
/** Create repeat pattern for preg
* @param string
* @param int
* @return string
*/
function repeat_pattern($pattern, $length) {
// fix for Compilation failed: number too big in {} quantifier
return str_repeat("$pattern{0,65535}", $length / 65535) . "$pattern{0," . ($length % 65535) . "}"; // can create {0,0} which is OK
}
/** Shorten UTF-8 string /** Shorten UTF-8 string
* @param string * @param string
* @param int * @param int
@@ -675,7 +695,7 @@ function input($field, $value, $function) {
} }
$first++; $first++;
} }
$onchange = ($first ? " onchange=\"var f = this.form['function[" . js_escape($name) . "]']; if ($first > f.selectedIndex) f.selectedIndex = $first;\"" : ""); $onchange = ($first ? " onchange=\"var f = this.form['function[" . h(js_escape(bracket_escape($field["field"]))) . "]']; if ($first > f.selectedIndex) f.selectedIndex = $first;\"" : "");
$attrs .= $onchange; $attrs .= $onchange;
echo (count($functions) > 1 ? html_select("function[$name]", $functions, !isset($function) || in_array($function, $functions) || isset($functions[$function]) ? $function : "", "functionChange(this);") : nbsp(reset($functions))) . '<td>'; echo (count($functions) > 1 ? html_select("function[$name]", $functions, !isset($function) || in_array($function, $functions) || isset($functions[$function]) ? $function : "", "functionChange(this);") : nbsp(reset($functions))) . '<td>';
$input = $adminer->editInput($_GET["edit"], $field, $attrs, $value); // usage in call is without a table $input = $adminer->editInput($_GET["edit"], $field, $attrs, $value); // usage in call is without a table
@@ -854,22 +874,3 @@ function is_url($string) {
$domain = '[a-z0-9]([-a-z0-9]{0,61}[a-z0-9])'; // one domain component //! IDN $domain = '[a-z0-9]([-a-z0-9]{0,61}[a-z0-9])'; // one domain component //! IDN
return (preg_match("~^(https?)://($domain?\\.)+$domain(:\\d+)?(/.*)?(\\?.*)?(#.*)?\$~i", $string, $match) ? strtolower($match[1]) : ""); //! restrict path, query and fragment characters return (preg_match("~^(https?)://($domain?\\.)+$domain(:\\d+)?(/.*)?(\\?.*)?(#.*)?\$~i", $string, $match) ? strtolower($match[1]) : ""); //! restrict path, query and fragment characters
} }
/** Print header for hidden fieldset (close by </div></fieldset>)
* @param string
* @param string
* @param bool
* @param string
* @return null
*/
function print_fieldset($id, $legend, $visible = false, $onclick = "") {
echo "<fieldset><legend><a href='#fieldset-$id' onclick=\"$onclick" . "return !toggle('fieldset-$id');\">$legend</a></legend><div id='fieldset-$id'" . ($visible ? "" : " class='hidden'") . ">\n";
}
/** Return class='active' if $bold is true
* @param bool
* @return string
*/
function bold($bold) {
return ($bold ? " class='active'" : "");
}

View File

@@ -1,2 +1,2 @@
<?php <?php
$VERSION = "3.3.0"; $VERSION = "3.3.2";

View File

@@ -14,6 +14,7 @@ function adminer_object() {
new AdminerDumpXml, new AdminerDumpXml,
//~ new AdminerEditCalendar("<script type='text/javascript' src='../externals/jquery-ui/jquery-1.4.4.js'></script>\n<script type='text/javascript' src='../externals/jquery-ui/ui/jquery.ui.core.js'></script>\n<script type='text/javascript' src='../externals/jquery-ui/ui/jquery.ui.widget.js'></script>\n<script type='text/javascript' src='../externals/jquery-ui/ui/jquery.ui.datepicker.js'></script>\n<script type='text/javascript' src='../externals/jquery-ui/ui/jquery.ui.mouse.js'></script>\n<script type='text/javascript' src='../externals/jquery-ui/ui/jquery.ui.slider.js'></script>\n<script type='text/javascript' src='../externals/jquery-timepicker/jquery-ui-timepicker-addon.js'></script>\n<link rel='stylesheet' href='../externals/jquery-ui/themes/base/jquery.ui.all.css'>\n<style type='text/css'>\n.ui-timepicker-div .ui-widget-header { margin-bottom: 8px; }\n.ui-timepicker-div dl { text-align: left; }\n.ui-timepicker-div dl dt { height: 25px; }\n.ui-timepicker-div dl dd { margin: -25px 0 10px 65px; }\n.ui-timepicker-div td { font-size: 90%; }\n</style>\n", "../externals/jquery-ui/ui/i18n/jquery.ui.datepicker-%s.js"), //~ new AdminerEditCalendar("<script type='text/javascript' src='../externals/jquery-ui/jquery-1.4.4.js'></script>\n<script type='text/javascript' src='../externals/jquery-ui/ui/jquery.ui.core.js'></script>\n<script type='text/javascript' src='../externals/jquery-ui/ui/jquery.ui.widget.js'></script>\n<script type='text/javascript' src='../externals/jquery-ui/ui/jquery.ui.datepicker.js'></script>\n<script type='text/javascript' src='../externals/jquery-ui/ui/jquery.ui.mouse.js'></script>\n<script type='text/javascript' src='../externals/jquery-ui/ui/jquery.ui.slider.js'></script>\n<script type='text/javascript' src='../externals/jquery-timepicker/jquery-ui-timepicker-addon.js'></script>\n<link rel='stylesheet' href='../externals/jquery-ui/themes/base/jquery.ui.all.css'>\n<style type='text/css'>\n.ui-timepicker-div .ui-widget-header { margin-bottom: 8px; }\n.ui-timepicker-div dl { text-align: left; }\n.ui-timepicker-div dl dt { height: 25px; }\n.ui-timepicker-div dl dd { margin: -25px 0 10px 65px; }\n.ui-timepicker-div td { font-size: 90%; }\n</style>\n", "../externals/jquery-ui/ui/i18n/jquery.ui.datepicker-%s.js"),
//~ new AdminerTinymce("../externals/tinymce/jscripts/tiny_mce/tiny_mce_dev.js"), //~ new AdminerTinymce("../externals/tinymce/jscripts/tiny_mce/tiny_mce_dev.js"),
//~ new AdminerWymeditor(array("../externals/wymeditor/src/jquery/jquery.js", "../externals/wymeditor/src/wymeditor/jquery.wymeditor.js", "../externals/wymeditor/src/wymeditor/jquery.wymeditor.explorer.js", "../externals/wymeditor/src/wymeditor/jquery.wymeditor.mozilla.js", "../externals/wymeditor/src/wymeditor/jquery.wymeditor.opera.js", "../externals/wymeditor/src/wymeditor/jquery.wymeditor.safari.js")),
new AdminerFileUpload(""), new AdminerFileUpload(""),
new AdminerSlugify, new AdminerSlugify,
new AdminerTranslation, new AdminerTranslation,

View File

@@ -1,5 +1,5 @@
<?php <?php
if ($_POST && !$error) { if (support("kill") && $_POST && !$error) {
$killed = 0; $killed = 0;
foreach ((array) $_POST["kill"] as $val) { foreach ((array) $_POST["kill"] as $val) {
if (queries("KILL " . (+$val))) { if (queries("KILL " . (+$val))) {
@@ -16,20 +16,24 @@ page_header(lang('Process list'), $error);
<table cellspacing="0" onclick="tableClick(event);" class="nowrap"> <table cellspacing="0" onclick="tableClick(event);" class="nowrap">
<?php <?php
$i = -1; $i = -1;
foreach (get_rows("SHOW FULL PROCESSLIST") as $i => $row) { foreach (process_list() as $i => $row) {
if (!$i) { if (!$i) {
echo "<thead><tr lang='en'><th>&nbsp;<th>" . implode("<th>", array_keys($row)) . "</thead>\n"; echo "<thead><tr lang='en'>" . (support("kill") ? "<th>&nbsp;" : "") . "<th>" . implode("<th>", array_keys($row)) . "</thead>\n";
} }
echo "<tr" . odd() . "><td>" . checkbox("kill[]", $row["Id"], 0); echo "<tr" . odd() . ">" . (support("kill") ? "<td>" . checkbox("kill[]", $row["Id"], 0) : "");
foreach ($row as $key => $val) { foreach ($row as $key => $val) {
echo "<td>" . ($key == "Info" && $val != "" ? "<code class='jush-$jush'>" . shorten_utf8($val, 100, "</code>") . ' <a href="' . h(ME . ($row["db"] != "" ? "db=" . urlencode($row["db"]) . "&" : "") . "sql=" . urlencode($val)) . '">' . lang('Edit') . '</a>' : nbsp($val)); echo "<td>" . (($jush == "sql" ? $key == "Info" && $val != "" : $key == "current_query" && $val != "<IDLE>") ? "<code class='jush-$jush'>" . shorten_utf8($val, 100, "</code>") . ' <a href="' . h(ME . ($row["db"] != "" ? "db=" . urlencode($row["db"]) . "&" : "") . "sql=" . urlencode($val)) . '">' . lang('Edit') . '</a>' : nbsp($val));
} }
echo "\n"; echo "\n";
} }
?> ?>
</table> </table>
<p><?php echo ($i + 1) . "/" . lang('%d in total', $connection->result("SELECT @@max_connections")); ?>
<p> <p>
<input type="submit" value="<?php echo lang('Kill'); ?>"> <?php
if (support("kill")) {
echo ($i + 1) . "/" . lang('%d in total', $connection->result("SELECT @@max_connections"));
echo "<p><input type='submit' value='" . lang('Kill') . "'>\n";
}
?>
<input type="hidden" name="token" value="<?php echo $token; ?>"> <input type="hidden" name="token" value="<?php echo $token; ?>">
</form> </form>

View File

@@ -1,9 +1,8 @@
<?php <?php
page_header(lang('Database schema'), "", array(), DB); page_header(lang('Database schema'), "", array(), DB . ($_GET["ns"] ? ".$_GET[ns]" : ""));
$table_pos = array(); $table_pos = array();
$table_pos_js = array(); $table_pos_js = array();
// saved in one cookie because there is a limit of 20 cookies per domain
$name = "adminer_schema"; $name = "adminer_schema";
$SCHEMA = ($_GET["schema"] ? $_GET["schema"] : $_COOKIE[($_COOKIE["$name-" . DB] ? "$name-" . DB : $name)]); // $_COOKIE["adminer_schema"] was used before 3.2.0 //! ':' in table name $SCHEMA = ($_GET["schema"] ? $_GET["schema"] : $_COOKIE[($_COOKIE["$name-" . DB] ? "$name-" . DB : $name)]); // $_COOKIE["adminer_schema"] was used before 3.2.0 //! ':' in table name
preg_match_all('~([^:]+):([-0-9.]+)x([-0-9.]+)(_|$)~', $SCHEMA, $matches, PREG_SET_ORDER); preg_match_all('~([^:]+):([-0-9.]+)x([-0-9.]+)(_|$)~', $SCHEMA, $matches, PREG_SET_ORDER);

View File

@@ -3,21 +3,21 @@ header("Content-Type: text/javascript; charset=utf-8");
if ($_GET["script"] == "db") { if ($_GET["script"] == "db") {
$sums = array("Data_length" => 0, "Index_length" => 0, "Data_free" => 0); $sums = array("Data_length" => 0, "Index_length" => 0, "Data_free" => 0);
foreach (table_status() as $row) { foreach (table_status() as $table_status) {
$id = js_escape($row["Name"]); $id = js_escape($table_status["Name"]);
json_row("Comment-$id", nbsp($row["Comment"])); json_row("Comment-$id", nbsp($table_status["Comment"]));
if (!is_view($row)) { if (!is_view($table_status)) {
foreach (array("Engine", "Collation") as $key) { foreach (array("Engine", "Collation") as $key) {
json_row("$key-$id", nbsp($row[$key])); json_row("$key-$id", nbsp($table_status[$key]));
} }
foreach ($sums + array("Auto_increment" => 0, "Rows" => 0) as $key => $val) { foreach ($sums + array("Auto_increment" => 0, "Rows" => 0) as $key => $val) {
if ($row[$key] != "") { if ($table_status[$key] != "") {
$val = number_format($row[$key], 0, '.', lang(',')); $val = number_format($table_status[$key], 0, '.', lang(','));
json_row("$key-$id", ($key == "Rows" && $row["Engine"] == "InnoDB" && $val ? "~ $val" : $val)); json_row("$key-$id", ($key == "Rows" && $table_status["Engine"] == "InnoDB" && $val ? "~ $val" : $val));
if (isset($sums[$key])) { if (isset($sums[$key])) {
$sums[$key] += ($row["Engine"] != "InnoDB" || $key != "Data_free" ? $row[$key] : 0); $sums[$key] += ($table_status["Engine"] != "InnoDB" || $key != "Data_free" ? $table_status[$key] : 0);
} }
} elseif (array_key_exists($key, $row)) { } elseif (array_key_exists($key, $table_status)) {
json_row("$key-$id"); json_row("$key-$id");
} }
} }

View File

@@ -373,8 +373,8 @@ if (!$columns) {
if ($rows || $page) { if ($rows || $page) {
$exact_count = true; $exact_count = true;
if ($_GET["page"] != "last" && +$limit && count($group) >= count($select) && ($found_rows >= $limit || $page)) { if ($_GET["page"] != "last" && +$limit && count($group) >= count($select) && ($found_rows >= $limit || $page)) {
$found_rows = $table_status["Rows"]; $found_rows = found_rows($table_status, $where);
if (!isset($found_rows) || $where || ($table_status["Engine"] == "InnoDB" && $found_rows < max(1e4, 2 * ($page + 1) * $limit))) { if ($found_rows < max(1e4, 2 * ($page + 1) * $limit)) {
// slow with big tables // slow with big tables
ob_flush(); //! doesn't work with AJAX ob_flush(); //! doesn't work with AJAX
flush(); flush();

View File

@@ -51,7 +51,7 @@ if (!$error && $_POST) {
} }
$commands = 0; $commands = 0;
$errors = array(); $errors = array();
$parse = '[\'`"]' . ($jush == "pgsql" ? '|\\$[^$]*\\$' : ($jush == "mssql" || $jush == "sqlite" ? '|\\[' : '')) . '|/\\*|-- |#'; //! ` and # not everywhere $parse = '[\'"' . ($jush == "sql" ? '`#' : ($jush == "sqlite" ? '`[' : ($jush == "mssql" ? '[' : ''))) . ']|/\\*|-- |$' . ($jush == "pgsql" ? '|\\$[^$]*\\$' : '');
$total_start = microtime(); $total_start = microtime();
parse_str($_COOKIE["adminer_export"], $adminer_export); parse_str($_COOKIE["adminer_export"], $adminer_export);
$dump_format = $adminer->dumpFormat(); $dump_format = $adminer->dumpFormat();
@@ -61,12 +61,12 @@ if (!$error && $_POST) {
$delimiter = $match[1]; $delimiter = $match[1];
$query = substr($query, strlen($match[0])); $query = substr($query, strlen($match[0]));
} else { } else {
preg_match('(' . preg_quote($delimiter) . "|$parse|\$)", $query, $match, PREG_OFFSET_CAPTURE, $offset); // should always match preg_match('(' . preg_quote($delimiter) . "|$parse)", $query, $match, PREG_OFFSET_CAPTURE, $offset); // should always match
$found = $match[0][0]; $found = $match[0][0];
$offset = $match[0][1] + strlen($found);
if (!$found && $fp && !feof($fp)) { if (!$found && $fp && !feof($fp)) {
$query .= fread($fp, 1e5); $query .= fread($fp, 1e5);
} else { } else {
$offset = $match[0][1] + strlen($found);
if (!$found && rtrim($query) == "") { if (!$found && rtrim($query) == "") {
break; break;
} }
@@ -75,7 +75,8 @@ if (!$error && $_POST) {
$s = $match[0][0]; $s = $match[0][0];
$offset = $match[0][1] + strlen($s); $offset = $match[0][1] + strlen($s);
if (!$s && $fp && !feof($fp)) { if (!$s && $fp && !feof($fp)) {
$query .= fread($fp, 1e6); $offset -= strlen($found); // strlen($found) >= strlen("\\.") - 1
$query .= fread($fp, 1e5);
} elseif ($s[0] != "\\") { } elseif ($s[0] != "\\") {
break; break;
} }
@@ -104,7 +105,7 @@ if (!$error && $_POST) {
echo "<p class='error'>" . lang('Error in query') . ": " . error() . "\n"; echo "<p class='error'>" . lang('Error in query') . ": " . error() . "\n";
$errors[] = " <a href='#sql-$commands'>$commands</a>"; $errors[] = " <a href='#sql-$commands'>$commands</a>";
if ($_POST["error_stops"]) { if ($_POST["error_stops"]) {
break; break 2;
} }
} elseif (is_object($result)) { } elseif (is_object($result)) {
select($result, $connection2); select($result, $connection2);
@@ -116,16 +117,16 @@ if (!$error && $_POST) {
. html_select("output", $adminer->dumpOutput(), $adminer_export["output"]) . " " . html_select("output", $adminer->dumpOutput(), $adminer_export["output"]) . " "
. html_select("format", $dump_format, $adminer_export["format"]) . html_select("format", $dump_format, $adminer_export["format"])
. "<input type='hidden' name='query' value='" . h($q) . "'>" . "<input type='hidden' name='query' value='" . h($q) . "'>"
. " <input type='submit' name='export' value='" . lang('Export') . "' onclick='eventStop(event);'><input type='hidden' name='token' value='$token'></span>" . " <input type='submit' name='export' value='" . lang('Export') . "' onclick='eventStop(event);'><input type='hidden' name='token' value='$token'></span>\n"
; ;
if ($connection2 && preg_match("~^($space|\\()*SELECT\\b~isU", $q) && ($explain = explain($connection2, $q))) { if ($connection2 && preg_match("~^($space|\\()*SELECT\\b~isU", $q) && ($explain = explain($connection2, $q))) {
$id = "explain-$commands"; $id = "explain-$commands";
echo ", <a href='#$id' onclick=\"return !toggle('$id');\">EXPLAIN</a>$export\n"; echo ", <a href='#$id' onclick=\"return !toggle('$id');\">EXPLAIN</a>$export";
echo "<div id='$id' class='hidden'>\n"; echo "<div id='$id' class='hidden'>\n";
select($explain, $connection2, ($jush == "sql" ? "http://dev.mysql.com/doc/refman/" . substr($connection->server_info, 0, 3) . "/en/explain-output.html#explain_" : "")); select($explain, $connection2, ($jush == "sql" ? "http://dev.mysql.com/doc/refman/" . substr($connection->server_info, 0, 3) . "/en/explain-output.html#explain_" : ""));
echo "</div>\n"; echo "</div>\n";
} else { } else {
echo "$export\n"; echo $export;
} }
echo "</form>\n"; echo "</form>\n";
} }

View File

@@ -309,7 +309,7 @@ function ajaxSend(url, data, popState, noscroll) {
history.pushState(data, '', url); //! remember window position history.pushState(data, '', url); //! remember window position
} }
} }
if (!noscroll) { if (!noscroll && !/&order/.test(url)) {
scrollTo(0, 0); scrollTo(0, 0);
} }
setHtml('content', xmlhttp.responseText); setHtml('content', xmlhttp.responseText);
@@ -376,9 +376,9 @@ function ajaxForm(form, data, noscroll) {
params.push(data); params.push(data);
} }
if (form.method == 'post') { if (form.method == 'post') {
return ajaxSend((/\?/.test(form.action) ? form.action : location.href), params.join('&'), noscroll); // ? - always part of Adminer URL return ajaxSend((/\?/.test(form.action) ? form.action : location.href), params.join('&'), false, noscroll); // ? - always part of Adminer URL
} }
return ajaxSend((form.action || location.href).replace(/\?.*/, '') + '?' + params.join('&'), noscroll); return ajaxSend((form.action || location.href).replace(/\?.*/, '') + '?' + params.join('&'), '', false, noscroll);
} }

View File

@@ -30,7 +30,7 @@ if ($_POST) {
<form action="" method="post" id="form"> <form action="" method="post" id="form">
<table cellspacing="0"> <table cellspacing="0">
<tr><th><?php echo lang('Time'); ?><td><?php echo html_select("Timing", $trigger_options["Timing"], $row["Timing"], "if (/^" . h(preg_quote($TABLE, "/")) . "_[ba][iud]$/.test(this.form['Trigger'].value)) this.form['Trigger'].value = '" . h(js_escape($TABLE)) . "_' + selectValue(this).charAt(0).toLowerCase() + selectValue(this.form['Event']).charAt(0).toLowerCase();"); ?> <tr><th><?php echo lang('Time'); ?><td><?php echo html_select("Timing", $trigger_options["Timing"], $row["Timing"], "if (/^" . preg_quote($TABLE, "/") . "_[ba][iud]$/.test(this.form['Trigger'].value)) this.form['Trigger'].value = '" . js_escape($TABLE) . "_' + selectValue(this).charAt(0).toLowerCase() + selectValue(this.form['Event']).charAt(0).toLowerCase();"); ?>
<tr><th><?php echo lang('Event'); ?><td><?php echo html_select("Event", $trigger_event, $row["Event"], "this.form['Timing'].onchange();"); ?> <tr><th><?php echo lang('Event'); ?><td><?php echo html_select("Event", $trigger_event, $row["Event"], "this.form['Timing'].onchange();"); ?>
<tr><th><?php echo lang('Type'); ?><td><?php echo html_select("Type", $trigger_options["Type"], $row["Type"]); ?> <tr><th><?php echo lang('Type'); ?><td><?php echo html_select("Type", $trigger_options["Type"], $row["Type"]); ?>
</table> </table>

View File

@@ -111,7 +111,7 @@ if ($_POST) {
if ($old_pass != "") { if ($old_pass != "") {
$row["hashed"] = true; $row["hashed"] = true;
} }
$grants[DB != "" && !isset($_GET["host"]) ? idf_escape($_GET["db"]) . ".*" : ""] = array(); $grants[DB != "" && !isset($_GET["host"]) ? idf_escape(addcslashes(DB, "%_")) . ".*" : ""] = array();
} }
?> ?>

View File

@@ -1,3 +1,16 @@
Adminer 3.3.2 (released 2011-08-08):
Display error with non-existent row in edit
Fix minor parser bug in SQL command with webserver file
Fix SQL command Stop on error
Don't scroll with AJAX select order and alter move column
Fast number of rows with big tables (PostgreSQL)
Sort databases and schemas (PostgreSQL)
Adminer 3.3.1 (released 2011-07-27):
Fix XSS introduced in Adminer 3.2.0
Fix altering default values (PostgreSQL)
Process list (PostgreSQL)
Adminer 3.3.0 (released 2011-07-19): Adminer 3.3.0 (released 2011-07-19):
Use Esc to disable in-place edit Use Esc to disable in-place edit
Shortcut for database privileges Shortcut for database privileges
@@ -22,7 +35,7 @@ Display searched columns (Editor)
Customizable favicon (customization) Customizable favicon (customization)
Method name can return a link (customization) Method name can return a link (customization)
Easier sending of default headers (customization) Easier sending of default headers (customization)
Romanian translation Lithuanian and Romanian translation
Adminer 3.2.2 (released 2011-03-28): Adminer 3.2.2 (released 2011-03-28):
Fix AJAX history after reload Fix AJAX history after reload
@@ -31,14 +44,14 @@ Adminer 3.2.1 (released 2011-03-23):
Ability to save expression in edit Ability to save expression in edit
Respect default database collation (bug #3191489) Respect default database collation (bug #3191489)
Don't export triggers without table (bug #3193489) Don't export triggers without table (bug #3193489)
Esc to focus next field in Tab textarea (thanks to David Grudl) Esc to focus next field in Tab textarea
Send forms by Ctrl+Enter on <select> Send forms by Ctrl+Enter on <select>
Enum editor and textarea Ctrl+Enter working in IE Enum editor and textarea Ctrl+Enter working in IE
AJAX forms in Google Chrome AJAX forms in Google Chrome
Parse UTF-16 and UTF-8 BOM in all text uploads Parse UTF-16 and UTF-8 BOM in all text uploads
Display ; in history (thanks to Jan Cerny) Display ; in history
Use DELIMITER in history Use DELIMITER in history
Show databases even with skip_show_database in MySQL 5 (thanks to Radoslaw Kowalewski) Show databases even with skip_show_database in MySQL 5
Disable maxlength with functions in edit Disable maxlength with functions in edit
Better placement of AJAX icon Better placement of AJAX icon
Table header in CSV export (Editor) Table header in CSV export (Editor)
@@ -194,9 +207,9 @@ Localize date (Editor)
Treat tinyint(1) as bool (Editor) Treat tinyint(1) as bool (Editor)
Divide types to groups in table creation Divide types to groups in table creation
Link e-mails in select Link e-mails in select
Show type in field name title (thanks to Jakub Sochor) Show type in field name title
Preselect now() for timestamp columns (thanks to paranoiq) Preselect now() for timestamp columns
Clear history (thanks to paranoiq) Clear history
Prefill insert by foreign key searches Prefill insert by foreign key searches
Print number of rows in SQL command Print number of rows in SQL command
Remove Delete button from Edit page - use mass operation for it Remove Delete button from Edit page - use mass operation for it
@@ -207,7 +220,7 @@ Use HTML Strict instead of XHTML
Remove function minification in favor of performance and customization Remove function minification in favor of performance and customization
Fix grant ALL PRIVILEGES with GRANT OPTION Fix grant ALL PRIVILEGES with GRANT OPTION
Fix CSV import Fix CSV import
Fix work with default values (thanks to Jiri Pospisil) Fix work with default values
Adminer 1.11.1 (released 2009-07-03): Adminer 1.11.1 (released 2009-07-03):
Fix problem with enabled Filter extension Fix problem with enabled Filter extension
@@ -236,15 +249,15 @@ Use \n in SQL commands
phpMinAdmin 1.10.1 (released 2009-05-07): phpMinAdmin 1.10.1 (released 2009-05-07):
Highlight odd and hover rows Highlight odd and hover rows
Partition editing comfort (bug #2783446) Partition editing comfort (bug #2783446)
Allow full length in limited int (thanks to Vlasta Neubauer) Allow full length in limited int
phpMinAdmin 1.10.0 (released 2009-04-28): phpMinAdmin 1.10.0 (released 2009-04-28):
Partitioning (MySQL 5.1) Partitioning (MySQL 5.1)
CSV import CSV import
Plus and minus functions Plus and minus functions
Option to stop on error in SQL command (thanks to Vaclav Marik) Option to stop on error in SQL command
Cross links to select and table (bug #2236232), link new item Cross links to select and table (bug #2236232), link new item
Suhosin compatibility (thanks to Klemens Hackel) Suhosin compatibility
Remove max_allowed_packet from export Remove max_allowed_packet from export
Read style from phpMinAdmin.css if exists Read style from phpMinAdmin.css if exists
Size reduction by minification of variables and functions Size reduction by minification of variables and functions
@@ -263,11 +276,11 @@ Search without column restriction
Use type=password for unhashed password Use type=password for unhashed password
Only one button for each action in select Only one button for each action in select
Choose language through option-list Choose language through option-list
XHTML syntax errors (thanks to kozotoc) XHTML syntax errors
Don't set global variable in export Don't set global variable in export
SHOW DATABASES can be revoked SHOW DATABASES can be revoked
Order by function result working also in older MySQL versions Order by function result working also in older MySQL versions
Tested on IIS (thanks to krasl.cz) Tested on IIS
phpMinAdmin 1.8.0 (released 2008-09-12): phpMinAdmin 1.8.0 (released 2008-09-12):
Events (MySQL 5.1) Events (MySQL 5.1)

View File

@@ -17,7 +17,7 @@ html/*\*/>/*/*/body #menu p a[href*="&select="] {background:url("data:image/png;
html/*\*/>/*/*/body #menu p a[href*="&table="], html/*\*/>/*/*/body #menu p a[href*="&view="] {clear:right; margin-left:24px; display:block; height:17px; padding-bottom:1px; text-decoration:none;} html/*\*/>/*/*/body #menu p a[href*="&table="], html/*\*/>/*/*/body #menu p a[href*="&view="] {clear:right; margin-left:24px; display:block; height:17px; padding-bottom:1px; text-decoration:none;}
html/*\*/>/*/*/body #menu p#tables br {display:none;} html/*\*/>/*/*/body #menu p br {display:none;}
html/*\*/>/*/*/body a[href*="&create="] {background:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAJ6SURBVDjLpZNZSNRRGMV//2XGsjFrMg2z0so2K21xIFpepYUiAsGIICLffI8eWiBBeg3qQV+KwBYKLB8qpHUmrahcKLc0QsxldNSxdPz/79LD1ChBUXTh8sG93POdc75zDa01/7NsgGvPR09rzQmpVZZSCqlAKIWUCqk0QqoZWyKFRir1uvxIbsAGUFqXHQqkpP1L57M3Pm5MMJBKpQHUdF9BKIGQAlcJXOlOVykSdye3leO6MmkGQNyHw+uO/1X3bzGBK+S0B1IqAKqDg3986HeCZPffwvJtoNT7lOZLvUdtAPEDAKBkRzo3QwMUb89InN1uGGD3spdE214xe8MRUnM2MfppNW0Pqy7YAK5UKK2xLbhdP4hlmdxpGMQwwQT8ziNiI534c7cT6WrFazikzF2Eb8HS1IQEDdiWwcHAQmpehTkQSAcgNvSMiYFW5uUUMdV3HW+ywefGNqITJsbUUL75k4FWYJtQ+yaMZcXrk1ANk/33mbdiD7EvlRieETy+FJLkMFcjRRSW3emIAwiF1hqPBfu2LGSWbbA1uZ41SfWkrtxPrPcypsfFiWYzFGzGKTjFV28WEJeIUHETLdOgrmkI1VdHpCdEet5enP4qLK9mKrqMgedv6cyrAP+qxOTiUxAi7oEJi8frELoFoTLpa7nI/HQvscgSRt+0kV1SSW7qYtp7xrBMphm4Mi5h/VIfTcEq1u0oJaknSEdNiMYHET7UvcMpPEN31Ed7zxgASmk1I0g6dK66s8CRak5mVxjnfS05+TsZCw/T9baTx1nnGb47DrQksjE6HrsHYPz6nYt3+Sc3L8+wA2tz0J6pF5OD4WP7Kpq7f5fO79DfSxjdtCtDAAAAAElFTkSuQmCC") no-repeat scroll 2px bottom; padding-left:22px;} html/*\*/>/*/*/body a[href*="&create="] {background:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAJ6SURBVDjLpZNZSNRRGMV//2XGsjFrMg2z0so2K21xIFpepYUiAsGIICLffI8eWiBBeg3qQV+KwBYKLB8qpHUmrahcKLc0QsxldNSxdPz/79LD1ChBUXTh8sG93POdc75zDa01/7NsgGvPR09rzQmpVZZSCqlAKIWUCqk0QqoZWyKFRir1uvxIbsAGUFqXHQqkpP1L57M3Pm5MMJBKpQHUdF9BKIGQAlcJXOlOVykSdye3leO6MmkGQNyHw+uO/1X3bzGBK+S0B1IqAKqDg3986HeCZPffwvJtoNT7lOZLvUdtAPEDAKBkRzo3QwMUb89InN1uGGD3spdE214xe8MRUnM2MfppNW0Pqy7YAK5UKK2xLbhdP4hlmdxpGMQwwQT8ziNiI534c7cT6WrFazikzF2Eb8HS1IQEDdiWwcHAQmpehTkQSAcgNvSMiYFW5uUUMdV3HW+ywefGNqITJsbUUL75k4FWYJtQ+yaMZcXrk1ANk/33mbdiD7EvlRieETy+FJLkMFcjRRSW3emIAwiF1hqPBfu2LGSWbbA1uZ41SfWkrtxPrPcypsfFiWYzFGzGKTjFV28WEJeIUHETLdOgrmkI1VdHpCdEet5enP4qLK9mKrqMgedv6cyrAP+qxOTiUxAi7oEJi8frELoFoTLpa7nI/HQvscgSRt+0kV1SSW7qYtp7xrBMphm4Mi5h/VIfTcEq1u0oJaknSEdNiMYHET7UvcMpPEN31Ed7zxgASmk1I0g6dK66s8CRak5mVxjnfS05+TsZCw/T9baTx1nnGb47DrQksjE6HrsHYPz6nYt3+Sc3L8+wA2tz0J6pF5OD4WP7Kpq7f5fO79DfSxjdtCtDAAAAAElFTkSuQmCC") no-repeat scroll 2px bottom; padding-left:22px;}
@@ -41,8 +41,10 @@ html/*\*/>/*/*/body table tbody input[name*="check"] {display:block; float:left;
html/*\*/>/*/*/body table a[href*="&edit="][href*="&where"] {background:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAFUSURBVDjLrZM/SAJxGIZdWwuDlnCplkAEm1zkaIiGFFpyMIwGK5KGoK2lphDKkMDg3LLUSIJsSKhIi+684CokOtTiMizCGuzEU5K3vOEgKvtBDe/2Pc8H3x8NAM1fQlx4H9M3pcOWp6TXWmM8A7j0629v1nraiAVC0IrrwATKIgs5xyG5QiE+Z4iQdoeU2oAsnqCSO1NSTu+D9VhqRLD8nIB8F0Q2MgmJDyipCzjvYJkIfpN2UBLG8MpP4dxvQ3ZzGuyyBQ2H+AnOOCBd9aL6soh81A5hyYSGWyCFvxUcerqI4S+CvYVOFPMHxLAq8I3qdHVY5LbBhJzEsCrwutpRFBlUHy6wO2tEYtWAzLELPN2P03kjfj3luqDycV2F8AgefWbEnVqEHa2IznSD6BdsVDNStB0lfh0FPoQjdx8RrAqGzC0YprSgxzsUMOY2bf37N/6Ud1Vc9yYcH50CAAAAAElFTkSuQmCC") no-repeat scroll right bottom; padding-right:18px;} html/*\*/>/*/*/body table a[href*="&edit="][href*="&where"] {background:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAFUSURBVDjLrZM/SAJxGIZdWwuDlnCplkAEm1zkaIiGFFpyMIwGK5KGoK2lphDKkMDg3LLUSIJsSKhIi+684CokOtTiMizCGuzEU5K3vOEgKvtBDe/2Pc8H3x8NAM1fQlx4H9M3pcOWp6TXWmM8A7j0629v1nraiAVC0IrrwATKIgs5xyG5QiE+Z4iQdoeU2oAsnqCSO1NSTu+D9VhqRLD8nIB8F0Q2MgmJDyipCzjvYJkIfpN2UBLG8MpP4dxvQ3ZzGuyyBQ2H+AnOOCBd9aL6soh81A5hyYSGWyCFvxUcerqI4S+CvYVOFPMHxLAq8I3qdHVY5LbBhJzEsCrwutpRFBlUHy6wO2tEYtWAzLELPN2P03kjfj3luqDycV2F8AgefWbEnVqEHa2IznSD6BdsVDNStB0lfh0FPoQjdx8RrAqGzC0YprSgxzsUMOY2bf37N/6Ud1Vc9yYcH50CAAAAAElFTkSuQmCC") no-repeat scroll right bottom; padding-right:18px;}
html/*\*/>/*/*/body table input + a[href*="&edit="][href*="&where"] {width:0; float:left; display:block; height:16px; overflow:hidden; text-decoration:none; padding:0 0 0 18px; background-position:2px bottom;} html/*\*/>/*/*/body table input + a[href*="&edit="][href*="&where"] {width:0; float:left; display:block; height:16px; overflow:hidden; text-decoration:none; padding:0 0 0 18px; background-position:2px bottom;}
html/*\*/>/*/*/body table tbody td:first-child {white-space:normal;}
html/*\*/>/*/*/body table thead input {margin-right:30px;} html/*\*/>/*/*/body table thead #all-page + a {background:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAFUSURBVDjLrZM/SAJxGIZdWwuDlnCplkAEm1zkaIiGFFpyMIwGK5KGoK2lphDKkMDg3LLUSIJsSKhIi+684CokOtTiMizCGuzEU5K3vOEgKvtBDe/2Pc8H3x8NAM1fQlx4H9M3pcOWp6TXWmM8A7j0629v1nraiAVC0IrrwATKIgs5xyG5QiE+Z4iQdoeU2oAsnqCSO1NSTu+D9VhqRLD8nIB8F0Q2MgmJDyipCzjvYJkIfpN2UBLG8MpP4dxvQ3ZzGuyyBQ2H+AnOOCBd9aL6soh81A5hyYSGWyCFvxUcerqI4S+CvYVOFPMHxLAq8I3qdHVY5LbBhJzEsCrwutpRFBlUHy6wO2tEYtWAzLELPN2P03kjfj3luqDycV2F8AgefWbEnVqEHa2IznSD6BdsVDNStB0lfh0FPoQjdx8RrAqGzC0YprSgxzsUMOY2bf37N/6Ud1Vc9yYcH50CAAAAAElFTkSuQmCC") no-repeat scroll right bottom; padding-right:18px;}
html/*\*/>/*/*/body table thead #all-page + a {width:0; display:inline-block; height:16px; overflow:hidden; text-decoration:none; padding:0 0 0 16px;}
html/*\*/>/*/*/body table td:first-child {white-space:nowrap;}
html/*\*/>/*/*/body input[name="delete"], html/*\*/>/*/*/body input[name="drop"] {background:transparent url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAHSSURBVHjapFM5bsJQEB2zSIDFJrHYpEtyAyoKJAp6CrqIkBPkNDlBAKXjBEgUpKOBCyQNijFiEZvZl8z7wsjESYpkpNFfPO/Nmz9j6Xg80n/M9fWi3W7fMOnd4XAo8qogAbvO5xKvL6lU6s0aL1kVMDjP5ye/36+Gw2FyOp3EQFqtVtTr9WixWHT5/JhOp6s2ghP4ORaLyaFQiGazGa3Xa0HgdrvJ6/WSpmk0Go0MjnvIZDLVM0Gr1brm/WskEkkA3O/3abvdQjq5XC6xgoiVka7rNB6PNT6ns9nsu+OkpODxeBLBYJAGgwHt9/uzQ8Vms6Hdbie+KYqC+ASTFrARBMx2HwgEaDKZiHqn0yktl0uxtzrMMAyKx+MCc+4Cs13hwQCC1GQy+W3Lms2mUIUygbEqEBLNun8z8zswVgUfLO0WD4Z6kekn8/l8okNM8GFVUMYDoVWQ6HA4bEAzoyzL1O12kbRsJajwhYZhiUajJEnShWSAQaqqKnU6HahEGysXg9RoNPJ8+cwZZLSKp47m8/k5Kxzg4XBocNxDLper2ka5Xq+LUeatilahJLN1mEJ+ZDHKJthGAKvVauJnYi9ysHIqQee1xOsLg3/+mf5inwIMAJMhb74NwG5wAAAAAElFTkSuQmCC") no-repeat scroll left center; padding:1px 5px 1px 18px; border:0; cursor:pointer; font-size:.9em;} html/*\*/>/*/*/body input[name="delete"], html/*\*/>/*/*/body input[name="drop"] {background:transparent url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAHSSURBVHjapFM5bsJQEB2zSIDFJrHYpEtyAyoKJAp6CrqIkBPkNDlBAKXjBEgUpKOBCyQNijFiEZvZl8z7wsjESYpkpNFfPO/Nmz9j6Xg80n/M9fWi3W7fMOnd4XAo8qogAbvO5xKvL6lU6s0aL1kVMDjP5ye/36+Gw2FyOp3EQFqtVtTr9WixWHT5/JhOp6s2ghP4ORaLyaFQiGazGa3Xa0HgdrvJ6/WSpmk0Go0MjnvIZDLVM0Gr1brm/WskEkkA3O/3abvdQjq5XC6xgoiVka7rNB6PNT6ns9nsu+OkpODxeBLBYJAGgwHt9/uzQ8Vms6Hdbie+KYqC+ASTFrARBMx2HwgEaDKZiHqn0yktl0uxtzrMMAyKx+MCc+4Cs13hwQCC1GQy+W3Lms2mUIUygbEqEBLNun8z8zswVgUfLO0WD4Z6kekn8/l8okNM8GFVUMYDoVWQ6HA4bEAzoyzL1O12kbRsJajwhYZhiUajJEnShWSAQaqqKnU6HahEGysXg9RoNPJ8+cwZZLSKp47m8/k5Kxzg4XBocNxDLper2ka5Xq+LUeatilahJLN1mEJ+ZDHKJthGAKvVauJnYi9ysHIqQee1xOsLg3/+mf5inwIMAJMhb74NwG5wAAAAAElFTkSuQmCC") no-repeat scroll left center; padding:1px 5px 1px 18px; border:0; cursor:pointer; font-size:.9em;}
html/*\*/>/*/*/body input[name="delete"]:hover, html/*\*/>/*/*/body input[name="drop"]:hover {color:red; background-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAJdSURBVDjLpZP7S1NhGMf9W7YfogSJboSEUVCY8zJ31trcps6zTI9bLGJpjp1hmkGNxVz4Q6ildtXKXzJNbJRaRmrXoeWx8tJOTWptnrNryre5YCYuI3rh+8vL+/m8PA/PkwIg5X+y5mJWrxfOUBXm91QZM6UluUmthntHqplxUml2lciF6wrmdHriI0Wx3xw2hAediLwZRWRkCPzdDswaSvGqkGCfq8VEUsEyPF1O8Qu3O7A09RbRvjuIttsRbT6HHzebsDjcB4/JgFFlNv9MnkmsEszodIIY7Oaut2OJcSF68Qx8dgv8tmqEL1gQaaARtp5A+N4NzB0lMXxon/uxbI8gIYjB9HytGYuusfiPIQcN71kjgnW6VeFOkgh3XcHLvAwMSDPohOADdYQJdF1FtLMZPmslvhZJk2ahkgRvq4HHUoWHRDqTEDDl2mDkfheiDgt8pw340/EocuClCuFvboQzb0cwIZgki4KhzlaE6w0InipbVzBfqoK/qRH94i0rgokSFeO11iBkp8EdV8cfJo0yD75aE2ZNRvSJ0lZKcBXLaUYmQrCzDT6tDN5SyRqYlWeDLZAg0H4JQ+Jt6M3atNLE10VSwQsN4Z6r0CBwqzXesHmV+BeoyAUri8EyMfi2FowXS5dhd7doo2DVII0V5BAjigP89GEVAtda8b2ehodU4rNaAW+dGfzlFkyo89GTlcrHYCLpKD+V7yeeHNzLjkp24Uu1Ed6G8/F8qjqGRzlbl2H2dzjpMg1KdwsHxOlmJ7GTeZC/nesXbeZ6c9OYnuxUc3fmBuFft/Ff8xMd0s65SXIb/gAAAABJRU5ErkJggg==")} html/*\*/>/*/*/body input[name="delete"]:hover, html/*\*/>/*/*/body input[name="drop"]:hover {color:red; background-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAJdSURBVDjLpZP7S1NhGMf9W7YfogSJboSEUVCY8zJ31trcps6zTI9bLGJpjp1hmkGNxVz4Q6ildtXKXzJNbJRaRmrXoeWx8tJOTWptnrNryre5YCYuI3rh+8vL+/m8PA/PkwIg5X+y5mJWrxfOUBXm91QZM6UluUmthntHqplxUml2lciF6wrmdHriI0Wx3xw2hAediLwZRWRkCPzdDswaSvGqkGCfq8VEUsEyPF1O8Qu3O7A09RbRvjuIttsRbT6HHzebsDjcB4/JgFFlNv9MnkmsEszodIIY7Oaut2OJcSF68Qx8dgv8tmqEL1gQaaARtp5A+N4NzB0lMXxon/uxbI8gIYjB9HytGYuusfiPIQcN71kjgnW6VeFOkgh3XcHLvAwMSDPohOADdYQJdF1FtLMZPmslvhZJk2ahkgRvq4HHUoWHRDqTEDDl2mDkfheiDgt8pw340/EocuClCuFvboQzb0cwIZgki4KhzlaE6w0InipbVzBfqoK/qRH94i0rgokSFeO11iBkp8EdV8cfJo0yD75aE2ZNRvSJ0lZKcBXLaUYmQrCzDT6tDN5SyRqYlWeDLZAg0H4JQ+Jt6M3atNLE10VSwQsN4Z6r0CBwqzXesHmV+BeoyAUri8EyMfi2FowXS5dhd7doo2DVII0V5BAjigP89GEVAtda8b2ehodU4rNaAW+dGfzlFkyo89GTlcrHYCLpKD+V7yeeHNzLjkp24Uu1Ed6G8/F8qjqGRzlbl2H2dzjpMg1KdwsHxOlmJ7GTeZC/nesXbeZ6c9OYnuxUc3fmBuFft/Ff8xMd0s65SXIb/gAAAABJRU5ErkJggg==")}

View File

@@ -197,8 +197,8 @@ ORDER BY ORDINAL_POSITION", null, "") as $row) { //! requires MySQL 5
$i = 0; $i = 0;
$fields = fields($_GET["select"]); $fields = fields($_GET["select"]);
foreach ($fields as $name => $field) { foreach ($fields as $name => $field) {
if (ereg("enum", $field["type"])) { //! set - uses 1 << $i and FIND_IN_SET() $desc = $columns[$name];
$desc = $columns[$name]; if (ereg("enum", $field["type"]) && $desc != "") { //! set - uses 1 << $i and FIND_IN_SET()
$key = $keys[$name]; $key = $keys[$name];
$i--; $i--;
echo "<div>" . h($desc) . "<input type='hidden' name='where[$i][col]' value='" . h($name) . "'>:"; echo "<div>" . h($desc) . "<input type='hidden' name='where[$i][col]' value='" . h($name) . "'>:";

View File

@@ -36,7 +36,7 @@ class AdminerEditCalendar {
if (ereg("date|time", $field["type"])) { if (ereg("date|time", $field["type"])) {
$dateFormat = "changeYear: true, dateFormat: 'yy-mm-dd'"; //! yy-mm-dd regional $dateFormat = "changeYear: true, dateFormat: 'yy-mm-dd'"; //! yy-mm-dd regional
$timeFormat = "showSecond: true, timeFormat: 'hh:mm:ss'"; $timeFormat = "showSecond: true, timeFormat: 'hh:mm:ss'";
return "<input id='fields-" . h($field["field"]) . "' value='" . h($value) . "'" . ($maxlength ? " maxlength='$maxlength'" : "") . "$attrs><script type='text/javascript'>jQuery(function () { jQuery('#fields-" . js_escape($field["field"]) . "')." return "<input id='fields-" . h($field["field"]) . "' value='" . h($value) . "'" . (+$field["length"] ? " maxlength='" . (+$field["length"]) . "'" : "") . "$attrs><script type='text/javascript'>jQuery(function () { jQuery('#fields-" . js_escape($field["field"]) . "')."
. ($field["type"] == "time" ? "timepicker({ $timeFormat })" . ($field["type"] == "time" ? "timepicker({ $timeFormat })"
: (ereg("time", $field["type"]) ? "datetimepicker({ $dateFormat, $timeFormat })" : (ereg("time", $field["type"]) ? "datetimepicker({ $dateFormat, $timeFormat })"
: "datepicker({ $dateFormat })" : "datepicker({ $dateFormat })"

View File

@@ -21,7 +21,7 @@ class AdminerFrames {
header("X-Frame-Options: SameOrigin"); header("X-Frame-Options: SameOrigin");
} }
header("X-XSS-Protection: 0"); header("X-XSS-Protection: 0");
return true; return false;
} }
} }

68
plugins/wymeditor.php Normal file
View File

@@ -0,0 +1,68 @@
<?php
/** Edit all fields containing "_html" by HTML editor WYMeditor and display the HTML in select
* @uses WYMeditor, http://www.wymeditor.org/
* @author Jakub Vrana, http://www.vrana.cz/
* @license http://www.apache.org/licenses/LICENSE-2.0 Apache License, Version 2.0
* @license http://www.gnu.org/licenses/gpl-2.0.html GNU General Public License, version 2 (one or other)
*/
class AdminerWymeditor {
/** @var array @access protected */
var $scripts;
/** @var string @access protected */
var $options;
/**
* @param array
* @param string in format "skin: 'custom', preInit: function () { }"
*/
function AdminerWymeditor($scripts = array("jquery/jquery.js", "wymeditor/jquery.wymeditor.min.js"), $options = "") {
$this->scripts = $scripts;
$this->options = $options;
}
function head() {
foreach ($this->scripts as $script) {
echo "<script type='text/javascript' src='" . h($script) . "'></script>\n";
}
}
function selectVal(&$val, $link, $field) {
// copied from tinymce.php
if (ereg("_html", $field["field"]) && $val != '&nbsp;') {
$shortened = (substr($val, -10) == "<i>...</i>");
if ($shortened) {
$val = substr($val, 0, -10);
}
//! shorten with regard to HTML tags - http://php.vrana.cz/zkraceni-textu-s-xhtml-znackami.php
$val = preg_replace('~<[^>]*$~', '', html_entity_decode($val, ENT_QUOTES)); // remove ending incomplete tag (text can be shortened)
if ($shortened) {
$val .= "<i>...</i>";
}
if (class_exists('DOMDocument')) { // close all opened tags
$dom = new DOMDocument;
if (@$dom->loadHTML("<meta http-equiv='Content-Type' content='text/html; charset=utf-8'></head>$val")) { // @ - $val can contain errors
$val = preg_replace('~.*<body[^>]*>(.*)</body>.*~is', '\\1', $dom->saveHTML());
}
}
}
}
function editInput($table, $field, $attrs, $value) {
static $lang = "";
if (!$lang && ereg("text", $field["type"]) && ereg("_html", $field["field"])) {
$lang = "en";
if (function_exists('get_lang')) { // since Adminer 3.2.0
$lang = get_lang();
$lang = ($lang == "zh" || $lang == "zh-tw" ? "zh_cn" : $lang);
}
return "<textarea$attrs id='fields-" . h($field["field"]) . "' rows='12' cols='50'>" . h($value) . "</textarea><script type='text/javascript'>
jQuery(function () {
jQuery('textarea[name*=\"_html\"]').wymeditor({ updateSelector: '#form [type=\"submit\"]', lang: '$lang'" . ($this->options ? ", $this->options" : "") . " });
});
</script>";
}
}
}

View File

@@ -31,6 +31,11 @@
<td>indexes[2][columns][1]</td> <td>indexes[2][columns][1]</td>
<td>label=name</td> <td>label=name</td>
</tr> </tr>
<tr>
<td>verifyValue</td>
<td>name=indexes[2][name]</td>
<td>name</td>
</tr>
<tr> <tr>
<td>clickAndWait</td> <td>clickAndWait</td>
<td>//input[@value='Save']</td> <td>//input[@value='Save']</td>
@@ -56,7 +61,6 @@
<td>Indexes have been altered.</td> <td>Indexes have been altered.</td>
<td></td> <td></td>
</tr> </tr>
</tbody></table> </tbody></table>
</body> </body>
</html> </html>