Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

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