Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

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