Rev Author Line No. Line
250 kaklik 1 <?php
2 /* $Id: setup.php,v 1.23.2.10.2.4 2006/08/22 17:36:34 lem9 Exp $ */
3 // vim: expandtab sw=4 ts=4 sts=4:
4  
5 // phpMyAdmin setup script by Michal Čihař <michal@cihar.com>
6  
7 // Grab phpMyAdmin version and PMA_dl function
8 define( 'PMA_MINIMUM_COMMON', TRUE );
9 chdir('..');
10 require_once('./libraries/common.lib.php');
11  
12 // Grab configuration defaults
13 // Do not use $PMA_Config, it interferes with the one in $_SESSION
14 // on servers with register_globals enabled
15 $PMA_Config_Setup = new PMA_Config();
16  
17 // Script information
18 $script_info = 'phpMyAdmin ' . $PMA_Config_Setup->get('PMA_VERSION') . ' setup script by Michal Čihař <michal@cihar.com>';
19 $script_version = '$Id: setup.php,v 1.23.2.10.2.4 2006/08/22 17:36:34 lem9 Exp $';
20  
21 // Grab action
22 if (isset($_POST['action'])) {
23 $action = $_POST['action'];
24 } else {
25 $action = '';
26 }
27  
28 if (isset($_POST['configuration']) && $action != 'clear' ) {
29 // Grab previous configuration, if it should not be cleared
30 $configuration = unserialize($_POST['configuration']);
31 } else {
32 // Start with empty configuration
33 $configuration = array();
34 }
35  
36 // We rely on Servers array to exist, so create it here
37 if (!isset($configuration['Servers']) || !is_array($configuration['Servers'])) {
38 $configuration['Servers'] = array();
39 }
40  
41 // Used later
42 $now = gmdate('D, d M Y H:i:s') . ' GMT';
43  
44 // General header for no caching
45 header('Expires: ' . $now); // rfc2616 - Section 14.21
46 header('Last-Modified: ' . $now);
47 header('Cache-Control: no-store, no-cache, must-revalidate, pre-check=0, post-check=0, max-age=0'); // HTTP/1.1
48 header('Pragma: no-cache'); // HTTP/1.0
49  
50 // whether to show html header?
51 if ($action != 'download') {
52  
53 // Define the charset to be used
54 header('Content-Type: text/html; charset=utf-8');
55  
56 // this needs to be echoed otherwise php with short tags complains
57 echo '<?xml version="1.0" encoding="utf-8"?>' . "\n";
58 ?>
59 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
60 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
61 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en" dir="ltr">
62 <head>
63 <link rel="icon" href="../favicon.ico" type="image/x-icon" />
64 <link rel="shortcut icon" href="../favicon.ico" type="image/x-icon" />
65 <title>phpMyAdmin <?php echo $PMA_Config_Setup->get('PMA_VERSION'); ?> setup</title>
66 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
67  
68 <script type="text/javascript" language="javascript">
69 //<![CDATA[
70 // show this window in top frame
71 if (top != self) {
72 window.top.location.href=location;
73 }
74 //]]>
75 </script>
76 <style type="text/css">
77 /* message boxes: warning, error, stolen from original theme */
78 div.notice {
79 color: #000000;
80 background-color: #FFFFDD;
81 }
82 h1.notice,
83 div.notice {
84 margin: 0.5em 0 0.5em 0;
85 border: 0.1em solid #FFD700;
86 background-image: url(../<?php echo $GLOBALS['cfg']['ThemePath']; ?>/original/img/s_notice.png);
87 background-repeat: no-repeat;
88 background-position: 10px 50%;
89 padding: 10px 10px 10px 36px;
90 }
91 div.notice h1 {
92 border-bottom: 0.1em solid #FFD700;
93 font-weight: bold;
94 font-size: large;
95 text-align: left;
96 margin: 0 0 0.2em 0;
97 }
98  
99 div.warning {
100 color: #CC0000;
101 background-color: #FFFFCC;
102 }
103 h1.warning,
104 div.warning {
105 margin: 0.5em 0 0.5em 0;
106 border: 0.1em solid #CC0000;
107 background-image: url(../<?php echo $GLOBALS['cfg']['ThemePath']; ?>/original/img/s_warn.png);
108 background-repeat: no-repeat;
109 background-position: 10px 50%;
110 padding: 10px 10px 10px 36px;
111 }
112 div.warning h1 {
113 border-bottom: 0.1em solid #cc0000;
114 font-weight: bold;
115 text-align: left;
116 font-size: large;
117 margin: 0 0 0.2em 0;
118 }
119  
120 div.error {
121 background-color: #FFFFCC;
122 color: #ff0000;
123 }
124 h1.error,
125 div.error {
126 margin: 0.5em 0 0.5em 0;
127 border: 0.1em solid #ff0000;
128 background-image: url(../<?php echo $GLOBALS['cfg']['ThemePath']; ?>/original/img/s_error.png);
129 background-repeat: no-repeat;
130 background-position: 10px 50%;
131 padding: 10px 10px 10px 36px;
132 }
133 div.error h1 {
134 border-bottom: 0.1em solid #ff0000;
135 font-weight: bold;
136 text-align: left;
137 font-size: large;
138 margin: 0 0 0.2em 0;
139 }
140  
141 fieldset.toolbar form.action {
142 display: block;
143 width: auto;
144 clear: none;
145 float: left;
146 margin: 0;
147 padding: 0;
148 border-right: 1px solid black;
149 }
150 fieldset.toolbar form.action input, fieldset.toolbar form.action select {
151 margin: 0.7em;
152 padding: 0.1em;
153 }
154  
155 fieldset.toolbar {
156 display: block;
157 width: 100%;
158 background-color: #dddddd;
159 padding: 0;
160 }
161 fieldset.optbox {
162 padding: 0;
163 background-color: #FFFFDD;
164 }
165 div.buttons, div.opts, fieldset.optbox p, fieldset.overview div.row {
166 clear: both;
167 padding: 0.5em;
168 margin: 0;
169 background-color: white;
170 }
171 div.opts, fieldset.optbox p, fieldset.overview div.row {
172 border-bottom: 1px dotted black;
173 }
174 fieldset.overview {
175 display: block;
176 width: 100%;
177 padding: 0;
178 }
179 fieldset.optbox p {
180 background-color: #FFFFDD;
181 }
182 div.buttons {
183 background-color: #dddddd;
184 }
185 div.buttons input {
186 margin: 0 1em 0 1em;
187 }
188 div.buttons form {
189 display: inline;
190 margin: 0;
191 padding: 0;
192 }
193 input.save {
194 color: green;
195 font-weight: bolder;
196 }
197 input.cancel {
198 color: red;
199 font-weight: bolder;
200 }
201 div.desc, label.desc, fieldset.overview div.desc {
202 float: left;
203 width: 27em;
204 max-width: 60%;
205 }
206 code:before, code:after {
207 content: '"';
208 }
209 a.doc {
210 margin: 0 1em 0 1em;
211 }
212 a.doc img {
213 border: none;
214 }
215 </style>
216 </head>
217  
218 <body>
219 <h1>phpMyAdmin <?php echo $PMA_Config_Setup->get('PMA_VERSION'); ?> setup</h1>
220 <?php
221 } // end show html header
222  
223 /**
224 * Calculates numerical equivalent of phpMyAdmin version string
225 *
226 * @param string version
227 *
228 * @return mixed FALSE on failure, integer on success
229 */
230 function version_to_int($version) {
231 if (!preg_match('/^(\d+)\.(\d+)\.(\d+)((\.|-(pl|rc|dev|beta|alpha))(\d+)?)?$/', $version, $matches)) {
232 return FALSE;
233 }
234 if (!empty($matches[6])) {
235 switch ($matches[6]) {
236 case 'pl':
237 $added = 60;
238 break;
239 case 'rc':
240 $added = 30;
241 break;
242 case 'beta':
243 $added = 20;
244 break;
245 case 'alpha':
246 $added = 10;
247 break;
248 case 'dev':
249 $added = 0;
250 break;
251 default:
252 message('notice', 'Unknown version part: ' . htmlspecialchars($matches[5]));
253 $added = 0;
254 break;
255 }
256 } else {
257 $added = 50; // for final
258 }
259 if (!empty($matches[7])) {
260 $added = $added + $matches[7];
261 }
262 return $matches[1] * 1000000 + $matches[2] * 10000 + $matches[3] * 100 + $added;
263 }
264  
265 /**
266 * Returns link to documentation of some configuration directive
267 *
268 * @param string confguration directive name
269 *
270 * @return string HTML link to documentation
271 */
272 function get_cfg_doc($anchor) {
273 return '<a href="../Documentation.html#cfg_' . $anchor . '" target="pma_doc" class="doc"><img class="icon" src="../' . $GLOBALS['cfg']['ThemePath'] . '/original/img/b_help.png" width="11" height="11" alt="Documentation" title="Documentation" /></a>';
274 }
275  
276 /**
277 * Displays message
278 *
279 * @param string type of message (notice/warning/error)
280 * @param string text of message
281 * @param title optional title of message
282 *
283 * @return nothing
284 */
285 function message($type, $text, $title = '') {
286 echo '<div class="' . $type . '">' . "\n";
287 if (!empty($title)) {
288 echo '<h1>';
289 echo $title;
290 echo '</h1>' . "\n";
291 }
292 echo $text . "\n";
293 echo '</div>' . "\n";
294 }
295  
296 /**
297 * Creates hidden input required for keeping current configuraion
298 *
299 * @return string HTML with hidden inputs
300 */
301 function get_hidden_cfg() {
302 global $configuration;
303  
304 return '<input type="hidden" name="configuration" value="' . htmlspecialchars(serialize($configuration)) . '" />' . "\n";
305 }
306  
307 /**
308 * Creates form for some action
309 *
310 * @param string action name
311 * @param string form title
312 * @param string optional additional inputs
313 *
314 * @return string HTML with form
315 */
316 function get_action($name, $title, $added = '', $enabled = TRUE) {
317 $ret = '';
318 $ret .= '<form class="action" method="post" action="">';
319 $ret .= '<input type="hidden" name="token" value="' . $_SESSION['PMA_token'] . '" />';
320 $ret .= '<input type="hidden" name="action" value="' . $name . '" />';
321 $ret .= $added;
322 $ret .= '<input type="submit" value="' . $title . '"';
323 if (!$enabled) {
324 $ret .= ' disabled="disabled"';
325 }
326 $ret .= ' />';
327 $ret .= get_hidden_cfg();
328 $ret .= '</form>';
329 $ret .= "\n";
330 return $ret;
331 }
332  
333 /**
334 * Creates form for going to some url
335 *
336 * @param string URL where to go
337 * @param string form title
338 * @param string optional array of parameters
339 *
340 * @return string HTML with form
341 */
342 function get_url_action($url, $title, $params = array()) {
343 $ret = '';
344 $ret .= '<form class="action" method="get" action="' . $url . '" target="_blank">';
345 $ret .= '<input type="hidden" name="token" value="' . $_SESSION['PMA_token'] . '" />';
346 foreach ($params as $key => $val) {
347 $ret .= '<input type="hidden" name="' . $key . '" value="' . $val . '" />';
348 }
349 $ret .= '<input type="submit" value="' . $title . '" />';
350 $ret .= '</form>';
351 $ret .= "\n";
352 return $ret;
353 }
354  
355 /**
356 * Terminates script and ends HTML
357 *
358 * @return nothing
359 */
360 function footer() {
361 echo '</body>';
362 echo '</html>';
363 exit;
364 }
365  
366 /**
367 * Creates string describing server authentication method
368 *
369 * @param array server configuration
370 *
371 * @return string authentication method description
372 */
373 function get_server_auth($val) {
374 global $PMA_Config_Setup;
375  
376 if (isset($val['auth_type'])) {
377 $auth = $val['auth_type'];
378 } else {
379 $auth = $PMA_Config_Setup->default_server['auth_type'];
380 }
381 $ret = $auth;
382 if ($auth == 'config') {
383 if (isset($val['user'])) {
384 $ret .= ':' . $val['user'];
385 } else {
386 $ret .= ':' . $PMA_Config_Setup->default_server['user'];
387 }
388 }
389 return $ret;
390 }
391  
392 /**
393 * Creates nice string with server name
394 *
395 * @param array server configuration
396 * @param int optional server id
397 *
398 * @return string fancy server name
399 */
400 function get_server_name($val, $id = FALSE, $escape = true) {
401 if (!empty($val['verbose'])) {
402 $ret = $val['verbose'];
403 } else {
404 $ret = $val['host'];
405 }
406 $ret .= ' (' . get_server_auth($val) . ')';
407 if ($id !== FALSE) {
408 $ret .= ' [' . ($id + 1) . ']' ;
409 }
410 if ($escape) {
411 return htmlspecialchars($ret);
412 } else {
413 return $ret;
414 }
415 }
416  
417  
418 /**
419 * Exports variable to PHP code, very limited version of var_export
420 *
421 * @param string data to export
422 *
423 * @see var_export
424 *
425 * @return string PHP code containing variable value
426 */
427 function PMA_var_export($input) {
428 $output = '';
429 if (is_null($input)) {
430 $output .= 'NULL';
431 } elseif (is_array($input)) {
432 $output .= "array (\n";
433 foreach($input as $key => $value) {
434 $output .= PMA_var_export($key) . ' => ' . PMA_var_export($value);
435 $output .= ",\n";
436 }
437 $output .= ')';
438 } elseif (is_string($input)) {
439 $output .= '\'' . addslashes($input) . '\'';
440 } elseif (is_int($input) || is_double($input)) {
441 $output .= (string) $input;
442 } elseif (is_bool($input)) {
443 $output .= $input ? 'true' : 'false';
444 } else {
445 die('Unknown type for PMA_var_export: ' . $input);
446 }
447 return $output;
448 }
449  
450 /**
451 * Creates configuration code for one variable
452 *
453 * @param string variable name
454 * @param mixed configuration
455 *
456 * @return string PHP code containing configuration
457 */
458 function get_cfg_val($name, $val) {
459 $ret = '';
460 if (is_array($val)) {
461 $ret .= "\n";
462 foreach ($val as $k => $v) {
463 if (!isset($type)) {
464 if (is_string($k)) {
465 $type = 'string';
466 } elseif (is_int($k)) {
467 $type = 'int';
468 $ret .= $name . " = array(\n";
469 } else {
470 // Something unknown...
471 $ret .= $name. ' = ' . PMA_var_export($val) . ";\n";
472 break;
473 }
474 }
475 if ($type == 'string') {
476 $ret .= get_cfg_val($name . "['$k']", $v);
477 } elseif ($type == 'int') {
478 $ret .= " " . PMA_var_export($v) . ",\n";
479 }
480 }
481 if (!isset($type)) {
482 /* Empty array */
483 $ret .= $name . " = array();\n";
484 } elseif ($type == 'int') {
485 $ret .= ");\n";
486 }
487 $ret .= "\n";
488 unset($type);
489 } else {
490 $ret .= $name . ' = ' . PMA_var_export($val) . ";\n";
491 }
492 return $ret;
493 }
494  
495 /**
496 * Creates configuration PHP code
497 *
498 * @param array configuration
499 *
500 * @return string PHP code containing configuration
501 */
502 function get_cfg_string($cfg) {
503 global $script_info, $script_version, $now;
504  
505 $c = $cfg;
506 $ret = "<?php\n/*\n * Generated configuration file\n * Generated by: $script_info\n * Version: $script_version\n * Date: " . $now . "\n */\n\n";
507  
508 if (count($c['Servers']) > 0) {
509 $ret .= "/* Servers configuration */\n\$i = 0;\n";
510 foreach ($c['Servers'] as $cnt => $srv) {
511 $ret .= "\n/* Server " . strtr(get_server_name($srv, $cnt, false), '*', '-') . " */\n\$i++;\n";
512 foreach ($srv as $key => $val) {
513 $ret .= get_cfg_val("\$cfg['Servers'][\$i]['$key']", $val);
514 }
515 }
516 $ret .= "\n/* End of servers configuration */\n\n";
517 }
518 unset($c['Servers']);
519  
520 foreach ($c as $key => $val) {
521 $ret .= get_cfg_val("\$cfg['$key']", $val);
522 }
523  
524 $ret .= "?>\n";
525 return $ret;
526 }
527  
528 /**
529 * Compresses server configuration to be indexed from 0 and contain no gaps
530 *
531 * @param array configuration
532 *
533 * @return nothing
534 */
535 function compress_servers(&$cfg) {
536 $ns = array();
537 foreach ($cfg['Servers'] as $val) {
538 if (!empty($val['host'])) {
539 $ns[] = $val;
540 }
541 }
542 $cfg['Servers'] = $ns;
543 }
544  
545 /**
546 * Grabs values from POST
547 *
548 * @param string list of values to grab, values are separated by ";",
549 * each can have defined type separated by ":", if no type
550 * is defined, string is assumed. Possible types: bool -
551 * boolean value, serialized - serialized value, int -
552 * integer, tristate - "TRUE"/"FALSE" converted to bool,
553 * other strings are kept.
554 *
555 * @return array array with grabbed values
556 */
557 function grab_values($list)
558 {
559 $a = split(';', $list);
560 $res = array();
561 foreach ($a as $val) {
562 $v = split(':', $val);
563 if (!isset($v[1])) {
564 $v[1] = '';
565 }
566 switch($v[1]) {
567 case 'bool':
568 $res[$v[0]] = isset($_POST[$v[0]]);
569 break;
570 case 'serialized':
571 if (isset($_POST[$v[0]]) && strlen($_POST[$v[0]]) > 0) {
572 $res[$v[0]] = unserialize($_POST[$v[0]]);
573 }
574 break;
575 case 'int':
576 if (isset($_POST[$v[0]]) && strlen($_POST[$v[0]]) > 0) {
577 $res[$v[0]] = (int)$_POST[$v[0]];
578 }
579 break;
580 case 'tristate':
581 if (isset($_POST[$v[0]]) && strlen($_POST[$v[0]]) > 0) {
582 $cur = $_POST[$v[0]];
583 if ($cur == 'TRUE') {
584 $res[$v[0]] = TRUE;
585 } elseif ($cur == 'FALSE') {
586 $res[$v[0]] = FALSE;
587 } else {
588 $res[$v[0]] = $cur;
589 }
590 }
591 break;
592 case 'string':
593 default:
594 if (isset($_POST[$v[0]]) && strlen($_POST[$v[0]]) > 0) {
595 $res[$v[0]] = $_POST[$v[0]];
596 }
597 break;
598 }
599 }
600 return $res;
601 }
602  
603 /**
604 * Displays overview
605 *
606 * @param string title of oveview
607 * @param array list of values to display (each element is array of two
608 * values - name and value)
609 * @param string optional buttons to be displayed
610 *
611 * @return nothing
612 */
613 function show_overview($title, $list, $buttons = '') {
614 echo '<fieldset class="overview">' . "\n";
615 echo '<legend>' . $title . '</legend>' . "\n";
616 foreach ($list as $val) {
617 echo '<div class="row">';
618 echo '<div class="desc">';
619 echo $val[0];
620 echo '</div>';
621 echo '<div class="data">';
622 echo $val[1];
623 echo '</div>';
624 echo '</div>' . "\n";
625 }
626 if (!empty($buttons)) {
627 echo '<div class="buttons">';
628 echo '<div class="desc">Actions:</div>';
629 echo $buttons;
630 echo '</div>' . "\n";
631 }
632 echo '</fieldset>' . "\n";
633 echo "\n";
634 }
635  
636 /**
637 * Displays configuration, fallback defaults are taken from global $PMA_Config_Setup
638 *
639 * @param array list of values to display (each element is array of two or
640 * three values - desription, name and optional type
641 * indicator). Type is determined by type of this parameter,
642 * array means select and array elements are items,
643 * 'password' means password input.
644 * @param string title of configuration
645 * @param string help string for this configuration
646 * @param array optional first level defaults
647 * @param string optional title for save button
648 * @param string optional prefix for documentation links
649 *
650 * @return nothing
651 */
652 function show_config_form($list, $legend, $help, $defaults = array(), $save = '', $prefix = '') {
653 global $PMA_Config_Setup;
654  
655 if (empty($save)) {
656 $save = 'Update';
657 }
658  
659 echo '<fieldset class="optbox">' . "\n";
660 echo '<legend>' . $legend . '</legend>' . "\n";
661 echo '<p>' . $help . '</p>' . "\n";
662 foreach ($list as $val) {
663 echo '<div class="opts">';
664 $type = 'text';
665 if (isset($val[3])) {
666 if (is_array($val[3])) {
667 $type = 'select';
668 } elseif (is_bool($val[3])) {
669 $type = 'check';
670 } elseif ($val[3] == 'password') {
671 $type = 'password';
672 }
673 }
674 switch ($type) {
675 case 'text':
676 case 'password':
677 echo '<label for="text_' . $val[1] . '" class="desc" title="' . $val[2] . '">' . $val[0] . get_cfg_doc($prefix . $val[1]) . '</label>';
678 echo '<input type="' . $type . '" name="' . $val[1] . '" id="text_' . $val[1] . '" title="' . $val[2] . '" size="50"';
679 if (isset($defaults[$val[1]])) {
680 echo ' value="' . htmlspecialchars($defaults[$val[1]]) . '"';
681 } else {
682 echo ' value="' . htmlspecialchars($PMA_Config_Setup->get($val[1])) . '"';
683 }
684 echo ' />';
685 break;
686 case 'check':
687 echo '<input type="checkbox" name="' . $val[1] . '" value="something" id="checkbox_' . $val[1] . '" title="' . $val[2] . '"';
688 if (isset($defaults[$val[1]])) {
689 if ($defaults[$val[1]]) {
690 echo ' checked="checked"';
691 }
692 } else {
693 if ($PMA_Config_Setup->get($val[1])) {
694 echo ' checked="checked"';
695 }
696 }
697 echo ' />';
698 echo '<label for="checkbox_' . $val[1] . '" title="' . $val[2] . '">' . $val[0] . get_cfg_doc($prefix . $val[1]) . '</label>';
699 break;
700 case 'select':
701 echo '<label for="select_' . $val[1] . '" class="desc" title="' . $val[2] . '">' . $val[0] . get_cfg_doc($prefix . $val[1]) . '</label>';
702 echo '<select name="' . $val[1] . '" id="select_' . $val[1] . '" ' . ' title="' . $val[2] . '">';
703 foreach ($val[3] as $opt) {
704 echo '<option value="' . $opt . '"';
705 if (isset($defaults[$val[1]])) {
706 if (is_bool($defaults[$val[1]])) {
707 if (($defaults[$val[1]] && $opt == 'TRUE') || (!$defaults[$val[1]] && $opt == 'FALSE')) {
708 echo ' selected="selected"';
709 }
710 } else {
711 if ($defaults[$val[1]] == $opt) {
712 echo ' selected="selected"';
713 }
714 }
715 } else {
716 $def_val = $PMA_Config_Setup->get($val[1]);
717 if (is_bool($val)) {
718 if (($def_val && $opt == 'TRUE') || (!$def_val && $opt == 'FALSE')) {
719 echo ' selected="selected"';
720 }
721 } else {
722 if ($def_val == $opt) {
723 echo ' selected="selected"';
724 }
725 }
726 unset($def_val);
727 }
728 echo '>' . $opt . '</option>';
729 }
730 echo '</select>';
731 break;
732 }
733 echo '</div>' . "\n";
734 }
735 echo '<div class="buttons">';
736 echo '<div class="desc">Actions:</div>';
737 echo '<input type="submit" name="submit_save" value="' . $save .'" class="save" />';
738 echo '<input type="submit" name="submit_ignore" value="Cancel" class="cancel" />';
739 echo '</div>' . "\n";
740 echo '</fieldset>' . "\n";
741 echo "\n";
742 }
743  
744 /**
745 * Shows security options configuration form
746 *
747 * @param array optional defaults
748 *
749 * @return nothing
750 */
751 function show_security_form($defaults = array()) {
752 ?>
753 <form method="post" action="">
754 <input type="hidden" name="token" value="<?php echo $_SESSION['PMA_token']; ?>" />
755 <input type="hidden" name="action" value="feat_security_real" />
756 <?php
757 echo get_hidden_cfg();
758 show_config_form(array(
759 array('Blowfish secret', 'blowfish_secret', 'Secret passphrase used for encrypting cookies'),
760 array('Force SSL connection', 'ForceSSL', 'Whether to force using secured connection while using phpMyAdmin', FALSE),
761 array('Show phpinfo output', 'ShowPhpInfo', 'Whether to allow users to see phpinfo() output', FALSE),
762 array('Show password change form', 'ShowChgPassword', 'Whether to show form for changing password, this does not limit ability to execute the same command directly', FALSE),
763 array('Allow login to any MySQL server', 'AllowArbitraryServer', 'If enabled user can enter any MySQL server in login form for cookie auth.', FALSE),
764 array('Recall user name', 'LoginCookieRecall', 'Whether to recall user name while using cookie auth.', TRUE),
765 array('Login cookie validity', 'LoginCookieValidity', 'How long is login valid without performing any action.'),
766 ),
767 'Configure security features',
768 'Please note that phpMyAdmin is just a user interface and it\'s features do not limit MySQL.',
769 $defaults);
770 ?>
771 </form>
772 <?php
773 }
774  
775 /**
776 * Shows MySQL manual configuration form
777 *
778 * @param array optional defaults
779 *
780 * @return nothing
781 */
782 function show_manual_form($defaults = array()) {
783 ?>
784 <form method="post" action="">
785 <input type="hidden" name="token" value="<?php echo $_SESSION['PMA_token']; ?>" />
786 <input type="hidden" name="action" value="feat_manual_real" />
787 <?php
788 echo get_hidden_cfg();
789 show_config_form(array(
790 array('Type of MySQL documentation', 'MySQLManualType', 'These types are same as listed on MySQL download page', array('viewable', 'chapters', 'big', 'none')),
791 array('Base URL of MySQL documentation', 'MySQLManualBase', 'Where is MySQL documentation placed, this is usually top level directory.'),
792 ),
793 'Configure MySQL manual links',
794 'If you have local copy of MySQL documentation, you might want to use it in documentation links. Otherwise use <code>viewable</code> type and <code>http://dev.mysql.com/doc/refman</code> as manual base URL.',
795 $defaults);
796 ?>
797 </form>
798 <?php
799 }
800  
801 /**
802 * Shows charset options configuration form
803 *
804 * @param array optional defaults
805 *
806 * @return nothing
807 */
808 function show_charset_form($defaults = array()) {
809 global $PMA_Config_Setup;
810 ?>
811 <form method="post" action="">
812 <input type="hidden" name="token" value="<?php echo $_SESSION['PMA_token']; ?>" />
813 <input type="hidden" name="action" value="feat_charset_real" />
814 <?php
815 echo get_hidden_cfg();
816 show_config_form(array(
817 array('Allow charset conversion', 'AllowAnywhereRecoding', 'If you want to use such functions.', FALSE),
818 array('Default charset', 'DefaultCharset', 'Default charset for conversion.', $PMA_Config_Setup->get('AvailableCharsets')),
819 array('Recoding engine', 'RecodingEngine', 'PHP can contain iconv and/or recode, select which one to use or keep autodetection.', array('auto', 'iconv', 'recode')),
820 array('Extra params for iconv', 'IconvExtraParams', 'Iconv can get some extra parameters for conversion see man iconv_open.'),
821 ),
822 'Configure charset conversions',
823 'phpMyAdmin can perform charset conversions so that you can import and export in any charset you want.',
824 $defaults);
825 ?>
826 </form>
827 <?php
828 }
829  
830 /**
831 * Shows PHP extensions configuration form
832 *
833 * @param array optional defaults
834 *
835 * @return nothing
836 */
837 function show_extensions_form($defaults = array()) {
838 ?>
839 <form method="post" action="">
840 <input type="hidden" name="token" value="<?php echo $_SESSION['PMA_token']; ?>" />
841 <input type="hidden" name="action" value="feat_extensions_real" />
842 <?php
843 echo get_hidden_cfg();
844 show_config_form(array(
845 array('GD 2 is available', 'GD2Available', 'Whether you have GD 2 or newer installed', array('auto', 'yes', 'no')),
846 ),
847 'Configure extensions',
848 'phpMyAdmin can use several extensions, however here are configured only those that didn\'t fit elsewhere. MySQL extension is configured within server, charset conversion one on separate charsets page.',
849 $defaults);
850 ?>
851 </form>
852 <?php
853 }
854  
855 /**
856 * Shows MIME/relation/history configuration form
857 *
858 * @param array optional defaults
859 *
860 * @return nothing
861 */
862 function show_relation_form($defaults = array()) {
863 global $PMA_Config_Setup;
864 ?>
865 <form method="post" action="">
866 <input type="hidden" name="token" value="<?php echo $_SESSION['PMA_token']; ?>" />
867 <input type="hidden" name="action" value="feat_relation_real" />
868 <?php
869 echo get_hidden_cfg();
870 show_config_form(array(
871 array('Permanent query history', 'QueryHistoryDB', 'Store history into database.', FALSE),
872 array('Maximal history size', 'QueryHistoryMax', 'How many queries are kept in history.'),
873 array('Use MIME transformations', 'BrowseMIME', 'Use MIME transformations while browsing.', TRUE),
874 array('PDF default page size', 'PDFDefaultPageSize', 'Default page size for PDF, you can change this while creating page.', $PMA_Config_Setup->get('PDFPageSizes')),
875 ),
876 'Configure MIME/relation/history',
877 'phpMyAdmin can provide additional featrues like MIME transformation, internal relations, permanent history and PDF pages generating. You have to configure database and tables that will store such information on server page. Behaviour of those functions is configured here.',
878 $defaults);
879 ?>
880 </form>
881 <?php
882 }
883  
884 /**
885 * Shows upload/save configuration form
886 *
887 * @param array optional defaults
888 *
889 * @return nothing
890 */
891 function show_upload_form($defaults = array()) {
892 ?>
893 <form method="post" action="">
894 <input type="hidden" name="token" value="<?php echo $_SESSION['PMA_token']; ?>" />
895 <input type="hidden" name="action" value="feat_upload_real" />
896 <?php
897 echo get_hidden_cfg();
898 show_config_form(array(
899 array('Upload directory', 'UploadDir', 'Directory on server where you can upload files for import'),
900 array('Save directory', 'SaveDir', 'Directory where exports can be saved on server'),
901 array('Directory with docSQL', 'docSQLDir', 'Directory on server where you can place docSQL files for import'),
902 ),
903 'Configure upload/save directories',
904 'Enter directories, either absolute path or relative to phpMyAdmin top level directory.',
905 $defaults);
906 ?>
907 </form>
908 <?php
909 }
910  
911 /**
912 * Shows server configuration form
913 *
914 * @param array optional defaults
915 *
916 * @return nothing
917 */
918 function show_server_form($defaults = array(), $number = FALSE) {
919 ?>
920 <form method="post" action="">
921 <input type="hidden" name="token" value="<?php echo $_SESSION['PMA_token']; ?>" />
922 <input type="hidden" name="action" value="addserver_real" />
923 <?php
924 echo get_hidden_cfg();
925 if (!($number === FALSE)) {
926 echo '<input type="hidden" name="server" value="' . $number . '" />';
927 }
928 $hi = array ('bookmarktable', 'relation', 'table_info', 'table_coords', 'pdf_pages', 'column_info', 'history', 'AllowDeny');
929 foreach ($hi as $k) {
930 if (isset($defaults[$k]) && (!is_string($defaults[$k]) || strlen($defaults[$k]) > 0)) {
931 echo '<input type="hidden" name="' . $k . '" value="' . htmlspecialchars(serialize($defaults[$k])) . '" />';
932 }
933 }
934 show_config_form(array(
935 array('Server hostname', 'host', 'Hostname where MySQL server is running'),
936 array('Server port', 'port', 'Port on which MySQL server is listening, leave empty if don\'t know'),
937 array('Server socket', 'socket', 'Socket on which MySQL server is listening, leave empty if don\'t know'),
938 array('Connection type', 'connect_type', 'How to connect to server, keep tcp if don\'t know', array('tcp', 'socket')),
939 array('PHP extension to use', 'extension', 'What PHP extension to use, use mysqli if supported', array('mysql', 'mysqli')),
940 array('Compress connection', 'compress', 'Whether to compress connection to MySQL server', FALSE),
941 array('Authentication type', 'auth_type', 'Authentication method to use', array('cookie', 'http', 'config')),
942 array('User for config auth', 'user', 'Leave empty if not using config auth'),
943 array('Password for config auth', 'password', 'Leave empty if not using config auth', 'password'),
944 array('Only database to show', 'only_db', 'Limit listing of databases in left frame to this one'),
945 array('Verbose name of this server', 'verbose', 'Name to display in server selection'),
946 array('phpMyAdmin control user', 'controluser', 'User which phpMyAdmin can use for various actions'),
947 array('phpMyAdmin control user password', 'controlpass', 'Password for user which phpMyAdmin can use for various actions', 'password'),
948 array('phpMyAdmin database for advanced features', 'pmadb', 'phpMyAdmin will allow much more when you enable this. Table names are filled in automatically.'),
949 ),
950 'Configure server',
951 ($number === FALSE) ? 'Enter new server connection parameters.' : 'Editing server ' . get_server_name($defaults, $number),
952 $defaults, $number === FALSE ? 'Add' : '', 'Servers_');
953 ?>
954 </form>
955 <?php
956 }
957  
958 /**
959 * Shows left frame configuration form
960 *
961 * @param array optional defaults
962 *
963 * @return nothing
964 */
965 function show_left_form($defaults = array()) {
966 ?>
967 <form method="post" action="">
968 <input type="hidden" name="token" value="<?php echo $_SESSION['PMA_token']; ?>" />
969 <input type="hidden" name="action" value="lay_left_real" />
970 <?php
971 echo get_hidden_cfg();
972 show_config_form(array(
973 array('Use light version', 'LeftFrameLight', 'Disable this if you want to see all databases at one time.', TRUE),
974 array('Display databases in tree', 'LeftFrameDBTree', 'Whether to display databases in tree (determined by separator defined lower)', TRUE),
975 array('Databases tree separator', 'LeftFrameDBSeparator', 'String that separates databases into different tree level'),
976 array('Table tree separator', 'LeftFrameTableSeparator', 'String that separates tables into different tree level'),
977 array('Maximum table tree nesting', 'LeftFrameTableLevel', 'Maximum number of childs in table tree'),
978 array('Show logo', 'LeftDisplayLogo', 'Whether to show logo in left frame', TRUE),
979 array('Display servers selection', 'LeftDisplayServers', 'Whether to show server selection in left frame', FALSE),
980 array('Enable pointer highlighting', 'LeftPointerEnable', 'Whether you want to highlight server under mouse', TRUE),
981 ),
982 'Configure left frame',
983 'Choose how do you like left frame.',
984 $defaults);
985 ?>
986 </form>
987 <?php
988 }
989  
990 /**
991 * Shows tabs configuration form
992 *
993 * @param array optional defaults
994 *
995 * @return nothing
996 */
997 function show_tabs_form($defaults = array()) {
998 ?>
999 <form method="post" action="">
1000 <input type="hidden" name="token" value="<?php echo $_SESSION['PMA_token']; ?>" />
1001 <input type="hidden" name="action" value="lay_tabs_real" />
1002 <?php
1003 echo get_hidden_cfg();
1004 show_config_form(array(
1005 array('Default tab for server', 'DefaultTabServer', 'Tab that is displayed when entering server', array('main.php', 'server_databases.php', 'server_status.php', 'server_variables.php', 'server_privileges.php', 'server_processlist.php')),
1006 array('Default tab for database', 'DefaultTabDatabase', 'Tab that is displayed when entering database', array('db_details_structure.php', 'db_details.php', 'db_search.php', 'db_operations.php')),
1007 array('Default tab for table', 'DefaultTabTable', 'Tab that is displayed when entering table', array('tbl_properties_structure.php', 'sql.php', 'tbl_properties.php', 'tbl_select.php', 'tbl_change.php')),
1008 array('Use lighter tabs', 'LightTabs', 'If you want simpler tabs enable this', FALSE),
1009 ),
1010 'Configure tabs',
1011 'Choose how you want tabs to work.',
1012 $defaults);
1013 ?>
1014 </form>
1015 <?php
1016 }
1017  
1018 /**
1019 * Shows icons configuration form
1020 *
1021 * @param array optional defaults
1022 *
1023 * @return nothing
1024 */
1025 function show_icons_form($defaults = array()) {
1026 ?>
1027 <form method="post" action="">
1028 <input type="hidden" name="token" value="<?php echo $_SESSION['PMA_token']; ?>" />
1029 <input type="hidden" name="action" value="lay_icons_real" />
1030 <?php
1031 echo get_hidden_cfg();
1032 show_config_form(array(
1033 array('Icons on errors', 'ErrorIconic', 'Whether to use icons in error messages.', TRUE),
1034 array('Icons on main page', 'MainPageIconic', 'Whether to use icons on main page.', TRUE),
1035 array('Icons as help links', 'ReplaceHelpImg', 'Whether to use icons as help links.', TRUE),
1036 array('Navigation with icons', 'NavigationBarIconic', 'Whether to display navigation (eg. tabs) with icons.', array('TRUE', 'FALSE', 'both')),
1037 array('Properties pages with icons', 'PropertiesIconic', 'Whether to display properties (eg. table lists and structure) with icons.', array('TRUE', 'FALSE', 'both')),
1038 ),
1039 'Configure icons',
1040 'Select whether you prefer text or icons. Both means that text and icons will be displayed.',
1041 $defaults);
1042 ?>
1043 </form>
1044 <?php
1045 }
1046  
1047 /**
1048 * Shows browsing configuration form
1049 *
1050 * @param array optional defaults
1051 *
1052 * @return nothing
1053 */
1054 function show_browse_form($defaults = array()) {
1055 ?>
1056 <form method="post" action="">
1057 <input type="hidden" name="token" value="<?php echo $_SESSION['PMA_token']; ?>" />
1058 <input type="hidden" name="action" value="lay_browse_real" />
1059 <?php
1060 echo get_hidden_cfg();
1061 show_config_form(array(
1062 array('Display of values', 'DefaultDisplay', 'How to list values while browsing', array('horizontal', 'vertical', 'horizontalflipped')),
1063 array('Hightlight pointer', 'BrowsePointerEnable', 'Whether to highlight row under mouse.', TRUE),
1064 array('Use row marker', 'BrowseMarkerEnable', 'Whether to highlight selected row.', TRUE),
1065 array('Action buttons on left', 'ModifyDeleteAtLeft', 'Show action buttons on left side of listing?', TRUE),
1066 array('Action buttons on right', 'ModifyDeleteAtRight', 'Show action buttons on right side of listing?', FALSE),
1067 array('Repeat heading', 'RepeatCells', 'After how many rows heading should be repeated.'),
1068 ),
1069 'Configure browsing',
1070 'Select desired browsing look and feel.',
1071 $defaults);
1072 ?>
1073 </form>
1074 <?php
1075 }
1076  
1077 /**
1078 * Shows editing options configuration form
1079 *
1080 * @param array optional defaults
1081 *
1082 * @return nothing
1083 */
1084 function show_edit_form($defaults = array()) {
1085 ?>
1086 <form method="post" action="">
1087 <input type="hidden" name="token" value="<?php echo $_SESSION['PMA_token']; ?>" />
1088 <input type="hidden" name="action" value="lay_edit_real" />
1089 <?php
1090 echo get_hidden_cfg();
1091 show_config_form(array(
1092 array('Display of properties while editing', 'DefaultPropDisplay', 'How to list properties (table structure or values) while editing', array('horizontal', 'vertical')),
1093 array('Number of inserted rows', 'InsertRows', 'How many rows can be inserted at once'),
1094 array('Move using Ctrl+arrows', 'CtrlArrowsMoving', 'Whether to enable moving using Ctrl+Arrows', TRUE),
1095 array('Autoselect text in textarea', 'TextareaAutoSelect', 'Whether to automatically select text in textarea on focus.', TRUE),
1096 array('Textarea columns', 'TextareaCols', 'Number of columns in textarea while editing TEXT fields'),
1097 array('Textarea rows', 'TextareaRows', 'Number of rows in textarea while editing TEXT fields'),
1098 array('Double textarea for LONGTEXT', 'LongtextDoubleTextarea', 'Whether to double textarea size for LONGTEXT fields', TRUE),
1099 array('Edit CHAR fields in textarea', 'CharEditing', 'Whether to edit CHAR fields in textaread', array('input', 'textarea')),
1100 array('CHAR textarea columns', 'CharTextareaCols', 'Number of columns in textarea while editing CHAR fields (must be enabled above)'),
1101 array('CHAR textarea rows', 'CharTextareaRows', 'Number of rows in textarea while editing CHAR fields (must be enabled above)'),
1102 ),
1103 'Configure editing',
1104 'Select desired editing look and feel.',
1105 $defaults);
1106 ?>
1107 </form>
1108 <?php
1109 }
1110  
1111 /**
1112 * Shows query window configuration form
1113 *
1114 * @param array optional defaults
1115 *
1116 * @return nothing
1117 */
1118 function show_window_form($defaults = array()) {
1119 ?>
1120 <form method="post" action="">
1121 <input type="hidden" name="token" value="<?php echo $_SESSION['PMA_token']; ?>" />
1122 <input type="hidden" name="action" value="lay_window_real" />
1123 <?php
1124 echo get_hidden_cfg();
1125 show_config_form(array(
1126 array('Edit SQL in window', 'EditInWindow', 'Whether edit links will edit in query window.', TRUE),
1127 array('Query window height', 'QueryWindowHeight', 'Height of query window'),
1128 array('Query window width', 'QueryWindowWidth', 'Width of query window'),
1129 array('Default tab', 'QueryWindowDefTab', 'Default tab on query window', array('sql', 'files', 'history', 'full')),
1130 ),
1131 'Configure query window',
1132 'Select desired query window look and feel.',
1133 $defaults);
1134 ?>
1135 </form>
1136 <?php
1137 }
1138  
1139 /**
1140 * Creates selection with servers
1141 *
1142 * @param array configuraion
1143 *
1144 * @return string HTML for server selection
1145 */
1146 function get_server_selection($cfg) {
1147 if (count($cfg['Servers']) == 0) {
1148 return '';
1149 }
1150 $ret = '<select name="server">';
1151 foreach ($cfg['Servers'] as $key => $val) {
1152 $ret .= '<option value="' . $key . '">' . get_server_name($val, $key) . '</option>';
1153 }
1154 $ret .= '</select>';
1155 return $ret;
1156 }
1157  
1158 /**
1159 * Loads configuration from file
1160 *
1161 * @param string filename
1162 *
1163 * @return mixed FALSE on failure, new config array on success
1164 */
1165 function load_config($config_file) {
1166 if ( file_exists( $config_file ) ) {
1167 $success_apply_user_config = FALSE;
1168 $old_error_reporting = error_reporting( 0 );
1169 if ( function_exists( 'file_get_contents' ) ) {
1170 $success_apply_user_config = eval('?>' . trim(file_get_contents($config_file)));
1171 } else {
1172 $success_apply_user_config =
1173 eval('?>' . trim(implode("\n", file($config_file))));
1174 }
1175 error_reporting( $old_error_reporting );
1176 unset( $old_error_reporting );
1177 if ($success_apply_user_config === FALSE) {
1178 message('error', 'Error while parsing configuration file!');
1179 } elseif (!isset($cfg) || count($cfg) == 0) {
1180 message('error', 'Config file seems to contain no configuration!');
1181 } else {
1182 // This must be set
1183 if (!isset($cfg['Servers'])) {
1184 $cfg['Servers'] = array();
1185 }
1186 message('notice', 'Configuration loaded');
1187 compress_servers($cfg);
1188 return $cfg;
1189 }
1190 } else {
1191 message('error', 'Configuration file not found!');
1192 }
1193 return FALSE;
1194 }
1195  
1196 if ($action != 'download') {
1197 // Check whether we can write to configuration
1198 $fail_dir = FALSE;
1199 $fail_dir = $fail_dir || !is_dir('./config/');
1200 $fail_dir = $fail_dir || !is_writable('./config/');
1201 $fail_dir = $fail_dir || (file_exists('./config/config.inc.php') && !is_writable('./config/config.inc.php'));
1202 $config = @fopen('./config/config.inc.php', 'a');
1203 $fail_dir = $fail_dir || ($config === FALSE);
1204 @fclose($config);
1205 }
1206  
1207 /**
1208 * @var boolean whether to show configuration overview
1209 */
1210 $show_info = FALSE;
1211  
1212 // Do the main work depending on selected action
1213 switch ($action) {
1214 case 'download':
1215 header('Content-Type: text/plain');
1216 header('Content-Disposition: attachment; filename="config.inc.php"');
1217  
1218 echo get_cfg_string($configuration);
1219 exit;
1220 break;
1221 case 'display':
1222 echo '<form method="none" action=""><textarea name="config" cols="50" rows="20" id="textconfig" wrap="off">' . "\n";
1223 echo htmlspecialchars(get_cfg_string($configuration));
1224 echo '</textarea></form>' . "\n";
1225 ?>
1226 <script type="text/javascript" language="javascript">
1227 //<![CDATA[
1228 var bodyWidth=null; var bodyHeight=null;
1229 if (document.getElementById('textconfig')) {
1230 bodyWidth = self.innerWidth;
1231 bodyHeight = self.innerHeight;
1232 if(!bodyWidth && !bodyHeight){
1233 if (document.compatMode && document.compatMode == "BackCompat") {
1234 bodyWidth = document.body.clientWidth;
1235 bodyHeight = document.body.clientHeight;
1236 } else if (document.compatMode && document.compatMode == "CSS1Compat") {
1237 bodyWidth = document.documentElement.clientWidth;
1238 bodyHeight = document.documentElement.clientHeight;
1239 }
1240 }
1241 document.getElementById('textconfig').style.width=(bodyWidth-50) + 'px';
1242 document.getElementById('textconfig').style.height=(bodyHeight-100) + 'px';
1243 }
1244 //]]>
1245 </script>
1246 <?php
1247 break;
1248 case 'save':
1249 $config = @fopen('./config/config.inc.php', 'w');
1250 if ($config === FALSE) {
1251 message('error', 'Could not open config file for writing! Bad permissions?');
1252 break;
1253 }
1254 $s = get_cfg_string($configuration);
1255 $r = fwrite($config, $s);
1256 if (!$r || $r != strlen($s)) {
1257 message('error', 'Could not write to config file! Not enough space?');
1258 break;
1259 } else {
1260 message('notice', 'Configuration saved to file config/config.inc.php in phpMyAdmin top level directory, copy it to top level one and delete directory config to use it.', 'File saved');
1261 }
1262 unset($r, $s);
1263 fclose($config);
1264 break;
1265 case 'load':
1266 if ($fail_dir) {
1267 message('error', 'Reading of configuration disabled because of permissions.');
1268 break;
1269 }
1270 $new_cfg = load_config('./config/config.inc.php');
1271 if (!($new_cfg === FALSE)) {
1272 $configuration = $new_cfg;
1273 }
1274 $show_info = TRUE;
1275 break;
1276  
1277 case 'addserver_real':
1278 if (isset($_POST['submit_save'])) {
1279 $new_server = grab_values('host;extension;port;socket;connect_type;compress:bool;controluser;controlpass;auth_type;user;password;only_db;verbose;pmadb;bookmarktable:serialized;relation:serialized;table_info:serialized;table_coords:serialized;pdf_pages:serialized;column_info:serialized;history:serialized;AllowDeny:serialized');
1280 $err = FALSE;
1281 if (empty($new_server['host'])) {
1282 message('error', 'Empty hostname!');
1283 $err = TRUE;
1284 }
1285 if ($new_server['auth_type'] == 'config' && empty($new_server['user'])) {
1286 message('error', 'Empty username while using config authentication method!');
1287 $err = TRUE;
1288 }
1289 if ( isset($new_server['pmadb']) && strlen($new_server['pmadb'])) {
1290 // Just use defaults, should be okay for most users
1291 $pmadb = array();
1292 $pmadb['bookmarktable'] = 'pma_bookmark';
1293 $pmadb['relation'] = 'pma_relation';
1294 $pmadb['table_info'] = 'pma_table_info';
1295 $pmadb['table_coords'] = 'pma_table_coords';
1296 $pmadb['pdf_pages'] = 'pma_pdf_pages';
1297 $pmadb['column_info'] = 'pma_column_info';
1298 $pmadb['history'] = 'pma_history';
1299  
1300 $new_server = array_merge($pmadb, $new_server);
1301 unset($pmadb);
1302 if (empty($new_server['controluser'])) {
1303 message('error', 'Empty phpMyAdmin control user while using pmadb!');
1304 $err = TRUE;
1305 }
1306 if (empty($new_server['controlpass'])) {
1307 message('error', 'Empty phpMyAdmin control user password while using pmadb!');
1308 $err = TRUE;
1309 }
1310 } else {
1311 message('warning', 'You didn\'t set phpMyAdmin database, so you can not use all phpMyAdmin features.');
1312 }
1313 if ($new_server['auth_type'] == 'config') {
1314 message('warning', 'Remember to protect your installation while using config authentication method!');
1315 } else {
1316 // Not needed:
1317 unset($new_server['user']);
1318 unset($new_server['password']);
1319 }
1320 if ($err) {
1321 show_server_form($new_server, isset($_POST['server']) ? $_POST['server'] : FALSE);
1322 } else {
1323 if (isset($_POST['server'])) {
1324 $configuration['Servers'][$_POST['server']] = $new_server;
1325 message('notice', 'Changed server ' . get_server_name($new_server, $_POST['server']));
1326 } else {
1327 $configuration['Servers'][] = $new_server;
1328 message('notice', 'New server added');
1329 }
1330 $show_info = TRUE;
1331 if ($new_server['auth_type'] == 'cookie' && empty($configuration['blowfish_secret'])) {
1332 message('notice', 'You did not have configured blowfish secret and you want to use cookie authentication so I generated blowfish secret for you. It is used to encrypt cookies.', 'Blowfish secret generated');
1333 $configuration['blowfish_secret'] = uniqid('', TRUE);
1334 }
1335 }
1336 unset($new_server);
1337 } else {
1338 $show_info = TRUE;
1339 }
1340 break;
1341 case 'addserver':
1342 if (count($configuration['Servers']) == 0) {
1343 // First server will use defaults as in config.default.php
1344 $defaults = $PMA_Config_Setup->default_server;
1345 unset($defaults['AllowDeny']); // Ignore this for now
1346 } else {
1347 $defaults = array();
1348 }
1349  
1350 // Guess MySQL extension to use, prefer mysqli
1351 if (!function_exists('mysql_get_client_info')) {
1352 PMA_dl('mysql');
1353 }
1354 if (!function_exists('mysqli_get_client_info')) {
1355 PMA_dl('mysqli');
1356 }
1357 if (function_exists('mysqli_get_client_info')) {
1358 $defaults['extension'] = 'mysqli';
1359 } elseif (function_exists('mysql_get_client_info')) {
1360 $defaults['extension'] = 'mysql';
1361 } else {
1362 message('warning', 'Could not load neither mysql nor mysqli extension, you might not be able to use phpMyAdmin!');
1363 }
1364 if (isset($defaults['extension'])) {
1365 message('notice', 'Autodetected MySQL extension to use: ' . $defaults['extension']);
1366 }
1367  
1368 // Display form
1369 show_server_form($defaults);
1370 break;
1371 case 'editserver':
1372 if (!isset($_POST['server'])) {
1373 footer();
1374 }
1375 show_server_form($configuration['Servers'][$_POST['server']], $_POST['server']);
1376 break;
1377 case 'deleteserver':
1378 if (!isset($_POST['server'])) {
1379 footer();
1380 }
1381 message('notice', 'Deleted server ' . get_server_name($configuration['Servers'][$_POST['server']], $_POST['server']));
1382 unset($configuration['Servers'][$_POST['server']]);
1383 compress_servers($configuration);
1384 $show_info = TRUE;
1385 break;
1386 case 'servers':
1387 if (count($configuration['Servers']) == 0) {
1388 message('notice', 'No servers defined, so none can be shown');
1389 } else {
1390 foreach ($configuration['Servers'] as $i => $srv) {
1391 $data = array();
1392 if (!empty($srv['verbose'])) {
1393 $data[] = array('Verbose name', $srv['verbose']);
1394 }
1395 $data[] = array('Host', $srv['host']);
1396 $data[] = array('MySQL extension', isset($srv['extension']) ? $srv['extension'] : $PMA_Config_Setup->default_server['extension']);
1397 $data[] = array('Authentication type', get_server_auth($srv));
1398 $data[] = array('phpMyAdmin advanced features', empty($srv['pmadb']) || empty($srv['controluser']) || empty($srv['controlpass']) ? 'disabled' : 'enabled, db: ' . $srv['pmadb'] . ', user: ' . $srv['controluser']);
1399 $buttons =
1400 get_action('deleteserver', 'Delete', '<input type="hidden" name="server" value="' . $i . '" />') .
1401 get_action('editserver', 'Edit', '<input type="hidden" name="server" value="' . $i . '" />');
1402 show_overview('Server ' . get_server_name($srv, $i), $data, $buttons);
1403 }
1404 }
1405 break;
1406  
1407 case 'feat_upload_real':
1408 if (isset($_POST['submit_save'])) {
1409 $dirs = grab_values('UploadDir;SaveDir;docSQLDir');
1410 $err = FALSE;
1411 if (!empty($dirs['UploadDir']) && !is_dir($dirs['UploadDir'])) {
1412 message('error', 'Upload directory ' . htmlspecialchars($dirs['UploadDir']) . ' does not exist!');
1413 $err = TRUE;
1414 }
1415 if (!empty($dirs['SaveDir']) && !is_dir($dirs['SaveDir'])) {
1416 message('error', 'Save directory ' . htmlspecialchars($dirs['SaveDir']) . ' does not exist!');
1417 $err = TRUE;
1418 }
1419 if (!empty($dirs['docSQLDir']) && !is_dir($dirs['docSQLDir'])) {
1420 message('error', 'docSQL directory ' . htmlspecialchars($dirs['docSQLDir']) . ' does not exist!');
1421 $err = TRUE;
1422 }
1423 if ($err) {
1424 show_upload_form($dirs);
1425 } else {
1426 $configuration = array_merge($configuration, $dirs);
1427 message('notice', 'Configuration changed');
1428 $show_info = TRUE;
1429 }
1430 } else {
1431 $show_info = TRUE;
1432 }
1433 break;
1434 case 'feat_upload':
1435 show_upload_form($configuration);
1436 break;
1437  
1438 case 'feat_security_real':
1439 if (isset($_POST['submit_save'])) {
1440 $vals = grab_values('blowfish_secret;ForceSSL:bool;ShowPhpInfo:bool;ShowChgPassword:bool;AllowArbitraryServer:bool;LoginCookieRecall:book;LoginCookieValidity:int');
1441 $err = FALSE;
1442 if (empty($vals['blowfish_secret'])) {
1443 message('warning', 'Blowfish secret is empty, you will not be able to use cookie authentication.');
1444 }
1445 if ($vals['AllowArbitraryServer']) {
1446 message('warning', 'Arbitrary server connection might be dangerous as it might allow access to internal servers that are not reachable from outside.');
1447 }
1448 if (isset($vals['LoginCookieValidity']) && $vals['LoginCookieValidity'] < 1) {
1449 message('error', 'Invalid cookie validity time');
1450 $err = TRUE;
1451 }
1452 if ($err) {
1453 show_security_form($vals);
1454 } else {
1455 $configuration = array_merge($configuration, $vals);
1456 message('notice', 'Configuration changed');
1457 $show_info = TRUE;
1458 }
1459 } else {
1460 $show_info = TRUE;
1461 }
1462 break;
1463 case 'feat_security':
1464 show_security_form($configuration);
1465 break;
1466  
1467 case 'feat_manual_real':
1468 if (isset($_POST['submit_save'])) {
1469 $vals = grab_values('MySQLManualBase;MySQLManualType');
1470 $err = FALSE;
1471 if ($vals['MySQLManualType'] != 'none' && empty($vals['MySQLManualBase'])) {
1472 message('error', 'You need to set manual base URL or choone none type.');
1473 $err = TRUE;
1474 }
1475 if ($err) {
1476 show_manual_form($vals);
1477 } else {
1478 $configuration = array_merge($configuration, $vals);
1479 message('notice', 'Configuration changed');
1480 $show_info = TRUE;
1481 }
1482 } else {
1483 $show_info = TRUE;
1484 }
1485 break;
1486 case 'feat_manual':
1487 show_manual_form($configuration);
1488 break;
1489  
1490 case 'feat_charset_real':
1491 if (isset($_POST['submit_save'])) {
1492 $vals = grab_values('AllowAnywhereRecoding:bool;DefaultCharset;RecodingEngine;IconvExtraParams');
1493 $err = FALSE;
1494 if ($err) {
1495 show_charset_form($vals);
1496 } else {
1497 $configuration = array_merge($configuration, $vals);
1498 message('notice', 'Configuration changed');
1499 $show_info = TRUE;
1500 }
1501 } else {
1502 $show_info = TRUE;
1503 }
1504 break;
1505 case 'feat_charset':
1506 $d = $configuration;
1507 if (!isset($d['RecodingEngine'])) {
1508 if (@extension_loaded('iconv')) {
1509 $d['RecodingEngine'] = 'iconv';
1510 } elseif (@extension_loaded('recode')) {
1511 $d['RecodingEngine'] = 'recode';
1512 } else {
1513 PMA_dl('iconv');
1514 if (!@extension_loaded('iconv')) {
1515 PMA_dl('recode');
1516 if (!@extension_loaded('recode')) {
1517 message('warning', 'Could not load neither recode nor iconv so charset conversion will most likely not work.');
1518 } else {
1519 $d['RecodingEngine'] = 'recode';
1520 }
1521 } else {
1522 $d['RecodingEngine'] = 'iconv';
1523 }
1524 }
1525 if (isset($d['RecodingEngine'])) {
1526 message('notice', 'Autodetected recoding engine: ' . $d['RecodingEngine']);
1527 }
1528 }
1529 show_charset_form($d);
1530 unset($d);
1531 break;
1532  
1533 case 'feat_extensions_real':
1534 if (isset($_POST['submit_save'])) {
1535 $vals = grab_values('GD2Available');
1536 $err = FALSE;
1537 if ($err) {
1538 show_extensions_form($vals);
1539 } else {
1540 $configuration = array_merge($configuration, $vals);
1541 message('notice', 'Configuration changed');
1542 $show_info = TRUE;
1543 }
1544 } else {
1545 $show_info = TRUE;
1546 }
1547 break;
1548 case 'feat_extensions':
1549 $d = $configuration;
1550 if (!@extension_loaded('mbstring')) {
1551 PMA_dl('mbstring');
1552 }
1553 if (!@extension_loaded('mbstring')) {
1554 message('warning', 'Could not load <code>mbstring</code> extension, which is required for work with multibyte strings like UTF-8 ones. Please consider installing it.');
1555 }
1556 if (!isset($d['GD2Available'])) {
1557 if (PMA_IS_GD2 == 1) {
1558 message('notice', 'GD 2 or newer found.');
1559 $d['GD2Available'] = 'yes';
1560 } else {
1561 message('warning', 'GD 2 or newer is not present.');
1562 $d['GD2Available'] = 'no';
1563 }
1564 }
1565 show_extensions_form($d);
1566 unset($d);
1567 break;
1568  
1569 case 'feat_relation_real':
1570 if (isset($_POST['submit_save'])) {
1571 $vals = grab_values('QueryHistoryDB:bool;QueryHistoryMax:int;BrowseMIME:bool;PDFDefaultPageSize');
1572 $err = FALSE;
1573 if (isset($vals['QueryHistoryMax']) && $vals['QueryHistoryMax'] < 1) {
1574 message('error', 'Invalid value for query maximal history size!');
1575 $err = TRUE;
1576 }
1577 if ($err) {
1578 show_relation_form($vals);
1579 } else {
1580 $configuration = array_merge($configuration, $vals);
1581 message('notice', 'Configuration changed');
1582 $show_info = TRUE;
1583 }
1584 } else {
1585 $show_info = TRUE;
1586 }
1587 break;
1588 case 'feat_relation':
1589 show_relation_form($configuration);
1590 break;
1591  
1592 case 'lay_left_real':
1593 if (isset($_POST['submit_save'])) {
1594 $vals = grab_values('LeftFrameLight:bool;LeftFrameDBTree:bool;LeftFrameDBSeparator;LeftFrameTableSeparator;LeftFrameTableLevel:int;LeftDisplayLogo:bool;LeftDisplayServers:bool;LeftPointerEnable:bool');
1595 $err = FALSE;
1596 if (isset($vals['LeftFrameTableLevel']) && $vals['LeftFrameTableLevel'] < 1) {
1597 message('error', 'Invalid value for maximum table nesting level!');
1598 $err = TRUE;
1599 }
1600 if ($err) {
1601 show_left_form($vals);
1602 } else {
1603 $configuration = array_merge($configuration, $vals);
1604 message('notice', 'Configuration changed');
1605 $show_info = TRUE;
1606 }
1607 } else {
1608 $show_info = TRUE;
1609 }
1610 break;
1611 case 'lay_left':
1612 show_left_form($configuration);
1613 break;
1614  
1615 case 'lay_tabs_real':
1616 if (isset($_POST['submit_save'])) {
1617 $vals = grab_values('DefaultTabServer;DefaultTabDatabase;DefaultTabTable;LightTabs:bool');
1618 $err = FALSE;
1619 if ($err) {
1620 show_tabs_form($vals);
1621 } else {
1622 $configuration = array_merge($configuration, $vals);
1623 message('notice', 'Configuration changed');
1624 $show_info = TRUE;
1625 }
1626 } else {
1627 $show_info = TRUE;
1628 }
1629 break;
1630 case 'lay_tabs':
1631 show_tabs_form($configuration);
1632 break;
1633  
1634 case 'lay_icons_real':
1635 if (isset($_POST['submit_save'])) {
1636 $vals = grab_values('ErrorIconic:bool;MainPageIconic:bool;ReplaceHelpImg:bool;NavigationBarIconic:tristate;PropertiesIconic:tristate');
1637 $err = FALSE;
1638 if ($err) {
1639 show_icons_form($vals);
1640 } else {
1641 $configuration = array_merge($configuration, $vals);
1642 message('notice', 'Configuration changed');
1643 $show_info = TRUE;
1644 }
1645 } else {
1646 $show_info = TRUE;
1647 }
1648 break;
1649 case 'lay_icons':
1650 show_icons_form($configuration);
1651 break;
1652  
1653 case 'lay_browse_real':
1654 if (isset($_POST['submit_save'])) {
1655 $vals = grab_values('BrowsePointerEnable:bool;BrowseMarkerEnable:bool;ModifyDeleteAtRight:bool;ModifyDeleteAtLeft:bool;RepeatCells:int;DefaultDisplay');
1656 $err = FALSE;
1657 if (isset($vals['RepeatCells']) && $vals['RepeatCells'] < 1) {
1658 message('error', 'Invalid value for header repeating!');
1659 $err = TRUE;
1660 }
1661 if (!$vals['ModifyDeleteAtLeft'] && !$vals['ModifyDeleteAtRight']) {
1662 message('error', 'No action buttons enabled!');
1663 $err = TRUE;
1664 }
1665 if ($err) {
1666 show_browse_form($vals);
1667 } else {
1668 $configuration = array_merge($configuration, $vals);
1669 message('notice', 'Configuration changed');
1670 $show_info = TRUE;
1671 }
1672 } else {
1673 $show_info = TRUE;
1674 }
1675 break;
1676 case 'lay_browse':
1677 show_browse_form($configuration);
1678 break;
1679  
1680 case 'lay_edit_real':
1681 if (isset($_POST['submit_save'])) {
1682 $vals = grab_values('TextareaCols:int;TextareaRows:int;LongtextDoubleTextarea:bool;TextareaAutoSelect:bool;CharEditing;CharTextareaCols:int;CharTextareaRows:int;CtrlArrowsMoving:bool;DefaultPropDisplay;InsertRows:int');
1683 $err = FALSE;
1684 if (isset($vals['TextareaCols']) && $vals['TextareaCols'] < 1) {
1685 message('error', 'Invalid value for textarea columns!');
1686 $err = TRUE;
1687 }
1688 if (isset($vals['TextareaRows']) && $vals['TextareaRows'] < 1) {
1689 message('error', 'Invalid value for textarea rows!');
1690 $err = TRUE;
1691 }
1692 if (isset($vals['CharTextareaCols']) && $vals['CharTextareaCols'] < 1) {
1693 message('error', 'Invalid value for CHAR textarea columns!');
1694 $err = TRUE;
1695 }
1696 if (isset($vals['CharTextareaRows']) && $vals['CharTextareaRows'] < 1) {
1697 message('error', 'Invalid value for CHAR textarea rows!');
1698 $err = TRUE;
1699 }
1700 if (isset($vals['InsertRows']) && $vals['InsertRows'] < 1) {
1701 message('error', 'Invalid value for inserted rows count!');
1702 $err = TRUE;
1703 }
1704 if ($err) {
1705 show_edit_form($vals);
1706 } else {
1707 $configuration = array_merge($configuration, $vals);
1708 message('notice', 'Configuration changed');
1709 $show_info = TRUE;
1710 }
1711 } else {
1712 $show_info = TRUE;
1713 }
1714 break;
1715 case 'lay_edit':
1716 show_edit_form($configuration);
1717 break;
1718  
1719 case 'lay_window_real':
1720 if (isset($_POST['submit_save'])) {
1721 $vals = grab_values('EditInWindow:bool;QueryWindowHeight:int;QueryWindowWidth:int;QueryWindowDefTab');
1722 $err = FALSE;
1723 if (isset($vals['QueryWindowWidth']) && $vals['QueryWindowWidth'] < 1) {
1724 message('error', 'Invalid value for query window width!');
1725 $err = TRUE;
1726 }
1727 if (isset($vals['QueryWindowHeight']) && $vals['QueryWindowHeight'] < 1) {
1728 message('error', 'Invalid value for query window height');
1729 $err = TRUE;
1730 }
1731 if ($err) {
1732 show_window_form($vals);
1733 } else {
1734 $configuration = array_merge($configuration, $vals);
1735 message('notice', 'Configuration changed');
1736 $show_info = TRUE;
1737 }
1738 } else {
1739 $show_info = TRUE;
1740 }
1741 break;
1742 case 'lay_window':
1743 show_window_form($configuration);
1744 break;
1745  
1746 /* Template for new actions:
1747 case 'blah_real':
1748 if (isset($_POST['submit_save'])) {
1749 $vals = grab_values('value1:bool;value2');
1750 $err = FALSE;
1751 if (somechekcfails) {
1752 message('error', 'Invalid value for blah!');
1753 $err = TRUE;
1754 }
1755 if ($err) {
1756 show_blah_form($vals);
1757 } else {
1758 $configuration = array_merge($configuration, $vals);
1759 message('notice', 'Configuration changed');
1760 $show_info = TRUE;
1761 }
1762 } else {
1763 $show_info = TRUE;
1764 }
1765 break;
1766 case 'blah':
1767 show_blah_form($configuration);
1768 break;
1769 */
1770 case 'versioncheck': // Check for latest available version
1771 PMA_dl('curl');
1772 $url = 'http://phpmyadmin.net/home_page/version.php';
1773 $data = '';
1774 $f = @fopen($url, 'r');
1775 if ($f === FALSE) {
1776 if (!function_exists('curl_init')) {
1777 message('error', 'Neither URL wrappers nor CURL are available. Version check is not possible.');
1778 break;
1779 }
1780 } else {
1781 $data = fread($f, 20);
1782 fclose($f);
1783 }
1784 if (empty($data) && function_exists('curl_init')) {
1785 $ch = curl_init($url);
1786 curl_setopt($ch, CURLOPT_HEADER, FALSE);
1787 curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
1788 $data = curl_exec($ch);
1789 curl_close($ch);
1790 }
1791 if (empty($data)) {
1792 message('error', 'Reading of version failed. Maybe you\'re offline or server does not respond.');
1793 break;
1794 }
1795  
1796 /* Format: version\ndate\n(download\n)* */
1797 $data_list = split("\n", $data);
1798  
1799 if (count($data_list) > 0) {
1800 $version = $data_list[0];
1801 } else {
1802 $version = '';
1803 }
1804  
1805 $version_upstream = version_to_int($version);
1806 if ($version_upstream === FALSE) {
1807 message('error', 'Got invalid version string from server.');
1808 break;
1809 }
1810  
1811 $version_local = version_to_int( $PMA_Config_Setup->get('PMA_VERSION') );
1812 if ($version_local === FALSE) {
1813 message('error', 'Unparsable version string.');
1814 break;
1815 }
1816  
1817 if ($version_upstream > $version_local) {
1818 message('notice', 'New version of phpMyAdmin is available, you should consider upgrade. New version is ' . htmlspecialchars($version) . '.');
1819 } else {
1820 if ($version_local % 100 == 0) {
1821 message('notice', 'You are using CVS version, run <code>cvs update</code> :-). However latest released version is ' . htmlspecialchars($version) . '.');
1822 } else {
1823 message('notice', 'No newer stable version is available.');
1824 }
1825 }
1826 break;
1827  
1828 case 'clear': // Actual clearing is done on beginning of this script
1829 case 'main':
1830 $show_info = TRUE;
1831 break;
1832  
1833 case '':
1834 message('notice', 'You want to configure phpMyAdmin using web interface. Please note that this only allows basic setup, please read <a href="../Documentation.html#config">documentation</a> to see full description of all configuration directives.', 'Welcome');
1835  
1836 if ( $PMA_Config_Setup->get( 'PMA_PHP_INT_VERSION' ) < 40100) {
1837 message('warning', 'Please upgrade to PHP 4.1.0, it is required for phpMyAdmin.', 'Too old PHP');
1838 }
1839  
1840 if ($fail_dir) {
1841 message('warning', 'Please create web server writable folder config in phpMyAdmin toplevel directory as described in <a href="../Documentation.html#setup_script">documentation</a>. Otherwise you will be only able to download or display it.', 'Can not load or save configuration');
1842 }
1843  
1844 if (empty($_SERVER['HTTPS']) || strtolower($_SERVER['HTTPS']) == 'off') {
1845 if (empty($_SERVER['REQUEST_URI']) || empty($_SERVER['HTTP_HOST'])) {
1846 $redir = '';
1847 } else {
1848 $redir = ' If your server is also configured to accept HTTPS request follow <a href="https://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'] . '">this link</a> to use secure connection.';
1849 }
1850 message('warning', 'You are not using secure connection, all data (including sensitive, like passwords) are transfered unencrypted!' . $redir, 'Not secure connection');
1851 }
1852 break;
1853 }
1854  
1855 // Should we show information?
1856 if ($show_info) {
1857 $servers = 'none';
1858 $servers_text = 'Servers';
1859 if (count($configuration['Servers']) == 0) {
1860 message('warning', 'No servers defined, you probably want to add one.');
1861 } else {
1862 $servers = '';
1863 $servers_text = 'Servers (' . count($configuration['Servers']) . ')';
1864  
1865 $sep = '';
1866 foreach ($configuration['Servers'] as $key => $val) {
1867 $servers .= $sep;
1868 $sep = ', ';
1869 $servers .= get_server_name($val, $key);
1870 }
1871 unset($sep);
1872 }
1873 show_overview('Current configuration overview',
1874 array(
1875 array($servers_text, $servers),
1876 array('SQL files upload', empty($configuration['UploadDir']) ? 'disabled' : 'enabled'),
1877 array('Exported files on server', empty($configuration['SaveDir']) ? 'disabled' : 'enabled'),
1878 array('Charset conversion', isset($configuration['AllowAnywhereRecoding']) && $configuration['AllowAnywhereRecoding'] ? 'enabled' : 'disabled'),
1879 ));
1880 unset($servers_text, $servers);
1881 }
1882  
1883 // And finally display all actions:
1884 echo '<p>Available global actions (please note that these will delete any changes you could have done above):</p>';
1885  
1886 echo '<fieldset class="toolbar"><legend>Servers</legend>' . "\n";
1887 echo get_action('addserver', 'Add');
1888 $servers = get_server_selection($configuration);
1889 if (!empty($servers)) {
1890 echo get_action('servers', 'List');
1891 echo get_action('deleteserver', 'Delete', $servers);
1892 echo get_action('editserver', 'Edit', $servers);
1893 }
1894 echo '</fieldset>' . "\n\n";
1895  
1896 echo '<fieldset class="toolbar"><legend>Layout</legend>' . "\n";
1897 echo get_action('lay_left', 'Left frame');
1898 echo get_action('lay_tabs', 'Tabs');
1899 echo get_action('lay_icons', 'Icons');
1900 echo get_action('lay_browse', 'Browsing');
1901 echo get_action('lay_edit', 'Editing');
1902 echo get_action('lay_window', 'Query window');
1903 echo '</fieldset>' . "\n\n";
1904  
1905 echo '<fieldset class="toolbar"><legend>Features</legend>' . "\n";
1906 echo get_action('feat_upload', 'Upload/Download');
1907 echo get_action('feat_security', 'Security');
1908 echo get_action('feat_manual', 'MySQL manual');
1909 echo get_action('feat_charset', 'Charsets');
1910 echo get_action('feat_extensions', 'Extensions');
1911 echo get_action('feat_relation', 'MIME/Relation/History');
1912 echo '</fieldset>' . "\n\n";
1913  
1914 echo '<fieldset class="toolbar"><legend>Configuration</legend>' . "\n";
1915 echo get_action('main', 'Overview');
1916 echo get_action('display', 'Display');
1917 echo get_action('download', 'Download');
1918 echo get_action('save', 'Save', '', !$fail_dir);
1919 echo get_action('load', 'Load', '', !$fail_dir);
1920 echo get_action('clear', 'Clear');
1921 echo '</fieldset>' . "\n\n";
1922  
1923 echo '<fieldset class="toolbar"><legend>Other actions</legend>' . "\n";
1924 echo get_action('versioncheck', 'Check for latest version');
1925 echo get_url_action('http://www.phpmyadmin.net/', 'Go to homepage');
1926 echo get_url_action('https://sourceforge.net/donate/index.php', 'Donate to phpMyAdmin', array('group_id' => 23067));
1927 echo '</fieldset>' . "\n\n";
1928  
1929 footer();
1930 ?>