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