Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

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