Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Newer
Older
100644 479 lines (460 sloc) 20.936 kb
667bfec Decomposition
jakubvrana authored
1 <?php
79d1902 Substitute table name to $TABLE
jakubvrana authored
2 $TABLE = $_GET["select"];
3 $table_status = table_status($TABLE);
4 $indexes = indexes($TABLE);
f425601 @vrana Hide hidden columns in PostgreSQL (thanks to Pavel Stehule)
authored
5 $fields = fields($TABLE);
dea345c Substitute foreign keys in e-mail fields
jakubvrana authored
6 $foreign_keys = column_foreign_keys($TABLE);
98483e1 @vrana SQLite: Better editing in tables without a primary key
authored
7 $oid = "";
37d8146 @vrana Utilize oids in PostgreSQL
authored
8 if ($table_status["Oid"] == "t") {
98483e1 @vrana SQLite: Better editing in tables without a primary key
authored
9 $oid = ($jush == "sqlite" ? "rowid" : "oid");
10 $indexes[] = array("type" => "PRIMARY", "columns" => array($oid));
37d8146 @vrana Utilize oids in PostgreSQL
authored
11 }
ead05e6 @vrana Remember export and import options
authored
12 parse_str($_COOKIE["adminer_import"], $adminer_import);
dea345c Substitute foreign keys in e-mail fields
jakubvrana authored
13
64ba924 Comments
jakubvrana authored
14 $rights = array(); // privilege => 0
15 $columns = array(); // selectable columns
0115315 Init with null
jakubvrana authored
16 $text_length = null;
ffcea8b Rights
jakubvrana authored
17 foreach ($fields as $key => $field) {
c64c4fd Adminer class
jakubvrana authored
18 $name = $adminer->fieldName($field);
7352c28 Replace strlen() by != ""
jakubvrana authored
19 if (isset($field["privileges"]["select"]) && $name != "") {
1e4d11e Select from foreign keys in Editor
jakubvrana authored
20 $columns[$key] = html_entity_decode(strip_tags($name));
375a5c8 @vrana Non-MySQL binary types
authored
21 if (ereg('text|lob', $field["type"])) {
d24ad78 Select boxes customization
jakubvrana authored
22 $text_length = $adminer->selectLengthProcess();
16c4ddb Single faster POST query with primary key
jakubvrana authored
23 }
ffcea8b Rights
jakubvrana authored
24 }
430034c Cottage homework
jakubvrana authored
25 $rights += $field["privileges"];
26 }
27
d24ad78 Select boxes customization
jakubvrana authored
28 list($select, $group) = $adminer->selectColumnsProcess($columns, $indexes);
07e1ae1 FOUND_ROWS only with GROUP BY
jakubvrana authored
29 $where = $adminer->selectSearchProcess($fields, $indexes);
30 $order = $adminer->selectOrderProcess($fields, $indexes);
d24ad78 Select boxes customization
jakubvrana authored
31 $limit = $adminer->selectLimitProcess();
98483e1 @vrana SQLite: Better editing in tables without a primary key
authored
32 $from = ($select ? implode(", ", $select) : ($oid ? "$oid, " : "") . "*") . "\nFROM " . table($TABLE);
e44fbc2 Wrap SQL query
jakubvrana authored
33 $group_by = ($group && count($group) < count($select) ? "\nGROUP BY " . implode(", ", $group) : "") . ($order ? "\nORDER BY " . implode(", ", $order) : "");
116faf2 Mass delete
jakubvrana authored
34
390e38b @vrana Load long texts for inline-edit by AJAX
authored
35 if ($_GET["val"] && is_ajax()) {
36 header("Content-Type: text/plain; charset=utf-8");
37 foreach ($_GET["val"] as $unique_idf => $row) {
38 echo $connection->result("SELECT" . limit(idf_escape(key($row)) . " FROM " . table($TABLE), " WHERE " . where_check($unique_idf) . ($where ? " AND " . implode(" AND ", $where) : "") . ($order ? " ORDER BY " . implode(", ", $order) : ""), 1));
39 }
40 exit;
41 }
42
116faf2 Mass delete
jakubvrana authored
43 if ($_POST && !$error) {
56948c9 $_POST[check] may be empty
jakubvrana authored
44 $where_check = "(" . implode(") OR (", array_map('where_check', (array) $_POST["check"])) . ")";
6e50eb8 @vrana Pass primary key to insert_update function
authored
45 $primary = $unselected = null;
2ad8ab4 @vrana Primary key detection for other drivers
authored
46 foreach ($indexes as $index) {
47 if ($index["type"] == "PRIMARY") {
6e50eb8 @vrana Pass primary key to insert_update function
authored
48 $primary = array_flip($index["columns"]);
49 $unselected = ($select ? $primary : array());
2ad8ab4 @vrana Primary key detection for other drivers
authored
50 break;
51 }
52 }
d2c513d @vrana Column names customization (bug #3194500)
authored
53 foreach ((array) $unselected as $key => $val) {
54 if (in_array(idf_escape($key), $select)) {
55 unset($unselected[$key]);
d24ad78 Select boxes customization
jakubvrana authored
56 }
57 }
78639a9 Function results in edit
jakubvrana authored
58 if ($_POST["export"]) {
ead05e6 @vrana Remember export and import options
authored
59 cookie("adminer_import", "output=" . urlencode($_POST["output"]) . "&format=" . urlencode($_POST["format"]));
8ab6fff @vrana Centralize dump_headers
authored
60 dump_headers($TABLE);
095d472 @vrana Customizable export
authored
61 $adminer->dumpTable($TABLE, "");
6e50eb8 @vrana Pass primary key to insert_update function
authored
62 if (!is_array($_POST["check"]) || $unselected === array()) {
ee3e045 @vrana Separate $where in limit function
authored
63 $where2 = $where;
64 if (is_array($_POST["check"])) {
65 $where2[] = "($where_check)";
66 }
15715b3 @vrana Export SQL command result (bug #3116854)
authored
67 $query = "SELECT $from" . ($where2 ? "\nWHERE " . implode(" AND ", $where2) : "") . $group_by;
16c4ddb Single faster POST query with primary key
jakubvrana authored
68 } else {
fa5c952 Use extended INSERT in select export
jakubvrana authored
69 $union = array();
f7452ad Import and export
jakubvrana authored
70 foreach ($_POST["check"] as $val) {
16c4ddb Single faster POST query with primary key
jakubvrana authored
71 // where is not unique so OR can't be used
ee3e045 @vrana Separate $where in limit function
authored
72 $union[] = "(SELECT" . limit($from, "\nWHERE " . ($where ? implode(" AND ", $where) . " AND " : "") . where_check($val) . $group_by, 1) . ")";
116faf2 Mass delete
jakubvrana authored
73 }
15715b3 @vrana Export SQL command result (bug #3116854)
authored
74 $query = implode(" UNION ALL ", $union);
116faf2 Mass delete
jakubvrana authored
75 }
15715b3 @vrana Export SQL command result (bug #3116854)
authored
76 $adminer->dumpData($TABLE, "table", $query);
78639a9 Function results in edit
jakubvrana authored
77 exit;
78 }
dea345c Substitute foreign keys in e-mail fields
jakubvrana authored
79 if (!$adminer->selectEmailProcess($where, $foreign_keys)) {
d90bde5 Fix delete in select
jakubvrana authored
80 if ($_POST["save"] || $_POST["delete"]) { // edit
00d9b36 E-mail sending only in Editor
jakubvrana authored
81 $result = true;
82 $affected = 0;
60c7ed9 @vrana MS SQL schema support
authored
83 $query = table($TABLE);
28b2b8d Readable variable initialization
jakubvrana authored
84 $set = array();
00d9b36 E-mail sending only in Editor
jakubvrana authored
85 if (!$_POST["delete"]) {
86 foreach ($columns as $name => $val) { //! should check also for edit or insert privileges
a0def47 Date localization
jakubvrana authored
87 $val = process_input($fields[$name]);
3f5b683 Reintegrate sqlite branch
jakubvrana authored
88 if ($val !== null) {
89 if ($_POST["clone"]) {
90 $set[idf_escape($name)] = ($val !== false ? $val : idf_escape($name));
91 } elseif ($val !== false) {
92 $set[] = idf_escape($name) . " = $val";
93 }
00d9b36 E-mail sending only in Editor
jakubvrana authored
94 }
e7eb28d CSV import
jakubvrana authored
95 }
60c7ed9 @vrana MS SQL schema support
authored
96 $query .= ($_POST["clone"] ? " (" . implode(", ", array_keys($set)) . ")\nSELECT " . implode(", ", $set) . "\nFROM " . table($TABLE) : " SET\n" . implode(",\n", $set));
e7eb28d CSV import
jakubvrana authored
97 }
00d9b36 E-mail sending only in Editor
jakubvrana authored
98 if ($_POST["delete"] || $set) {
3f5b683 Reintegrate sqlite branch
jakubvrana authored
99 $command = "UPDATE";
100 if ($_POST["delete"]) {
101 $command = "DELETE";
102 $query = "FROM $query";
103 }
104 if ($_POST["clone"]) {
105 $command = "INSERT";
106 $query = "INTO $query";
107 }
6e50eb8 @vrana Pass primary key to insert_update function
authored
108 if ($_POST["all"] || ($unselected === array() && $_POST["check"]) || count($group) < count($select)) {
f1153aa @vrana Display assigned auto_increment after clone
authored
109 $result = queries("$command $query" . ($_POST["all"] ? ($where ? "\nWHERE " . implode(" AND ", $where) : "") : "\nWHERE $where_check"));
64d616c Rename get_dbh to connection
jakubvrana authored
110 $affected = $connection->affected_rows;
00d9b36 E-mail sending only in Editor
jakubvrana authored
111 } else {
112 foreach ((array) $_POST["check"] as $val) {
113 // where is not unique so OR can't be used
ee3e045 @vrana Separate $where in limit function
authored
114 $result = queries($command . limit1($query, "\nWHERE " . where_check($val)));
00d9b36 E-mail sending only in Editor
jakubvrana authored
115 if (!$result) {
116 break;
117 }
64d616c Rename get_dbh to connection
jakubvrana authored
118 $affected += $connection->affected_rows;
38059b6 Remove empty if
jakubvrana authored
119 }
e7eb28d CSV import
jakubvrana authored
120 }
78639a9 Function results in edit
jakubvrana authored
121 }
f1153aa @vrana Display assigned auto_increment after clone
authored
122 $message = lang('%d item(s) have been affected.', $affected);
123 if ($_POST["clone"] && $result && $affected == 1) {
124 $last_id = last_id();
125 if ($last_id) {
126 $message = lang('Item%s has been inserted.', " $last_id");
127 }
128 }
129 queries_redirect(remove_from_uri("page"), $message, $result);
00d9b36 E-mail sending only in Editor
jakubvrana authored
130 //! display edit page in case of an error
e0d9b3c In-place editation in select
jakubvrana authored
131 } elseif (!$_POST["import"]) { // modify
5050de5 @vrana Display modify hint as title
authored
132 if (!$_POST["val"]) {
133 $error = lang('Double click on a value to modify it.');
134 } else {
135 $result = true;
136 $affected = 0;
137 foreach ($_POST["val"] as $unique_idf => $row) {
138 $set = array();
139 foreach ($row as $key => $val) {
140 $key = bracket_escape($key, 1); // 1 - back
0782a7b @vrana Save '' instead of NULL for empty char (some drivers don't have varchar)
authored
141 $set[] = idf_escape($key) . " = " . (ereg('char|text', $fields[$key]["type"]) || $val != "" ? $adminer->processInput($fields[$key], $val) : "NULL");
5050de5 @vrana Display modify hint as title
authored
142 }
ca27ffc @vrana Display 0 in SQLite (bug #3120685)
authored
143 $query = table($TABLE) . " SET " . implode(", ", $set);
144 $where2 = " WHERE " . where_check($unique_idf) . ($where ? " AND " . implode(" AND ", $where) : "");
145 $result = queries("UPDATE" . (count($group) < count($select) ? " $query$where2" : limit1($query, $where2))); // can change row on a different page without unique key
5050de5 @vrana Display modify hint as title
authored
146 if (!$result) {
147 break;
148 }
149 $affected += $connection->affected_rows;
e0d9b3c In-place editation in select
jakubvrana authored
150 }
5050de5 @vrana Display modify hint as title
authored
151 queries_redirect(remove_from_uri(), lang('%d item(s) have been affected.', $affected), $result);
e0d9b3c In-place editation in select
jakubvrana authored
152 }
25f01d3 Compress export and import
jakubvrana authored
153 } elseif (is_string($file = get_file("csv_file", true))) {
9ff10f8 @vrana Parse UTF-16 and UTF-8 BOM in all text uploads
authored
154 //! character set
ead05e6 @vrana Remember export and import options
authored
155 cookie("adminer_import", "output=" . urlencode($adminer_import["output"]) . "&format=" . urlencode($_POST["separator"]));
cb370a8 Respect max_allowed_packet in CSV import
jakubvrana authored
156 $result = true;
e895368 Use ON DUPLICATE KEY UPDATE for CSV import
jakubvrana authored
157 $cols = array_keys($fields);
8a04897 Use atomic group for CSV regexp
jakubvrana authored
158 preg_match_all('~(?>"[^"]*"|[^"\\r\\n]+)+~', $file, $matches);
e895368 Use ON DUPLICATE KEY UPDATE for CSV import
jakubvrana authored
159 $affected = count($matches[0]);
d0c72ec Driver specific BEGIN
jakubvrana authored
160 begin();
e225d22 @vrana TSV export and import (bug #3097657)
authored
161 $separator = ($_POST["separator"] == "csv" ? "," : ($_POST["separator"] == "tsv" ? "\t" : ";"));
00d9b36 E-mail sending only in Editor
jakubvrana authored
162 foreach ($matches[0] as $key => $val) {
3f5b683 Reintegrate sqlite branch
jakubvrana authored
163 preg_match_all("~((\"[^\"]*\")+|[^$separator]*)$separator~", $val . $separator, $matches2);
e895368 Use ON DUPLICATE KEY UPDATE for CSV import
jakubvrana authored
164 if (!$key && !array_diff($matches2[1], $cols)) { //! doesn't work with column names containing ",\n
00d9b36 E-mail sending only in Editor
jakubvrana authored
165 // first row corresponds to column names - use it for table structure
e895368 Use ON DUPLICATE KEY UPDATE for CSV import
jakubvrana authored
166 $cols = $matches2[1];
167 $affected--;
00d9b36 E-mail sending only in Editor
jakubvrana authored
168 } else {
782921b @vrana Finish SQLite
authored
169 $set = array();
e895368 Use ON DUPLICATE KEY UPDATE for CSV import
jakubvrana authored
170 foreach ($matches2[1] as $i => $col) {
7e644b4 @vrana Save bytes ($connection->quote shortcut)
authored
171 $set[idf_escape($cols[$i])] = ($col == "" && $fields[$cols[$i]]["null"] ? "NULL" : q(str_replace('""', '"', preg_replace('~^"|"$~', '', $col))));
00d9b36 E-mail sending only in Editor
jakubvrana authored
172 }
6e50eb8 @vrana Pass primary key to insert_update function
authored
173 $result = insert_update($TABLE, $set, $primary);
e895368 Use ON DUPLICATE KEY UPDATE for CSV import
jakubvrana authored
174 if (!$result) {
175 break;
cb370a8 Respect max_allowed_packet in CSV import
jakubvrana authored
176 }
177 }
178 }
6ba224b Rollback unsuccessful CSV import
jakubvrana authored
179 if ($result) {
acf7a42 Improve CSV; export
jakubvrana authored
180 queries("COMMIT");
6ba224b Rollback unsuccessful CSV import
jakubvrana authored
181 }
dbdd40a Introduce queries_redirect function
jakubvrana authored
182 queries_redirect(remove_from_uri("page"), lang('%d row(s) have been imported.', $affected), $result);
782921b @vrana Finish SQLite
authored
183 queries("ROLLBACK"); // after queries_redirect() to not overwrite error
00d9b36 E-mail sending only in Editor
jakubvrana authored
184 } else {
185 $error = upload_error($file);
d83b654 Detect import errors
jakubvrana authored
186 }
ec23248 Exportable select
jakubvrana authored
187 }
116faf2 Mass delete
jakubvrana authored
188 }
c16c57b E-mail sending
jakubvrana authored
189
b9ffd64 Remove common prefix in backward key
jakubvrana authored
190 $table_name = $adminer->tableName($table_status);
72b8015 @vrana Load more data in select
authored
191 if (is_ajax()) {
364dcfe @vrana Comment
authored
192 // needs to send headers
72b8015 @vrana Load more data in select
authored
193 ob_start('clean_output');
194 }
b9ffd64 Remove common prefix in backward key
jakubvrana authored
195 page_header(lang('Select') . ": $table_name", $error);
116faf2 Mass delete
jakubvrana authored
196
f2ed237 Display table links above table structure
jakubvrana authored
197 $set = null;
430034c Cottage homework
jakubvrana authored
198 if (isset($rights["insert"])) {
98507da Function verify_version doesn't use version parameter
jakubvrana authored
199 $set = "";
200 foreach ((array) $_GET["where"] as $val) {
201 if (count($foreign_keys[$val["col"]]) == 1 && ($val["op"] == "="
a1609c7 Align numbers to right in select
jakubvrana authored
202 || (!$val["op"] && !ereg('[_%]', $val["val"])) // LIKE in Editor
98507da Function verify_version doesn't use version parameter
jakubvrana authored
203 )) {
204 $set .= "&set" . urlencode("[" . bracket_escape($val["col"]) . "]") . "=" . urlencode($val["val"]);
205 }
206 }
667bfec Decomposition
jakubvrana authored
207 }
f2ed237 Display table links above table structure
jakubvrana authored
208 $adminer->selectLinks($table_status, $set);
667bfec Decomposition
jakubvrana authored
209
ffcea8b Rights
jakubvrana authored
210 if (!$columns) {
3f5b683 Reintegrate sqlite branch
jakubvrana authored
211 echo "<p class='error'>" . lang('Unable to select the table') . ($fields ? "." : ": " . error()) . "\n";
ffcea8b Rights
jakubvrana authored
212 } else {
b68ddca @vrana Send all forms by Ctrl+Enter on <select>
authored
213 echo "<form action='' id='form'>\n";
d24ad78 Select boxes customization
jakubvrana authored
214 echo "<div style='display: none;'>";
3f5b683 Reintegrate sqlite branch
jakubvrana authored
215 hidden_fields_get();
8878799 @vrana Respect namespace
authored
216 echo (DB != "" ? '<input type="hidden" name="db" value="' . h(DB) . '">' . (isset($_GET["ns"]) ? '<input type="hidden" name="ns" value="' . h($_GET["ns"]) . '">' : "") : ""); // not used in Editor
79d1902 Substitute table name to $TABLE
jakubvrana authored
217 echo '<input type="hidden" name="select" value="' . h($TABLE) . '">';
d24ad78 Select boxes customization
jakubvrana authored
218 echo "</div>\n";
219 $adminer->selectColumnsPrint($select, $columns);
220 $adminer->selectSearchPrint($where, $columns, $indexes);
221 $adminer->selectOrderPrint($order, $columns, $indexes);
222 $adminer->selectLimitPrint($limit);
223 $adminer->selectLengthPrint($text_length);
739bcb0 @vrana Warn about selecting data without index
authored
224 $adminer->selectActionPrint($indexes);
ffcea8b Rights
jakubvrana authored
225 echo "</form>\n";
226
bd25295 Don't redirect from last page
jakubvrana authored
227 $page = $_GET["page"];
228 if ($page == "last") {
60c7ed9 @vrana MS SQL schema support
authored
229 $found_rows = $connection->result("SELECT COUNT(*) FROM " . table($TABLE) . ($where ? " WHERE " . implode(" AND ", $where) : ""));
31afb96 @vrana Last page with empty result (thanks to Frantisek Svoboda)
authored
230 $page = floor(max(0, $found_rows - 1) / $limit);
bd25295 Don't redirect from last page
jakubvrana authored
231 }
232
700a78b @vrana selectQueryBuild() method
authored
233 $query = $adminer->selectQueryBuild($select, $where, $group, $order, $limit, $page);
234 if (!$query) {
235 $query = "SELECT" . limit(
236 (+$limit && $group && count($group) < count($select) && $jush == "sql" ? "SQL_CALC_FOUND_ROWS " : "") . $from,
237 ($where ? "\nWHERE " . implode(" AND ", $where) : "") . $group_by,
238 ($limit != "" ? +$limit : null),
239 ($page ? $limit * $page : 0),
240 "\n"
241 );
242 }
c64c4fd Adminer class
jakubvrana authored
243 echo $adminer->selectQuery($query);
8b74511 Print SQL query (fixes #2082448)
jakubvrana authored
244
64d616c Rename get_dbh to connection
jakubvrana authored
245 $result = $connection->query($query);
21ea4ae Check errors
jakubvrana authored
246 if (!$result) {
c1130ed Simplify SQL syntax errors everywhere
jakubvrana authored
247 echo "<p class='error'>" . error() . "\n";
ffcea8b Rights
jakubvrana authored
248 } else {
e672694 @vrana Rename $driver to $jush
authored
249 if ($jush == "mssql") {
1b144a1 MS SQL pagination
jakubvrana authored
250 $result->seek($limit * $page);
251 }
f2365d0 Typo
jakubvrana authored
252 $email_fields = array();
b535853 @vrana Full AJAX only with pushState to work correctly with history
authored
253 echo "<form action='' method='post' enctype='multipart/form-data'>\n";
3f5b683 Reintegrate sqlite branch
jakubvrana authored
254 $rows = array();
255 while ($row = $result->fetch_assoc()) {
6a49137 @vrana Pagination support in Oracle (bug #3306828)
authored
256 if ($page && $jush == "oracle") {
257 unset($row["RNUM"]);
258 }
3f5b683 Reintegrate sqlite branch
jakubvrana authored
259 $rows[] = $row;
260 }
261 // use count($rows) without LIMIT, COUNT(*) without grouping, FOUND_ROWS otherwise (slowest)
1b144a1 MS SQL pagination
jakubvrana authored
262 if ($_GET["page"] != "last") {
04eccba @vrana Allow bigger numbers under 32 bits
authored
263 $found_rows = (+$limit && $group && count($group) < count($select)
e672694 @vrana Rename $driver to $jush
authored
264 ? ($jush == "sql" ? $connection->result(" SELECT FOUND_ROWS()") : $connection->result("SELECT COUNT(*) FROM ($query) x")) // space to allow mysql.trace_mode
1b144a1 MS SQL pagination
jakubvrana authored
265 : count($rows)
266 );
267 }
3f5b683 Reintegrate sqlite branch
jakubvrana authored
268
269 if (!$rows) {
ace55ed HTML instead of XHTML
jakubvrana authored
270 echo "<p class='message'>" . lang('No rows.') . "\n";
21ea4ae Check errors
jakubvrana authored
271 } else {
09e93de Move backward keys to Editor
jakubvrana authored
272 $backward_keys = $adminer->backwardKeys($TABLE, $table_name);
c42c46a Table relations
jakubvrana authored
273
72b8015 @vrana Load more data in select
authored
274 echo "<table id='table' cellspacing='0' class='nowrap checkable' onclick='tableClick(event);' onkeydown='return editingKeydown(event);'>\n";
22a7ebd @vrana Hide edit link without columns
authored
275 echo "<thead><tr>" . (!$group && $select ? "" : "<td><input type='checkbox' id='all-page' onclick='formCheck(this, /check/);'> <a href='" . h($_GET["modify"] ? remove_from_uri("modify") : $_SERVER["REQUEST_URI"] . "&modify=1") . "'>" . lang('edit') . "</a>");
5034123 Apply field name with functions
jakubvrana authored
276 $names = array();
c40d1d0 Always handle double click
jakubvrana authored
277 $functions = array();
5034123 Apply field name with functions
jakubvrana authored
278 reset($select);
9bc9b9f @vrana Don't overwrite variable
authored
279 $rank = 1;
ba90d60 Introduce adminer_select_val
jakubvrana authored
280 foreach ($rows[0] as $key => $val) {
98483e1 @vrana SQLite: Better editing in tables without a primary key
authored
281 if ($key != $oid) {
37d8146 @vrana Utilize oids in PostgreSQL
authored
282 $val = $_GET["columns"][key($select)];
d2c513d @vrana Column names customization (bug #3194500)
authored
283 $field = $fields[$select ? ($val ? $val["col"] : current($select)) : $key];
37d8146 @vrana Utilize oids in PostgreSQL
authored
284 $name = ($field ? $adminer->fieldName($field, $rank) : "*");
285 if ($name != "") {
286 $rank++;
287 $names[$key] = $name;
1501d60 @vrana Descending order after second click on column caption
authored
288 $column = idf_escape($key);
70fb696 @vrana Link to descending order
authored
289 $href = remove_from_uri('(order|desc)[^=]*|page') . '&order%5B0%5D=' . urlencode($key);
1501d60 @vrana Descending order after second click on column caption
authored
290 $desc = "&desc%5B0%5D=1";
57e5896 @vrana Autohide column context menu in select
authored
291 echo '<th onmouseover="columnMouse(this);" onmouseout="columnMouse(this, \' hidden\');">';
1501d60 @vrana Descending order after second click on column caption
authored
292 echo '<a href="' . h($href . ($order[0] == $column || $order[0] == $key || (!$order && count($group) < count($select) && $group[0] == $column) ? $desc : '')) . '">'; // $order[0] == $key - COUNT(*)
293 echo (!$select || $val ? apply_sql_function($val["fun"], $name) : h(current($select))) . "</a>"; //! columns looking like functions
57e5896 @vrana Autohide column context menu in select
authored
294 echo "<span class='column hidden'>";
1501d60 @vrana Descending order after second click on column caption
authored
295 echo "<a href='" . h($href . $desc) . "' title='" . lang('descending') . "' class='text'> ↓</a>";
e2dbb9c @vrana Links for column search in select
authored
296 if (!$val["fun"]) {
297 echo '<a href="#fieldset-search" onclick="selectSearch(\'' . h(js_escape($key)) . '\'); return false;" title="' . lang('Search') . '" class="text jsonly"> =</a>';
298 }
57e5896 @vrana Autohide column context menu in select
authored
299 echo "</span>";
37d8146 @vrana Utilize oids in PostgreSQL
authored
300 }
301 $functions[$key] = $val["fun"];
302 next($select);
116c873 Ignore tables and fields with empty name
jakubvrana authored
303 }
ba90d60 Introduce adminer_select_val
jakubvrana authored
304 }
e0d9b3c In-place editation in select
jakubvrana authored
305 $lengths = array();
306 if ($_GET["modify"]) {
307 foreach ($rows as $row) {
308 foreach ($row as $key => $val) {
309 $lengths[$key] = max($lengths[$key], min(40, strlen(utf8_decode($val))));
310 }
311 }
312 }
09e93de Move backward keys to Editor
jakubvrana authored
313 echo ($backward_keys ? "<th>" . lang('Relations') : "") . "</thead>\n";
72b8015 @vrana Load more data in select
authored
314 if (is_ajax()) {
315 if ($limit % 2 == 1 && $page % 2 == 1) {
316 odd();
317 }
318 ob_end_clean();
319 }
dea345c Substitute foreign keys in e-mail fields
jakubvrana authored
320 foreach ($adminer->rowDescriptions($rows, $foreign_keys) as $n => $row) {
3f5b683 Reintegrate sqlite branch
jakubvrana authored
321 $unique_array = unique_array($rows[$n], $indexes);
16290b0 Respect where in COUNT(*) link
jakubvrana authored
322 $unique_idf = "";
323 foreach ($unique_array as $key => $val) {
6591d48 @vrana Replace isset($var) by $var !== null
authored
324 $unique_idf .= "&" . ($val !== null ? urlencode("where[" . bracket_escape($key) . "]") . "=" . urlencode($val) : "null%5B%5D=" . urlencode($key));
16290b0 Respect where in COUNT(*) link
jakubvrana authored
325 }
22a7ebd @vrana Hide edit link without columns
authored
326 echo "<tr" . odd() . ">" . (!$group && $select ? "" : "<td>" . checkbox("check[]", substr($unique_idf, 1), in_array(substr($unique_idf, 1), (array) $_POST["check"]), "", "this.form['all'].checked = false; formUncheck('all-page');") . (count($group) < count($select) || information_schema(DB) ? "" : " <a href='" . h(ME . "edit=" . urlencode($TABLE) . $unique_idf) . "'>" . lang('edit') . "</a>"));
21ea4ae Check errors
jakubvrana authored
327 foreach ($row as $key => $val) {
78e49f0 Pass $field to select_val
jakubvrana authored
328 if (isset($names[$key])) {
a1609c7 Align numbers to right in select
jakubvrana authored
329 $field = $fields[$key];
7352c28 Replace strlen() by != ""
jakubvrana authored
330 if ($val != "" && (!isset($email_fields[$key]) || $email_fields[$key] != "")) {
1cf374b @vrana Rename functions (avoid conflict with WordPress)
authored
331 $email_fields[$key] = (is_mail($val) ? $names[$key] : ""); //! filled e-mails can be contained on other pages
116c873 Ignore tables and fields with empty name
jakubvrana authored
332 }
5911cf1 Always call select_val
jakubvrana authored
333 $link = "";
a1609c7 Align numbers to right in select
jakubvrana authored
334 $val = $adminer->editVal($val, $field);
c4a5724 @vrana Simplify work with NULL values in select
authored
335 if ($val !== null) {
5a73c01 @vrana Treat binary type as hex
authored
336 if (ereg('blob|bytea|raw|file', $field["type"]) && $val != "") {
35ec64c Link COUNT(*) result to listing
jakubvrana authored
337 $link = h(ME . 'download=' . urlencode($TABLE) . '&field=' . urlencode($key) . $unique_idf);
97b8c7b Display images in Editor
jakubvrana authored
338 }
ca27ffc @vrana Display 0 in SQLite (bug #3120685)
authored
339 if ($val === "") { // === - may be int
116c873 Ignore tables and fields with empty name
jakubvrana authored
340 $val = "&nbsp;";
c4a5724 @vrana Simplify work with NULL values in select
authored
341 } elseif (is_utf8($val)) {
342 if ($text_length != "" && ereg('text|blob', $field["type"])) {
343 $val = shorten_utf8($val, max(0, +$text_length)); // usage of LEFT() would reduce traffic but complicate query - expected average speedup: .001 s VS .01 s on local network
344 } else {
345 $val = h($val);
346 }
21ea4ae Check errors
jakubvrana authored
347 }
116c873 Ignore tables and fields with empty name
jakubvrana authored
348
db46fc2 Maintain insert prefill value
jakubvrana authored
349 if (!$link) { // link related items
350 foreach ((array) $foreign_keys[$key] as $foreign_key) {
81f58ed @vrana Link more foreign keys
authored
351 if (count($foreign_keys[$key]) == 1 || end($foreign_key["source"]) == $key) {
352 $link = "";
db46fc2 Maintain insert prefill value
jakubvrana authored
353 foreach ($foreign_key["source"] as $i => $source) {
354 $link .= where_link($i, $foreign_key["target"][$i], $rows[$n][$source]);
355 }
7352c28 Replace strlen() by != ""
jakubvrana authored
356 $link = h(($foreign_key["db"] != "" ? preg_replace('~([?&]db=)[^&]+~', '\\1' . urlencode($foreign_key["db"]), ME) : ME) . 'select=' . urlencode($foreign_key["table"]) . $link); // InnoDB supports non-UNIQUE keys
81f58ed @vrana Link more foreign keys
authored
357 if (count($foreign_key["source"]) == 1) {
358 break;
359 }
116c873 Ignore tables and fields with empty name
jakubvrana authored
360 }
21ea4ae Check errors
jakubvrana authored
361 }
ffcea8b Rights
jakubvrana authored
362 }
35ec64c Link COUNT(*) result to listing
jakubvrana authored
363 if ($key == "COUNT(*)") { //! columns looking like functions
364 $link = h(ME . "select=" . urlencode($TABLE));
365 $i = 0;
16290b0 Respect where in COUNT(*) link
jakubvrana authored
366 foreach ((array) $_GET["where"] as $v) {
367 if (!array_key_exists($v["col"], $unique_array)) {
22eb69b @vrana Remove operator double encode
authored
368 $link .= h(where_link($i++, $v["col"], $v["val"], $v["op"]));
16290b0 Respect where in COUNT(*) link
jakubvrana authored
369 }
370 }
371 foreach ($unique_array as $k => $v) {
8062648 @vrana Use IS NULL operator for null value in where_link function
authored
372 $link .= h(where_link($i++, $k, $v));
35ec64c Link COUNT(*) result to listing
jakubvrana authored
373 }
374 }
fa3dd55 Parent
jakubvrana authored
375 }
2cec758 @vrana Direct links from HTTPS to HTTP
authored
376 if (!$link) {
1cf374b @vrana Rename functions (avoid conflict with WordPress)
authored
377 if (is_mail($val)) {
2cec758 @vrana Direct links from HTTPS to HTTP
authored
378 $link = "mailto:$val";
379 }
380 if ($protocol = is_url($row[$key])) {
381 $link = ($protocol == "http" && $HTTPS
382 ? $row[$key] // HTTP links from HTTPS pages don't receive Referer automatically
383 : "$protocol://www.adminer.org/redirect/?url=" . urlencode($row[$key]) // intermediate page to hide Referer, may be changed to rel="noreferrer" in HTML5
384 );
385 }
bc78866 Link URLs in select
jakubvrana authored
386 }
e0d9b3c In-place editation in select
jakubvrana authored
387 $id = h("val[$unique_idf][" . bracket_escape($key) . "]");
de24145 @vrana Clear POST with AJAX redirect
authored
388 $value = $_POST["val"][$unique_idf][bracket_escape($key)];
6591d48 @vrana Replace isset($var) by $var !== null
authored
389 $h_value = h($value !== null ? $value : $row[$key]);
687b3fd @vrana Replace <strong> by <b> and <em> by <i>
authored
390 $long = strpos($val, "<i>...</i>");
390e38b @vrana Load long texts for inline-edit by AJAX
authored
391 $editable = is_utf8($val) && $rows[$n][$key] == $row[$key] && !$functions[$key];
375a5c8 @vrana Non-MySQL binary types
authored
392 $text = ereg('text|lob', $field["type"]);
6591d48 @vrana Replace isset($var) by $var !== null
authored
393 echo (($_GET["modify"] && $editable) || $value !== null
7d152fb @vrana Utilize bodyKeydown function
authored
394 ? "<td>" . ($text ? "<textarea name='$id' cols='30' rows='" . (substr_count($row[$key], "\n") + 1) . "'>$h_value</textarea>" : "<input name='$id' value='$h_value' size='$lengths[$key]'>")
390e38b @vrana Load long texts for inline-edit by AJAX
authored
395 : "<td id='$id' ondblclick=\"" . ($editable ? "selectDblClick(this, event" . ($long ? ", 2" : ($text ? ", 1" : "")) . ")" : "alert('" . h(lang('Use edit link to modify this value.')) . "')") . ";\">" . $adminer->selectVal($val, $link, $field)
e0d9b3c In-place editation in select
jakubvrana authored
396 );
667bfec Decomposition
jakubvrana authored
397 }
398 }
33aec2c @vrana Move <td> from Adminer::backwardKeysPrint
authored
399 if ($backward_keys) {
400 echo "<td>";
401 }
09e93de Move backward keys to Editor
jakubvrana authored
402 $adminer->backwardKeysPrint($backward_keys, $rows[$n]);
26e8ab9 Close </tr> because of white-space: pre
jakubvrana authored
403 echo "</tr>\n"; // close to allow white-space: pre
5ab708a Compact pages
jakubvrana authored
404 }
72b8015 @vrana Load more data in select
authored
405 if (is_ajax()) {
406 exit;
407 }
21ea4ae Check errors
jakubvrana authored
408 echo "</table>\n";
023b62a @vrana Highlight checked rows
authored
409 echo (!$group && $select ? "" : "<script type='text/javascript'>tableCheck();</script>\n");
3f5b683 Reintegrate sqlite branch
jakubvrana authored
410 }
411
bd25295 Don't redirect from last page
jakubvrana authored
412 if ($rows || $page) {
3f5b683 Reintegrate sqlite branch
jakubvrana authored
413 $exact_count = true;
04eccba @vrana Allow bigger numbers under 32 bits
authored
414 if ($_GET["page"] != "last" && +$limit && count($group) >= count($select) && ($found_rows >= $limit || $page)) {
c828299 @vrana Fast number of rows with big tables in PostgreSQL (thanks to juzna)
authored
415 $found_rows = found_rows($table_status, $where);
416 if ($found_rows < max(1e4, 2 * ($page + 1) * $limit)) {
3f5b683 Reintegrate sqlite branch
jakubvrana authored
417 // slow with big tables
ea6d6e0 @vrana Simplify slow queries
authored
418 $found_rows = reset(slow_query("SELECT COUNT(*) FROM " . table($TABLE) . ($where ? " WHERE " . implode(" AND ", $where) : "")));
3f5b683 Reintegrate sqlite branch
jakubvrana authored
419 } else {
420 $exact_count = false;
421 }
4cdc459 FOUND_ROWS works with last SELECT
jakubvrana authored
422 }
fde1171 Add CSS classes (thanks to cvicebni ubor)
jakubvrana authored
423 echo "<p class='pages'>";
6a7021d @vrana Time out long running select count
authored
424 if (+$limit && ($found_rows === false || $found_rows > $limit)) {
bd25295 Don't redirect from last page
jakubvrana authored
425 // display first, previous 4, next 4 and last page
6a7021d @vrana Time out long running select count
authored
426 $max_page = ($found_rows === false
427 ? $page + (count($rows) >= $limit ? 2 : 1)
428 : floor(($found_rows - 1) / $limit)
429 );
9802869 @vrana Merge from master
authored
430 echo '<a href="' . h(remove_from_uri("page")) . "\" onclick=\"pageClick(this.href, +prompt('" . lang('Page') . "', '" . ($page + 1) . "'), event); return false;\">" . lang('Page') . "</a>:";
6e3c7cb @vrana Use AJAX for pagination
authored
431 echo pagination(0, $page) . ($page > 5 ? " ..." : "");
bd25295 Don't redirect from last page
jakubvrana authored
432 for ($i = max(1, $page - 4); $i < min($max_page, $page + 5); $i++) {
433 echo pagination($i, $page);
21ea4ae Check errors
jakubvrana authored
434 }
fc689f5 @vrana Fix last page link
authored
435 echo ($page + 5 < $max_page ? " ..." : "") . ($exact_count && $found_rows !== false ? pagination($max_page, $page) : ' <a href="' . h(remove_from_uri("page") . "&page=last") . '">' . lang('last') . "</a>");
5ab708a Compact pages
jakubvrana authored
436 }
68211ac @vrana Don't display Load more data on last page
authored
437 echo ($found_rows !== false ? " (" . ($exact_count ? "" : "~ ") . lang('%d row(s)', $found_rows) . ")" : "");
438 echo (+$limit && ($found_rows === false ? count($rows) + 1 : $found_rows - $page * $limit) > $limit ? ' <a href="' . h(remove_from_uri("page") . "&page=" . ($page + 1)) . '" onclick="return !selectLoadMore(this, ' . (+$limit) . ', \'' . lang('Loading') . '\');">' . lang('Load more data') . '</a>' : '');
439 echo " " . checkbox("all", 1, 0, lang('whole result')) . "\n";
8b74511 Print SQL query (fixes #2082448)
jakubvrana authored
440
e641e5c @vrana Limit commands and import in customization (bug #3194432)
authored
441 if ($adminer->selectCommandPrint()) {
e0d9b3c In-place editation in select
jakubvrana authored
442 ?>
443 <fieldset><legend><?php echo lang('Edit'); ?></legend><div>
db2ac19 @vrana Save is available without JS
authored
444 <input type="submit" value="<?php echo lang('Save'); ?>"<?php echo ($_GET["modify"] ? '' : ' title="' . lang('Double click on a value to modify it.') . '" class="jsonly"'); ?>>
38894b2 @vrana Send all forms by AJAX
authored
445 <input type="submit" name="edit" value="<?php echo lang('Edit'); ?>">
446 <input type="submit" name="clone" value="<?php echo lang('Clone'); ?>">
447 <input type="submit" name="delete" value="<?php echo lang('Delete'); ?>" onclick="return confirm('<?php echo lang('Are you sure?'); ?> (' + (this.form['all'].checked ? <?php echo $found_rows; ?> : formChecked(this, /check/)) + ')');">
e0d9b3c In-place editation in select
jakubvrana authored
448 </div></fieldset>
449 <?php
450 }
1e70b74 @vrana Ability to disable export
authored
451 $format = $adminer->dumpFormat();
452 if ($format) {
453 print_fieldset("export", lang('Export'));
454 $output = $adminer->dumpOutput();
455 echo ($output ? html_select("output", $output, $adminer_import["output"]) . " " : "");
456 echo html_select("format", $format, $adminer_import["format"]);
f498219 @vrana Remove eventStop() used by AJAXification in past
authored
457 echo " <input type='submit' name='export' value='" . lang('Export') . "'>\n";
1e70b74 @vrana Ability to disable export
authored
458 echo "</div></fieldset>\n";
459 }
667bfec Decomposition
jakubvrana authored
460 }
e641e5c @vrana Limit commands and import in customization (bug #3194432)
authored
461 if ($adminer->selectImportPrint()) {
462 print_fieldset("import", lang('Import'), !$rows);
463 echo "<input type='file' name='csv_file'> ";
ead05e6 @vrana Remember export and import options
authored
464 echo html_select("separator", array("csv" => "CSV,", "csv;" => "CSV;", "tsv" => "TSV"), $adminer_import["format"], 1); // 1 - select
e641e5c @vrana Limit commands and import in customization (bug #3194432)
authored
465 echo " <input type='submit' name='import' value='" . lang('Import') . "'>";
466 echo "<input type='hidden' name='token' value='$token'>\n";
467 echo "</div></fieldset>\n";
468 }
c16c57b E-mail sending
jakubvrana authored
469
1e55d47 User interface for e-mail {$name}
jakubvrana authored
470 $adminer->selectEmailPrint(array_filter($email_fields, 'strlen'), $columns);
c16c57b E-mail sending
jakubvrana authored
471
e7eb28d CSV import
jakubvrana authored
472 echo "</form>\n";
667bfec Decomposition
jakubvrana authored
473 }
474 }
72b8015 @vrana Load more data in select
authored
475
476 if (is_ajax()) {
477 exit;
478 }
Something went wrong with that request. Please try again.