0 $columns = array(); // selectable columns $text_length = null; foreach ($fields as $key => $field) { $name = $adminer->fieldName($field); if (isset($field["privileges"]["select"]) && $name != "") { $columns[$key] = html_entity_decode(strip_tags($name), ENT_QUOTES); if (is_shortable($field)) { $text_length = $adminer->selectLengthProcess(); } } $rights += $field["privileges"]; } list($select, $group) = $adminer->selectColumnsProcess($columns, $indexes); $is_group = count($group) < count($select) || strstr($select[0], "DISTINCT"); $where = $adminer->selectSearchProcess($fields, $indexes); $order = $adminer->selectOrderProcess($fields, $indexes); $limit = $adminer->selectLimitProcess(); if ($_GET["val"] && is_ajax()) { header("Content-Type: text/plain; charset=utf-8"); foreach ($_GET["val"] as $unique_idf => $row) { $as = convert_field($fields[key($row)]); $select = array($as ? $as : idf_escape(key($row))); $where[] = where_check($unique_idf, $fields); $return = $driver->select($TABLE, $select, $where, $select); if ($return) { echo reset($return->fetch_row()); } } exit; } $primary = $unselected = null; foreach ($indexes as $index) { if ($index["type"] == "PRIMARY") { $primary = array_flip($index["columns"]); $unselected = ($select ? $primary : array()); foreach ($unselected as $key => $val) { if (in_array(idf_escape($key), $select)) { unset($unselected[$key]); } } break; } } if ($oid && !$primary) { $primary = $unselected = array($oid => 0); $indexes[] = array("type" => "PRIMARY", "columns" => array($oid)); } if ($_POST && !$error) { $where_check = $where; if (!$_POST["all"] && is_array($_POST["check"])) { $checks = array(); foreach ($_POST["check"] as $check) { $checks[] = where_check($check, $fields); } $where_check[] = "((" . implode(") OR (", $checks) . "))"; } $where_check = ($where_check ? "\nWHERE " . implode(" AND ", $where_check) : ""); if ($_POST["export"]) { cookie("adminer_import", "output=" . urlencode($_POST["output"]) . "&format=" . urlencode($_POST["format"])); dump_headers($TABLE); $adminer->dumpTable($TABLE, ""); $from = ($select ? implode(", ", $select) : "*") . convert_fields($columns, $fields, $select) . "\nFROM " . table($TABLE); $group_by = ($group && $is_group ? "\nGROUP BY " . implode(", ", $group) : "") . ($order ? "\nORDER BY " . implode(", ", $order) : ""); if (!is_array($_POST["check"]) || $primary) { $query = "SELECT $from$where_check$group_by"; } else { $union = array(); foreach ($_POST["check"] as $val) { // where is not unique so OR can't be used $union[] = "(SELECT" . limit($from, "\nWHERE " . ($where ? implode(" AND ", $where) . " AND " : "") . where_check($val, $fields) . $group_by, 1) . ")"; } $query = implode(" UNION ALL ", $union); } $adminer->dumpData($TABLE, "table", $query); exit; } if (!$adminer->selectEmailProcess($where, $foreign_keys)) { if ($_POST["save"] || $_POST["delete"]) { // edit $result = true; $affected = 0; $set = array(); if (!$_POST["delete"]) { foreach ($columns as $name => $val) { //! should check also for edit or insert privileges $val = process_input($fields[$name]); if ($val !== null && ($_POST["clone"] || $val !== false)) { $set[idf_escape($name)] = ($val !== false ? $val : idf_escape($name)); } } } if ($_POST["delete"] || $set) { if ($_POST["clone"]) { $query = "INTO " . table($TABLE) . " (" . implode(", ", array_keys($set)) . ")\nSELECT " . implode(", ", $set) . "\nFROM " . table($TABLE); } if ($_POST["all"] || ($primary && is_array($_POST["check"])) || $is_group) { $result = ($_POST["delete"] ? $driver->delete($TABLE, $where_check) : ($_POST["clone"] ? queries("INSERT $query$where_check") : $driver->update($TABLE, $set, $where_check) ) ); $affected = $connection->affected_rows; } else { foreach ((array) $_POST["check"] as $val) { // where is not unique so OR can't be used $where2 = "\nWHERE " . ($where ? implode(" AND ", $where) . " AND " : "") . where_check($val, $fields); $result = ($_POST["delete"] ? $driver->delete($TABLE, $where2, 1) : ($_POST["clone"] ? queries("INSERT" . limit1($TABLE, $query, $where2)) : $driver->update($TABLE, $set, $where2, 1) ) ); if (!$result) { break; } $affected += $connection->affected_rows; } } } $message = lang('%d item(s) have been affected.', $affected); if ($_POST["clone"] && $result && $affected == 1) { $last_id = last_id(); if ($last_id) { $message = lang('Item%s has been inserted.', " $last_id"); } } queries_redirect(remove_from_uri($_POST["all"] && $_POST["delete"] ? "page" : ""), $message, $result); if (!$_POST["delete"]) { edit_form($TABLE, $fields, (array) $_POST["fields"], !$_POST["clone"]); page_footer(); exit; } } elseif (!$_POST["import"]) { // modify if (!$_POST["val"]) { $error = lang('Ctrl+click on a value to modify it.'); } else { $result = true; $affected = 0; foreach ($_POST["val"] as $unique_idf => $row) { $set = array(); foreach ($row as $key => $val) { $key = bracket_escape($key, 1); // 1 - back $set[idf_escape($key)] = (preg_match('~char|text~', $fields[$key]["type"]) || $val != "" ? $adminer->processInput($fields[$key], $val) : "NULL"); } $result = $driver->update( $TABLE, $set, " WHERE " . ($where ? implode(" AND ", $where) . " AND " : "") . where_check($unique_idf, $fields), !$is_group && !$primary, " " ); if (!$result) { break; } $affected += $connection->affected_rows; } queries_redirect(remove_from_uri(), lang('%d item(s) have been affected.', $affected), $result); } } elseif (!is_string($file = get_file("csv_file", true))) { $error = upload_error($file); } elseif (!preg_match('~~u', $file)) { $error = lang('File must be in UTF-8 encoding.'); } else { cookie("adminer_import", "output=" . urlencode($adminer_import["output"]) . "&format=" . urlencode($_POST["separator"])); $result = true; $cols = array_keys($fields); preg_match_all('~(?>"[^"]*"|[^"\r\n]+)+~', $file, $matches); $affected = count($matches[0]); $driver->begin(); $separator = ($_POST["separator"] == "csv" ? "," : ($_POST["separator"] == "tsv" ? "\t" : ";")); $rows = array(); foreach ($matches[0] as $key => $val) { preg_match_all("~((?>\"[^\"]*\")+|[^$separator]*)$separator~", $val . $separator, $matches2); if (!$key && !array_diff($matches2[1], $cols)) { //! doesn't work with column names containing ",\n // first row corresponds to column names - use it for table structure $cols = $matches2[1]; $affected--; } else { $set = array(); foreach ($matches2[1] as $i => $col) { $set[idf_escape($cols[$i])] = ($col == "" && $fields[$cols[$i]]["null"] ? "NULL" : q(str_replace('""', '"', preg_replace('~^"|"$~', '', $col)))); } $rows[] = $set; } } $result = (!$rows || $driver->insertUpdate($TABLE, $rows, $primary)); if ($result) { $result = $driver->commit(); } queries_redirect(remove_from_uri("page"), lang('%d row(s) have been imported.', $affected), $result); $driver->rollback(); // after queries_redirect() to not overwrite error } } } $table_name = $adminer->tableName($table_status); if (is_ajax()) { page_headers(); ob_start(); } else { page_header(lang('Select') . ": $table_name", $error); } $set = null; if (isset($rights["insert"]) || !support("table")) { $set = ""; foreach ((array) $_GET["where"] as $val) { if ($foreign_keys[$val["col"]] && count($foreign_keys[$val["col"]]) == 1 && ($val["op"] == "=" || (!$val["op"] && !preg_match('~[_%]~', $val["val"])) // LIKE in Editor )) { $set .= "&set" . urlencode("[" . bracket_escape($val["col"]) . "]") . "=" . urlencode($val["val"]); } } } $adminer->selectLinks($table_status, $set); if (!$columns && support("table")) { echo "

