Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Newer
Older
100644 899 lines (843 sloc) 32.102 kb
2c445a8 Extensibility basics
jakubvrana authored
1 <?php
e641e5c @vrana Limit commands and import in customization (bug #3194432)
authored
2 // any method change in this file should be transferred to editor/include/adminer.inc.php and plugins/plugin.php
3
c64c4fd Adminer class
jakubvrana authored
4 class Adminer {
3f5b683 Reintegrate sqlite branch
jakubvrana authored
5 /** @var array operators used in select, null for all operators */
6 var $operators;
c64c4fd Adminer class
jakubvrana authored
7
8 /** Name in title and navigation
3ebfdd3 @vrana Simpler customization of name() link
authored
9 * @return string HTML code
c64c4fd Adminer class
jakubvrana authored
10 */
11 function name() {
3ebfdd3 @vrana Simpler customization of name() link
authored
12 return "<a href='http://www.adminer.org/' id='h1'>Adminer</a>";
c64c4fd Adminer class
jakubvrana authored
13 }
14
15 /** Connection parameters
16 * @return array ($server, $username, $password)
17 */
18 function credentials() {
49565e0 @vrana Rename variables to avoid conflict with Adminer 2 sessions and enable…
authored
19 return array(SERVER, $_GET["username"], get_session("pwds"));
c64c4fd Adminer class
jakubvrana authored
20 }
21
95b4ea4 Permanent login
jakubvrana authored
22 /** Get key used for permanent login
23 * @return string cryptic string which gets combined with password
24 */
25 function permanentLogin() {
4ba2d85 @vrana Allow permanent login without customization
authored
26 return password_file();
95b4ea4 Permanent login
jakubvrana authored
27 }
28
c64c4fd Adminer class
jakubvrana authored
29 /** Identifier of selected database
30 * @return string
31 */
32 function database() {
3022dcb Define DB
jakubvrana authored
33 // should be used everywhere instead of DB
34 return DB;
c64c4fd Adminer class
jakubvrana authored
35 }
36
c7f1a63 @vrana Extensible list of databases
authored
37 /** Get cached list of databases
38 * @param bool
39 * @return array
40 */
41 function databases($flush = true) {
42 return get_databases($flush);
43 }
44
1f53cd3 @vrana Time out long running database list
authored
45 /** Specify limit for waiting on some slow queries like DB list
46 * @return float number of seconds
47 */
48 function queryTimeout() {
49 return 5;
50 }
51
9db4259 @vrana Introduce Adminer::headers method
authored
52 /** Headers to send before HTML output
0f00277 @vrana Easier sending of default headers (customization)
authored
53 * @return bool true to send security headers
9db4259 @vrana Introduce Adminer::headers method
authored
54 */
55 function headers() {
0f00277 @vrana Easier sending of default headers (customization)
authored
56 return true;
9db4259 @vrana Introduce Adminer::headers method
authored
57 }
58
d8cba0e @vrana Allow own code in <head> (thanks to Nikolaj Vasilcuk)
authored
59 /** Print HTML code inside <head>
60 * @return bool true to link adminer.css if exists
61 */
62 function head() {
63 return true;
64 }
65
c64c4fd Adminer class
jakubvrana authored
66 /** Print login form
67 * @return null
68 */
3f5b683 Reintegrate sqlite branch
jakubvrana authored
69 function loginForm() {
b0d637b @vrana Avoid fatal errors
authored
70 global $drivers;
2faa08c Customize login and login form
jakubvrana authored
71 ?>
0205440 HTML whitespace
jakubvrana authored
72 <table cellspacing="0">
f595f93 @vrana Use namespace in login form
authored
73 <tr><th><?php echo lang('System'); ?><td><?php echo html_select("auth[driver]", $drivers, DRIVER, "loginDriver(this);"); ?>
74 <tr><th><?php echo lang('Server'); ?><td><input name="auth[server]" value="<?php echo h(SERVER); ?>" title="hostname[:port]">
75 <tr><th><?php echo lang('Username'); ?><td><input id="username" name="auth[username]" value="<?php echo h($_GET["username"]); ?>">
76 <tr><th><?php echo lang('Password'); ?><td><input type="password" name="auth[password]">
8be29af @vrana Allow specifying database in login form (bug #3499359)
authored
77 <tr><th><?php echo lang('Database'); ?><td><input name="auth[db]" value="<?php echo h($_GET["db"]); ?>">
0205440 HTML whitespace
jakubvrana authored
78 </table>
4269b7b Auto-focus user-name in login form
jakubvrana authored
79 <script type="text/javascript">
1d47454 @vrana Hide credentials for SQLite
authored
80 var username = document.getElementById('username');
81 username.focus();
f595f93 @vrana Use namespace in login form
authored
82 username.form['auth[driver]'].onchange();
4269b7b Auto-focus user-name in login form
jakubvrana authored
83 </script>
2faa08c Customize login and login form
jakubvrana authored
84 <?php
8474399 Move Login button to customization
jakubvrana authored
85 echo "<p><input type='submit' value='" . lang('Login') . "'>\n";
f595f93 @vrana Use namespace in login form
authored
86 echo checkbox("auth[permanent]", 1, $_COOKIE["adminer_permanent"], lang('Permanent login')) . "\n";
2faa08c Customize login and login form
jakubvrana authored
87 }
c64c4fd Adminer class
jakubvrana authored
88
89 /** Authorize the user
90 * @param string
91 * @param string
92 * @return bool
93 */
94 function login($login, $password) {
95 return true;
97b8c7b Display images in Editor
jakubvrana authored
96 }
c64c4fd Adminer class
jakubvrana authored
97
98 /** Table caption used in navigation and headings
99 * @param array result of SHOW TABLE STATUS
5ee1407 @vrana Avoid double escaping
authored
100 * @return string HTML code, "" to ignore table
c64c4fd Adminer class
jakubvrana authored
101 */
102 function tableName($tableStatus) {
689699a Shortcut for htmlspecialchars
jakubvrana authored
103 return h($tableStatus["Name"]);
c64c4fd Adminer class
jakubvrana authored
104 }
105
106 /** Field caption used in select and edit
107 * @param array single field returned from fields()
6c97b80 Display only first five columns in Editor example
jakubvrana authored
108 * @param int order of column in select
5ee1407 @vrana Avoid double escaping
authored
109 * @return string HTML code, "" to ignore field
c64c4fd Adminer class
jakubvrana authored
110 */
6c97b80 Display only first five columns in Editor example
jakubvrana authored
111 function fieldName($field, $order = 0) {
689699a Shortcut for htmlspecialchars
jakubvrana authored
112 return '<span title="' . h($field["full_type"]) . '">' . h($field["field"]) . '</span>';
c64c4fd Adminer class
jakubvrana authored
113 }
114
f2ed237 Display table links above table structure
jakubvrana authored
115 /** Print links after select heading
c64c4fd Adminer class
jakubvrana authored
116 * @param array result of SHOW TABLE STATUS
294b10b Highlight current link
jakubvrana authored
117 * @param string new item options, NULL for no new item
f2ed237 Display table links above table structure
jakubvrana authored
118 * @return null
c64c4fd Adminer class
jakubvrana authored
119 */
f2ed237 Display table links above table structure
jakubvrana authored
120 function selectLinks($tableStatus, $set = "") {
294b10b Highlight current link
jakubvrana authored
121 echo '<p class="tabs">';
2d8a2de Change table operations descriptions
jakubvrana authored
122 $links = array("select" => lang('Select data'), "table" => lang('Show structure'));
da6f1f8 @vrana Driver specific view detection
authored
123 if (is_view($tableStatus)) {
294b10b Highlight current link
jakubvrana authored
124 $links["view"] = lang('Alter view');
3f5b683 Reintegrate sqlite branch
jakubvrana authored
125 } else {
126 $links["create"] = lang('Alter table');
f2ed237 Display table links above table structure
jakubvrana authored
127 }
6591d48 @vrana Replace isset($var) by $var !== null
authored
128 if ($set !== null) {
294b10b Highlight current link
jakubvrana authored
129 $links["edit"] = lang('New item');
130 }
131 foreach ($links as $key => $val) {
8ad4809 @vrana Use class="active" instead of <b>
authored
132 echo " <a href='" . h(ME) . "$key=" . urlencode($tableStatus["Name"]) . ($key == "edit" ? $set : "") . "'" . bold(isset($_GET[$key])) . ">$val</a>";
f2ed237 Display table links above table structure
jakubvrana authored
133 }
134 echo "\n";
c64c4fd Adminer class
jakubvrana authored
135 }
136
753909e @vrana Support for virtual foreign keys
authored
137 /** Get foreign keys for table
138 * @param string
139 * @return array same format as foreign_keys()
140 */
141 function foreignKeys($table) {
142 return foreign_keys($table);
143 }
144
c64c4fd Adminer class
jakubvrana authored
145 /** Find backward keys for table
146 * @param string
09e93de Move backward keys to Editor
jakubvrana authored
147 * @param string
148 * @return array $return[$target_table]["keys"][$key_name][$target_column] = $source_column; $return[$target_table]["name"] = $this->tableName($target_table);
c64c4fd Adminer class
jakubvrana authored
149 */
09e93de Move backward keys to Editor
jakubvrana authored
150 function backwardKeys($table, $tableName) {
c64c4fd Adminer class
jakubvrana authored
151 return array();
152 }
153
09e93de Move backward keys to Editor
jakubvrana authored
154 /** Print backward keys for row
155 * @param array result of $this->backwardKeys()
156 * @param array
157 * @return null
158 */
159 function backwardKeysPrint($backwardKeys, $row) {
160 }
161
c64c4fd Adminer class
jakubvrana authored
162 /** Query printed in select before execution
163 * @param string query to be executed
164 * @return string
165 */
166 function selectQuery($query) {
e672694 @vrana Rename $driver to $jush
authored
167 global $jush;
931f7ef @vrana Fix inline edit in IE9
authored
168 return "<p><a href='" . h(remove_from_uri("page")) . "&amp;page=last' title='" . lang('Last page') . "'>&gt;&gt;</a> <code class='jush-$jush'>" . h(str_replace("\n", " ", $query)) . "</code> <a href='" . h(ME) . "sql=" . urlencode($query) . "'>" . lang('Edit') . "</a></p>\n"; // </p> - required for IE9 inline edit
c64c4fd Adminer class
jakubvrana authored
169 }
170
171 /** Description of a row in a table
172 * @param string
173 * @return string SQL expression, empty string for no description
174 */
175 function rowDescription($table) {
176 return "";
177 }
178
179 /** Get descriptions of selected data
180 * @param array all data to print
181 * @param array
182 * @return array
183 */
184 function rowDescriptions($rows, $foreignKeys) {
185 return $rows;
186 }
187
188 /** Value printed in select table
a0def47 Date localization
jakubvrana authored
189 * @param string HTML-escaped value to print
c64c4fd Adminer class
jakubvrana authored
190 * @param string link to foreign key
191 * @param array single field returned from fields()
192 * @return string
193 */
194 function selectVal($val, $link, $field) {
c4a5724 @vrana Simplify work with NULL values in select
authored
195 $return = ($val === null ? "<i>NULL</i>" : (ereg("char|binary", $field["type"]) && !ereg("var", $field["type"]) ? "<code>$val</code>" : $val));
5a73c01 @vrana Treat binary type as hex
authored
196 if (ereg('blob|bytea|raw|file', $field["type"]) && !is_utf8($val)) {
c4a5724 @vrana Simplify work with NULL values in select
authored
197 $return = lang('%d byte(s)', strlen($val));
4921235 Hide edit functions in Editor
jakubvrana authored
198 }
12c042c Function htmlspecialchars now uses ENT_QUOTES
jakubvrana authored
199 return ($link ? "<a href='$link'>$return</a>" : $return);
c64c4fd Adminer class
jakubvrana authored
200 }
201
a0def47 Date localization
jakubvrana authored
202 /** Value conversion used in select and edit
203 * @param string
204 * @param array single field returned from fields()
2011428 Use LIKE operator in Editor
jakubvrana authored
205 * @return string
a0def47 Date localization
jakubvrana authored
206 */
207 function editVal($val, $field) {
5a73c01 @vrana Treat binary type as hex
authored
208 return (ereg("binary", $field["type"]) ? reset(unpack("H*", $val)) : $val);
a0def47 Date localization
jakubvrana authored
209 }
210
d24ad78 Select boxes customization
jakubvrana authored
211 /** Print columns box in select
d2c513d @vrana Column names customization (bug #3194500)
authored
212 * @param array result of selectColumnsProcess()[0]
d24ad78 Select boxes customization
jakubvrana authored
213 * @param array selectable columns
214 * @return null
215 */
216 function selectColumnsPrint($select, $columns) {
3f5b683 Reintegrate sqlite branch
jakubvrana authored
217 global $functions, $grouping;
dc667ea Hide select export and import
jakubvrana authored
218 print_fieldset("select", lang('Select'), $select);
d24ad78 Select boxes customization
jakubvrana authored
219 $i = 0;
3f5b683 Reintegrate sqlite branch
jakubvrana authored
220 $fun_group = array(lang('Functions') => $functions, lang('Aggregation') => $grouping);
d24ad78 Select boxes customization
jakubvrana authored
221 foreach ($select as $key => $val) {
222 $val = $_GET["columns"][$key];
0698409 Utilize html_select
jakubvrana authored
223 echo "<div>" . html_select("columns[$i][fun]", array(-1 => "") + $fun_group, $val["fun"]);
5583109 @vrana Warn about grouping data without index
authored
224 echo "(<select name='columns[$i][col]' onchange='selectFieldChange(this.form);'><option>" . optionlist($columns, $val["col"], true) . "</select>)</div>\n";
d24ad78 Select boxes customization
jakubvrana authored
225 $i++;
226 }
3f5b683 Reintegrate sqlite branch
jakubvrana authored
227 echo "<div>" . html_select("columns[$i][fun]", array(-1 => "") + $fun_group, "", "this.nextSibling.nextSibling.onchange();");
228 echo "(<select name='columns[$i][col]' onchange='selectAddRow(this);'><option>" . optionlist($columns, null, true) . "</select>)</div>\n";
d24ad78 Select boxes customization
jakubvrana authored
229 echo "</div></fieldset>\n";
230 }
231
232 /** Print search box in select
233 * @param array result of selectSearchProcess()
234 * @param array selectable columns
235 * @param array
236 * @return null
237 */
238 function selectSearchPrint($where, $columns, $indexes) {
dc667ea Hide select export and import
jakubvrana authored
239 print_fieldset("search", lang('Search'), $where);
d24ad78 Select boxes customization
jakubvrana authored
240 foreach ($indexes as $i => $index) {
241 if ($index["type"] == "FULLTEXT") {
689699a Shortcut for htmlspecialchars
jakubvrana authored
242 echo "(<i>" . implode("</i>, <i>", array_map('h', $index["columns"])) . "</i>) AGAINST";
739bcb0 @vrana Warn about selecting data without index
authored
243 echo " <input name='fulltext[$i]' value='" . h($_GET["fulltext"][$i]) . "' onchange='selectFieldChange(this.form);'>";
6b30cfa Separate checkbox
jakubvrana authored
244 echo checkbox("boolean[$i]", 1, isset($_GET["boolean"][$i]), "BOOL");
d24ad78 Select boxes customization
jakubvrana authored
245 echo "<br>\n";
246 }
247 }
739bcb0 @vrana Warn about selecting data without index
authored
248 $_GET["where"] = (array) $_GET["where"];
249 reset($_GET["where"]);
250 $change_next = "this.nextSibling.onchange();";
251 for ($i = 0; $i <= count($_GET["where"]); $i++) {
252 list(, $val) = each($_GET["where"]);
253 if (!$val || ("$val[col]$val[val]" != "" && in_array($val["op"], $this->operators))) {
254 echo "<div><select name='where[$i][col]' onchange='$change_next'><option value=''>(" . lang('anywhere') . ")" . optionlist($columns, $val["col"], true) . "</select>";
255 echo html_select("where[$i][op]", $this->operators, $val["op"], $change_next);
256 echo "<input name='where[$i][val]' value='" . h($val["val"]) . "' onchange='" . ($val ? "selectFieldChange(this.form)" : "selectAddRow(this)") . ";'></div>\n";
d24ad78 Select boxes customization
jakubvrana authored
257 }
258 }
259 echo "</div></fieldset>\n";
260 }
261
262 /** Print order box in select
263 * @param array result of selectOrderProcess()
264 * @param array selectable columns
265 * @param array
266 * @return null
267 */
268 function selectOrderPrint($order, $columns, $indexes) {
dc667ea Hide select export and import
jakubvrana authored
269 print_fieldset("sort", lang('Sort'), $order);
d24ad78 Select boxes customization
jakubvrana authored
270 $i = 0;
271 foreach ((array) $_GET["order"] as $key => $val) {
272 if (isset($columns[$val])) {
739bcb0 @vrana Warn about selecting data without index
authored
273 echo "<div><select name='order[$i]' onchange='selectFieldChange(this.form);'><option>" . optionlist($columns, $val, true) . "</select>";
6b30cfa Separate checkbox
jakubvrana authored
274 echo checkbox("desc[$i]", 1, isset($_GET["desc"][$key]), lang('descending')) . "</div>\n";
d24ad78 Select boxes customization
jakubvrana authored
275 $i++;
276 }
277 }
3c5c0f0 Use camelCase in JavaScript
jakubvrana authored
278 echo "<div><select name='order[$i]' onchange='selectAddRow(this);'><option>" . optionlist($columns, null, true) . "</select>";
e25e780 @vrana DESC labels (bug #3192356)
authored
279 echo "<label><input type='checkbox' name='desc[$i]' value='1'>" . lang('descending') . "</label></div>\n"; // not checkbox() to allow selectAddRow()
d24ad78 Select boxes customization
jakubvrana authored
280 echo "</div></fieldset>\n";
281 }
282
283 /** Print limit box in select
284 * @param string result of selectLimitProcess()
285 * @return null
286 */
287 function selectLimitPrint($limit) {
288 echo "<fieldset><legend>" . lang('Limit') . "</legend><div>"; // <div> for easy styling
ac668d1 @vrana Treat queries with no limit as full table scans
authored
289 echo "<input name='limit' size='3' value='" . h($limit) . "' onchange='selectFieldChange(this.form);'>";
d24ad78 Select boxes customization
jakubvrana authored
290 echo "</div></fieldset>\n";
291 }
292
293 /** Print text length box in select
294 * @param string result of selectLengthProcess()
295 * @return null
296 */
297 function selectLengthPrint($text_length) {
6591d48 @vrana Replace isset($var) by $var !== null
authored
298 if ($text_length !== null) {
d24ad78 Select boxes customization
jakubvrana authored
299 echo "<fieldset><legend>" . lang('Text length') . "</legend><div>";
689699a Shortcut for htmlspecialchars
jakubvrana authored
300 echo '<input name="text_length" size="3" value="' . h($text_length) . '">';
d24ad78 Select boxes customization
jakubvrana authored
301 echo "</div></fieldset>\n";
302 }
303 }
304
305 /** Print action box in select
739bcb0 @vrana Warn about selecting data without index
authored
306 * @param array
d24ad78 Select boxes customization
jakubvrana authored
307 * @return null
308 */
739bcb0 @vrana Warn about selecting data without index
authored
309 function selectActionPrint($indexes) {
d24ad78 Select boxes customization
jakubvrana authored
310 echo "<fieldset><legend>" . lang('Action') . "</legend><div>";
311 echo "<input type='submit' value='" . lang('Select') . "'>";
739bcb0 @vrana Warn about selecting data without index
authored
312 echo " <span id='noindex' title='" . lang('Full table scan') . "'></span>";
313 echo "<script type='text/javascript'>\n";
314 echo "var indexColumns = ";
315 $columns = array();
316 foreach ($indexes as $index) {
317 if ($index["type"] != "FULLTEXT") {
318 $columns[reset($index["columns"])] = 1;
319 }
320 }
321 $columns[""] = 1;
322 foreach ($columns as $key => $val) {
323 json_row($key);
324 }
325 echo ";\n";
326 echo "selectFieldChange(document.getElementById('form'));\n";
327 echo "</script>\n";
d24ad78 Select boxes customization
jakubvrana authored
328 echo "</div></fieldset>\n";
329 }
330
e641e5c @vrana Limit commands and import in customization (bug #3194432)
authored
331 /** Print command box in select
332 * @return bool whether to print default commands
333 */
334 function selectCommandPrint() {
335 return !information_schema(DB);
336 }
337
338 /** Print import box in select
339 * @return bool whether to print default import
340 */
341 function selectImportPrint() {
b9eb811 @vrana Hide import in information_schema
authored
342 return !information_schema(DB);
e641e5c @vrana Limit commands and import in customization (bug #3194432)
authored
343 }
344
1a6a73a Rename selectExtra to selectEmail
jakubvrana authored
345 /** Print extra text in the end of a select form
346 * @param array fields holding e-mails
1e55d47 User interface for e-mail {$name}
jakubvrana authored
347 * @param array selectable columns
1a6a73a Rename selectExtra to selectEmail
jakubvrana authored
348 * @return null
349 */
1e55d47 User interface for e-mail {$name}
jakubvrana authored
350 function selectEmailPrint($emailFields, $columns) {
1a6a73a Rename selectExtra to selectEmail
jakubvrana authored
351 }
352
d24ad78 Select boxes customization
jakubvrana authored
353 /** Process columns box in select
354 * @param array selectable columns
1e55d47 User interface for e-mail {$name}
jakubvrana authored
355 * @param array
d24ad78 Select boxes customization
jakubvrana authored
356 * @return array (array(select_expressions), array(group_expressions))
357 */
358 function selectColumnsProcess($columns, $indexes) {
3f5b683 Reintegrate sqlite branch
jakubvrana authored
359 global $functions, $grouping;
d24ad78 Select boxes customization
jakubvrana authored
360 $select = array(); // select expressions, empty for *
361 $group = array(); // expressions without aggregation - will be used for GROUP BY if an aggregation function is used
362 foreach ((array) $_GET["columns"] as $key => $val) {
3f5b683 Reintegrate sqlite branch
jakubvrana authored
363 if ($val["fun"] == "count" || (isset($columns[$val["col"]]) && (!$val["fun"] || in_array($val["fun"], $functions) || in_array($val["fun"], $grouping)))) {
d24ad78 Select boxes customization
jakubvrana authored
364 $select[$key] = apply_sql_function($val["fun"], (isset($columns[$val["col"]]) ? idf_escape($val["col"]) : "*"));
3f5b683 Reintegrate sqlite branch
jakubvrana authored
365 if (!in_array($val["fun"], $grouping)) {
d24ad78 Select boxes customization
jakubvrana authored
366 $group[] = $select[$key];
367 }
368 }
369 }
370 return array($select, $group);
371 }
372
373 /** Process search box in select
374 * @param array
375 * @param array
376 * @return array expressions to join by AND
377 */
07e1ae1 FOUND_ROWS only with GROUP BY
jakubvrana authored
378 function selectSearchProcess($fields, $indexes) {
7e644b4 @vrana Save bytes ($connection->quote shortcut)
authored
379 global $jush;
d24ad78 Select boxes customization
jakubvrana authored
380 $return = array();
381 foreach ($indexes as $i => $index) {
7352c28 Replace strlen() by != ""
jakubvrana authored
382 if ($index["type"] == "FULLTEXT" && $_GET["fulltext"][$i] != "") {
7e644b4 @vrana Save bytes ($connection->quote shortcut)
authored
383 $return[] = "MATCH (" . implode(", ", array_map('idf_escape', $index["columns"])) . ") AGAINST (" . q($_GET["fulltext"][$i]) . (isset($_GET["boolean"][$i]) ? " IN BOOLEAN MODE" : "") . ")";
d24ad78 Select boxes customization
jakubvrana authored
384 }
385 }
386 foreach ((array) $_GET["where"] as $val) {
7352c28 Replace strlen() by != ""
jakubvrana authored
387 if ("$val[col]$val[val]" != "" && in_array($val["op"], $this->operators)) {
3f5b683 Reintegrate sqlite branch
jakubvrana authored
388 $cond = " $val[op]";
389 if (ereg('IN$', $val["op"])) {
390 $in = process_length($val["val"]);
391 $cond .= " (" . ($in != "" ? $in : "NULL") . ")";
675ac01 @vrana Ability to search by expression in select (bug #3158017)
authored
392 } elseif (!$val["op"]) {
393 $cond .= $val["val"]; // SQL injection
3f5b683 Reintegrate sqlite branch
jakubvrana authored
394 } elseif ($val["op"] == "LIKE %%") {
395 $cond = " LIKE " . $this->processInput($fields[$val["col"]], "%$val[val]%");
396 } elseif (!ereg('NULL$', $val["op"])) {
397 $cond .= " " . $this->processInput($fields[$val["col"]], $val["val"]);
398 }
7352c28 Replace strlen() by != ""
jakubvrana authored
399 if ($val["col"] != "") {
98b88eb Remove fulltext search without index
jakubvrana authored
400 $return[] = idf_escape($val["col"]) . $cond;
d24ad78 Select boxes customization
jakubvrana authored
401 } else {
98b88eb Remove fulltext search without index
jakubvrana authored
402 // find anywhere
403 $cols = array();
404 foreach ($fields as $name => $field) {
ca32e71 @vrana Ignore bit type when searching strings
authored
405 if (is_numeric($val["val"]) || !ereg('int|float|double|decimal|bit', $field["type"])) {
d79b160 Illegal mix of collations
jakubvrana authored
406 $name = idf_escape($name);
782921b @vrana Finish SQLite
authored
407 $cols[] = ($jush == "sql" && ereg('char|text|enum|set', $field["type"]) && !ereg('^utf8', $field["collation"]) ? "CONVERT($name USING utf8)" : $name);
d24ad78 Select boxes customization
jakubvrana authored
408 }
409 }
d79b160 Illegal mix of collations
jakubvrana authored
410 $return[] = ($cols ? "(" . implode("$cond OR ", $cols) . "$cond)" : "0");
d24ad78 Select boxes customization
jakubvrana authored
411 }
412 }
413 }
414 return $return;
415 }
416
417 /** Process order box in select
418 * @param array
419 * @param array
420 * @return array expressions to join by comma
421 */
07e1ae1 FOUND_ROWS only with GROUP BY
jakubvrana authored
422 function selectOrderProcess($fields, $indexes) {
d24ad78 Select boxes customization
jakubvrana authored
423 $return = array();
424 foreach ((array) $_GET["order"] as $key => $val) {
3f5b683 Reintegrate sqlite branch
jakubvrana authored
425 if (isset($fields[$val]) || preg_match('~^((COUNT\\(DISTINCT |[A-Z0-9_]+\\()(`(?:[^`]|``)+`|"(?:[^"]|"")+")\\)|COUNT\\(\\*\\))$~', $val)) { //! MS SQL uses []
426 $return[] = (isset($fields[$val]) ? idf_escape($val) : $val) . (isset($_GET["desc"][$key]) ? " DESC" : "");
d24ad78 Select boxes customization
jakubvrana authored
427 }
428 }
429 return $return;
430 }
431
432 /** Process limit box in select
433 * @return string expression to use in LIMIT, will be escaped
434 */
435 function selectLimitProcess() {
436 return (isset($_GET["limit"]) ? $_GET["limit"] : "30");
437 }
438
439 /** Process length box in select
440 * @return string number of characters to shorten texts, will be escaped
441 */
442 function selectLengthProcess() {
443 return (isset($_GET["text_length"]) ? $_GET["text_length"] : "100");
444 }
445
c64c4fd Adminer class
jakubvrana authored
446 /** Process extras in select form
447 * @param array AND conditions
dea345c Substitute foreign keys in e-mail fields
jakubvrana authored
448 * @param array
c64c4fd Adminer class
jakubvrana authored
449 * @return bool true if processed, false to process other parts of form
450 */
dea345c Substitute foreign keys in e-mail fields
jakubvrana authored
451 function selectEmailProcess($where, $foreignKeys) {
c64c4fd Adminer class
jakubvrana authored
452 return false;
453 }
454
700a78b @vrana selectQueryBuild() method
authored
455 /** Build SQL query used in select
456 * @param array result of selectColumnsProcess()[0]
457 * @param array result of selectSearchProcess()
458 * @param array result of selectColumnsProcess()[1]
459 * @param array result of selectOrderProcess()
460 * @param int result of selectLimitProcess()
461 * @param int index of page starting at zero
462 * @return string empty string to use default query
463 */
464 function selectQueryBuild($select, $where, $group, $order, $limit, $page) {
465 return "";
466 }
467
c64c4fd Adminer class
jakubvrana authored
468 /** Query printed after execution in the message
469 * @param string executed query
470 * @return string
471 */
472 function messageQuery($query) {
e672694 @vrana Rename $driver to $jush
authored
473 global $jush;
79fa7da @vrana Minimize the chance of displaying message on different page (thanks t…
authored
474 static $count = 0;
be49e08 Improve session restarting
jakubvrana authored
475 restart_session();
79fa7da @vrana Minimize the chance of displaying message on different page (thanks t…
authored
476 $id = "sql-" . ($count++);
49565e0 @vrana Rename variables to avoid conflict with Adminer 2 sessions and enable…
authored
477 $history = &get_session("queries");
24c51fe @vrana Print current time next to executed SQL queries
authored
478 if (strlen($query) > 1e6) {
0bc930c @vrana Avoid big ternary (save memory)
authored
479 $query = ereg_replace('[\x80-\xFF]+$', '', substr($query, 0, 1e6)) . "\n..."; // [\x80-\xFF] - valid UTF-8, \n - can end by one-line comment
480 }
24c51fe @vrana Print current time next to executed SQL queries
authored
481 $history[$_GET["db"]][] = array($query, time()); // not DB - $_GET["db"] is changed in database.inc.php //! respect $_GET["ns"]
482 return " <span class='time'>" . @date("H:i:s") . "</span> <a href='#$id' onclick=\"return !toggle('$id');\">" . lang('SQL command') . "</a><div id='$id' class='hidden'><pre><code class='jush-$jush'>" . shorten_utf8($query, 1000) . '</code></pre><p><a href="' . h(str_replace("db=" . urlencode(DB), "db=" . urlencode($_GET["db"]), ME) . 'sql=&history=' . (count($history[$_GET["db"]]) - 1)) . '">' . lang('Edit') . '</a></div>'; // @ - time zone may be not set
c64c4fd Adminer class
jakubvrana authored
483 }
484
485 /** Functions displayed in edit form
486 * @param array single field from fields()
487 * @return array
488 */
489 function editFunctions($field) {
3f5b683 Reintegrate sqlite branch
jakubvrana authored
490 global $edit_functions;
02f7521 Fix input onchange
jakubvrana authored
491 $return = ($field["null"] ? "NULL/" : "");
3f5b683 Reintegrate sqlite branch
jakubvrana authored
492 foreach ($edit_functions as $key => $functions) {
493 if (!$key || (!isset($_GET["call"]) && (isset($_GET["select"]) || where($_GET)))) { // relative functions
494 foreach ($functions as $pattern => $val) {
495 if (!$pattern || ereg($pattern, $field["type"])) {
496 $return .= "/$val";
497 }
498 }
2671a47 @vrana No edit expression with set and binary
authored
499 if ($key && !ereg('set|blob|bytea|raw|file', $field["type"])) {
327b56b @vrana Ability to save expression in edit
authored
500 $return .= "/=";
501 }
309f681 Relative function concat
jakubvrana authored
502 }
4921235 Hide edit functions in Editor
jakubvrana authored
503 }
3f5b683 Reintegrate sqlite branch
jakubvrana authored
504 return explode("/", $return);
4921235 Hide edit functions in Editor
jakubvrana authored
505 }
c64c4fd Adminer class
jakubvrana authored
506
507 /** Get options to display edit field
508 * @param string table name
509 * @param array single field from fields()
e1abcda Treat tinyint(1) as boolean
jakubvrana authored
510 * @param string attributes to use inside the tag
511 * @param string
512 * @return string custom input field or empty string for default
c64c4fd Adminer class
jakubvrana authored
513 */
e1abcda Treat tinyint(1) as boolean
jakubvrana authored
514 function editInput($table, $field, $attrs, $value) {
ec0282b Enum editing
jakubvrana authored
515 if ($field["type"] == "enum") {
fe06908 @vrana Allow redefining editInput for enum (bug #3048711)
authored
516 return (isset($_GET["select"]) ? "<label><input type='radio'$attrs value='-1' checked><i>" . lang('original') . "</i></label> " : "")
6591d48 @vrana Replace isset($var) by $var !== null
authored
517 . ($field["null"] ? "<label><input type='radio'$attrs value=''" . ($value !== null || isset($_GET["select"]) ? "" : " checked") . "><i>NULL</i></label> " : "")
684e70d @vrana Search for empty enum
authored
518 . enum_input("radio", $attrs, $field, $value, 0) // 0 - empty
ec0282b Enum editing
jakubvrana authored
519 ;
520 }
521 return "";
4921235 Hide edit functions in Editor
jakubvrana authored
522 }
c64c4fd Adminer class
jakubvrana authored
523
524 /** Process sent input
525 * @param array single field from fields()
a0def47 Date localization
jakubvrana authored
526 * @param string
527 * @param string
c64c4fd Adminer class
jakubvrana authored
528 * @return string expression to use in a query
529 */
a0def47 Date localization
jakubvrana authored
530 function processInput($field, $value, $function = "") {
327b56b @vrana Ability to save expression in edit
authored
531 if ($function == "=") {
532 return $value; // SQL injection
533 }
a0def47 Date localization
jakubvrana authored
534 $name = $field["field"];
4ff2f03 @vrana Alter bit type default value
authored
535 $return = ($field["type"] == "bit" && ereg("^([0-9]+|b'[0-1]+')\$", $value) ? $value : q($value));
3f5b683 Reintegrate sqlite branch
jakubvrana authored
536 if (ereg('^(now|getdate|uuid)$', $function)) {
c64c4fd Adminer class
jakubvrana authored
537 $return = "$function()";
e4df0c6 @vrana MS SQL functions
authored
538 } elseif (ereg('^current_(date|timestamp)$', $function)) {
539 $return = $function;
3f5b683 Reintegrate sqlite branch
jakubvrana authored
540 } elseif (ereg('^([+-]|\\|\\|)$', $function)) {
c64c4fd Adminer class
jakubvrana authored
541 $return = idf_escape($name) . " $function $return";
542 } elseif (ereg('^[+-] interval$', $function)) {
5002b89 @vrana Big numbers without E
authored
543 $return = idf_escape($name) . " $function " . (preg_match("~^(\\d+|'[0-9.: -]') [A-Z_]+$~i", $value) ? $value : $return);
309f681 Relative function concat
jakubvrana authored
544 } elseif (ereg('^(addtime|subtime|concat)$', $function)) {
c64c4fd Adminer class
jakubvrana authored
545 $return = "$function(" . idf_escape($name) . ", $return)";
31a608e @vrana MySQL: Unsupport hex function
authored
546 } elseif (ereg('^(md5|sha1|password|encrypt)$', $function)) {
c64c4fd Adminer class
jakubvrana authored
547 $return = "$function($return)";
548 }
5a73c01 @vrana Treat binary type as hex
authored
549 if (ereg("binary", $field["type"])) {
550 $return = "unhex($return)";
551 }
c64c4fd Adminer class
jakubvrana authored
552 return $return;
a78c941 Empty value in Editor as NULL
jakubvrana authored
553 }
c64c4fd Adminer class
jakubvrana authored
554
e40612a Use radio in export
jakubvrana authored
555 /** Returns export output options
be3410f @vrana Simplify dumpOutput, dumpFormat and dumpData methods
authored
556 * @return array
e40612a Use radio in export
jakubvrana authored
557 */
be3410f @vrana Simplify dumpOutput, dumpFormat and dumpData methods
authored
558 function dumpOutput() {
e40612a Use radio in export
jakubvrana authored
559 $return = array('text' => lang('open'), 'file' => lang('save'));
560 if (function_exists('gzencode')) {
561 $return['gz'] = 'gzip';
562 }
563 if (function_exists('bzcompress')) {
564 $return['bz2'] = 'bzip2';
565 }
566 // ZipArchive requires temporary file, ZIP can be created by gzcompress - see PEAR File_Archive
be3410f @vrana Simplify dumpOutput, dumpFormat and dumpData methods
authored
567 return $return;
e40612a Use radio in export
jakubvrana authored
568 }
569
570 /** Returns export format options
1e70b74 @vrana Ability to disable export
authored
571 * @return array empty to disable export
e40612a Use radio in export
jakubvrana authored
572 */
be3410f @vrana Simplify dumpOutput, dumpFormat and dumpData methods
authored
573 function dumpFormat() {
e225d22 @vrana TSV export and import (bug #3097657)
authored
574 return array('sql' => 'SQL', 'csv' => 'CSV,', 'csv;' => 'CSV;', 'tsv' => 'TSV');
e40612a Use radio in export
jakubvrana authored
575 }
576
095d472 @vrana Customizable export
authored
577 /** Export table structure
578 * @param string
579 * @param string
580 * @param bool
581 * @return null prints data
582 */
583 function dumpTable($table, $style, $is_view = false) {
584 if ($_POST["format"] != "sql") {
585 echo "\xef\xbb\xbf"; // UTF-8 byte order mark
586 if ($style) {
587 dump_csv(array_keys(fields($table)));
588 }
589 } elseif ($style) {
590 $create = create_sql($table, $_POST["auto_increment"]);
591 if ($create) {
592 if ($style == "DROP+CREATE") {
593 echo "DROP " . ($is_view ? "VIEW" : "TABLE") . " IF EXISTS " . table($table) . ";\n";
594 }
595 if ($is_view) {
a4e38a2 @vrana Remove definer from routine and event
authored
596 $create = remove_definer($create);
095d472 @vrana Customizable export
authored
597 }
598 echo ($style != "CREATE+ALTER" ? $create : ($is_view ? substr_replace($create, " OR REPLACE", 6, 0) : substr_replace($create, " IF NOT EXISTS", 12, 0))) . ";\n\n";
599 }
600 if ($style == "CREATE+ALTER" && !$is_view) {
601 // create procedure which iterates over original columns and adds new and removes old
602 $query = "SELECT COLUMN_NAME, COLUMN_DEFAULT, IS_NULLABLE, COLLATION_NAME, COLUMN_TYPE, EXTRA, COLUMN_COMMENT FROM information_schema.COLUMNS WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = " . q($table) . " ORDER BY ORDINAL_POSITION";
603 echo "DELIMITER ;;
604 CREATE PROCEDURE adminer_alter (INOUT alter_command text) BEGIN
605 DECLARE _column_name, _collation_name, after varchar(64) DEFAULT '';
606 DECLARE _column_type, _column_default text;
607 DECLARE _is_nullable char(3);
608 DECLARE _extra varchar(30);
609 DECLARE _column_comment varchar(255);
610 DECLARE done, set_after bool DEFAULT 0;
611 DECLARE add_columns text DEFAULT '";
612 $fields = array();
613 $after = "";
614 foreach (get_rows($query) as $row) {
615 $default = $row["COLUMN_DEFAULT"];
6591d48 @vrana Replace isset($var) by $var !== null
authored
616 $row["default"] = ($default !== null ? q($default) : "NULL");
095d472 @vrana Customizable export
authored
617 $row["after"] = q($after); //! rgt AFTER lft, lft AFTER id doesn't work
618 $row["alter"] = escape_string(idf_escape($row["COLUMN_NAME"])
619 . " $row[COLUMN_TYPE]"
620 . ($row["COLLATION_NAME"] ? " COLLATE $row[COLLATION_NAME]" : "")
6591d48 @vrana Replace isset($var) by $var !== null
authored
621 . ($default !== null ? " DEFAULT " . ($default == "CURRENT_TIMESTAMP" ? $default : $row["default"]) : "")
095d472 @vrana Customizable export
authored
622 . ($row["IS_NULLABLE"] == "YES" ? "" : " NOT NULL")
623 . ($row["EXTRA"] ? " $row[EXTRA]" : "")
624 . ($row["COLUMN_COMMENT"] ? " COMMENT " . q($row["COLUMN_COMMENT"]) : "")
625 . ($after ? " AFTER " . idf_escape($after) : " FIRST")
626 );
627 echo ", ADD $row[alter]";
628 $fields[] = $row;
629 $after = $row["COLUMN_NAME"];
630 }
631 echo "';
632 DECLARE columns CURSOR FOR $query;
633 DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = 1;
634 SET @alter_table = '';
635 OPEN columns;
636 REPEAT
637 FETCH columns INTO _column_name, _column_default, _is_nullable, _collation_name, _column_type, _extra, _column_comment;
638 IF NOT done THEN
639 SET set_after = 1;
640 CASE _column_name";
641 foreach ($fields as $row) {
642 echo "
643 WHEN " . q($row["COLUMN_NAME"]) . " THEN
1c1537b @vrana Fix ALTER export: add columns together with modify
authored
644 SET add_columns = REPLACE(add_columns, ', ADD $row[alter]', IF(
645 _column_default <=> $row[default] AND _is_nullable = '$row[IS_NULLABLE]' AND _collation_name <=> " . (isset($row["COLLATION_NAME"]) ? "'$row[COLLATION_NAME]'" : "NULL") . " AND _column_type = " . q($row["COLUMN_TYPE"]) . " AND _extra = '$row[EXTRA]' AND _column_comment = " . q($row["COLUMN_COMMENT"]) . " AND after = $row[after]
646 , '', ', MODIFY $row[alter]'));"
647 ; //! don't replace in comment
095d472 @vrana Customizable export
authored
648 }
649 echo "
650 ELSE
651 SET @alter_table = CONCAT(@alter_table, ', DROP ', _column_name);
652 SET set_after = 0;
653 END CASE;
654 IF set_after THEN
655 SET after = _column_name;
656 END IF;
657 END IF;
658 UNTIL done END REPEAT;
659 CLOSE columns;
660 IF @alter_table != '' OR add_columns != '' THEN
661 SET alter_command = CONCAT(alter_command, 'ALTER TABLE " . table($table) . "', SUBSTR(CONCAT(add_columns, @alter_table), 2), ';\\n');
662 END IF;
663 END;;
664 DELIMITER ;
665 CALL adminer_alter(@adminer_alter);
666 DROP PROCEDURE adminer_alter;
667
668 ";
669 //! indexes
670 }
671 }
672 }
673
674 /** Export table data
675 * @param string
676 * @param string
be3410f @vrana Simplify dumpOutput, dumpFormat and dumpData methods
authored
677 * @param string
095d472 @vrana Customizable export
authored
678 * @return null prints data
679 */
be3410f @vrana Simplify dumpOutput, dumpFormat and dumpData methods
authored
680 function dumpData($table, $style, $query) {
095d472 @vrana Customizable export
authored
681 global $connection, $jush;
682 $max_packet = ($jush == "sqlite" ? 0 : 1048576); // default, minimum is 1024
683 if ($style) {
684 if ($_POST["format"] == "sql" && $style == "TRUNCATE+INSERT") {
685 echo truncate_sql($table) . ";\n";
686 }
15715b3 @vrana Export SQL command result (bug #3116854)
authored
687 if ($_POST["format"] == "sql") {
688 $fields = fields($table);
689 }
be3410f @vrana Simplify dumpOutput, dumpFormat and dumpData methods
authored
690 $result = $connection->query($query, 1); // 1 - MYSQLI_USE_RESULT //! enum and set as numbers
095d472 @vrana Customizable export
authored
691 if ($result) {
692 $insert = "";
693 $buffer = "";
69d49e3 @vrana Support same name fields in CSV export
authored
694 $keys = array();
3a38156 @vrana Use VALUES() in INSERT+UPDATE export
authored
695 $suffix = "";
69d49e3 @vrana Support same name fields in CSV export
authored
696 while ($row = $result->fetch_row()) {
697 if (!$keys) {
3a38156 @vrana Use VALUES() in INSERT+UPDATE export
authored
698 $values = array();
69d49e3 @vrana Support same name fields in CSV export
authored
699 foreach ($row as $val) {
700 $field = $result->fetch_field();
701 $keys[] = $field->name;
3a38156 @vrana Use VALUES() in INSERT+UPDATE export
authored
702 $key = idf_escape($field->name);
703 $values[] = "$key = VALUES($key)";
69d49e3 @vrana Support same name fields in CSV export
authored
704 }
3a38156 @vrana Use VALUES() in INSERT+UPDATE export
authored
705 $suffix = ($style == "INSERT+UPDATE" ? "\nON DUPLICATE KEY UPDATE " . implode(", ", $values) : "") . ";\n";
69d49e3 @vrana Support same name fields in CSV export
authored
706 }
095d472 @vrana Customizable export
authored
707 if ($_POST["format"] != "sql") {
15715b3 @vrana Export SQL command result (bug #3116854)
authored
708 if ($style == "table") {
69d49e3 @vrana Support same name fields in CSV export
authored
709 dump_csv($keys);
15715b3 @vrana Export SQL command result (bug #3116854)
authored
710 $style = "INSERT";
711 }
095d472 @vrana Customizable export
authored
712 dump_csv($row);
713 } else {
714 if (!$insert) {
69d49e3 @vrana Support same name fields in CSV export
authored
715 $insert = "INSERT INTO " . table($table) . " (" . implode(", ", array_map('idf_escape', $keys)) . ") VALUES";
095d472 @vrana Customizable export
authored
716 }
717 foreach ($row as $key => $val) {
69d49e3 @vrana Support same name fields in CSV export
authored
718 $row[$key] = ($val !== null ? (ereg('int|float|double|decimal|bit', $fields[$keys[$key]]["type"]) ? $val : q($val)) : "NULL"); //! columns looking like functions
095d472 @vrana Customizable export
authored
719 }
3a38156 @vrana Use VALUES() in INSERT+UPDATE export
authored
720 $s = ($max_packet ? "\n" : " ") . "(" . implode(",\t", $row) . ")";
721 if (!$buffer) {
722 $buffer = $insert . $s;
723 } elseif (strlen($buffer) + 4 + strlen($s) + strlen($suffix) < $max_packet) { // 4 - length specification
724 $buffer .= ",$s";
095d472 @vrana Customizable export
authored
725 } else {
3a38156 @vrana Use VALUES() in INSERT+UPDATE export
authored
726 echo $buffer . $suffix;
727 $buffer = $insert . $s;
095d472 @vrana Customizable export
authored
728 }
729 }
730 }
3a38156 @vrana Use VALUES() in INSERT+UPDATE export
authored
731 if ($buffer) {
732 echo $buffer . $suffix;
095d472 @vrana Customizable export
authored
733 }
164cd3b @vrana Report errors in data export
authored
734 } elseif ($_POST["format"] == "sql") {
735 echo "-- " . str_replace("\n", " ", $connection->error) . "\n";
095d472 @vrana Customizable export
authored
736 }
737 }
738 }
739
b78b0cd @vrana Plugin for including date in export filename
authored
740 /** Set export filename
741 * @param string
742 * @return string filename without extension
743 */
744 function dumpFilename($identifier) {
745 return friendly_url($identifier != "" ? $identifier : (SERVER != "" ? SERVER : "localhost"));
746 }
747
095d472 @vrana Customizable export
authored
748 /** Send headers for export
749 * @param string
750 * @param bool
751 * @return string extension
752 */
753 function dumpHeaders($identifier, $multi_table = false) {
754 $output = $_POST["output"];
755 $ext = ($_POST["format"] == "sql" ? "sql" : ($multi_table ? "tar" : "csv")); // multiple CSV packed to TAR
756 header("Content-Type: " .
757 ($output == "bz2" ? "application/x-bzip" :
758 ($output == "gz" ? "application/x-gzip" :
759 ($ext == "tar" ? "application/x-tar" :
760 ($ext == "sql" || $output != "file" ? "text/plain" : "text/csv") . "; charset=utf-8"
761 ))));
8ab6fff @vrana Centralize dump_headers
authored
762 if ($output == "bz2") {
095d472 @vrana Customizable export
authored
763 ob_start('bzcompress', 1e6);
764 }
8ab6fff @vrana Centralize dump_headers
authored
765 if ($output == "gz") {
095d472 @vrana Customizable export
authored
766 ob_start('gzencode', 1e6);
767 }
768 return $ext;
e40612a Use radio in export
jakubvrana authored
769 }
770
7416164 @vrana Homepage customization
authored
771 /** Print homepage
772 * @return bool whether to print default homepage
773 */
774 function homepage() {
775 echo '<p>' . ($_GET["ns"] == "" ? '<a href="' . h(ME) . 'database=">' . lang('Alter database') . "</a>\n" : "");
98e410f @vrana Move schema link to Adminer::homepage method
authored
776 echo (support("scheme") ? "<a href='" . h(ME) . "scheme='>" . ($_GET["ns"] != "" ? lang('Alter schema') : lang('Create schema')) . "</a>\n" : "");
33c4623 @vrana Hide schema link in homepage with no schema
authored
777 echo ($_GET["ns"] !== "" ? '<a href="' . h(ME) . 'schema=">' . lang('Database schema') . "</a>\n" : "");
16a72b4 @vrana Shortcut for database privileges
authored
778 echo (support("privileges") ? "<a href='" . h(ME) . "privileges='>" . lang('Privileges') . "</a>\n" : "");
7416164 @vrana Homepage customization
authored
779 return true;
780 }
781
c64c4fd Adminer class
jakubvrana authored
782 /** Prints navigation after Adminer title
d49903b @vrana Report invalid schema
authored
783 * @param string can be "auth" if there is no database connection, "db" if there is no database selected, "ns" with invalid schema
c64c4fd Adminer class
jakubvrana authored
784 * @return null
785 */
786 function navigation($missing) {
beafccb @vrana Separate printing databases in customization
authored
787 global $VERSION, $token, $jush, $drivers;
d3227c9 Move <h1> to $adminer->navigation
jakubvrana authored
788 ?>
789 <h1>
3ebfdd3 @vrana Simpler customization of name() link
authored
790 <?php echo $this->name(); ?> <span class="version"><?php echo $VERSION; ?></span>
d3227c9 Move <h1> to $adminer->navigation
jakubvrana authored
791 <a href="http://www.adminer.org/#download" id="version"><?php echo (version_compare($VERSION, $_COOKIE["adminer_version"]) < 0 ? h($_COOKIE["adminer_version"]) : ""); ?></a>
792 </h1>
793 <?php
605b093 @vrana List authentications
authored
794 if ($missing == "auth") {
795 $first = true;
49565e0 @vrana Rename variables to avoid conflict with Adminer 2 sessions and enable…
authored
796 foreach ((array) $_SESSION["pwds"] as $driver => $servers) {
605b093 @vrana List authentications
authored
797 foreach ($servers as $server => $usernames) {
798 foreach ($usernames as $username => $password) {
6591d48 @vrana Replace isset($var) by $var !== null
authored
799 if ($password !== null) {
605b093 @vrana List authentications
authored
800 if ($first) {
5d337fe @vrana Reveal menu items only if mouse is over wide links
authored
801 echo "<p id='logins' onmouseover='menuOver(this, event);' onmouseout='menuOut(this);'>\n";
605b093 @vrana List authentications
authored
802 $first = false;
803 }
a0d00cf @vrana Store database to permanent login
authored
804 $dbs = $_SESSION["db"][$driver][$server][$username];
805 foreach (($dbs ? array_keys($dbs) : array("")) as $db) {
806 echo "<a href='" . h(auth_url($driver, $server, $username, $db)) . "'>($drivers[$driver]) " . h($username . ($server != "" ? "@$server" : "") . ($db != "" ? " - $db" : "")) . "</a><br>\n";
807 }
605b093 @vrana List authentications
authored
808 }
809 }
810 }
811 }
812 } else {
c64c4fd Adminer class
jakubvrana authored
813 ?>
b95f24e Editor: User friendly data editor
jakubvrana authored
814 <form action="" method="post">
fde1171 Add CSS classes (thanks to cvicebni ubor)
jakubvrana authored
815 <p class="logout">
f7d4587 @vrana Hide SQL command link in case of an error
authored
816 <?php
9d47d1e @vrana Whitespace
authored
817 if (DB == "" || !$missing) {
8ad4809 @vrana Use class="active" instead of <b>
authored
818 echo "<a href='" . h(ME) . "sql='" . bold(isset($_GET["sql"])) . ">" . lang('SQL command') . "</a>\n";
9d47d1e @vrana Whitespace
authored
819 if (support("dump")) {
29d7d6c @vrana Modify dump link in AJAX
authored
820 echo "<a href='" . h(ME) . "dump=" . urlencode(isset($_GET["table"]) ? $_GET["table"] : $_GET["select"]) . "' id='dump'" . bold(isset($_GET["dump"])) . ">" . lang('Dump') . "</a>\n";
9d47d1e @vrana Whitespace
authored
821 }
822 }
823 ?>
98bc4fc @vrana Style logout button as link
authored
824 <input type="submit" name="logout" value="<?php echo lang('Logout'); ?>" id="logout">
740ae10 @vrana Don't send incomplete forms
authored
825 <input type="hidden" name="token" value="<?php echo $token; ?>">
d2ba593 Browsers interpret <form><p></form> as <form><p></form></p>
jakubvrana authored
826 </p>
b95f24e Editor: User friendly data editor
jakubvrana authored
827 </form>
828 <?php
beafccb @vrana Separate printing databases in customization
authored
829 $this->databasesPrint($missing);
b783b94 @vrana Don't display tables list on server pages
authored
830 if ($_GET["ns"] !== "" && !$missing && DB != "") {
6a48618 @vrana Autodisplay long table names in tables list
authored
831 echo '<p><a href="' . h(ME) . 'create="' . bold($_GET["create"] === "") . ">" . lang('Create new table') . "</a>\n";
832 $tables = tables_list();
833 if (!$tables) {
834 echo "<p class='message'>" . lang('No tables.') . "\n";
835 } else {
836 $this->tablesPrint($tables);
837 $links = array();
838 foreach ($tables as $table => $type) {
839 $links[] = preg_quote($table, '/');
840 }
841 echo "<script type='text/javascript'>\n";
842 echo "var jushLinks = { $jush: [ '" . js_escape(ME) . "table=\$&', /\\b(" . implode("|", $links) . ")\\b/g ] };\n";
843 foreach (array("bac", "bra", "sqlite_quo", "mssql_bra") as $val) {
844 echo "jushLinks.$val = jushLinks.$jush;\n";
845 }
846 echo "</script>\n";
847 }
848 }
d3227c9 Move <h1> to $adminer->navigation
jakubvrana authored
849 }
850 }
851
beafccb @vrana Separate printing databases in customization
authored
852 /** Prints databases list in menu
853 * @param string
854 * @return null
855 */
856 function databasesPrint($missing) {
857 global $connection;
858 $databases = $this->databases();
859 ?>
860 <form action="">
861 <p id="dbs">
862 <?php hidden_fields_get(); ?>
863 <?php echo ($databases ? html_select("db", array("" => "(" . lang('database') . ")") + $databases, DB, "this.form.submit();") : '<input name="db" value="' . h(DB) . '">'); ?>
864 <input type="submit" value="<?php echo lang('Use'); ?>"<?php echo ($databases ? " class='hidden'" : ""); ?>>
865 <?php
866 if ($missing != "db" && DB != "" && $connection->select_db(DB)) {
867 if (support("scheme")) {
868 echo "<br>" . html_select("ns", array("" => "(" . lang('schema') . ")") + schemas(), $_GET["ns"], "this.form.submit();");
869 if ($_GET["ns"] != "") {
870 set_schema($_GET["ns"]);
871 }
872 }
873 }
874 echo (isset($_GET["sql"]) ? '<input type="hidden" name="sql" value="">'
875 : (isset($_GET["schema"]) ? '<input type="hidden" name="schema" value="">'
876 : (isset($_GET["dump"]) ? '<input type="hidden" name="dump" value="">'
877 : "")));
878 echo "</p></form>\n";
879 }
880
d3227c9 Move <h1> to $adminer->navigation
jakubvrana authored
881 /** Prints table list in menu
df0c4bb Simplify tablesPrint
jakubvrana authored
882 * @param array
d3227c9 Move <h1> to $adminer->navigation
jakubvrana authored
883 * @return null
884 */
df0c4bb Simplify tablesPrint
jakubvrana authored
885 function tablesPrint($tables) {
5d337fe @vrana Reveal menu items only if mouse is over wide links
authored
886 echo "<p id='tables' onmouseover='menuOver(this, event);' onmouseout='menuOut(this);'>\n";
3f5b683 Reintegrate sqlite branch
jakubvrana authored
887 foreach ($tables as $table => $type) {
8ad4809 @vrana Use class="active" instead of <b>
authored
888 echo '<a href="' . h(ME) . 'select=' . urlencode($table) . '"' . bold($_GET["select"] == $table) . ">" . lang('select') . "</a> ";
b92fe58 @vrana Titles of links in navigation
authored
889 echo '<a href="' . h(ME) . 'table=' . urlencode($table) . '"' . bold($_GET["table"] == $table) . " title='" . lang('Show structure') . "'>" . $this->tableName(array("Name" => $table)) . "</a><br>\n"; //! Adminer::tableName may work with full table status
b95f24e Editor: User friendly data editor
jakubvrana authored
890 }
891 }
c64c4fd Adminer class
jakubvrana authored
892
2c445a8 Extensibility basics
jakubvrana authored
893 }
464d84a Define functions unconditionally
jakubvrana authored
894
895 $adminer = (function_exists('adminer_object') ? adminer_object() : new Adminer);
6591d48 @vrana Replace isset($var) by $var !== null
authored
896 if ($adminer->operators === null) {
3f5b683 Reintegrate sqlite branch
jakubvrana authored
897 $adminer->operators = $operators;
898 }
Something went wrong with that request. Please try again.