/** Get database collation
* @param string[][] $collations result of collations()
*/
- function db_collation(string $db, array $collations): string {
+ function db_collation(string $db, array $collations): ?string {
$return = null;
$create = get_val("SHOW CREATE DATABASE " . idf_escape($db), 1);
if (preg_match('~ COLLATE ([^ ]+)~', $create, $match)) {
* @param string $auto_increment number
* @return Result|bool
*/
- function alter_table(string $table, string $name, array $fields, array $foreign, string $comment, string $engine, string $collation, string $auto_increment, string $partitioning) {
+ function alter_table(string $table, string $name, array $fields, array $foreign, ?string $comment, string $engine, string $collation, string $auto_increment, string $partitioning) {
global $connection;
$alter = array();
foreach ($fields as $field) {
}
/** Get last auto increment ID
- * @param Result $result or true
+ * @param Result|bool $result
*/
function last_id($result): string {
return get_val("SELECT LAST_INSERT_ID()"); // mysql_insert_id() truncates bigint
);
}
- function value(string $val, array $field): string {
+ function value(?string $val, array $field): ?string {
return ($field["type"] == "bytea" && $val !== null ? pg_unescape_bytea($val) : $val);
}
// any method change in this file should be transferred to editor/include/adminer.inc.php and plugins.inc.php
class Adminer {
- /** @var list<string> */ public array $operators; // operators used in select, null for all operators
+ /** @var ?list<string> */ public ?array $operators = null; // operators used in select, null for all operators
/** @visibility protected(set) */ public string $error = ''; // HTML
/** Name in title and navigation
/** Get server name displayed in breadcrumbs
* @return string HTML code or null
*/
- function serverName(string $server): string {
+ function serverName(?string $server): string {
return h($server);
}
/** Print links after select heading
* @param TableStatus $tableStatus result of table_status1()
- * @param string $set new item options, NULL for no new item
+ * @param ?string $set new item options, NULL for no new item
*/
- function selectLinks(array $tableStatus, string $set = ""): void {
+ function selectLinks(array $tableStatus, ?string $set = ""): void {
global $driver;
echo '<p class="links">';
$links = array("select" => lang('Select data'));
* @param Field $field single field returned from fields()
* @return string|void null to create the default link
*/
- function selectLink(string $val, array $field) {
+ function selectLink(?string $val, array $field) {
}
/** Value printed in select table
- * @param string $val HTML-escaped value to print
- * @param string $link link to foreign key
+ * @param ?string $val HTML-escaped value to print
+ * @param ?string $link link to foreign key
* @param Field $field single field returned from fields()
* @param string $original original value before applying editVal() and escaping
*/
- function selectVal(string $val, string $link, array $field, string $original): string {
+ function selectVal(?string $val, ?string $link, array $field, ?string $original): string {
$return = ($val === null ? "<i>NULL</i>"
: (preg_match("~char|binary|boolean~", $field["type"]) && !preg_match("~var~", $field["type"]) ? "<code>$val</code>"
: (preg_match('~json~', $field["type"]) ? "<code class='jush-js'>$val</code>"
/** Value conversion used in select and edit
* @param Field $field single field returned from fields()
*/
- function editVal(string $val, array $field): string {
+ function editVal(?string $val, array $field): ?string {
return $val;
}
* @param int $page index of page starting at zero
* @return string empty string to use default query
*/
- function selectQueryBuild(array $select, array $where, array $group, array $order, int $limit, int $page): string {
+ function selectQueryBuild(array $select, array $where, array $group, array $order, ?int $limit, ?int $page): string {
return "";
}
* @param Field[] $fields
* @param mixed $row
*/
- function editRowPrint(string $table, array $fields, $row, bool $update): void {
+ function editRowPrint(string $table, array $fields, $row, ?bool $update): void {
}
/** Functions displayed in edit form
* @param string $attrs attributes to use inside the tag
* @return string custom input field or empty string for default
*/
- function editInput(string $table, array $field, string $attrs, string $value): string {
+ function editInput(string $table, array $field, string $attrs, ?string $value): string {
if ($field["type"] == "enum") {
return (isset($_GET["select"]) ? "<label><input type='radio'$attrs value='-1' checked><i>" . lang('original') . "</i></label> " : "")
. ($field["null"] ? "<label><input type='radio'$attrs value=''" . ($value !== null || isset($_GET["select"]) ? "" : " checked") . "><i>NULL</i></label> " : "")
* @param string $table table name
* @param Field $field single field from fields()
*/
- function editHint(string $table, array $field, string $value): string {
+ function editHint(string $table, array $field, ?string $value): string {
return "";
}
* @param Field $field single field from fields()
* @return string expression to use in a query
*/
- function processInput(array $field, string $value, string $function = ""): string {
+ function processInput(array $field, string $value, ?string $function = ""): string {
if ($function == "SQL") {
return $value; // SQL injection
}
* @param bool $print whether to print the query
* @return Result|false
*/
- function select(string $table, array $select, array $where, array $group, array $order = array(), $limit = 1, int $page = 0, bool $print = false) {
+ function select(string $table, array $select, array $where, array $group, array $order = array(), $limit = 1, ?int $page = 0, bool $print = false) {
global $adminer;
$is_group = (count($group) < count($select));
$query = $adminer->selectQueryBuild($select, $where, $group, $order, $limit, $page);
/** Convert value returned by database to actual value
* @param Field $field
*/
- function value(string $val, array $field): string {
+ function value(?string $val, array $field): ?string {
return (method_exists($this->conn, 'value')
? $this->conn->value($val, $field)
: (is_resource($val) ? stream_get_contents($val) : $val)
* @param Result $result
* @param Db $connection2 connection to examine indexes
* @param string[] $orgtables
+* @param int|numeric-string $limit
* @return string[] $orgtables
*/
-function select($result, Db $connection2 = null, array $orgtables = array(), int $limit = 0): array {
+function select($result, Db $connection2 = null, array $orgtables = array(), $limit = 0): array {
$links = array(); // colno => orgtable - create links from these columns
$indexes = array(); // orgtable => array(column => colno) - primary keys
$columns = array(); // orgtable => array(column => ) - not selected columns in primary key
/** Generate HTML <select> or <input> if $options are empty
* @param string[] $options
*/
-function select_input(string $attrs, array $options, string $value = "", string $onchange = "", string $placeholder = ""): string {
+function select_input(string $attrs, array $options, ?string $value = "", string $onchange = "", string $placeholder = ""): string {
$tag = ($options ? "select" : "input");
return "<$tag$attrs" . ($options
? "><option value=''>$placeholder" . optionlist($options, $value, true) . "</select>"
}
/** Filter length value including enums */
-function process_length(string $length): string {
+function process_length(?string $length): string {
global $driver;
$enum_length = $driver->enumLength;
return (preg_match("~^\\s*\\(?\\s*$enum_length(?:\\s*,\\s*$enum_length)*+\\s*\\)?\\s*\$~", $length) && preg_match_all("~$enum_length~", $length, $matches)
* @param Index[] $indexes result of indexes()
* @return string[]|void null if there is no unique identifier
*/
-function unique_array(array $row, array $indexes) {
+function unique_array(?array $row, array $indexes) {
foreach ($indexes as $index) {
if (preg_match("~PRIMARY|UNIQUE~", $index["type"])) {
$return = array();
class Queries {
/** @var string[] */ static array $queries = array();
- static float $start;
+ static float $start = 0;
}
/** Execute and remember query
/** Apply SQL function
* @param string $column escaped column identifier
*/
-function apply_sql_function(string $function, string $column): string {
+function apply_sql_function(?string $function, string $column): string {
return ($function ? ($function == "unixepoch" ? "DATETIME($column, '$function')" : ($function == "count distinct" ? "COUNT(DISTINCT " : strtoupper("$function(")) . "$column)") : $column);
}
}
/** Check whether the string is URL address */
-function is_url(string $string): bool {
+function is_url(?string $string): bool {
$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); //! restrict path, query and fragment characters
}
}
/** Escape for HTML */
-function h(string $string): string {
+function h(?string $string): string {
return str_replace("\0", "�", htmlspecialchars($string, ENT_QUOTES, 'utf-8'));
}
/** Generate HTML checkbox
* @param string|int $value
*/
-function checkbox(string $name, $value, bool $checked, string $label = "", string $onclick = "", string $class = "", string $labelled_by = ""): string {
+function checkbox(string $name, $value, ?bool $checked, string $label = "", string $onclick = "", string $class = "", string $labelled_by = ""): string {
$return = "<input type='checkbox' name='$name' value='" . h($value) . "'"
. ($checked ? " checked" : "")
. ($labelled_by ? " aria-labelledby='$labelled_by'" : "")
/** Generate HTML <select>
* @param string[] $options
*/
-function html_select(string $name, array $options, string $value = "", string $onchange = "", string $labelled_by = ""): string {
+function html_select(string $name, array $options, ?string $value = "", string $onchange = "", string $labelled_by = ""): string {
return "<select name='" . h($name) . "'"
. ($labelled_by ? " aria-labelledby='$labelled_by'" : "")
. ">" . optionlist($options, $value) . "</select>"
return script("$selector.onclick = () => confirm('" . ($message ? js_escape($message) : lang('Are you sure?')) . "');", "");
}
-/** Print header for hidden fieldset (close by </div></fieldset>) */
-function print_fieldset(string $id, string $legend, bool $visible = false): void {
+/** Print header for hidden fieldset (close by </div></fieldset>)
+* @param bool $visible
+*/
+function print_fieldset(string $id, string $legend, $visible = false): void {
echo "<fieldset><legend>";
echo "<a href='#fieldset-$id'>$legend</a>";
echo script("qsl('a').onclick = partial(toggle, 'fieldset-$id');", "");
}
/** Generate page number for pagination */
-function pagination(int $page, int $current): string {
+function pagination(int $page, ?int $current): string {
return " " . ($page == $current
? $page + 1
: '<a href="' . h(remove_from_uri("page") . ($page ? "&page=$page" . ($_GET["next"] ? "&next=" . urlencode($_GET["next"]) : "") : "")) . '">' . ($page + 1) . "</a>"
$field["length"] = $enums;
}
echo $driver->unconvertFunction($field) . " ";
+ $table = $_GET["edit"] ?: $_GET["select"];
if ($field["type"] == "enum") {
- echo h($functions[""]) . "<td>" . $adminer->editInput($_GET["edit"], $field, $attrs, $value);
+ echo h($functions[""]) . "<td>" . $adminer->editInput($table, $field, $attrs, $value);
} else {
$has_function = (in_array($function, $functions) || isset($functions[$function]));
echo (count($functions) > 1
. script("qsl('select').onchange = functionChange;", "")
: h(reset($functions))
) . '<td>';
- $input = $adminer->editInput($_GET["edit"], $field, $attrs, $value); // usage in call is without a table
+ $input = $adminer->editInput($table, $field, $attrs, $value); // usage in call is without a table
if ($input != "") {
echo $input;
} elseif (preg_match('~bool~', $field["type"])) {
. "$attrs>"
;
}
- echo $adminer->editHint($_GET["edit"], $field, $value);
+ echo $adminer->editHint($table, $field, $value);
// skip 'original'
$first = 0;
foreach ($functions as $key => $val) {
* @param Field[] $fields
* @param mixed $row
*/
-function edit_form(string $table, array $fields, $row, bool $update): void {
+function edit_form(string $table, array $fields, $row, ?bool $update): void {
global $adminer, $error;
$table_name = $adminer->tableName(table_status1($table, true));
page_header(
);
}
- function select(string $table, array $select, array $where, array $group, array $order = array(), $limit = 1, int $page = 0, bool $print = false) {
+ function select(string $table, array $select, array $where, array $group, array $order = array(), $limit = 1, ?int $page = 0, bool $print = false) {
$data = array();
if ($select != array("*")) {
$data["fields"] = array_values($select);
public $primary = "_id";
- function select(string $table, array $select, array $where, array $group, array $order = array(), $limit = 1, int $page = 0, bool $print = false) {
+ function select(string $table, array $select, array $where, array $group, array $order = array(), $limit = 1, ?int $page = 0, bool $print = false) {
$select = ($select == array("*")
? array()
: array_fill_keys($select, 1)
return $return;
}
- function select(string $table, array $select, array $where, array $group, array $order = array(), $limit = 1, int $page = 0, bool $print = false) {
+ function select(string $table, array $select, array $where, array $group, array $order = array(), $limit = 1, ?int $page = 0, bool $print = false) {
$connection = connection();
$connection->next = $_GET["next"];
$return = parent::select($table, $select, $where, $group, $order, $limit, $page, $print);