" . lang('Unable to select the table') . ($fields ? "." : ": " . error()) . "\n"; } else { echo "

\n"; echo "
"; hidden_fields_get(); echo (DB != "" ? '' . (isset($_GET["ns"]) ? '' : "") : ""); // not used in Editor echo ''; echo ''; # hidden default submit so filter remove buttons aren't "clicked" on submission from enter key echo "
\n"; $adminer->selectColumnsPrint($select, $columns); $adminer->selectSearchPrint($where, $columns, $indexes); $adminer->selectOrderPrint($order, $columns, $indexes); $adminer->selectLimitPrint($limit); $adminer->selectLengthPrint($text_length); $adminer->selectActionPrint($indexes); echo "
\n"; $page = $_GET["page"]; if ($page == "last") { $found_rows = $connection->result(count_rows($TABLE, $where, $is_group, $group)); $page = floor(max(0, $found_rows - 1) / $limit); } $select2 = $select; $group2 = $group; if (!$select2) { $select2[] = "*"; $convert_fields = convert_fields($columns, $fields, $select); if ($convert_fields) { $select2[] = substr($convert_fields, 2); } } foreach ($select as $key => $val) { $field = $fields[idf_unescape($val)]; if ($field && ($as = convert_field($field))) { $select2[$key] = "$as AS $val"; } } if (!$is_group && $unselected) { foreach ($unselected as $key => $val) { $select2[] = idf_escape($key); if ($group2) { $group2[] = idf_escape($key); } } } $result = $driver->select($TABLE, $select2, $where, $group2, $order, $limit, $page, true); if (!$result) { echo "

