bug #1989081 [profiling] Profiling causes query to be executed again
[phpmyadmin/crack.git] / scripts / setup.php
blobee723523d49935fc8e64c77546a8113e43823154
1 <?php
2 /* vim: set expandtab sw=4 ts=4 sts=4: */
3 /**
4 * phpMyAdmin setup script
6 * PHP versions 4 and 5
8 * @category Setup
9 * @package phpMyAdmin-setup
10 * @author Michal Čihař <michal@cihar.com>
11 * @copyright 2006 Michal Čihař <michal@cihar.com>
12 * @license http://www.gnu.org/licenses/gpl.html GNU GPL 2.0
13 * @version $Id$
16 // Grab phpMyAdmin version and PMA_dl function
17 define('PMA_MINIMUM_COMMON', TRUE);
18 define('PMA_SETUP', TRUE);
19 chdir('..');
20 require_once './libraries/common.inc.php';
22 // Grab configuration defaults
23 // Do not use $PMA_Config, it interferes with the one in $_SESSION
24 // on servers with register_globals enabled
25 $PMA_Config_Setup = new PMA_Config();
27 // Script information
28 $script_info = 'phpMyAdmin ' . $PMA_Config_Setup->get('PMA_VERSION') . ' setup script by Michal Čihař <michal@cihar.com>';
29 $script_version = '$Id$';
31 // Grab action
32 if (isset($_POST['action'])) {
33 $action = $_POST['action'];
34 } else {
35 $action = '';
38 // Grab wanted CRLF type
39 if (isset($_POST['eoltype'])) {
40 $eoltype = $_POST['eoltype'];
41 } else {
42 if (PMA_USR_OS == 'Win') {
43 $eoltype = 'dos';
44 } else {
45 $eoltype = 'unix';
49 // Detect which CRLF to use
50 if ($eoltype == 'dos') {
51 $crlf = "\r\n";
52 } elseif ($eoltype == 'mac') {
53 $crlf = "\r";
54 } else {
55 $crlf = "\n";
58 if (isset($_POST['configuration']) && $action != 'clear') {
59 // Grab previous configuration, if it should not be cleared
60 $configuration = unserialize($_POST['configuration']);
61 } else {
62 // Start with empty configuration
63 $configuration = array();
66 // We rely on Servers array to exist, so create it here
67 if (!isset($configuration['Servers']) || !is_array($configuration['Servers'])) {
68 $configuration['Servers'] = array();
71 // Used later
72 $now = gmdate('D, d M Y H:i:s') . ' GMT';
74 // General header for no caching
75 header('Expires: ' . $now); // rfc2616 - Section 14.21
76 header('Last-Modified: ' . $now);
77 header('Cache-Control: no-store, no-cache, must-revalidate, pre-check=0, post-check=0, max-age=0'); // HTTP/1.1
78 header('Pragma: no-cache'); // HTTP/1.0
80 // whether to show html header?
81 if ($action != 'download') {
83 // Define the charset to be used
84 header('Content-Type: text/html; charset=utf-8');
86 // this needs to be echoed otherwise php with short tags complains
87 echo '<?xml version="1.0" encoding="utf-8"?>' . "\n";
89 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
90 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
91 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en" dir="ltr">
92 <head>
93 <link rel="icon" href="../favicon.ico" type="image/x-icon" />
94 <link rel="shortcut icon" href="../favicon.ico" type="image/x-icon" />
95 <title>phpMyAdmin <?php echo $PMA_Config_Setup->get('PMA_VERSION'); ?> setup</title>
96 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
98 <script type="text/javascript">
99 //<![CDATA[
100 // show this window in top frame
101 if (top != self) {
102 window.top.location.href=location;
104 //]]>
105 </script>
106 <style type="text/css">
107 /* message boxes: warning, error, stolen from original theme */
108 div.notice {
109 color: #000000;
110 background-color: #FFFFDD;
112 h1.notice,
113 div.notice {
114 margin: 0.5em 0 0.5em 0;
115 border: 0.1em solid #FFD700;
116 background-image: url(../<?php echo $GLOBALS['cfg']['ThemePath']; ?>/original/img/s_notice.png);
117 background-repeat: no-repeat;
118 background-position: 10px 50%;
119 padding: 10px 10px 10px 36px;
121 div.notice h1 {
122 border-bottom: 0.1em solid #FFD700;
123 font-weight: bold;
124 font-size: large;
125 text-align: left;
126 margin: 0 0 0.2em 0;
129 div.warning {
130 color: #CC0000;
131 background-color: #FFFFCC;
133 h1.warning,
134 div.warning {
135 margin: 0.5em 0 0.5em 0;
136 border: 0.1em solid #CC0000;
137 background-image: url(../<?php echo $GLOBALS['cfg']['ThemePath']; ?>/original/img/s_warn.png);
138 background-repeat: no-repeat;
139 background-position: 10px 50%;
140 padding: 10px 10px 10px 36px;
142 div.warning h1 {
143 border-bottom: 0.1em solid #cc0000;
144 font-weight: bold;
145 text-align: left;
146 font-size: large;
147 margin: 0 0 0.2em 0;
150 div.error {
151 background-color: #FFFFCC;
152 color: #ff0000;
154 h1.error,
155 div.error {
156 margin: 0.5em 0 0.5em 0;
157 border: 0.1em solid #ff0000;
158 background-image: url(../<?php echo $GLOBALS['cfg']['ThemePath']; ?>/original/img/s_error.png);
159 background-repeat: no-repeat;
160 background-position: 10px 50%;
161 padding: 10px 10px 10px 36px;
163 div.error h1 {
164 border-bottom: 0.1em solid #ff0000;
165 font-weight: bold;
166 text-align: left;
167 font-size: large;
168 margin: 0 0 0.2em 0;
171 fieldset.toolbar form.action {
172 display: block;
173 width: auto;
174 clear: none;
175 float: left;
176 margin: 0;
177 padding: 0;
178 border-right: 1px solid black;
180 fieldset.toolbar form.action input, fieldset.toolbar form.action select {
181 margin: 0.7em;
182 padding: 0.1em;
185 fieldset.toolbar {
186 display: block;
187 width: 100%;
188 background-color: #dddddd;
189 padding: 0;
191 fieldset.optbox {
192 padding: 0;
193 background-color: #FFFFDD;
195 div.buttons, div.opts, fieldset.optbox p, fieldset.overview div.row {
196 clear: both;
197 padding: 0.5em;
198 margin: 0;
199 background-color: white;
201 div.opts, fieldset.optbox p, fieldset.overview div.row {
202 border-bottom: 1px dotted black;
204 fieldset.overview {
205 display: block;
206 width: 100%;
207 padding: 0;
209 fieldset.optbox p {
210 background-color: #FFFFDD;
212 div.buttons {
213 background-color: #dddddd;
215 div.buttons input {
216 margin: 0 1em 0 1em;
218 div.buttons form {
219 display: inline;
220 margin: 0;
221 padding: 0;
223 input.save {
224 color: green;
225 font-weight: bolder;
227 input.cancel {
228 color: red;
229 font-weight: bolder;
231 div.desc, label.desc, fieldset.overview div.desc {
232 float: left;
233 width: 27em;
234 max-width: 60%;
236 code:before, code:after {
237 content: '"';
239 span.doc {
240 margin: 0 1em 0 1em;
242 span.doc a {
243 margin: 0 0.1em 0 0.1em;
245 span.doc a img {
246 border: none;
248 </style>
249 </head>
251 <body>
252 <h1>phpMyAdmin <?php echo $PMA_Config_Setup->get('PMA_VERSION'); ?> setup</h1>
253 <?php
254 } // end show html header
257 * Calculates numerical equivalent of phpMyAdmin version string
259 * @param string version
261 * @return mixed FALSE on failure, integer on success
263 function version_to_int($version) {
264 if (!preg_match('/^(\d+)\.(\d+)\.(\d+)((\.|-(pl|rc|dev|beta|alpha))(\d+)?)?$/', $version, $matches)) {
265 return FALSE;
267 if (!empty($matches[6])) {
268 switch ($matches[6]) {
269 case 'pl':
270 $added = 60;
271 break;
272 case 'rc':
273 $added = 30;
274 break;
275 case 'beta':
276 $added = 20;
277 break;
278 case 'alpha':
279 $added = 10;
280 break;
281 case 'dev':
282 $added = 0;
283 break;
284 default:
285 message('notice', 'Unknown version part: ' . htmlspecialchars($matches[5]));
286 $added = 0;
287 break;
289 } else {
290 $added = 50; // for final
292 if (!empty($matches[7])) {
293 $added = $added + $matches[7];
295 return $matches[1] * 1000000 + $matches[2] * 10000 + $matches[3] * 100 + $added;
299 * Returns link to documentation of some configuration directive
301 * @param string confguration directive name
303 * @return string HTML link to documentation
305 function get_cfg_doc($anchor) {
306 /* Link for wiki */
307 $wiki = $anchor;
308 if (strncmp($anchor, 'Servers_', 8) == 0) {
309 $wiki = substr($anchor, 8);
311 return
312 '<span class="doc">' .
313 '<a href="../Documentation.html#cfg_' . $anchor . '" target="pma_doc" class="doc">' .
314 '<img class="icon" src="../' . $GLOBALS['cfg']['ThemePath'] . '/original/img/b_help.png" width="11" height="11" alt="Documentation" title="Documentation" />' .
315 '</a>' .
316 '<a href="http://wiki.cihar.com/pma/Config#' . $wiki . '" target="pma_doc" class="doc">' .
317 '<img class="icon" src="../' . $GLOBALS['cfg']['ThemePath'] . '/original/img/b_info.png" width="11" height="11" alt="Wiki" title="Wiki" />' .
318 '</a>' .
319 '</span>'
324 * Displays message
326 * @param string type of message (notice/warning/error)
327 * @param string text of message
328 * @param title optional title of message
330 * @return nothing
332 function message($type, $text, $title = '') {
333 echo '<div class="' . $type . '">' . "\n";
334 if (!empty($title)) {
335 echo '<h1>';
336 echo $title;
337 echo '</h1>' . "\n";
339 echo $text . "\n";
340 echo '</div>' . "\n";
344 * Creates hidden input required for keeping current configuraion
346 * @return string HTML with hidden inputs
348 function get_hidden_cfg() {
349 global $configuration, $eoltype;
351 $ret = '<input type="hidden" name="configuration" value="' . htmlspecialchars(serialize($configuration)) . '" />' . "\n";
352 $ret .= '<input type="hidden" name="eoltype" value="' . htmlspecialchars($eoltype) . '" />' . "\n";
354 return $ret;
358 * Returns needed hidden input for forms.
360 * @return string HTML with hidden inputs
362 function get_hidden_inputs() {
363 return '<input type="hidden" name="token" value="' . $_SESSION[' PMA_token '] . '" />';
367 * Creates form for some action
369 * @param string action name
370 * @param string form title
371 * @param string optional additional inputs
373 * @return string HTML with form
375 function get_action($name, $title, $added = '', $enabled = TRUE) {
376 $ret = '';
377 $ret .= '<form class="action" method="post" action="">';
378 $ret .= get_hidden_inputs();
379 $ret .= '<input type="hidden" name="action" value="' . $name . '" />';
380 $ret .= $added;
381 $ret .= '<input type="submit" value="' . $title . '"';
382 if (!$enabled) {
383 $ret .= ' disabled="disabled"';
385 $ret .= ' />';
386 $ret .= get_hidden_cfg();
387 $ret .= '</form>';
388 $ret .= "\n";
389 return $ret;
393 * Creates form for going to some url
395 * @param string URL where to go
396 * @param string form title
397 * @param string optional array of parameters
399 * @return string HTML with form
401 function get_url_action($url, $title, $params = array()) {
402 $ret = '';
403 $ret .= '<form class="action" method="get" action="' . $url . '" target="_blank">';
404 $ret .= get_hidden_inputs();
405 foreach ($params as $key => $val) {
406 $ret .= '<input type="hidden" name="' . $key . '" value="' . $val . '" />';
408 $ret .= '<input type="submit" value="' . $title . '" />';
409 $ret .= '</form>';
410 $ret .= "\n";
411 return $ret;
415 * Terminates script and ends HTML
417 * @return nothing
419 function footer() {
420 echo '</body>';
421 echo '</html>';
422 exit;
426 * Creates string describing server authentication method
428 * @param array server configuration
430 * @return string authentication method description
432 function get_server_auth($val) {
433 global $PMA_Config_Setup;
435 if (isset($val['auth_type'])) {
436 $auth = $val['auth_type'];
437 } else {
438 $auth = $PMA_Config_Setup->default_server['auth_type'];
440 $ret = $auth;
441 if ($auth == 'config') {
442 if (isset($val['user'])) {
443 $ret .= ':' . $val['user'];
444 } else {
445 $ret .= ':' . $PMA_Config_Setup->default_server['user'];
448 return $ret;
452 * Creates nice string with server name
454 * @param array server configuration
455 * @param int optional server id
457 * @return string fancy server name
459 function get_server_name($val, $id = FALSE, $escape = true) {
460 if (!empty($val['verbose'])) {
461 $ret = $val['verbose'];
462 } else {
463 $ret = $val['host'];
465 $ret .= ' (' . get_server_auth($val) . ')';
466 if ($id !== FALSE) {
467 $ret .= ' [' . ($id + 1) . ']' ;
469 if ($escape) {
470 return htmlspecialchars($ret);
471 } else {
472 return $ret;
478 * Exports variable to PHP code, very limited version of var_export
480 * @param string data to export
482 * @see var_export
484 * @return string PHP code containing variable value
486 function PMA_var_export($input) {
487 global $crlf;
489 $output = '';
490 if (is_null($input)) {
491 $output .= 'NULL';
492 } elseif (is_array($input)) {
493 $output .= 'array (' . $crlf;
494 foreach($input as $key => $value) {
495 $output .= PMA_var_export($key) . ' => ' . PMA_var_export($value);
496 $output .= ',' . $crlf;
498 $output .= ')';
499 } elseif (is_string($input)) {
500 $output .= '\'' . addslashes($input) . '\'';
501 } elseif (is_int($input) || is_double($input)) {
502 $output .= (string) $input;
503 } elseif (is_bool($input)) {
504 $output .= $input ? 'true' : 'false';
505 } else {
506 die('Unknown type for PMA_var_export: ' . $input);
508 return $output;
512 * Creates configuration code for one variable
514 * @param string variable name
515 * @param mixed configuration
517 * @return string PHP code containing configuration
519 function get_cfg_val($name, $val) {
520 global $crlf;
522 $ret = '';
523 if (is_array($val)) {
524 $ret .= $crlf;
525 foreach ($val as $k => $v) {
526 if (!isset($type)) {
527 if (is_string($k)) {
528 $type = 'string';
529 } elseif (is_int($k)) {
530 $type = 'int';
531 $ret .= $name . ' = array(' . $crlf;
532 } else {
533 // Something unknown...
534 $ret .= $name. ' = ' . PMA_var_export($val) . ';' . $crlf;
535 break;
538 if ($type == 'string') {
539 $ret .= get_cfg_val($name . "['$k']", $v);
540 } elseif ($type == 'int') {
541 $ret .= ' ' . PMA_var_export($v) . ',' . $crlf;
544 if (!isset($type)) {
545 /* Empty array */
546 $ret .= $name . ' = array();' . $crlf;
547 } elseif ($type == 'int') {
548 $ret .= ');' . $crlf;
550 $ret .= $crlf;
551 unset($type);
552 } else {
553 $ret .= $name . ' = ' . PMA_var_export($val) . ';' . $crlf;
555 return $ret;
559 * Creates configuration PHP code
561 * @param array configuration
563 * @return string PHP code containing configuration
565 function get_cfg_string($cfg) {
566 global $script_info, $script_version, $now, $crlf;
568 $c = $cfg;
569 $ret = "<?php$crlf/*$crlf * Generated configuration file$crlf * Generated by: $script_info$crlf * Version: $script_version$crlf * Date: " . $now . $crlf . ' */' . $crlf . $crlf;
571 if (count($c['Servers']) > 0) {
572 $ret .= "/* Servers configuration */$crlf\$i = 0;" . $crlf;
573 foreach ($c['Servers'] as $cnt => $srv) {
574 $ret .= $crlf . '/* Server ' . strtr(get_server_name($srv, $cnt, false), '*', '-') . " */$crlf\$i++;" . $crlf;
575 foreach ($srv as $key => $val) {
576 $ret .= get_cfg_val("\$cfg['Servers'][\$i]['$key']", $val);
579 $ret .= $crlf . '/* End of servers configuration */' . $crlf . $crlf;
581 unset($c['Servers']);
583 foreach ($c as $key => $val) {
584 $ret .= get_cfg_val("\$cfg['$key']", $val);
587 $ret .= '?>' . $crlf;
588 return $ret;
592 * Compresses server configuration to be indexed from 0 and contain no gaps
594 * @param array configuration
596 * @return nothing
598 function compress_servers(&$cfg) {
599 $ns = array();
600 foreach ($cfg['Servers'] as $val) {
601 if (!empty($val['host'])) {
602 $ns[] = $val;
605 $cfg['Servers'] = $ns;
609 * Grabs values from POST
611 * @param string list of values to grab, values are separated by ";",
612 * each can have defined type separated by ":", if no type
613 * is defined, string is assumed. Possible types: bool -
614 * boolean value, serialized - serialized value, int -
615 * integer, tristate - "TRUE"/"FALSE" converted to bool,
616 * other strings are kept.
618 * @return array array with grabbed values
620 function grab_values($list)
622 $a = split(';', $list);
623 $res = array();
624 foreach ($a as $val) {
625 $v = split(':', $val);
626 if (!isset($v[1])) {
627 $v[1] = '';
629 switch($v[1]) {
630 case 'bool':
631 $res[$v[0]] = isset($_POST[$v[0]]);
632 break;
633 case 'serialized':
634 if (isset($_POST[$v[0]]) && strlen($_POST[$v[0]]) > 0) {
635 $res[$v[0]] = unserialize($_POST[$v[0]]);
637 break;
638 case 'int':
639 if (isset($_POST[$v[0]]) && strlen($_POST[$v[0]]) > 0) {
640 $res[$v[0]] = (int)$_POST[$v[0]];
642 break;
643 case 'tristate':
644 if (isset($_POST[$v[0]]) && strlen($_POST[$v[0]]) > 0) {
645 $cur = $_POST[$v[0]];
646 if ($cur == 'TRUE') {
647 $res[$v[0]] = TRUE;
648 } elseif ($cur == 'FALSE') {
649 $res[$v[0]] = FALSE;
650 } else {
651 $res[$v[0]] = $cur;
654 break;
655 case 'string':
656 default:
657 if (isset($_POST[$v[0]]) && strlen($_POST[$v[0]]) > 0) {
658 $res[$v[0]] = $_POST[$v[0]];
660 break;
663 return $res;
667 * Displays overview
669 * @param string title of oveview
670 * @param array list of values to display (each element is array of two
671 * values - name and value)
672 * @param string optional buttons to be displayed
674 * @return nothing
676 function show_overview($title, $list, $buttons = '') {
677 echo '<fieldset class="overview">' . "\n";
678 echo '<legend>' . $title . '</legend>' . "\n";
679 foreach ($list as $val) {
680 echo '<div class="row">';
681 echo '<div class="desc">';
682 echo $val[0];
683 echo '</div>';
684 echo '<div class="data">';
685 echo $val[1];
686 echo '</div>';
687 echo '</div>' . "\n";
689 if (!empty($buttons)) {
690 echo '<div class="buttons">';
691 echo '<div class="desc">Actions:</div>';
692 echo $buttons;
693 echo '</div>' . "\n";
695 echo '</fieldset>' . "\n";
696 echo "\n";
700 * Displays configuration, fallback defaults are taken from global $PMA_Config_Setup
702 * @param array list of values to display (each element is array of two or
703 * three values - desription, name and optional type
704 * indicator). Type is determined by type of this parameter,
705 * array means select and array elements are items,
706 * 'password' means password input.
707 * @param string title of configuration
708 * @param string help string for this configuration
709 * @param array optional first level defaults
710 * @param string optional title for save button
711 * @param string optional prefix for documentation links
713 * @return nothing
715 function show_config_form($list, $legend, $help, $defaults = array(), $save = '', $prefix = '') {
716 global $PMA_Config_Setup;
718 if (empty($save)) {
719 $save = 'Update';
722 echo '<fieldset class="optbox">' . "\n";
723 echo '<legend>' . $legend . '</legend>' . "\n";
724 echo '<p>' . $help . '</p>' . "\n";
725 foreach ($list as $val) {
726 echo '<div class="opts">';
727 $type = 'text';
728 if (isset($val[3])) {
729 if (is_array($val[3])) {
730 $type = 'select';
731 } elseif (is_bool($val[3])) {
732 $type = 'check';
733 } elseif ($val[3] == 'password') {
734 $type = 'password';
737 switch ($type) {
738 case 'text':
739 case 'password':
740 echo '<label for="text_' . $val[1] . '" class="desc" title="' . $val[2] . '">' . $val[0] . get_cfg_doc($prefix . $val[1]) . '</label>';
741 echo '<input type="' . $type . '" name="' . $val[1] . '" id="text_' . $val[1] . '" title="' . $val[2] . '" size="50"';
742 if (isset($defaults[$val[1]])) {
743 echo ' value="' . htmlspecialchars($defaults[$val[1]]) . '"';
744 } else {
745 echo ' value="' . htmlspecialchars($PMA_Config_Setup->get($val[1])) . '"';
747 echo ' />';
748 break;
749 case 'check':
750 echo '<input type="checkbox" name="' . $val[1] . '" value="something" id="checkbox_' . $val[1] . '" title="' . $val[2] . '"';
751 if (isset($defaults[$val[1]])) {
752 if ($defaults[$val[1]]) {
753 echo ' checked="checked"';
755 } else {
756 if ($PMA_Config_Setup->get($val[1])) {
757 echo ' checked="checked"';
760 echo ' />';
761 echo '<label for="checkbox_' . $val[1] . '" title="' . $val[2] . '">' . $val[0] . get_cfg_doc($prefix . $val[1]) . '</label>';
762 break;
763 case 'select':
764 echo '<label for="select_' . $val[1] . '" class="desc" title="' . $val[2] . '">' . $val[0] . get_cfg_doc($prefix . $val[1]) . '</label>';
765 echo '<select name="' . $val[1] . '" id="select_' . $val[1] . '" ' . ' title="' . $val[2] . '">';
766 foreach ($val[3] as $opt) {
767 echo '<option value="' . $opt . '"';
768 if (isset($defaults[$val[1]])) {
769 if (is_bool($defaults[$val[1]])) {
770 if (($defaults[$val[1]] && $opt == 'TRUE') || (!$defaults[$val[1]] && $opt == 'FALSE')) {
771 echo ' selected="selected"';
773 } else {
774 if ($defaults[$val[1]] == $opt) {
775 echo ' selected="selected"';
778 } else {
779 $def_val = $PMA_Config_Setup->get($val[1]);
780 if (is_bool($val)) {
781 if (($def_val && $opt == 'TRUE') || (!$def_val && $opt == 'FALSE')) {
782 echo ' selected="selected"';
784 } else {
785 if ($def_val == $opt) {
786 echo ' selected="selected"';
789 unset($def_val);
791 echo '>' . $opt . '</option>';
793 echo '</select>';
794 break;
796 echo '</div>' . "\n";
798 echo '<div class="buttons">';
799 echo '<div class="desc">Actions:</div>';
800 echo '<input type="submit" name="submit_save" value="' . $save .'" class="save" />';
801 echo '<input type="submit" name="submit_ignore" value="Cancel" class="cancel" />';
802 echo '</div>' . "\n";
803 echo '</fieldset>' . "\n";
804 echo "\n";
808 * Shows security options configuration form
810 * @param array optional defaults
812 * @return nothing
814 function show_security_form($defaults = array()) {
816 <form method="post" action="">
817 <?php echo get_hidden_inputs();?>
818 <input type="hidden" name="action" value="feat_security_real" />
819 <?php
820 echo get_hidden_cfg();
821 show_config_form(array(
822 array('Blowfish secret', 'blowfish_secret', 'Secret passphrase used for encrypting cookies'),
823 array('Force SSL connection', 'ForceSSL', 'Whether to force using secured connection while using phpMyAdmin', FALSE),
824 array('Show phpinfo output', 'ShowPhpInfo', 'Whether to allow users to see phpinfo() output', FALSE),
825 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),
826 array('Allow login to any MySQL server', 'AllowArbitraryServer', 'If enabled user can enter any MySQL server in login form for cookie auth.', FALSE),
827 array('Recall user name', 'LoginCookieRecall', 'Whether to recall user name on log in prompt while using cookie auth.', TRUE),
828 array('Login cookie validity', 'LoginCookieValidity', 'How long is login valid without performing any action.'),
830 'Configure security features',
831 'Please note that phpMyAdmin is just a user interface and it\'s features do not limit MySQL.',
832 $defaults);
834 </form>
835 <?php
839 * Shows MySQL manual configuration form
841 * @param array optional defaults
843 * @return nothing
845 function show_manual_form($defaults = array()) {
847 <form method="post" action="">
848 <?php echo get_hidden_inputs();?>
849 <input type="hidden" name="action" value="feat_manual_real" />
850 <?php
851 echo get_hidden_cfg();
852 show_config_form(array(
853 array('Type of MySQL documentation', 'MySQLManualType', 'These types are same as listed on MySQL download page', array('viewable', 'chapters', 'big', 'none')),
854 array('Base URL of MySQL documentation', 'MySQLManualBase', 'Where is MySQL documentation placed, this is usually top level directory.'),
856 'Configure MySQL manual links',
857 '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.',
858 $defaults);
860 </form>
861 <?php
865 * Shows charset options configuration form
867 * @param array optional defaults
869 * @return nothing
871 function show_charset_form($defaults = array()) {
872 global $PMA_Config_Setup;
874 <form method="post" action="">
875 <?php echo get_hidden_inputs();?>
876 <input type="hidden" name="action" value="feat_charset_real" />
877 <?php
878 echo get_hidden_cfg();
879 show_config_form(array(
880 array('Allow charset conversion', 'AllowAnywhereRecoding', 'If you want to use such functions.', FALSE),
881 array('Default charset', 'DefaultCharset', 'Default charset for conversion.', $PMA_Config_Setup->get('AvailableCharsets')),
882 array('Recoding engine', 'RecodingEngine', 'PHP can contain iconv and/or recode, select which one to use or keep autodetection.', array('auto', 'iconv', 'recode')),
883 array('Extra params for iconv', 'IconvExtraParams', 'Iconv can get some extra parameters for conversion see man iconv_open.'),
885 'Configure charset conversions',
886 'phpMyAdmin can perform charset conversions so that you can import and export in any charset you want.',
887 $defaults);
889 </form>
890 <?php
894 * Shows PHP extensions configuration form
896 * @param array optional defaults
898 * @return nothing
900 function show_extensions_form($defaults = array()) {
902 <form method="post" action="">
903 <?php echo get_hidden_inputs();?>
904 <input type="hidden" name="action" value="feat_extensions_real" />
905 <?php
906 echo get_hidden_cfg();
907 show_config_form(array(
908 array('GD 2 is available', 'GD2Available', 'Whether you have GD 2 or newer installed', array('auto', 'yes', 'no')),
910 'Configure extensions',
911 '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.',
912 $defaults);
914 </form>
915 <?php
919 * Shows MIME/relation/history configuration form
921 * @param array optional defaults
923 * @return nothing
925 function show_relation_form($defaults = array()) {
926 global $PMA_Config_Setup;
928 <form method="post" action="">
929 <?php echo get_hidden_inputs();?>
930 <input type="hidden" name="action" value="feat_relation_real" />
931 <?php
932 echo get_hidden_cfg();
933 show_config_form(array(
934 array('Permanent query history', 'QueryHistoryDB', 'Store history into database.', FALSE),
935 array('Maximal history size', 'QueryHistoryMax', 'How many queries are kept in history.'),
936 array('Use MIME transformations', 'BrowseMIME', 'Use MIME transformations while browsing.', TRUE),
937 array('PDF default page size', 'PDFDefaultPageSize', 'Default page size for PDF, you can change this while creating page.', $PMA_Config_Setup->get('PDFPageSizes')),
939 'Configure MIME/relation/history',
940 'phpMyAdmin can provide additional features like MIME transformation, internal relations, permanent history and PDF pages generation. You have to configure the database and tables that will store this information on the server page. Behaviour of those functions is configured here.',
941 $defaults);
943 </form>
944 <?php
948 * Shows upload/save configuration form
950 * @param array optional defaults
952 * @return nothing
954 function show_upload_form($defaults = array()) {
956 <form method="post" action="">
957 <?php echo get_hidden_inputs();?>
958 <input type="hidden" name="action" value="feat_upload_real" />
959 <?php
960 echo get_hidden_cfg();
961 show_config_form(array(
962 array('Upload directory', 'UploadDir', 'Directory on server where you can upload files for import'),
963 array('Save directory', 'SaveDir', 'Directory where exports can be saved on server'),
965 'Configure upload/save directories',
966 'Enter directories, either absolute path or relative to phpMyAdmin top level directory.',
967 $defaults);
969 </form>
970 <?php
974 * Shows server configuration form
976 * @param array optional defaults
978 * @return nothing
980 function show_server_form($defaults = array(), $number = FALSE) {
982 <form method="post" action="">
983 <?php echo get_hidden_inputs();?>
984 <input type="hidden" name="action" value="addserver_real" />
985 <?php
986 echo get_hidden_cfg();
987 if (!($number === FALSE)) {
988 echo '<input type="hidden" name="server" value="' . $number . '" />';
990 $hi = array ('bookmarktable', 'relation', 'table_info', 'table_coords', 'pdf_pages', 'column_info', 'designer_coords', 'history', 'AllowDeny');
991 foreach ($hi as $k) {
992 if (isset($defaults[$k]) && (!is_string($defaults[$k]) || strlen($defaults[$k]) > 0)) {
993 echo '<input type="hidden" name="' . $k . '" value="' . htmlspecialchars(serialize($defaults[$k])) . '" />';
996 show_config_form(array(
997 array('Server hostname', 'host', 'Hostname where MySQL server is running'),
998 array('Server port', 'port', 'Port on which MySQL server is listening, leave empty for default'),
999 array('Server socket', 'socket', 'Socket on which MySQL server is listening, leave empty for default'),
1000 array('Connection type', 'connect_type', 'How to connect to server, keep tcp if unsure', array('tcp', 'socket')),
1001 array('PHP extension to use', 'extension', 'What PHP extension to use, use mysqli if supported', array('mysql', 'mysqli')),
1002 array('Compress connection', 'compress', 'Whether to compress connection to MySQL server', FALSE),
1003 array('Authentication type', 'auth_type', 'Authentication method to use', array('cookie', 'http', 'config', 'signon')),
1004 array('User for config auth', 'user', 'Leave empty if not using config auth'),
1005 array('Password for config auth', 'password', 'Leave empty if not using config auth', 'password'),
1006 array('Only database to show', 'only_db', 'Limit listing of databases in left frame to this one'),
1007 array('Verbose name of this server', 'verbose', 'Name to display in server selection'),
1008 array('phpMyAdmin control user', 'controluser', 'User which phpMyAdmin can use for various actions'),
1009 array('phpMyAdmin control user password', 'controlpass', 'Password for user which phpMyAdmin can use for various actions', 'password'),
1010 array('phpMyAdmin database for advanced features', 'pmadb', 'phpMyAdmin will allow much more when you enable this. Table names are filled in automatically.'),
1011 array('Session name for signon auth', 'SignonSession', 'Leave empty if not using signon auth'),
1012 array('Login URL for signon auth', 'SignonURL', 'Leave empty if not using signon auth'),
1013 array('Logout URL', 'LogoutURL', 'Where to redirect user after logout'),
1015 'Configure server',
1016 ($number === FALSE) ? 'Enter new server connection parameters.' : 'Editing server ' . get_server_name($defaults, $number),
1017 $defaults, $number === FALSE ? 'Add' : '', 'Servers_');
1019 </form>
1020 <?php
1024 * Shows left frame configuration form
1026 * @param array optional defaults
1028 * @return nothing
1030 function show_left_form($defaults = array()) {
1032 <form method="post" action="">
1033 <?php echo get_hidden_inputs();?>
1034 <input type="hidden" name="action" value="lay_navigation_real" />
1035 <?php
1036 echo get_hidden_cfg();
1037 show_config_form(array(
1038 array('Use light version', 'LeftFrameLight', 'Disable this if you want to see all databases at one time.', TRUE),
1039 array('Display databases in tree', 'LeftFrameDBTree', 'Whether to display databases in tree (determined by separator defined lower)', TRUE),
1040 array('Databases tree separator', 'LeftFrameDBSeparator', 'String that separates databases into different tree level'),
1041 array('Table tree separator', 'LeftFrameTableSeparator', 'String that separates tables into different tree level'),
1042 array('Maximum table tree nesting', 'LeftFrameTableLevel', 'Maximum number of children in table tree'),
1043 array('Show logo', 'LeftDisplayLogo', 'Whether to show logo in left frame', TRUE),
1044 array('Display servers selection', 'LeftDisplayServers', 'Whether to show server selection in left frame', FALSE),
1045 array('Display servers as list', 'DisplayServersList', 'Whether to show server listing as list instead of drop down', FALSE),
1046 array('Display databases as list', 'DisplayDatabasesList', 'Whether to show database listing in navigation as list instead of drop down', array('auto', 'yes', 'no')),
1047 array('Enable pointer highlighting', 'LeftPointerEnable', 'Whether you want to highlight server under mouse', TRUE),
1049 'Configure navigation frame',
1050 'Customize the appears of the navigation frame.',
1051 $defaults);
1053 </form>
1054 <?php
1058 * Shows tabs configuration form
1060 * @param array optional defaults
1062 * @return nothing
1064 function show_tabs_form($defaults = array()) {
1066 <form method="post" action="">
1067 <?php echo get_hidden_inputs();?>
1068 <input type="hidden" name="action" value="lay_tabs_real" />
1069 <?php
1070 echo get_hidden_cfg();
1071 show_config_form(array(
1072 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')),
1073 array('Default tab for database', 'DefaultTabDatabase', 'Tab that is displayed when entering database', array('db_structure.php', 'db_sql.php', 'db_search.php', 'db_operations.php')),
1074 array('Default tab for table', 'DefaultTabTable', 'Tab that is displayed when entering table', array('tbl_structure.php', 'sql.php', 'tbl_sql.php', 'tbl_select.php', 'tbl_change.php')),
1075 array('Use lighter tabs', 'LightTabs', 'If you want simpler tabs enable this', FALSE),
1077 'Configure tabs',
1078 'Choose how you want tabs to work.',
1079 $defaults);
1081 </form>
1082 <?php
1086 * Shows icons configuration form
1088 * @param array optional defaults
1090 * @return nothing
1092 function show_icons_form($defaults = array()) {
1094 <form method="post" action="">
1095 <?php echo get_hidden_inputs();?>
1096 <input type="hidden" name="action" value="lay_icons_real" />
1097 <?php
1098 echo get_hidden_cfg();
1099 show_config_form(array(
1100 array('Icons on errors', 'ErrorIconic', 'Whether to use icons in error messages.', TRUE),
1101 array('Icons on main page', 'MainPageIconic', 'Whether to use icons on main page.', TRUE),
1102 array('Icons as help links', 'ReplaceHelpImg', 'Whether to use icons as help links.', TRUE),
1103 array('Navigation with icons', 'NavigationBarIconic', 'Whether to display navigation (eg. tabs) with icons.', array('TRUE', 'FALSE', 'both')),
1104 array('Properties pages with icons', 'PropertiesIconic', 'Whether to display properties (eg. table lists and structure) with icons.', array('TRUE', 'FALSE', 'both')),
1106 'Configure icons',
1107 'Select whether you prefer text or icons. Both means that text and icons will be displayed.',
1108 $defaults);
1110 </form>
1111 <?php
1115 * Shows browsing configuration form
1117 * @param array optional defaults
1119 * @return nothing
1121 function show_browse_form($defaults = array()) {
1123 <form method="post" action="">
1124 <?php echo get_hidden_inputs();?>
1125 <input type="hidden" name="action" value="lay_browse_real" />
1126 <?php
1127 echo get_hidden_cfg();
1128 show_config_form(array(
1129 array('Display of values', 'DefaultDisplay', 'How to list values while browsing', array('horizontal', 'vertical', 'horizontalflipped')),
1130 array('Hightlight pointer', 'BrowsePointerEnable', 'Whether to highlight row under mouse.', TRUE),
1131 array('Use row marker', 'BrowseMarkerEnable', 'Whether to highlight selected row.', TRUE),
1132 array('Action buttons on left', 'ModifyDeleteAtLeft', 'Show action buttons on left side of listing?', TRUE),
1133 array('Action buttons on right', 'ModifyDeleteAtRight', 'Show action buttons on right side of listing?', FALSE),
1134 array('Repeat heading', 'RepeatCells', 'After how many rows heading should be repeated.'),
1136 'Configure browsing',
1137 'Select desired browsing look and feel.',
1138 $defaults);
1140 </form>
1141 <?php
1145 * Shows editing options configuration form
1147 * @param array optional defaults
1149 * @return nothing
1151 function show_edit_form($defaults = array()) {
1153 <form method="post" action="">
1154 <?php echo get_hidden_inputs();?>
1155 <input type="hidden" name="action" value="lay_edit_real" />
1156 <?php
1157 echo get_hidden_cfg();
1158 show_config_form(array(
1159 array('Display of properties while editing', 'DefaultPropDisplay', 'How to list properties (table structure or values) while editing', array('horizontal', 'vertical')),
1160 array('Number of inserted rows', 'InsertRows', 'How many rows can be inserted at once'),
1161 array('Move using Ctrl+arrows', 'CtrlArrowsMoving', 'Whether to enable moving using Ctrl+Arrows', TRUE),
1162 array('Autoselect text in textarea', 'TextareaAutoSelect', 'Whether to automatically select text in textarea on focus.', TRUE),
1163 array('Textarea columns', 'TextareaCols', 'Number of columns in textarea while editing TEXT fields'),
1164 array('Textarea rows', 'TextareaRows', 'Number of rows in textarea while editing TEXT fields'),
1165 array('Double textarea for LONGTEXT', 'LongtextDoubleTextarea', 'Whether to double textarea size for LONGTEXT fields', TRUE),
1166 array('Edit CHAR fields in textarea', 'CharEditing', 'Whether to edit CHAR fields in textarea', array('input', 'textarea')),
1167 array('CHAR textarea columns', 'CharTextareaCols', 'Number of columns in textarea while editing CHAR fields (must be enabled above)'),
1168 array('CHAR textarea rows', 'CharTextareaRows', 'Number of rows in textarea while editing CHAR fields (must be enabled above)'),
1170 'Configure editing',
1171 'Select desired editing look and feel.',
1172 $defaults);
1174 </form>
1175 <?php
1179 * Shows query window configuration form
1181 * @param array optional defaults
1183 * @return nothing
1185 function show_window_form($defaults = array()) {
1187 <form method="post" action="">
1188 <?php echo get_hidden_inputs();?>
1189 <input type="hidden" name="action" value="lay_window_real" />
1190 <?php
1191 echo get_hidden_cfg();
1192 show_config_form(array(
1193 array('Edit SQL in window', 'EditInWindow', 'Whether edit links will edit in query window.', TRUE),
1194 array('Query window height', 'QueryWindowHeight', 'Height of query window'),
1195 array('Query window width', 'QueryWindowWidth', 'Width of query window'),
1196 array('Default tab', 'QueryWindowDefTab', 'Default tab on query window', array('sql', 'files', 'history', 'full')),
1198 'Configure query window',
1199 'Select desired query window look and feel.',
1200 $defaults);
1202 </form>
1203 <?php
1207 * Creates selection with servers
1209 * @param array configuraion
1211 * @return string HTML for server selection
1213 function get_server_selection($cfg) {
1214 if (count($cfg['Servers']) == 0) {
1215 return '';
1217 $ret = '<select name="server">';
1218 foreach ($cfg['Servers'] as $key => $val) {
1219 $ret .= '<option value="' . $key . '">' . get_server_name($val, $key) . '</option>';
1221 $ret .= '</select>';
1222 return $ret;
1226 * Loads configuration from file
1228 * @param string filename
1230 * @return mixed FALSE on failure, new config array on success
1232 function load_config($config_file) {
1233 if (file_exists($config_file)) {
1234 $success_apply_user_config = FALSE;
1235 $old_error_reporting = error_reporting(0);
1236 if (function_exists('file_get_contents')) {
1237 $success_apply_user_config = eval('?>' . trim(file_get_contents($config_file)));
1238 } else {
1239 $success_apply_user_config =
1240 eval('?>' . trim(implode("\n", file($config_file))));
1242 error_reporting($old_error_reporting);
1243 unset($old_error_reporting);
1244 if ($success_apply_user_config === FALSE) {
1245 message('error', 'Error while parsing configuration file!');
1246 } elseif (!isset($cfg) || count($cfg) == 0) {
1247 message('error', 'Config file seems to contain no configuration!');
1248 } else {
1249 // This must be set
1250 if (!isset($cfg['Servers'])) {
1251 $cfg['Servers'] = array();
1253 message('notice', 'Configuration loaded');
1254 compress_servers($cfg);
1255 return $cfg;
1257 } else {
1258 message('error', 'Configuration file not found!');
1260 return FALSE;
1263 if ($action != 'download') {
1264 // Check whether we can write to configuration
1265 $fail_dir = FALSE;
1266 $fail_dir = $fail_dir || !is_dir('./config/');
1267 $fail_dir = $fail_dir || !is_writable('./config/');
1268 $fail_dir = $fail_dir || (file_exists('./config/config.inc.php') && !is_writable('./config/config.inc.php'));
1269 $config = @fopen('./config/config.inc.php', 'a');
1270 $fail_dir = $fail_dir || ($config === FALSE);
1271 @fclose($config);
1275 * @var boolean whether to show configuration overview
1277 $show_info = FALSE;
1279 // Do the main work depending on selected action
1280 switch ($action) {
1281 case 'download':
1282 header('Content-Type: text/plain');
1283 header('Content-Disposition: attachment; filename="config.inc.php"');
1285 echo get_cfg_string($configuration);
1286 exit;
1287 break;
1288 case 'display':
1289 echo '<form method="none" action=""><textarea name="config" cols="50" rows="20" id="textconfig" wrap="off">' . "\n";
1290 echo htmlspecialchars(get_cfg_string($configuration));
1291 echo '</textarea></form>' . "\n";
1293 <script type="text/javascript">
1294 //<![CDATA[
1295 var bodyWidth=null; var bodyHeight=null;
1296 if (document.getElementById('textconfig')) {
1297 bodyWidth = self.innerWidth;
1298 bodyHeight = self.innerHeight;
1299 if(!bodyWidth && !bodyHeight){
1300 if (document.compatMode && document.compatMode == "BackCompat") {
1301 bodyWidth = document.body.clientWidth;
1302 bodyHeight = document.body.clientHeight;
1303 } else if (document.compatMode && document.compatMode == "CSS1Compat") {
1304 bodyWidth = document.documentElement.clientWidth;
1305 bodyHeight = document.documentElement.clientHeight;
1308 document.getElementById('textconfig').style.width=(bodyWidth-50) + 'px';
1309 document.getElementById('textconfig').style.height=(bodyHeight-100) + 'px';
1311 //]]>
1312 </script>
1313 <?php
1314 break;
1315 case 'save':
1316 $config = @fopen('./config/config.inc.php', 'w');
1317 if ($config === FALSE) {
1318 message('error', 'Could not open config file for writing! Bad permissions?');
1319 break;
1321 $s = get_cfg_string($configuration);
1322 $r = fwrite($config, $s);
1323 if (!$r || $r != strlen($s)) {
1324 message('error', 'Could not write to config file! Not enough space?');
1325 break;
1326 } else {
1327 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');
1329 unset($r, $s);
1330 fclose($config);
1331 break;
1332 case 'load':
1333 if ($fail_dir) {
1334 message('error', 'Reading of configuration disabled because of permissions.');
1335 break;
1337 $new_cfg = load_config('./config/config.inc.php');
1338 if (!($new_cfg === FALSE)) {
1339 $configuration = $new_cfg;
1341 $show_info = TRUE;
1342 break;
1344 case 'addserver_real':
1345 if (isset($_POST['submit_save'])) {
1346 $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;designer_coords:serialized;history:serialized;AllowDeny:serialized;SignonSession;SignonURL;LogoutURL');
1347 $err = FALSE;
1348 if (empty($new_server['host'])) {
1349 message('error', 'Empty hostname!');
1350 $err = TRUE;
1352 if ($new_server['auth_type'] == 'config' && empty($new_server['user'])) {
1353 message('error', 'Empty username while using config authentication method!');
1354 $err = TRUE;
1356 if ($new_server['auth_type'] == 'signon' && empty($new_server['SignonSession'])) {
1357 message('error', 'Empty signon session name while using signon authentication method!');
1358 $err = TRUE;
1360 if ($new_server['auth_type'] == 'signon' && empty($new_server['SignonURL'])) {
1361 message('error', 'Empty signon URL while using signon authentication method!');
1362 $err = TRUE;
1364 if (isset($new_server['pmadb']) && strlen($new_server['pmadb'])) {
1365 // Just use defaults, should be okay for most users
1366 $pmadb = array();
1367 $pmadb['bookmarktable'] = 'pma_bookmark';
1368 $pmadb['relation'] = 'pma_relation';
1369 $pmadb['table_info'] = 'pma_table_info';
1370 $pmadb['table_coords'] = 'pma_table_coords';
1371 $pmadb['pdf_pages'] = 'pma_pdf_pages';
1372 $pmadb['column_info'] = 'pma_column_info';
1373 $pmadb['designer_coords'] = 'pma_designer_coords';
1374 $pmadb['history'] = 'pma_history';
1376 $new_server = array_merge($pmadb, $new_server);
1377 unset($pmadb);
1378 if (empty($new_server['controluser'])) {
1379 message('error', 'Empty phpMyAdmin control user while using pmadb!');
1380 $err = TRUE;
1382 if (empty($new_server['controlpass'])) {
1383 message('error', 'Empty phpMyAdmin control user password while using pmadb!');
1384 $err = TRUE;
1386 /* Check whether we can connect as control user */
1387 if (!empty($new_server['controluser']) && !empty($new_server['controlpass'])) {
1388 if ($new_server['extension'] == 'mysql') {
1389 $socket = empty($new_server['socket']) || $new_server['connect_type'] == 'tcp' ? '' : ':' . $new_server['socket'];
1390 $port = empty($new_server['port']) || $new_server['connect_type'] == 'socket' ? '' : ':' . $new_server['port'];
1391 $conn = @mysql_connect($new_server['host'] . $socket . $port, $new_server['controluser'], $new_server['controlpass']);
1392 if ($conn === FALSE) {
1393 message('error', 'Could not connect as control user!');
1394 $err = TRUE;
1395 } else {
1396 mysql_close($conn);
1398 } else {
1399 $socket = empty($new_server['socket']) || $new_server['connect_type'] == 'tcp' ? NULL : $new_server['socket'];
1400 $port = empty($new_server['port']) || $new_server['connect_type'] == 'socket' ? NULL : $new_server['port'];
1401 $conn = @mysqli_connect($new_server['host'], $new_server['controluser'], $new_server['controlpass'], NULL, $port, $socket);
1402 if ($conn === FALSE) {
1403 message('error', 'Could not connect as control user!');
1404 $err = TRUE;
1405 } else {
1406 mysqli_close($conn);
1410 } else {
1411 message('warning', 'You didn\'t set phpMyAdmin database, so you can not use all phpMyAdmin features.');
1413 if ($new_server['auth_type'] == 'config') {
1414 message('warning', 'Remember to protect your installation while using config authentication method!');
1415 } else {
1416 // Not needed:
1417 unset($new_server['user']);
1418 unset($new_server['password']);
1420 if ($err) {
1421 show_server_form($new_server, isset($_POST['server']) ? $_POST['server'] : FALSE);
1422 } else {
1423 if (isset($_POST['server'])) {
1424 $configuration['Servers'][$_POST['server']] = $new_server;
1425 message('notice', 'Changed server ' . get_server_name($new_server, $_POST['server']));
1426 } else {
1427 $configuration['Servers'][] = $new_server;
1428 message('notice', 'New server added');
1430 $show_info = TRUE;
1431 if ($new_server['auth_type'] == 'cookie' && empty($configuration['blowfish_secret'])) {
1432 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');
1433 $configuration['blowfish_secret'] = uniqid('', TRUE);
1436 unset($new_server);
1437 } else {
1438 $show_info = TRUE;
1440 break;
1441 case 'addserver':
1442 if (count($configuration['Servers']) == 0) {
1443 // First server will use defaults as in config.default.php
1444 $defaults = $PMA_Config_Setup->default_server;
1445 unset($defaults['AllowDeny']); // Ignore this for now
1446 } else {
1447 $defaults = array();
1450 // Guess MySQL extension to use, prefer mysqli
1451 if (!function_exists('mysql_get_client_info')) {
1452 PMA_dl('mysql');
1454 if (!function_exists('mysqli_get_client_info')) {
1455 PMA_dl('mysqli');
1457 if (function_exists('mysqli_get_client_info')) {
1458 $defaults['extension'] = 'mysqli';
1459 } elseif (function_exists('mysql_get_client_info')) {
1460 $defaults['extension'] = 'mysql';
1461 } else {
1462 message('warning', 'Could not load either mysql or mysqli extension, you might not be able to use phpMyAdmin! Check your PHP configuration.');
1464 if (isset($defaults['extension'])) {
1465 message('notice', 'Autodetected MySQL extension to use: ' . $defaults['extension']);
1468 // Display form
1469 show_server_form($defaults);
1470 break;
1471 case 'editserver':
1472 if (!isset($_POST['server'])) {
1473 footer();
1475 show_server_form($configuration['Servers'][$_POST['server']], $_POST['server']);
1476 break;
1477 case 'deleteserver':
1478 if (!isset($_POST['server'])) {
1479 footer();
1481 message('notice', 'Deleted server ' . get_server_name($configuration['Servers'][$_POST['server']], $_POST['server']));
1482 unset($configuration['Servers'][$_POST['server']]);
1483 compress_servers($configuration);
1484 $show_info = TRUE;
1485 break;
1486 case 'servers':
1487 if (count($configuration['Servers']) == 0) {
1488 message('notice', 'No servers defined, so none can be shown');
1489 } else {
1490 foreach ($configuration['Servers'] as $i => $srv) {
1491 $data = array();
1492 if (!empty($srv['verbose'])) {
1493 $data[] = array('Verbose name', $srv['verbose']);
1495 $data[] = array('Host', $srv['host']);
1496 $data[] = array('MySQL extension', isset($srv['extension']) ? $srv['extension'] : $PMA_Config_Setup->default_server['extension']);
1497 $data[] = array('Authentication type', get_server_auth($srv));
1498 $data[] = array('phpMyAdmin advanced features', empty($srv['pmadb']) || empty($srv['controluser']) || empty($srv['controlpass']) ? 'disabled' : 'enabled, db: ' . $srv['pmadb'] . ', user: ' . $srv['controluser']);
1499 $buttons =
1500 get_action('deleteserver', 'Delete', '<input type="hidden" name="server" value="' . $i . '" />') .
1501 get_action('editserver', 'Edit', '<input type="hidden" name="server" value="' . $i . '" />');
1502 show_overview('Server ' . get_server_name($srv, $i), $data, $buttons);
1505 break;
1507 case 'feat_upload_real':
1508 if (isset($_POST['submit_save'])) {
1509 $dirs = grab_values('UploadDir;SaveDir');
1510 $err = FALSE;
1511 if (!empty($dirs['UploadDir']) && !is_dir($dirs['UploadDir'])) {
1512 message('error', 'Upload directory ' . htmlspecialchars($dirs['UploadDir']) . ' does not exist!');
1513 $err = TRUE;
1515 if (!empty($dirs['SaveDir']) && !is_dir($dirs['SaveDir'])) {
1516 message('error', 'Save directory ' . htmlspecialchars($dirs['SaveDir']) . ' does not exist!');
1517 $err = TRUE;
1519 if ($err) {
1520 show_upload_form($dirs);
1521 } else {
1522 $configuration = array_merge($configuration, $dirs);
1523 message('notice', 'Configuration changed');
1524 $show_info = TRUE;
1526 } else {
1527 $show_info = TRUE;
1529 break;
1530 case 'feat_upload':
1531 show_upload_form($configuration);
1532 break;
1534 case 'feat_security_real':
1535 if (isset($_POST['submit_save'])) {
1536 $vals = grab_values('blowfish_secret;ForceSSL:bool;ShowPhpInfo:bool;ShowChgPassword:bool;AllowArbitraryServer:bool;LoginCookieRecall:book;LoginCookieValidity:int');
1537 $err = FALSE;
1538 if (empty($vals['blowfish_secret'])) {
1539 message('warning', 'Blowfish secret is empty, you will not be able to use cookie authentication.');
1541 if ($vals['AllowArbitraryServer']) {
1542 message('warning', 'Arbitrary server connection might be dangerous as it might allow access to internal servers that are not reachable from outside.');
1544 if (isset($vals['LoginCookieValidity']) && $vals['LoginCookieValidity'] < 1) {
1545 message('error', 'Invalid cookie validity time');
1546 $err = TRUE;
1548 if ($err) {
1549 show_security_form($vals);
1550 } else {
1551 $configuration = array_merge($configuration, $vals);
1552 message('notice', 'Configuration changed');
1553 $show_info = TRUE;
1555 } else {
1556 $show_info = TRUE;
1558 break;
1559 case 'feat_security':
1560 show_security_form($configuration);
1561 break;
1563 case 'feat_manual_real':
1564 if (isset($_POST['submit_save'])) {
1565 $vals = grab_values('MySQLManualBase;MySQLManualType');
1566 $err = FALSE;
1567 if ($vals['MySQLManualType'] != 'none' && empty($vals['MySQLManualBase'])) {
1568 message('error', 'You need to set manual base URL or choose type \'none\'.');
1569 $err = TRUE;
1571 if ($err) {
1572 show_manual_form($vals);
1573 } else {
1574 $configuration = array_merge($configuration, $vals);
1575 message('notice', 'Configuration changed');
1576 $show_info = TRUE;
1578 } else {
1579 $show_info = TRUE;
1581 break;
1582 case 'feat_manual':
1583 show_manual_form($configuration);
1584 break;
1586 case 'feat_charset_real':
1587 if (isset($_POST['submit_save'])) {
1588 $vals = grab_values('AllowAnywhereRecoding:bool;DefaultCharset;RecodingEngine;IconvExtraParams');
1589 $err = FALSE;
1590 if ($err) {
1591 show_charset_form($vals);
1592 } else {
1593 $configuration = array_merge($configuration, $vals);
1594 message('notice', 'Configuration changed');
1595 $show_info = TRUE;
1597 } else {
1598 $show_info = TRUE;
1600 break;
1601 case 'feat_charset':
1602 $d = $configuration;
1603 if (!isset($d['RecodingEngine'])) {
1604 if (@extension_loaded('iconv')) {
1605 $d['RecodingEngine'] = 'iconv';
1606 } elseif (@extension_loaded('recode')) {
1607 $d['RecodingEngine'] = 'recode';
1608 } else {
1609 PMA_dl('iconv');
1610 if (!@extension_loaded('iconv')) {
1611 PMA_dl('recode');
1612 if (!@extension_loaded('recode')) {
1613 message('warning', 'Neither recode nor iconv could be loaded so charset conversion will most likely not work.');
1614 } else {
1615 $d['RecodingEngine'] = 'recode';
1617 } else {
1618 $d['RecodingEngine'] = 'iconv';
1621 if (isset($d['RecodingEngine'])) {
1622 message('notice', 'Autodetected recoding engine: ' . $d['RecodingEngine']);
1625 show_charset_form($d);
1626 unset($d);
1627 break;
1629 case 'feat_extensions_real':
1630 if (isset($_POST['submit_save'])) {
1631 $vals = grab_values('GD2Available');
1632 $err = FALSE;
1633 if ($err) {
1634 show_extensions_form($vals);
1635 } else {
1636 $configuration = array_merge($configuration, $vals);
1637 message('notice', 'Configuration changed');
1638 $show_info = TRUE;
1640 } else {
1641 $show_info = TRUE;
1643 break;
1644 case 'feat_extensions':
1645 $d = $configuration;
1646 if (!@extension_loaded('mbstring')) {
1647 PMA_dl('mbstring');
1649 if (!@extension_loaded('mbstring')) {
1650 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.');
1652 if (!isset($d['GD2Available'])) {
1653 if (PMA_IS_GD2 == 1) {
1654 message('notice', 'GD 2 or newer found.');
1655 $d['GD2Available'] = 'yes';
1656 } else {
1657 message('warning', 'GD 2 or newer is not present.');
1658 $d['GD2Available'] = 'no';
1661 show_extensions_form($d);
1662 unset($d);
1663 break;
1665 case 'feat_relation_real':
1666 if (isset($_POST['submit_save'])) {
1667 $vals = grab_values('QueryHistoryDB:bool;QueryHistoryMax:int;BrowseMIME:bool;PDFDefaultPageSize');
1668 $err = FALSE;
1669 if (isset($vals['QueryHistoryMax']) && $vals['QueryHistoryMax'] < 1) {
1670 message('error', 'Invalid value for query maximum history size!');
1671 $err = TRUE;
1673 if ($err) {
1674 show_relation_form($vals);
1675 } else {
1676 $configuration = array_merge($configuration, $vals);
1677 message('notice', 'Configuration changed');
1678 $show_info = TRUE;
1680 } else {
1681 $show_info = TRUE;
1683 break;
1684 case 'feat_relation':
1685 show_relation_form($configuration);
1686 break;
1688 case 'lay_navigation_real':
1689 if (isset($_POST['submit_save'])) {
1690 $vals = grab_values('LeftFrameLight:bool;LeftFrameDBTree:bool;LeftFrameDBSeparator;LeftFrameTableSeparator;LeftFrameTableLevel:int;LeftDisplayLogo:bool;LeftDisplayServers:bool;DisplayServersList:bool;DisplayDatabasesList;LeftPointerEnable:bool');
1691 $err = FALSE;
1692 if (isset($vals['DisplayDatabasesList'])) {
1693 if ($vals['DisplayDatabasesList'] == 'yes') {
1694 $vals['DisplayDatabasesList'] = true;
1695 } elseif ($vals['DisplayDatabasesList'] == 'no') {
1696 $vals['DisplayDatabasesList'] = false;
1699 if (isset($vals['LeftFrameTableLevel']) && $vals['LeftFrameTableLevel'] < 1) {
1700 message('error', 'Invalid value for maximum table nesting level!');
1701 $err = TRUE;
1703 if ($err) {
1704 show_left_form($vals);
1705 } else {
1706 $configuration = array_merge($configuration, $vals);
1707 message('notice', 'Configuration changed');
1708 $show_info = TRUE;
1710 } else {
1711 $show_info = TRUE;
1713 break;
1714 case 'lay_navigation':
1715 show_left_form($configuration);
1716 break;
1718 case 'lay_tabs_real':
1719 if (isset($_POST['submit_save'])) {
1720 $vals = grab_values('DefaultTabServer;DefaultTabDatabase;DefaultTabTable;LightTabs:bool');
1721 $err = FALSE;
1722 if ($err) {
1723 show_tabs_form($vals);
1724 } else {
1725 $configuration = array_merge($configuration, $vals);
1726 message('notice', 'Configuration changed');
1727 $show_info = TRUE;
1729 } else {
1730 $show_info = TRUE;
1732 break;
1733 case 'lay_tabs':
1734 show_tabs_form($configuration);
1735 break;
1737 case 'lay_icons_real':
1738 if (isset($_POST['submit_save'])) {
1739 $vals = grab_values('ErrorIconic:bool;MainPageIconic:bool;ReplaceHelpImg:bool;NavigationBarIconic:tristate;PropertiesIconic:tristate');
1740 $err = FALSE;
1741 if ($err) {
1742 show_icons_form($vals);
1743 } else {
1744 $configuration = array_merge($configuration, $vals);
1745 message('notice', 'Configuration changed');
1746 $show_info = TRUE;
1748 } else {
1749 $show_info = TRUE;
1751 break;
1752 case 'lay_icons':
1753 show_icons_form($configuration);
1754 break;
1756 case 'lay_browse_real':
1757 if (isset($_POST['submit_save'])) {
1758 $vals = grab_values('BrowsePointerEnable:bool;BrowseMarkerEnable:bool;ModifyDeleteAtRight:bool;ModifyDeleteAtLeft:bool;RepeatCells:int;DefaultDisplay');
1759 $err = FALSE;
1760 if (isset($vals['RepeatCells']) && $vals['RepeatCells'] < 1) {
1761 message('error', 'Invalid value for header repeating!');
1762 $err = TRUE;
1764 if (!$vals['ModifyDeleteAtLeft'] && !$vals['ModifyDeleteAtRight']) {
1765 message('error', 'No action buttons enabled!');
1766 $err = TRUE;
1768 if ($err) {
1769 show_browse_form($vals);
1770 } else {
1771 $configuration = array_merge($configuration, $vals);
1772 message('notice', 'Configuration changed');
1773 $show_info = TRUE;
1775 } else {
1776 $show_info = TRUE;
1778 break;
1779 case 'lay_browse':
1780 show_browse_form($configuration);
1781 break;
1783 case 'lay_edit_real':
1784 if (isset($_POST['submit_save'])) {
1785 $vals = grab_values('TextareaCols:int;TextareaRows:int;LongtextDoubleTextarea:bool;TextareaAutoSelect:bool;CharEditing;CharTextareaCols:int;CharTextareaRows:int;CtrlArrowsMoving:bool;DefaultPropDisplay;InsertRows:int');
1786 $err = FALSE;
1787 if (isset($vals['TextareaCols']) && $vals['TextareaCols'] < 1) {
1788 message('error', 'Invalid value for textarea columns!');
1789 $err = TRUE;
1791 if (isset($vals['TextareaRows']) && $vals['TextareaRows'] < 1) {
1792 message('error', 'Invalid value for textarea rows!');
1793 $err = TRUE;
1795 if (isset($vals['CharTextareaCols']) && $vals['CharTextareaCols'] < 1) {
1796 message('error', 'Invalid value for CHAR textarea columns!');
1797 $err = TRUE;
1799 if (isset($vals['CharTextareaRows']) && $vals['CharTextareaRows'] < 1) {
1800 message('error', 'Invalid value for CHAR textarea rows!');
1801 $err = TRUE;
1803 if (isset($vals['InsertRows']) && $vals['InsertRows'] < 1) {
1804 message('error', 'Invalid value for inserted rows count!');
1805 $err = TRUE;
1807 if ($err) {
1808 show_edit_form($vals);
1809 } else {
1810 $configuration = array_merge($configuration, $vals);
1811 message('notice', 'Configuration changed');
1812 $show_info = TRUE;
1814 } else {
1815 $show_info = TRUE;
1817 break;
1818 case 'lay_edit':
1819 show_edit_form($configuration);
1820 break;
1822 case 'lay_window_real':
1823 if (isset($_POST['submit_save'])) {
1824 $vals = grab_values('EditInWindow:bool;QueryWindowHeight:int;QueryWindowWidth:int;QueryWindowDefTab');
1825 $err = FALSE;
1826 if (isset($vals['QueryWindowWidth']) && $vals['QueryWindowWidth'] < 1) {
1827 message('error', 'Invalid value for query window width!');
1828 $err = TRUE;
1830 if (isset($vals['QueryWindowHeight']) && $vals['QueryWindowHeight'] < 1) {
1831 message('error', 'Invalid value for query window height');
1832 $err = TRUE;
1834 if ($err) {
1835 show_window_form($vals);
1836 } else {
1837 $configuration = array_merge($configuration, $vals);
1838 message('notice', 'Configuration changed');
1839 $show_info = TRUE;
1841 } else {
1842 $show_info = TRUE;
1844 break;
1845 case 'lay_window':
1846 show_window_form($configuration);
1847 break;
1849 /* Template for new actions:
1850 case 'blah_real':
1851 if (isset($_POST['submit_save'])) {
1852 $vals = grab_values('value1:bool;value2');
1853 $err = FALSE;
1854 if (somechekcfails) {
1855 message('error', 'Invalid value for blah!');
1856 $err = TRUE;
1858 if ($err) {
1859 show_blah_form($vals);
1860 } else {
1861 $configuration = array_merge($configuration, $vals);
1862 message('notice', 'Configuration changed');
1863 $show_info = TRUE;
1865 } else {
1866 $show_info = TRUE;
1868 break;
1869 case 'blah':
1870 show_blah_form($configuration);
1871 break;
1873 case 'versioncheck': // Check for latest available version
1874 PMA_dl('curl');
1875 $url = 'http://phpmyadmin.net/home_page/version.php';
1876 $data = '';
1877 $f = @fopen($url, 'r');
1878 if ($f === FALSE) {
1879 if (!function_exists('curl_init')) {
1880 message('error', 'Neither URL wrappers nor CURL are available. Version check is not possible.');
1881 break;
1883 } else {
1884 $data = fread($f, 20);
1885 fclose($f);
1887 if (empty($data) && function_exists('curl_init')) {
1888 $ch = curl_init($url);
1889 curl_setopt($ch, CURLOPT_HEADER, FALSE);
1890 curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
1891 $data = curl_exec($ch);
1892 curl_close($ch);
1894 if (empty($data)) {
1895 message('error', 'Reading of version failed. Maybe you\'re offline or the upgrade server does not respond.');
1896 break;
1899 /* Format: version\ndate\n(download\n)* */
1900 $data_list = split("\n", $data);
1902 if (count($data_list) > 0) {
1903 $version = $data_list[0];
1904 } else {
1905 $version = '';
1908 $version_upstream = version_to_int($version);
1909 if ($version_upstream === FALSE) {
1910 message('error', 'Got invalid version string from server.');
1911 break;
1914 $version_local = version_to_int($PMA_Config_Setup->get('PMA_VERSION'));
1915 if ($version_local === FALSE) {
1916 message('error', 'Unparsable version string.');
1917 break;
1920 if ($version_upstream > $version_local) {
1921 message('notice', 'New version of phpMyAdmin is available, you should consider upgrade. New version is ' . htmlspecialchars($version) . '.');
1922 } else {
1923 if ($version_local % 100 == 0) {
1924 message('notice', 'You are using subversion version, run <code>svn update</code> :-). However latest released version is ' . htmlspecialchars($version) . '.');
1925 } else {
1926 message('notice', 'No newer stable version is available.');
1929 break;
1931 case 'seteol':
1932 $eoltype = $_POST['neweol'];
1933 message('notice', 'End of line format changed.');
1934 case 'clear': // Actual clearing is done on beginning of this script
1935 case 'main':
1936 $show_info = TRUE;
1937 break;
1939 case '':
1940 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');
1942 if ($PMA_Config_Setup->get('PMA_PHP_INT_VERSION') < 40100) {
1943 message('warning', 'Please upgrade to PHP 4.1.0, it is required for phpMyAdmin.', 'Too old PHP');
1946 if ($fail_dir) {
1947 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');
1950 if (empty($_SERVER['HTTPS']) || strtolower($_SERVER['HTTPS']) == 'off') {
1951 if (empty($_SERVER['REQUEST_URI']) || empty($_SERVER['HTTP_HOST'])) {
1952 $redir = '';
1953 } else {
1954 $redir = ' If your server is also configured to accept HTTPS request'
1955 . ' follow <a href="https://'
1956 . htmlspecialchars($_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'])
1957 . '">this link</a> to use secure connection.';
1959 message('warning', 'You are not using secure connection, all data (including sensitive, like passwords) are transfered unencrypted!' . $redir, 'Not secure connection');
1961 break;
1964 // Should we show information?
1965 if ($show_info) {
1966 $servers = 'none';
1967 $servers_text = 'Servers';
1968 if (count($configuration['Servers']) == 0) {
1969 message('warning', 'No servers defined, you probably want to add one.');
1970 } else {
1971 $servers = '';
1972 $servers_text = 'Servers (' . count($configuration['Servers']) . ')';
1974 $sep = '';
1975 foreach ($configuration['Servers'] as $key => $val) {
1976 $servers .= $sep;
1977 $sep = ', ';
1978 $servers .= get_server_name($val, $key);
1980 unset($sep);
1982 show_overview('Current configuration overview',
1983 array(
1984 array($servers_text, $servers),
1985 array('SQL files upload', empty($configuration['UploadDir']) ? 'disabled' : 'enabled'),
1986 array('Exported files on server', empty($configuration['SaveDir']) ? 'disabled' : 'enabled'),
1987 array('Charset conversion', isset($configuration['AllowAnywhereRecoding']) && $configuration['AllowAnywhereRecoding'] ? 'enabled' : 'disabled'),
1989 unset($servers_text, $servers);
1992 // And finally display all actions:
1993 echo '<p>Available global actions (please note that these will delete any changes you could have done above):</p>';
1995 echo '<fieldset class="toolbar"><legend>Servers</legend>' . "\n";
1996 echo get_action('addserver', 'Add');
1997 $servers = get_server_selection($configuration);
1998 if (!empty($servers)) {
1999 echo get_action('servers', 'List');
2000 echo get_action('deleteserver', 'Delete', $servers);
2001 echo get_action('editserver', 'Edit', $servers);
2003 echo '</fieldset>' . "\n\n";
2005 echo '<fieldset class="toolbar"><legend>Layout</legend>' . "\n";
2006 echo get_action('lay_navigation', 'Navigation frame');
2007 echo get_action('lay_tabs', 'Tabs');
2008 echo get_action('lay_icons', 'Icons');
2009 echo get_action('lay_browse', 'Browsing');
2010 echo get_action('lay_edit', 'Editing');
2011 echo get_action('lay_window', 'Query window');
2012 echo '</fieldset>' . "\n\n";
2014 echo '<fieldset class="toolbar"><legend>Features</legend>' . "\n";
2015 echo get_action('feat_upload', 'Upload/Download');
2016 echo get_action('feat_security', 'Security');
2017 echo get_action('feat_manual', 'MySQL manual');
2018 echo get_action('feat_charset', 'Charsets');
2019 echo get_action('feat_extensions', 'Extensions');
2020 echo get_action('feat_relation', 'MIME/Relation/History');
2021 echo '</fieldset>' . "\n\n";
2023 echo '<fieldset class="toolbar"><legend>Configuration</legend>' . "\n";
2024 echo get_action('main', 'Overview');
2025 echo get_action('display', 'Display');
2026 echo get_action('download', 'Download');
2027 echo get_action('save', 'Save', '', !$fail_dir);
2028 echo get_action('load', 'Load', '', !$fail_dir);
2029 echo get_action('clear', 'Clear');
2030 echo get_action('seteol', 'Change end of line',
2031 '<select name="neweol">' .
2032 '<option value="unix" ' . ($eoltype == 'unix' ? ' selected="selected"' : '') . '>UNIX/Linux (\\n)</option>' .
2033 '<option value="dos" ' . ($eoltype == 'dos' ? ' selected="selected"' : '') . '>DOS/Windows (\\r\\n)</option>' .
2034 '<option value="mac" ' . ($eoltype == 'mac' ? ' selected="selected"' : '') . '>Macintosh (\\r)</option>' . '
2035 </select>');
2036 echo '</fieldset>' . "\n\n";
2038 echo '<fieldset class="toolbar"><legend>Other actions</legend>' . "\n";
2039 echo get_action('versioncheck', 'Check for latest version');
2040 echo get_url_action('http://www.phpmyadmin.net/', 'Go to homepage');
2041 echo get_url_action('https://sourceforge.net/donate/index.php', 'Donate to phpMyAdmin', array('group_id' => 23067));
2042 echo '</fieldset>' . "\n\n";
2044 footer();