Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

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