" . error() . "\n"; } else { if ($jush == "mssql" && $page) { $result->seek($limit * $page); } $email_fields = array(); echo "

\n"; $rows = array(); while ($row = $result->fetch_assoc()) { if ($page && $jush == "oracle") { unset($row["RNUM"]); } $rows[] = $row; } // use count($rows) without LIMIT, COUNT(*) without grouping, FOUND_ROWS otherwise (slowest) if ($_GET["page"] != "last" && $limit != "" && $group && $is_group && $jush == "sql") { $found_rows = $connection->result(" SELECT FOUND_ROWS()"); // space to allow mysql.trace_mode } if (!$rows) { echo "

" . lang('No rows.') . "\n"; } else { $backward_keys = $adminer->backwardKeys($TABLE, $table_name); echo "

"; echo ""; echo script("mixin(qs('#table'), {onclick: tableClick, ondblclick: partialArg(tableClick, true), onkeydown: editingKeydown});"); echo "" . (!$group && $select ? "" : "\n"; if (is_ajax()) { if ($limit % 2 == 1 && $page % 2 == 1) { odd(); } ob_end_clean(); } foreach ($adminer->rowDescriptions($rows, $foreign_keys) as $n => $row) { $unique_array = unique_array($rows[$n], $indexes); if (!$unique_array) { $unique_array = array(); foreach ($rows[$n] as $key => $val) { if (!preg_match('~^(COUNT\((\*|(DISTINCT )?`(?:[^`]|``)+`)\)|(AVG|GROUP_CONCAT|MAX|MIN|SUM)\(`(?:[^`]|``)+`\))$~', $key)) { //! columns looking like functions $unique_array[$key] = $val; } } } $unique_idf = ""; foreach ($unique_array as $key => $val) { if (($jush == "sql" || $jush == "pgsql") && preg_match('~char|text|enum|set~', $fields[$key]["type"]) && strlen($val) > 64) { $key = (strpos($key, '(') ? $key : idf_escape($key)); //! columns looking like functions $key = "MD5(" . ($jush != 'sql' || preg_match("~^utf8~", $fields[$key]["collation"]) ? $key : "CONVERT($key USING " . charset($connection) . ")") . ")"; $val = md5($val); } $unique_idf .= "&" . ($val !== null ? urlencode("where[" . bracket_escape($key) . "]") . "=" . urlencode($val === false ? "f" : $val) : "null%5B%5D=" . urlencode($key)); } echo "" . (!$group && $select ? "" : "" ; } } } if ($backward_keys) { echo "\n"; // close to allow white-space: pre } if (is_ajax()) { exit; } echo "
" . script("qs('#all-page').onclick = partial(formCheck, /check/);", "") . " " . lang('Modify') . ""); $names = array(); $functions = array(); reset($select); $rank = 1; foreach ($rows[0] as $key => $val) { if (!isset($unselected[$key])) { $val = $_GET["columns"][key($select)] ?? null; $field = $fields[$select ? ($val ? $val["col"] : current($select)) : $key]; $name = ($field ? $adminer->fieldName($field, $rank) : ($val["fun"] ? "*" : $key)); if ($name != "") { $rank++; $names[$key] = $name; $column = idf_escape($key); $href = remove_from_uri('(order|desc)[^=]*|page') . '&order%5B0%5D=' . urlencode($key); $desc = "&desc%5B0%5D=1"; echo "" . script("mixin(qsl('th'), {onmouseover: partial(columnMouse), onmouseout: partial(columnMouse, ' hidden')});", ""); echo ''; // $order[0] == $key - COUNT(*) echo apply_sql_function($val["fun"] ?? null, $name) . ""; //! columns looking like functions echo ""; } $functions[$key] = $val["fun"] ?? null; next($select); } } $lengths = array(); if ($_GET["modify"]) { foreach ($rows as $row) { foreach ($row as $key => $val) { $lengths[$key] = max($lengths[$key], min(40, strlen(utf8_decode($val)))); } } } echo ($backward_keys ? "" . lang('Relations') : "") . "
" . checkbox("check[]", substr($unique_idf, 1), in_array(substr($unique_idf, 1), (array) $_POST["check"])) . ($is_group || information_schema(DB) ? "" : " " . lang('edit') . "") ); foreach ($row as $key => $val) { if (isset($names[$key])) { $field = $fields[$key]; $val = $driver->value($val, $field); if ($val != "" && (!isset($email_fields[$key]) || $email_fields[$key] != "")) { $email_fields[$key] = (is_mail($val) ? $names[$key] : ""); //! filled e-mails can be contained on other pages } $link = ""; if (preg_match('~blob|bytea|raw|file~', $field["type"] ?? null) && $val != "") { $link = ME . 'download=' . urlencode($TABLE) . '&field=' . urlencode($key) . $unique_idf; } if (!$link && $val !== null) { // link related items foreach ((array) $foreign_keys[$key] as $foreign_key) { if (count($foreign_keys[$key]) == 1 || end($foreign_key["source"]) == $key) { $link = ""; foreach ($foreign_key["source"] as $i => $source) { $link .= where_link($i, $foreign_key["target"][$i], $rows[$n][$source]); } $link = ($foreign_key["db"] != "" ? preg_replace('~([?&]db=)[^&]+~', '\1' . urlencode($foreign_key["db"]), ME) : ME) . 'select=' . urlencode($foreign_key["table"]) . $link; // InnoDB supports non-UNIQUE keys if ($foreign_key["ns"]) { $link = preg_replace('~([?&]ns=)[^&]+~', '\1' . urlencode($foreign_key["ns"]), $link); } if (count($foreign_key["source"]) == 1) { break; } } } } if ($key == "COUNT(*)") { //! columns looking like functions $link = ME . "select=" . urlencode($TABLE); $i = 0; foreach ((array) $_GET["where"] as $v) { if (!array_key_exists($v["col"], $unique_array)) { $link .= where_link($i++, $v["col"], $v["val"], $v["op"]); } } foreach ($unique_array as $k => $v) { $link .= where_link($i++, $k, $v); } } $val = select_value($val, $link, $field, $text_length); $id = h("val[$unique_idf][" . bracket_escape($key) . "]"); $value = null; if (isset($_POST["val"][$unique_idf][bracket_escape($key)])) { $_POST["val"][$unique_idf][bracket_escape($key)]; } $editable = !is_array($row[$key]) && is_utf8($val) && $rows[$n][$key] == $row[$key] && !$functions[$key]; $text = preg_match('~text|lob~', $field["type"] ?? null); echo "" . ($text ? "" : ""); } else { $long = strpos($val, ""); echo " data-text='" . ($long ? 2 : ($text ? 1 : 0)) . "'" . ($editable ? "" : " data-warning='" . h(lang('Use edit link to modify this value.')) . "'") . ">$val"; } $adminer->backwardKeysPrint($backward_keys, $rows[$n]); echo "
\n"; echo "
\n"; } if (!is_ajax()) { if ($rows || $page) { $exact_count = true; if ($_GET["page"] != "last") { if ($limit == "" || (count($rows) < $limit && ($rows || !$page))) { $found_rows = ($page ? $page * $limit : 0) + count($rows); } elseif ($jush != "sql" || !$is_group) { $found_rows = ($is_group ? false : found_rows($table_status, $where)); if ($found_rows < max(1e4, 2 * ($page + 1) * $limit)) { // slow with big tables $found_rows = reset(slow_query(count_rows($TABLE, $where, $is_group, $group))); } else { $exact_count = false; } } } $pagination = ($limit != "" && ($found_rows === false || $found_rows > $limit || $page)); if ($pagination) { echo (($found_rows === false ? count($rows) + 1 : $found_rows - $page * $limit) > $limit ? '

' . lang('Load more data') . '' . script("qsl('a').onclick = partial(selectLoadMore, " . (+$limit) . ", '" . lang('Loading') . "…');", "") : '' ); echo "\n"; } } echo "

\n"; if ($adminer->selectImportPrint()) { echo "
"; echo "" . lang('Import') . ""; echo script("qsl('a').onclick = partial(toggle, 'import');", ""); echo ""; echo "
"; } echo "\n"; echo "
\n"; echo (!$group && $select ? "" : script("tableCheck();")); } } } if (is_ajax()) { ob_end_clean(); exit; }