Implement own minimalistic var_export and drop the one from PEAR.
[phpmyadmin/last10db.git] / scripts / setup.php
blob594bfa8b7c0d92fbf520f77a0b780a6e4f27d42c
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) {
399 if (!empty($val['verbose'])) {
400 $ret = htmlspecialchars($val['verbose']);
401 } else {
402 $ret = htmlspecialchars($val['host']);
404 $ret .= ' (' . get_server_auth($val) . ')';
405 if ($id !== FALSE) {
406 $ret .= ' [' . ($id + 1) . ']' ;
408 return $ret;
413 * Exports variable to PHP code, very limited version of var_export
415 * @param string data to export
417 * @see var_export
419 * @return string PHP code containing variable value
421 function PMA_var_export($input) {
422 $output = '';
423 if (is_null($input)) {
424 $output .= 'NULL';
425 } elseif (is_array($input)) {
426 $output .= "array (\n";
427 foreach($input as $key => $value) {
428 $output .= PMA_var_export($key) . ' => ' . PMA_var_export($value);
429 $output .= ",\n";
431 $output .= ')';
432 } elseif (is_string($input)) {
433 $output .= '\'' . addslashes($input) . '\'';
434 } elseif (is_int($input) || is_double($input)) {
435 $output .= (string) $input;
436 } elseif (is_bool($input)) {
437 $output .= $input ? 'true' : 'false';
438 } else {
439 die('Unknown type for PMA_var_export: ' . $input);
441 return $output;
445 * Creates configuration code for one variable
447 * @param string variable name
448 * @param mixed configuration
450 * @return string PHP code containing configuration
452 function get_cfg_val($name, $val) {
453 $ret = '';
454 if (is_array($val)) {
455 $ret .= "\n";
456 foreach ($val as $k => $v) {
457 if (!isset($type)) {
458 if (is_string($k)) {
459 $type = 'string';
460 } elseif (is_int($k)) {
461 $type = 'int';
462 $ret .= $name . " = array(\n";
463 } else {
464 // Something unknown...
465 $ret .= $name. ' = ' . PMA_var_export($val) . ";\n";
466 break;
469 if ($type == 'string') {
470 $ret .= get_cfg_val($name . "['$k']", $v);
471 } elseif ($type == 'int') {
472 $ret .= " " . PMA_var_export($v) . ",\n";
475 if (!isset($type)) {
476 /* Empty array */
477 $ret .= $name . " = array();\n";
478 } elseif ($type == 'int') {
479 $ret .= ");\n";
481 $ret .= "\n";
482 unset($type);
483 } else {
484 $ret .= $name . ' = ' . PMA_var_export($val) . ";\n";
486 return $ret;
490 * Creates configuration PHP code
492 * @param array configuration
494 * @return string PHP code containing configuration
496 function get_cfg_string($cfg) {
497 global $script_info, $script_version, $now;
499 $c = $cfg;
500 $ret = "<?php\n/*\n * Generated configuration file\n * Generated by: $script_info\n * Version: $script_version\n * Date: " . $now . "\n */\n\n";
502 if (count($c['Servers']) > 0) {
503 $ret .= "/* Servers configuration */\n\$i = 0;\n";
504 foreach ($c['Servers'] as $cnt => $srv) {
505 $ret .= "\n/* Server " . get_server_name($srv, $cnt) . " */\n\$i++;\n";
506 foreach ($srv as $key => $val) {
507 $ret .= get_cfg_val("\$cfg['Servers'][\$i]['$key']", $val);
510 $ret .= "\n/* End of servers configuration */\n\n";
512 unset($c['Servers']);
514 foreach ($c as $key => $val) {
515 $ret .= get_cfg_val("\$cfg['$key']", $val);
518 $ret .= "?>\n";
519 return $ret;
523 * Compresses server configuration to be indexed from 0 and contain no gaps
525 * @param array configuration
527 * @return nothing
529 function compress_servers(&$cfg) {
530 $ns = array();
531 foreach ($cfg['Servers'] as $val) {
532 if (!empty($val['host'])) {
533 $ns[] = $val;
536 $cfg['Servers'] = $ns;
540 * Grabs values from POST
542 * @param string list of values to grab, values are separated by ";",
543 * each can have defined type separated by ":", if no type
544 * is defined, string is assumed. Possible types: bool -
545 * boolean value, serialized - serialized value, int -
546 * integer, tristate - "TRUE"/"FALSE" converted to bool,
547 * other strings are kept.
549 * @return array array with grabbed values
551 function grab_values($list)
553 $a = split(';', $list);
554 $res = array();
555 foreach ($a as $val) {
556 $v = split(':', $val);
557 if (!isset($v[1])) {
558 $v[1] = '';
560 switch($v[1]) {
561 case 'bool':
562 $res[$v[0]] = isset($_POST[$v[0]]);
563 break;
564 case 'serialized':
565 if (isset($_POST[$v[0]]) && strlen($_POST[$v[0]]) > 0) {
566 $res[$v[0]] = unserialize($_POST[$v[0]]);
568 break;
569 case 'int':
570 if (isset($_POST[$v[0]]) && strlen($_POST[$v[0]]) > 0) {
571 $res[$v[0]] = (int)$_POST[$v[0]];
573 break;
574 case 'tristate':
575 if (isset($_POST[$v[0]]) && strlen($_POST[$v[0]]) > 0) {
576 $cur = $_POST[$v[0]];
577 if ($cur == 'TRUE') {
578 $res[$v[0]] = TRUE;
579 } elseif ($cur == 'FALSE') {
580 $res[$v[0]] = FALSE;
581 } else {
582 $res[$v[0]] = $cur;
585 break;
586 case 'string':
587 default:
588 if (isset($_POST[$v[0]]) && strlen($_POST[$v[0]]) > 0) {
589 $res[$v[0]] = $_POST[$v[0]];
591 break;
594 return $res;
598 * Displays overview
600 * @param string title of oveview
601 * @param array list of values to display (each element is array of two
602 * values - name and value)
603 * @param string optional buttons to be displayed
605 * @return nothing
607 function show_overview($title, $list, $buttons = '') {
608 echo '<fieldset class="overview">' . "\n";
609 echo '<legend>' . $title . '</legend>' . "\n";
610 foreach ($list as $val) {
611 echo '<div class="row">';
612 echo '<div class="desc">';
613 echo $val[0];
614 echo '</div>';
615 echo '<div class="data">';
616 echo $val[1];
617 echo '</div>';
618 echo '</div>' . "\n";
620 if (!empty($buttons)) {
621 echo '<div class="buttons">';
622 echo '<div class="desc">Actions:</div>';
623 echo $buttons;
624 echo '</div>' . "\n";
626 echo '</fieldset>' . "\n";
627 echo "\n";
631 * Displays configuration, fallback defaults are taken from global $PMA_Config
633 * @param array list of values to display (each element is array of two or
634 * three values - desription, name and optional type
635 * indicator). Type is determined by type of this parameter,
636 * array means select and array elements are items,
637 * 'password' means password input.
638 * @param string title of configuration
639 * @param string help string for this configuration
640 * @param array optional first level defaults
641 * @param string optional title for save button
642 * @param string optional prefix for documentation links
644 * @return nothing
646 function show_config_form($list, $legend, $help, $defaults = array(), $save = '', $prefix = '') {
647 global $PMA_Config;
649 if (empty($save)) {
650 $save = 'Update';
653 echo '<fieldset class="optbox">' . "\n";
654 echo '<legend>' . $legend . '</legend>' . "\n";
655 echo '<p>' . $help . '</p>' . "\n";
656 foreach ($list as $val) {
657 echo '<div class="opts">';
658 $type = 'text';
659 if (isset($val[3])) {
660 if (is_array($val[3])) {
661 $type = 'select';
662 } elseif (is_bool($val[3])) {
663 $type = 'check';
664 } elseif ($val[3] == 'password') {
665 $type = 'password';
668 switch ($type) {
669 case 'text':
670 case 'password':
671 echo '<label for="text_' . $val[1] . '" class="desc" title="' . $val[2] . '">' . $val[0] . get_cfg_doc($prefix . $val[1]) . '</label>';
672 echo '<input type="' . $type . '" name="' . $val[1] . '" id="text_' . $val[1] . '" title="' . $val[2] . '" size="50"';
673 if (isset($defaults[$val[1]])) {
674 echo ' value="' . htmlspecialchars($defaults[$val[1]]) . '"';
675 } else {
676 echo ' value="' . htmlspecialchars($PMA_Config->get($val[1])) . '"';
678 echo ' />';
679 break;
680 case 'check':
681 echo '<input type="checkbox" name="' . $val[1] . '" value="something" id="checkbox_' . $val[1] . '" title="' . $val[2] . '"';
682 if (isset($defaults[$val[1]])) {
683 if ($defaults[$val[1]]) {
684 echo ' checked="checked"';
686 } else {
687 if ($PMA_Config->get($val[1])) {
688 echo ' checked="checked"';
691 echo ' />';
692 echo '<label for="checkbox_' . $val[1] . '" title="' . $val[2] . '">' . $val[0] . get_cfg_doc($prefix . $val[1]) . '</label>';
693 break;
694 case 'select':
695 echo '<label for="select_' . $val[1] . '" class="desc" title="' . $val[2] . '">' . $val[0] . get_cfg_doc($prefix . $val[1]) . '</label>';
696 echo '<select name="' . $val[1] . '" id="select_' . $val[1] . '" ' . ' title="' . $val[2] . '">';
697 foreach ($val[3] as $opt) {
698 echo '<option value="' . $opt . '"';
699 if (isset($defaults[$val[1]])) {
700 if (is_bool($defaults[$val[1]])) {
701 if (($defaults[$val[1]] && $opt == 'TRUE') || (!$defaults[$val[1]] && $opt == 'FALSE')) {
702 echo ' selected="selected"';
704 } else {
705 if ($defaults[$val[1]] == $opt) {
706 echo ' selected="selected"';
709 } else {
710 $def_val = $PMA_Config->get($val[1]);
711 if (is_bool($val)) {
712 if (($def_val && $opt == 'TRUE') || (!$def_val && $opt == 'FALSE')) {
713 echo ' selected="selected"';
715 } else {
716 if ($def_val == $opt) {
717 echo ' selected="selected"';
720 unset($def_val);
722 echo '>' . $opt . '</option>';
724 echo '</select>';
725 break;
727 echo '</div>' . "\n";
729 echo '<div class="buttons">';
730 echo '<div class="desc">Actions:</div>';
731 echo '<input type="submit" name="submit_save" value="' . $save .'" class="save" />';
732 echo '<input type="submit" name="submit_ignore" value="Cancel" class="cancel" />';
733 echo '</div>' . "\n";
734 echo '</fieldset>' . "\n";
735 echo "\n";
739 * Shows security options configuration form
741 * @param array optional defaults
743 * @return nothing
745 function show_security_form($defaults = array()) {
747 <form method="post" action="">
748 <input type="hidden" name="token" value="<?php echo $_SESSION['PMA_token']; ?>" />
749 <input type="hidden" name="action" value="feat_security_real" />
750 <?php
751 echo get_hidden_cfg();
752 show_config_form(array(
753 array('Blowfish secret', 'blowfish_secret', 'Secret passphrase used for encrypting cookies'),
754 array('Force SSL connection', 'ForceSSL', 'Whether to force using secured connection while using phpMyAdmin', FALSE),
755 array('Show phpinfo output', 'ShowPhpInfo', 'Whether to allow users to see phpinfo() output', FALSE),
756 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),
757 array('Allow login to any MySQL server', 'AllowArbitraryServer', 'If enabled user can enter any MySQL server in login form for cookie auth.', FALSE),
758 array('Recall user name', 'LoginCookieRecall', 'Whether to recall user name while using cookie auth.', TRUE),
759 array('Login cookie validity', 'LoginCookieValidity', 'How long is login valid without performing any action.'),
761 'Configure security features',
762 'Please note that phpMyAdmin is just a user interface and it\'s features do not limit MySQL.',
763 $defaults);
765 </form>
766 <?php
770 * Shows MySQL manual configuration form
772 * @param array optional defaults
774 * @return nothing
776 function show_manual_form($defaults = array()) {
778 <form method="post" action="">
779 <input type="hidden" name="token" value="<?php echo $_SESSION['PMA_token']; ?>" />
780 <input type="hidden" name="action" value="feat_manual_real" />
781 <?php
782 echo get_hidden_cfg();
783 show_config_form(array(
784 array('Type of MySQL documentation', 'MySQLManualType', 'These types are same as listed on MySQL download page', array('viewable', 'chapters', 'big', 'none')),
785 array('Base URL of MySQL documentation', 'MySQLManualBase', 'Where is MySQL documentation placed, this is usually top level directory.'),
787 'Configure MySQL manual links',
788 '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.',
789 $defaults);
791 </form>
792 <?php
796 * Shows charset options configuration form
798 * @param array optional defaults
800 * @return nothing
802 function show_charset_form($defaults = array()) {
803 global $PMA_Config;
805 <form method="post" action="">
806 <input type="hidden" name="token" value="<?php echo $_SESSION['PMA_token']; ?>" />
807 <input type="hidden" name="action" value="feat_charset_real" />
808 <?php
809 echo get_hidden_cfg();
810 show_config_form(array(
811 array('Allow charset conversion', 'AllowAnywhereRecoding', 'If you want to use such functions.', FALSE),
812 array('Default charset', 'DefaultCharset', 'Default charset for conversion.', $PMA_Config->get('AvailableCharsets')),
813 array('Recoding engine', 'RecodingEngine', 'PHP can contain iconv and/or recode, select which one to use or keep autodetection.', array('auto', 'iconv', 'recode')),
814 array('Extra params for iconv', 'IconvExtraParams', 'Iconv can get some extra parameters for conversion see man iconv_open.'),
816 'Configure charset conversions',
817 'phpMyAdmin can perform charset conversions so that you can import and export in any charset you want.',
818 $defaults);
820 </form>
821 <?php
825 * Shows PHP extensions configuration form
827 * @param array optional defaults
829 * @return nothing
831 function show_extensions_form($defaults = array()) {
833 <form method="post" action="">
834 <input type="hidden" name="token" value="<?php echo $_SESSION['PMA_token']; ?>" />
835 <input type="hidden" name="action" value="feat_extensions_real" />
836 <?php
837 echo get_hidden_cfg();
838 show_config_form(array(
839 array('GD 2 is available', 'GD2Available', 'Whether you have GD 2 or newer installed', array('auto', 'yes', 'no')),
841 'Configure extensions',
842 '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.',
843 $defaults);
845 </form>
846 <?php
850 * Shows MIME/relation/history configuration form
852 * @param array optional defaults
854 * @return nothing
856 function show_relation_form($defaults = array()) {
857 global $PMA_Config;
859 <form method="post" action="">
860 <input type="hidden" name="token" value="<?php echo $_SESSION['PMA_token']; ?>" />
861 <input type="hidden" name="action" value="feat_relation_real" />
862 <?php
863 echo get_hidden_cfg();
864 show_config_form(array(
865 array('Permanent query history', 'QueryHistoryDB', 'Store history into database.', FALSE),
866 array('Maximal history size', 'QueryHistoryMax', 'How many queries are kept in history.'),
867 array('Use MIME transformations', 'BrowseMIME', 'Use MIME transformations while browsing.', TRUE),
868 array('PDF default page size', 'PDFDefaultPageSize', 'Default page size for PDF, you can change this while creating page.', $PMA_Config->get('PDFPageSizes')),
870 'Configure MIME/relation/history',
871 'phpMyAdmin can provide additional featrues like MIME transformation, internal relations, permanent history and PDF pages generating. You have to configure database and tables that will store such information on server page. Behaviour of those functions is configured here.',
872 $defaults);
874 </form>
875 <?php
879 * Shows upload/save configuration form
881 * @param array optional defaults
883 * @return nothing
885 function show_upload_form($defaults = array()) {
887 <form method="post" action="">
888 <input type="hidden" name="token" value="<?php echo $_SESSION['PMA_token']; ?>" />
889 <input type="hidden" name="action" value="feat_upload_real" />
890 <?php
891 echo get_hidden_cfg();
892 show_config_form(array(
893 array('Upload directory', 'UploadDir', 'Directory on server where you can upload files for import'),
894 array('Save directory', 'SaveDir', 'Directory where exports can be saved on server'),
895 array('Directory with docSQL', 'docSQLDir', 'Directory on server where you can place docSQL files for import'),
897 'Configure upload/save directories',
898 'Enter directories, either absolute path or relative to phpMyAdmin top level directory.',
899 $defaults);
901 </form>
902 <?php
906 * Shows server configuration form
908 * @param array optional defaults
910 * @return nothing
912 function show_server_form($defaults = array(), $number = FALSE) {
914 <form method="post" action="">
915 <input type="hidden" name="token" value="<?php echo $_SESSION['PMA_token']; ?>" />
916 <input type="hidden" name="action" value="addserver_real" />
917 <?php
918 echo get_hidden_cfg();
919 if (!($number === FALSE)) {
920 echo '<input type="hidden" name="server" value="' . $number . '" />';
922 $hi = array ('bookmarktable', 'relation', 'table_info', 'table_coords', 'pdf_pages', 'column_info', 'history', 'AllowDeny');
923 foreach ($hi as $k) {
924 if (isset($defaults[$k]) && (!is_string($defaults[$k]) || strlen($defaults[$k]) > 0)) {
925 echo '<input type="hidden" name="' . $k . '" value="' . htmlspecialchars(serialize($defaults[$k])) . '" />';
928 show_config_form(array(
929 array('Server hostname', 'host', 'Hostname where MySQL server is running'),
930 array('Server port', 'port', 'Port on which MySQL server is listening, leave empty if don\'t know'),
931 array('Server socket', 'socket', 'Socket on which MySQL server is listening, leave empty if don\'t know'),
932 array('Connection type', 'connect_type', 'How to connect to server, keep tcp if don\'t know', array('tcp', 'socket')),
933 array('PHP extension to use', 'extension', 'What PHP extension to use, use mysqli if supported', array('mysql', 'mysqli')),
934 array('Compress connection', 'compress', 'Whether to compress connection to MySQL server', FALSE),
935 array('Authentication type', 'auth_type', 'Authentication method to use', array('cookie', 'http', 'config')),
936 array('User for config auth', 'user', 'Leave empty if not using config auth'),
937 array('Password for config auth', 'password', 'Leave empty if not using config auth', 'password'),
938 array('Only database to show', 'only_db', 'Limit listing of databases in left frame to this one'),
939 array('Verbose name of this server', 'verbose', 'Name to display in server selection'),
940 array('phpMyAdmin control user', 'controluser', 'User which phpMyAdmin can use for various actions'),
941 array('phpMyAdmin control user password', 'controlpass', 'Password for user which phpMyAdmin can use for various actions', 'password'),
942 array('phpMyAdmin database for advanced features', 'pmadb', 'phpMyAdmin will allow much more when you enable this. Table names are filled in automatically.'),
944 'Configure server',
945 ($number === FALSE) ? 'Enter new server connection parameters.' : 'Editing server ' . get_server_name($defaults, $number),
946 $defaults, $number === FALSE ? 'Add' : '', 'Servers_');
948 </form>
949 <?php
953 * Shows left frame configuration form
955 * @param array optional defaults
957 * @return nothing
959 function show_left_form($defaults = array()) {
961 <form method="post" action="">
962 <input type="hidden" name="token" value="<?php echo $_SESSION['PMA_token']; ?>" />
963 <input type="hidden" name="action" value="lay_left_real" />
964 <?php
965 echo get_hidden_cfg();
966 show_config_form(array(
967 array('Use light version', 'LeftFrameLight', 'Disable this if you want to see all databases at one time.', TRUE),
968 array('Display databases in tree', 'LeftFrameDBTree', 'Whether to display databases in tree (determined by separator defined lower)', TRUE),
969 array('Databases tree separator', 'LeftFrameDBSeparator', 'String that separates databases into different tree level'),
970 array('Table tree separator', 'LeftFrameTableSeparator', 'String that separates tables into different tree level'),
971 array('Maximum table tree nesting', 'LeftFrameTableLevel', 'Maximum number of childs in table tree'),
972 array('Show logo', 'LeftDisplayLogo', 'Whether to show logo in left frame', TRUE),
973 array('Display servers selection', 'LeftDisplayServers', 'Whether to show server selection in left frame', FALSE),
974 array('Enable pointer highlighting', 'LeftPointerEnable', 'Whether you want to highlight server under mouse', TRUE),
976 'Configure left frame',
977 'Choose how do you like left frame.',
978 $defaults);
980 </form>
981 <?php
985 * Shows tabs configuration form
987 * @param array optional defaults
989 * @return nothing
991 function show_tabs_form($defaults = array()) {
993 <form method="post" action="">
994 <input type="hidden" name="token" value="<?php echo $_SESSION['PMA_token']; ?>" />
995 <input type="hidden" name="action" value="lay_tabs_real" />
996 <?php
997 echo get_hidden_cfg();
998 show_config_form(array(
999 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')),
1000 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')),
1001 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')),
1002 array('Use lighter tabs', 'LightTabs', 'If you want simpler tabs enable this', FALSE),
1004 'Configure tabs',
1005 'Choose how you want tabs to work.',
1006 $defaults);
1008 </form>
1009 <?php
1013 * Shows icons configuration form
1015 * @param array optional defaults
1017 * @return nothing
1019 function show_icons_form($defaults = array()) {
1021 <form method="post" action="">
1022 <input type="hidden" name="token" value="<?php echo $_SESSION['PMA_token']; ?>" />
1023 <input type="hidden" name="action" value="lay_icons_real" />
1024 <?php
1025 echo get_hidden_cfg();
1026 show_config_form(array(
1027 array('Icons on errors', 'ErrorIconic', 'Whether to use icons in error messages.', TRUE),
1028 array('Icons on main page', 'MainPageIconic', 'Whether to use icons on main page.', TRUE),
1029 array('Icons as help links', 'ReplaceHelpImg', 'Whether to use icons as help links.', TRUE),
1030 array('Navigation with icons', 'NavigationBarIconic', 'Whether to display navigation (eg. tabs) with icons.', array('TRUE', 'FALSE', 'both')),
1031 array('Properties pages with icons', 'PropertiesIconic', 'Whether to display properties (eg. table lists and structure) with icons.', array('TRUE', 'FALSE', 'both')),
1033 'Configure icons',
1034 'Select whether you prefer text or icons. Both means that text and icons will be displayed.',
1035 $defaults);
1037 </form>
1038 <?php
1042 * Shows browsing configuration form
1044 * @param array optional defaults
1046 * @return nothing
1048 function show_browse_form($defaults = array()) {
1050 <form method="post" action="">
1051 <input type="hidden" name="token" value="<?php echo $_SESSION['PMA_token']; ?>" />
1052 <input type="hidden" name="action" value="lay_browse_real" />
1053 <?php
1054 echo get_hidden_cfg();
1055 show_config_form(array(
1056 array('Display of values', 'DefaultDisplay', 'How to list values while browsing', array('horizontal', 'vertical', 'horizontalflipped')),
1057 array('Hightlight pointer', 'BrowsePointerEnable', 'Whether to highlight row under mouse.', TRUE),
1058 array('Use row marker', 'BrowseMarkerEnable', 'Whether to highlight selected row.', TRUE),
1059 array('Action buttons on left', 'ModifyDeleteAtLeft', 'Show action buttons on left side of listing?', TRUE),
1060 array('Action buttons on right', 'ModifyDeleteAtRight', 'Show action buttons on right side of listing?', FALSE),
1061 array('Repeat heading', 'RepeatCells', 'After how many rows heading should be repeated.'),
1063 'Configure browsing',
1064 'Select desired browsing look and feel.',
1065 $defaults);
1067 </form>
1068 <?php
1072 * Shows editing options configuration form
1074 * @param array optional defaults
1076 * @return nothing
1078 function show_edit_form($defaults = array()) {
1080 <form method="post" action="">
1081 <input type="hidden" name="token" value="<?php echo $_SESSION['PMA_token']; ?>" />
1082 <input type="hidden" name="action" value="lay_edit_real" />
1083 <?php
1084 echo get_hidden_cfg();
1085 show_config_form(array(
1086 array('Display of properties while editing', 'DefaultPropDisplay', 'How to list properties (table structure or values) while editing', array('horizontal', 'vertical')),
1087 array('Number of inserted rows', 'InsertRows', 'How many rows can be inserted at once'),
1088 array('Move using Ctrl+arrows', 'CtrlArrowsMoving', 'Whether to enable moving using Ctrl+Arrows', TRUE),
1089 array('Autoselect text in textarea', 'TextareaAutoSelect', 'Whether to automatically select text in textarea on focus.', TRUE),
1090 array('Textarea columns', 'TextareaCols', 'Number of columns in textarea while editing TEXT fields'),
1091 array('Textarea rows', 'TextareaRows', 'Number of rows in textarea while editing TEXT fields'),
1092 array('Double textarea for LONGTEXT', 'LongtextDoubleTextarea', 'Whether to double textarea size for LONGTEXT fields', TRUE),
1093 array('Edit CHAR fields in textarea', 'CharEditing', 'Whether to edit CHAR fields in textaread', array('input', 'textarea')),
1094 array('CHAR textarea columns', 'CharTextareaCols', 'Number of columns in textarea while editing CHAR fields (must be enabled above)'),
1095 array('CHAR textarea rows', 'CharTextareaRows', 'Number of rows in textarea while editing CHAR fields (must be enabled above)'),
1097 'Configure editing',
1098 'Select desired editing look and feel.',
1099 $defaults);
1101 </form>
1102 <?php
1106 * Shows query window configuration form
1108 * @param array optional defaults
1110 * @return nothing
1112 function show_window_form($defaults = array()) {
1114 <form method="post" action="">
1115 <input type="hidden" name="token" value="<?php echo $_SESSION['PMA_token']; ?>" />
1116 <input type="hidden" name="action" value="lay_window_real" />
1117 <?php
1118 echo get_hidden_cfg();
1119 show_config_form(array(
1120 array('Edit SQL in window', 'EditInWindow', 'Whether edit links will edit in query window.', TRUE),
1121 array('Query window height', 'QueryWindowHeight', 'Height of query window'),
1122 array('Query window width', 'QueryWindowWidth', 'Width of query window'),
1123 array('Default tab', 'QueryWindowDefTab', 'Default tab on query window', array('sql', 'files', 'history', 'full')),
1125 'Configure query window',
1126 'Select desired query window look and feel.',
1127 $defaults);
1129 </form>
1130 <?php
1134 * Creates selection with servers
1136 * @param array configuraion
1138 * @return string HTML for server selection
1140 function get_server_selection($cfg) {
1141 if (count($cfg['Servers']) == 0) {
1142 return '';
1144 $ret = '<select name="server">';
1145 foreach ($cfg['Servers'] as $key => $val) {
1146 $ret .= '<option value="' . $key . '">' . get_server_name($val, $key) . '</option>';
1148 $ret .= '</select>';
1149 return $ret;
1153 * Loads configuration from file
1155 * @param string filename
1157 * @return mixed FALSE on failure, new config array on success
1159 function load_config($config_file) {
1160 if ( file_exists( $config_file ) ) {
1161 $success_apply_user_config = FALSE;
1162 $old_error_reporting = error_reporting( 0 );
1163 if ( function_exists( 'file_get_contents' ) ) {
1164 $success_apply_user_config = eval('?>' . trim(file_get_contents($config_file)));
1165 } else {
1166 $success_apply_user_config =
1167 eval('?>' . trim(implode("\n", file($config_file))));
1169 error_reporting( $old_error_reporting );
1170 unset( $old_error_reporting );
1171 if ($success_apply_user_config === FALSE) {
1172 message('error', 'Error while parsing configuration file!');
1173 } elseif (!isset($cfg) || count($cfg) == 0) {
1174 message('error', 'Config file seems to contain no configuration!');
1175 } else {
1176 // This must be set
1177 if (!isset($cfg['Servers'])) {
1178 $cfg['Servers'] = array();
1180 message('notice', 'Configuration loaded');
1181 compress_servers($cfg);
1182 return $cfg;
1184 } else {
1185 message('error', 'Configuration file not found!');
1187 return FALSE;
1190 if ($action != 'download') {
1191 // Check whether we can write to configuration
1192 $fail_dir = FALSE;
1193 $fail_dir = $fail_dir || !is_dir('./config/');
1194 $fail_dir = $fail_dir || !is_writable('./config/');
1195 $fail_dir = $fail_dir || (file_exists('./config/config.inc.php') && !is_writable('./config/config.inc.php'));
1196 $config = @fopen('./config/config.inc.php', 'a');
1197 $fail_dir = $fail_dir || ($config === FALSE);
1198 @fclose($config);
1202 * @var boolean whether to show configuration overview
1204 $show_info = FALSE;
1206 // Do the main work depending on selected action
1207 switch ($action) {
1208 case 'download':
1209 header('Content-Type: text/plain');
1210 header('Content-Disposition: attachment; filename="config.inc.php"');
1212 echo get_cfg_string($configuration);
1213 exit;
1214 break;
1215 case 'display':
1216 echo '<form method="none" action=""><textarea name="config" cols="50" rows="20" id="textconfig" wrap="off">' . "\n";
1217 echo htmlspecialchars(get_cfg_string($configuration));
1218 echo '</textarea></form>' . "\n";
1220 <script type="text/javascript" language="javascript">
1221 //<![CDATA[
1222 var bodyWidth=null; var bodyHeight=null;
1223 if (document.getElementById('textconfig')) {
1224 bodyWidth = self.innerWidth;
1225 bodyHeight = self.innerHeight;
1226 if(!bodyWidth && !bodyHeight){
1227 if (document.compatMode && document.compatMode == "BackCompat") {
1228 bodyWidth = document.body.clientWidth;
1229 bodyHeight = document.body.clientHeight;
1230 } else if (document.compatMode && document.compatMode == "CSS1Compat") {
1231 bodyWidth = document.documentElement.clientWidth;
1232 bodyHeight = document.documentElement.clientHeight;
1235 document.getElementById('textconfig').style.width=(bodyWidth-50) + 'px';
1236 document.getElementById('textconfig').style.height=(bodyHeight-100) + 'px';
1238 //]]>
1239 </script>
1240 <?php
1241 break;
1242 case 'save':
1243 $config = @fopen('./config/config.inc.php', 'w');
1244 if ($config === FALSE) {
1245 message('error', 'Could not open config file for writing! Bad permissions?');
1246 break;
1248 $s = get_cfg_string($configuration);
1249 $r = fwrite($config, $s);
1250 if (!$r || $r != strlen($s)) {
1251 message('error', 'Could not write to config file! Not enough space?');
1252 break;
1253 } else {
1254 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');
1256 unset($r, $s);
1257 fclose($config);
1258 break;
1259 case 'load':
1260 if ($fail_dir) {
1261 message('error', 'Reading of configuration disabled because of permissions.');
1262 break;
1264 $new_cfg = load_config('./config/config.inc.php');
1265 if (!($new_cfg === FALSE)) {
1266 $configuration = $new_cfg;
1268 $show_info = TRUE;
1269 break;
1271 case 'addserver_real':
1272 if (isset($_POST['submit_save'])) {
1273 $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');
1274 $err = FALSE;
1275 if (empty($new_server['host'])) {
1276 message('error', 'Empty hostname!');
1277 $err = TRUE;
1279 if ($new_server['auth_type'] == 'config' && empty($new_server['user'])) {
1280 message('error', 'Empty username while using config authentication method!');
1281 $err = TRUE;
1283 if ( isset($new_server['pmadb']) && strlen($new_server['pmadb'])) {
1284 // Just use defaults, should be okay for most users
1285 $pmadb = array();
1286 $pmadb['bookmarktable'] = 'pma_bookmark';
1287 $pmadb['relation'] = 'pma_relation';
1288 $pmadb['table_info'] = 'pma_table_info';
1289 $pmadb['table_coords'] = 'pma_table_coords';
1290 $pmadb['pdf_pages'] = 'pma_pdf_pages';
1291 $pmadb['column_info'] = 'pma_column_info';
1292 $pmadb['history'] = 'pma_history';
1294 $new_server = array_merge($pmadb, $new_server);
1295 unset($pmadb);
1296 if (empty($new_server['controluser'])) {
1297 message('error', 'Empty phpMyAdmin control user while using pmadb!');
1298 $err = TRUE;
1300 if (empty($new_server['controlpass'])) {
1301 message('error', 'Empty phpMyAdmin control user password while using pmadb!');
1302 $err = TRUE;
1304 } else {
1305 message('warning', 'You didn\'t set phpMyAdmin database, so you can not use all phpMyAdmin features.');
1307 if ($new_server['auth_type'] == 'config') {
1308 message('warning', 'Remember to protect your installation while using config authentication method!');
1309 } else {
1310 // Not needed:
1311 unset($new_server['user']);
1312 unset($new_server['password']);
1314 if ($err) {
1315 show_server_form($new_server, isset($_POST['server']) ? $_POST['server'] : FALSE);
1316 } else {
1317 if (isset($_POST['server'])) {
1318 $configuration['Servers'][$_POST['server']] = $new_server;
1319 message('notice', 'Changed server ' . get_server_name($new_server, $_POST['server']));
1320 } else {
1321 $configuration['Servers'][] = $new_server;
1322 message('notice', 'New server added');
1324 $show_info = TRUE;
1325 if ($new_server['auth_type'] == 'cookie' && empty($configuration['blowfish_secret'])) {
1326 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');
1327 $configuration['blowfish_secret'] = uniqid('', TRUE);
1330 unset($new_server);
1331 } else {
1332 $show_info = TRUE;
1334 break;
1335 case 'addserver':
1336 if (count($configuration['Servers']) == 0) {
1337 // First server will use defaults as in config.default.php
1338 $defaults = $PMA_Config->default_server;
1339 unset($defaults['AllowDeny']); // Ignore this for now
1340 } else {
1341 $defaults = array();
1344 // Guess MySQL extension to use, prefer mysqli
1345 if (!function_exists('mysql_get_client_info')) {
1346 PMA_dl('mysql');
1348 if (!function_exists('mysqli_get_client_info')) {
1349 PMA_dl('mysqli');
1351 if (function_exists('mysqli_get_client_info')) {
1352 $defaults['extension'] = 'mysqli';
1353 } elseif (function_exists('mysql_get_client_info')) {
1354 $defaults['extension'] = 'mysql';
1355 } else {
1356 message('warning', 'Could not load neither mysql nor mysqli extension, you might not be able to use phpMyAdmin!');
1358 if (isset($defaults['extension'])) {
1359 message('notice', 'Autodetected MySQL extension to use: ' . $defaults['extension']);
1362 // Display form
1363 show_server_form($defaults);
1364 break;
1365 case 'editserver':
1366 if (!isset($_POST['server'])) {
1367 footer();
1369 show_server_form($configuration['Servers'][$_POST['server']], $_POST['server']);
1370 break;
1371 case 'deleteserver':
1372 if (!isset($_POST['server'])) {
1373 footer();
1375 message('notice', 'Deleted server ' . get_server_name($configuration['Servers'][$_POST['server']], $_POST['server']));
1376 unset($configuration['Servers'][$_POST['server']]);
1377 compress_servers($configuration);
1378 $show_info = TRUE;
1379 break;
1380 case 'servers':
1381 if (count($configuration['Servers']) == 0) {
1382 message('notice', 'No servers defined, so none can be shown');
1383 } else {
1384 foreach ($configuration['Servers'] as $i => $srv) {
1385 $data = array();
1386 if (!empty($srv['verbose'])) {
1387 $data[] = array('Verbose name', $srv['verbose']);
1389 $data[] = array('Host', $srv['host']);
1390 $data[] = array('MySQL extension', isset($srv['extension']) ? $srv['extension'] : $PMA_Config->default_server['extension']);
1391 $data[] = array('Authentication type', get_server_auth($srv));
1392 $data[] = array('phpMyAdmin advanced features', empty($srv['pmadb']) || empty($srv['controluser']) || empty($srv['controlpass']) ? 'disabled' : 'enabled, db: ' . $srv['pmadb'] . ', user: ' . $srv['controluser']);
1393 $buttons =
1394 get_action('deleteserver', 'Delete', '<input type="hidden" name="server" value="' . $i . '" />') .
1395 get_action('editserver', 'Edit', '<input type="hidden" name="server" value="' . $i . '" />');
1396 show_overview('Server ' . get_server_name($srv, $i), $data, $buttons);
1399 break;
1401 case 'feat_upload_real':
1402 if (isset($_POST['submit_save'])) {
1403 $dirs = grab_values('UploadDir;SaveDir;docSQLDir');
1404 $err = FALSE;
1405 if (!empty($dirs['UploadDir']) && !is_dir($dirs['UploadDir'])) {
1406 message('error', 'Upload directory ' . htmlspecialchars($dirs['UploadDir']) . ' does not exist!');
1407 $err = TRUE;
1409 if (!empty($dirs['SaveDir']) && !is_dir($dirs['SaveDir'])) {
1410 message('error', 'Save directory ' . htmlspecialchars($dirs['SaveDir']) . ' does not exist!');
1411 $err = TRUE;
1413 if (!empty($dirs['docSQLDir']) && !is_dir($dirs['docSQLDir'])) {
1414 message('error', 'docSQL directory ' . htmlspecialchars($dirs['docSQLDir']) . ' does not exist!');
1415 $err = TRUE;
1417 if ($err) {
1418 show_upload_form($dirs);
1419 } else {
1420 $configuration = array_merge($configuration, $dirs);
1421 message('notice', 'Configuration changed');
1422 $show_info = TRUE;
1424 } else {
1425 $show_info = TRUE;
1427 break;
1428 case 'feat_upload':
1429 show_upload_form($configuration);
1430 break;
1432 case 'feat_security_real':
1433 if (isset($_POST['submit_save'])) {
1434 $vals = grab_values('blowfish_secret;ForceSSL:bool;ShowPhpInfo:bool;ShowChgPassword:bool;AllowArbitraryServer:bool;LoginCookieRecall:book;LoginCookieValidity:int');
1435 $err = FALSE;
1436 if (empty($vals['blowfish_secret'])) {
1437 message('warning', 'Blowfish secret is empty, you will not be able to use cookie authentication.');
1439 if ($vals['AllowArbitraryServer']) {
1440 message('warning', 'Arbitrary server connection might be dangerous as it might allow access to internal servers that are not reachable from outside.');
1442 if (isset($vals['LoginCookieValidity']) && $vals['LoginCookieValidity'] < 1) {
1443 message('error', 'Invalid cookie validity time');
1444 $err = TRUE;
1446 if ($err) {
1447 show_security_form($vals);
1448 } else {
1449 $configuration = array_merge($configuration, $vals);
1450 message('notice', 'Configuration changed');
1451 $show_info = TRUE;
1453 } else {
1454 $show_info = TRUE;
1456 break;
1457 case 'feat_security':
1458 show_security_form($configuration);
1459 break;
1461 case 'feat_manual_real':
1462 if (isset($_POST['submit_save'])) {
1463 $vals = grab_values('MySQLManualBase;MySQLManualType');
1464 $err = FALSE;
1465 if ($vals['MySQLManualType'] != 'none' && empty($vals['MySQLManualBase'])) {
1466 message('error', 'You need to set manual base URL or choone none type.');
1467 $err = TRUE;
1469 if ($err) {
1470 show_manual_form($vals);
1471 } else {
1472 $configuration = array_merge($configuration, $vals);
1473 message('notice', 'Configuration changed');
1474 $show_info = TRUE;
1476 } else {
1477 $show_info = TRUE;
1479 break;
1480 case 'feat_manual':
1481 show_manual_form($configuration);
1482 break;
1484 case 'feat_charset_real':
1485 if (isset($_POST['submit_save'])) {
1486 $vals = grab_values('AllowAnywhereRecoding:bool;DefaultCharset;RecodingEngine;IconvExtraParams');
1487 $err = FALSE;
1488 if ($err) {
1489 show_charset_form($vals);
1490 } else {
1491 $configuration = array_merge($configuration, $vals);
1492 message('notice', 'Configuration changed');
1493 $show_info = TRUE;
1495 } else {
1496 $show_info = TRUE;
1498 break;
1499 case 'feat_charset':
1500 $d = $configuration;
1501 if (!isset($d['RecodingEngine'])) {
1502 if (@extension_loaded('iconv')) {
1503 $d['RecodingEngine'] = 'iconv';
1504 } elseif (@extension_loaded('recode')) {
1505 $d['RecodingEngine'] = 'recode';
1506 } else {
1507 PMA_dl('iconv');
1508 if (!@extension_loaded('iconv')) {
1509 PMA_dl('recode');
1510 if (!@extension_loaded('recode')) {
1511 message('warning', 'Could not load neither recode nor iconv so charset conversion will most likely not work.');
1512 } else {
1513 $d['RecodingEngine'] = 'recode';
1515 } else {
1516 $d['RecodingEngine'] = 'iconv';
1519 if (isset($d['RecodingEngine'])) {
1520 message('notice', 'Autodetected recoding engine: ' . $d['RecodingEngine']);
1523 show_charset_form($d);
1524 unset($d);
1525 break;
1527 case 'feat_extensions_real':
1528 if (isset($_POST['submit_save'])) {
1529 $vals = grab_values('GD2Available');
1530 $err = FALSE;
1531 if ($err) {
1532 show_extensions_form($vals);
1533 } else {
1534 $configuration = array_merge($configuration, $vals);
1535 message('notice', 'Configuration changed');
1536 $show_info = TRUE;
1538 } else {
1539 $show_info = TRUE;
1541 break;
1542 case 'feat_extensions':
1543 $d = $configuration;
1544 if (!@extension_loaded('mbstring')) {
1545 PMA_dl('mbstring');
1547 if (!@extension_loaded('mbstring')) {
1548 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.');
1550 if (!isset($d['GD2Available'])) {
1551 if (PMA_IS_GD2 == 1) {
1552 message('notice', 'GD 2 or newer found.');
1553 $d['GD2Available'] = 'yes';
1554 } else {
1555 message('warning', 'GD 2 or newer is not present.');
1556 $d['GD2Available'] = 'no';
1559 show_extensions_form($d);
1560 unset($d);
1561 break;
1563 case 'feat_relation_real':
1564 if (isset($_POST['submit_save'])) {
1565 $vals = grab_values('QueryHistoryDB:bool;QueryHistoryMax:int;BrowseMIME:bool;PDFDefaultPageSize');
1566 $err = FALSE;
1567 if (isset($vals['QueryHistoryMax']) && $vals['QueryHistoryMax'] < 1) {
1568 message('error', 'Invalid value for query maximal history size!');
1569 $err = TRUE;
1571 if ($err) {
1572 show_relation_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_relation':
1583 show_relation_form($configuration);
1584 break;
1586 case 'lay_left_real':
1587 if (isset($_POST['submit_save'])) {
1588 $vals = grab_values('LeftFrameLight:bool;LeftFrameDBTree:bool;LeftFrameDBSeparator;LeftFrameTableSeparator;LeftFrameTableLevel:int;LeftDisplayLogo:bool;LeftDisplayServers:bool;LeftPointerEnable:bool');
1589 $err = FALSE;
1590 if (isset($vals['LeftFrameTableLevel']) && $vals['LeftFrameTableLevel'] < 1) {
1591 message('error', 'Invalid value for maximum table nesting level!');
1592 $err = TRUE;
1594 if ($err) {
1595 show_left_form($vals);
1596 } else {
1597 $configuration = array_merge($configuration, $vals);
1598 message('notice', 'Configuration changed');
1599 $show_info = TRUE;
1601 } else {
1602 $show_info = TRUE;
1604 break;
1605 case 'lay_left':
1606 show_left_form($configuration);
1607 break;
1609 case 'lay_tabs_real':
1610 if (isset($_POST['submit_save'])) {
1611 $vals = grab_values('DefaultTabServer;DefaultTabDatabase;DefaultTabTable;LightTabs:bool');
1612 $err = FALSE;
1613 if ($err) {
1614 show_tabs_form($vals);
1615 } else {
1616 $configuration = array_merge($configuration, $vals);
1617 message('notice', 'Configuration changed');
1618 $show_info = TRUE;
1620 } else {
1621 $show_info = TRUE;
1623 break;
1624 case 'lay_tabs':
1625 show_tabs_form($configuration);
1626 break;
1628 case 'lay_icons_real':
1629 if (isset($_POST['submit_save'])) {
1630 $vals = grab_values('ErrorIconic:bool;MainPageIconic:bool;ReplaceHelpImg:bool;NavigationBarIconic:tristate;PropertiesIconic:tristate');
1631 $err = FALSE;
1632 if ($err) {
1633 show_icons_form($vals);
1634 } else {
1635 $configuration = array_merge($configuration, $vals);
1636 message('notice', 'Configuration changed');
1637 $show_info = TRUE;
1639 } else {
1640 $show_info = TRUE;
1642 break;
1643 case 'lay_icons':
1644 show_icons_form($configuration);
1645 break;
1647 case 'lay_browse_real':
1648 if (isset($_POST['submit_save'])) {
1649 $vals = grab_values('BrowsePointerEnable:bool;BrowseMarkerEnable:bool;ModifyDeleteAtRight:bool;ModifyDeleteAtLeft:bool;RepeatCells:int;DefaultDisplay');
1650 $err = FALSE;
1651 if (isset($vals['RepeatCells']) && $vals['RepeatCells'] < 1) {
1652 message('error', 'Invalid value for header repeating!');
1653 $err = TRUE;
1655 if (!$vals['ModifyDeleteAtLeft'] && !$vals['ModifyDeleteAtRight']) {
1656 message('error', 'No action buttons enabled!');
1657 $err = TRUE;
1659 if ($err) {
1660 show_browse_form($vals);
1661 } else {
1662 $configuration = array_merge($configuration, $vals);
1663 message('notice', 'Configuration changed');
1664 $show_info = TRUE;
1666 } else {
1667 $show_info = TRUE;
1669 break;
1670 case 'lay_browse':
1671 show_browse_form($configuration);
1672 break;
1674 case 'lay_edit_real':
1675 if (isset($_POST['submit_save'])) {
1676 $vals = grab_values('TextareaCols:int;TextareaRows:int;LongtextDoubleTextarea:bool;TextareaAutoSelect:bool;CharEditing;CharTextareaCols:int;CharTextareaRows:int;CtrlArrowsMoving:bool;DefaultPropDisplay;InsertRows:int');
1677 $err = FALSE;
1678 if (isset($vals['TextareaCols']) && $vals['TextareaCols'] < 1) {
1679 message('error', 'Invalid value for textarea columns!');
1680 $err = TRUE;
1682 if (isset($vals['TextareaRows']) && $vals['TextareaRows'] < 1) {
1683 message('error', 'Invalid value for textarea rows!');
1684 $err = TRUE;
1686 if (isset($vals['CharTextareaCols']) && $vals['CharTextareaCols'] < 1) {
1687 message('error', 'Invalid value for CHAR textarea columns!');
1688 $err = TRUE;
1690 if (isset($vals['CharTextareaRows']) && $vals['CharTextareaRows'] < 1) {
1691 message('error', 'Invalid value for CHAR textarea rows!');
1692 $err = TRUE;
1694 if (isset($vals['InsertRows']) && $vals['InsertRows'] < 1) {
1695 message('error', 'Invalid value for inserted rows count!');
1696 $err = TRUE;
1698 if ($err) {
1699 show_edit_form($vals);
1700 } else {
1701 $configuration = array_merge($configuration, $vals);
1702 message('notice', 'Configuration changed');
1703 $show_info = TRUE;
1705 } else {
1706 $show_info = TRUE;
1708 break;
1709 case 'lay_edit':
1710 show_edit_form($configuration);
1711 break;
1713 case 'lay_window_real':
1714 if (isset($_POST['submit_save'])) {
1715 $vals = grab_values('EditInWindow:bool;QueryWindowHeight:int;QueryWindowWidth:int;QueryWindowDefTab');
1716 $err = FALSE;
1717 if (isset($vals['QueryWindowWidth']) && $vals['QueryWindowWidth'] < 1) {
1718 message('error', 'Invalid value for query window width!');
1719 $err = TRUE;
1721 if (isset($vals['QueryWindowHeight']) && $vals['QueryWindowHeight'] < 1) {
1722 message('error', 'Invalid value for query window height');
1723 $err = TRUE;
1725 if ($err) {
1726 show_window_form($vals);
1727 } else {
1728 $configuration = array_merge($configuration, $vals);
1729 message('notice', 'Configuration changed');
1730 $show_info = TRUE;
1732 } else {
1733 $show_info = TRUE;
1735 break;
1736 case 'lay_window':
1737 show_window_form($configuration);
1738 break;
1740 /* Template for new actions:
1741 case 'blah_real':
1742 if (isset($_POST['submit_save'])) {
1743 $vals = grab_values('value1:bool;value2');
1744 $err = FALSE;
1745 if (somechekcfails) {
1746 message('error', 'Invalid value for blah!');
1747 $err = TRUE;
1749 if ($err) {
1750 show_blah_form($vals);
1751 } else {
1752 $configuration = array_merge($configuration, $vals);
1753 message('notice', 'Configuration changed');
1754 $show_info = TRUE;
1756 } else {
1757 $show_info = TRUE;
1759 break;
1760 case 'blah':
1761 show_blah_form($configuration);
1762 break;
1764 case 'versioncheck': // Check for latest available version
1765 PMA_dl('curl');
1766 $url = 'http://phpmyadmin.net/home_page/version.php';
1767 $data = '';
1768 $f = @fopen($url, 'r');
1769 if ($f === FALSE) {
1770 if (!function_exists('curl_init')) {
1771 message('error', 'Neither URL wrappers nor CURL are available. Version check is not possible.');
1772 break;
1774 } else {
1775 $data = fread($f, 20);
1776 fclose($f);
1778 if (empty($data) && function_exists('curl_init')) {
1779 $ch = curl_init($url);
1780 curl_setopt($ch, CURLOPT_HEADER, FALSE);
1781 curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
1782 $data = curl_exec($ch);
1783 curl_close($ch);
1785 if (empty($data)) {
1786 message('error', 'Reading of version failed. Maybe you\'re offline or server does not respond.');
1787 break;
1790 /* Format: version\ndate\n(download\n)* */
1791 $data_list = split("\n", $data);
1793 if (count($data_list) > 0) {
1794 $version = $data_list[0];
1795 } else {
1796 $version = '';
1799 $version_upstream = version_to_int($version);
1800 if ($version_upstream === FALSE) {
1801 message('error', 'Got invalid version string from server.');
1802 break;
1805 $version_local = version_to_int( $GLOBALS['PMA_Config']->get('PMA_VERSION') );
1806 if ($version_local === FALSE) {
1807 message('error', 'Unparsable version string.');
1808 break;
1811 if ($version_upstream > $version_local) {
1812 message('notice', 'New version of phpMyAdmin is available, you should consider upgrade. New version is ' . htmlspecialchars($version) . '.');
1813 } else {
1814 if ($version_local % 100 == 0) {
1815 message('notice', 'You are using CVS version, run <code>cvs update</code> :-). However latest released version is ' . htmlspecialchars($version) . '.');
1816 } else {
1817 message('notice', 'No newer stable version is available.');
1820 break;
1822 case 'clear': // Actual clearing is done on beginning of this script
1823 case 'main':
1824 $show_info = TRUE;
1825 break;
1827 case '':
1828 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');
1830 if ( $GLOBALS['PMA_Config']->get( 'PMA_PHP_INT_VERSION' ) < 40100) {
1831 message('warning', 'Please upgrade to PHP 4.1.0, it is required for phpMyAdmin.', 'Too old PHP');
1834 if ($fail_dir) {
1835 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');
1838 if (empty($_SERVER['HTTPS']) || strtolower($_SERVER['HTTPS']) == 'off') {
1839 if (empty($_SERVER['REQUEST_URI']) || empty($_SERVER['HTTP_HOST'])) {
1840 $redir = '';
1841 } else {
1842 $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.';
1844 message('warning', 'You are not using secure connection, all data (including sensitive, like passwords) are transfered unencrypted!' . $redir, 'Not secure connection');
1846 break;
1849 // Should we show information?
1850 if ($show_info) {
1851 $servers = 'none';
1852 $servers_text = 'Servers';
1853 if (count($configuration['Servers']) == 0) {
1854 message('warning', 'No servers defined, you probably want to add one.');
1855 } else {
1856 $servers = '';
1857 $servers_text = 'Servers (' . count($configuration['Servers']) . ')';
1859 $sep = '';
1860 foreach ($configuration['Servers'] as $key => $val) {
1861 $servers .= $sep;
1862 $sep = ', ';
1863 $servers .= get_server_name($val, $key);
1865 unset($sep);
1867 show_overview('Current configuration overview',
1868 array(
1869 array($servers_text, $servers),
1870 array('SQL files upload', empty($configuration['UploadDir']) ? 'disabled' : 'enabled'),
1871 array('Exported files on server', empty($configuration['SaveDir']) ? 'disabled' : 'enabled'),
1872 array('Charset conversion', isset($configuration['AllowAnywhereRecoding']) && $configuration['AllowAnywhereRecoding'] ? 'enabled' : 'disabled'),
1874 unset($servers_text, $servers);
1877 // And finally display all actions:
1878 echo '<p>Available global actions (please note that these will delete any changes you could have done above):</p>';
1880 echo '<fieldset class="toolbar"><legend>Servers</legend>' . "\n";
1881 echo get_action('addserver', 'Add');
1882 $servers = get_server_selection($configuration);
1883 if (!empty($servers)) {
1884 echo get_action('servers', 'List');
1885 echo get_action('deleteserver', 'Delete', $servers);
1886 echo get_action('editserver', 'Edit', $servers);
1888 echo '</fieldset>' . "\n\n";
1890 echo '<fieldset class="toolbar"><legend>Layout</legend>' . "\n";
1891 echo get_action('lay_left', 'Left frame');
1892 echo get_action('lay_tabs', 'Tabs');
1893 echo get_action('lay_icons', 'Icons');
1894 echo get_action('lay_browse', 'Browsing');
1895 echo get_action('lay_edit', 'Editing');
1896 echo get_action('lay_window', 'Query window');
1897 echo '</fieldset>' . "\n\n";
1899 echo '<fieldset class="toolbar"><legend>Features</legend>' . "\n";
1900 echo get_action('feat_upload', 'Upload/Download');
1901 echo get_action('feat_security', 'Security');
1902 echo get_action('feat_manual', 'MySQL manual');
1903 echo get_action('feat_charset', 'Charsets');
1904 echo get_action('feat_extensions', 'Extensions');
1905 echo get_action('feat_relation', 'MIME/Relation/History');
1906 echo '</fieldset>' . "\n\n";
1908 echo '<fieldset class="toolbar"><legend>Configuration</legend>' . "\n";
1909 echo get_action('main', 'Overview');
1910 echo get_action('display', 'Display');
1911 echo get_action('download', 'Download');
1912 echo get_action('save', 'Save', '', !$fail_dir);
1913 echo get_action('load', 'Load', '', !$fail_dir);
1914 echo get_action('clear', 'Clear');
1915 echo '</fieldset>' . "\n\n";
1917 echo '<fieldset class="toolbar"><legend>Other actions</legend>' . "\n";
1918 echo get_action('versioncheck', 'Check for latest version');
1919 echo get_url_action('http://www.phpmyadmin.net/', 'Go to homepage');
1920 echo get_url_action('https://sourceforge.net/donate/index.php', 'Donate to phpMyAdmin', array('group_id' => 23067));
1921 echo '</fieldset>' . "\n\n";
1923 footer();