Bug: Live query chart always zero
[phpmyadmin/tyronm.git] / libraries / Config.class.php
blob7beb4ccbe58b095bede2d4558869d2fec5029686
1 <?php
2 /* vim: set expandtab sw=4 ts=4 sts=4: */
3 /**
4 * Configuration handling.
6 * @package phpMyAdmin
7 */
9 /**
10 * Load vendor configuration.
12 require './libraries/vendor_config.php';
14 /**
15 * Configuration class
17 * @package phpMyAdmin
19 class PMA_Config
21 /**
22 * @var string default config source
24 var $default_source = './libraries/config.default.php';
26 /**
27 * @var array default configuration settings
29 var $default = array();
31 /**
32 * @var array configuration settings
34 var $settings = array();
36 /**
37 * @var string config source
39 var $source = '';
41 /**
42 * @var int source modification time
44 var $source_mtime = 0;
45 var $default_source_mtime = 0;
46 var $set_mtime = 0;
48 /**
49 * @var boolean
51 var $error_config_file = false;
53 /**
54 * @var boolean
56 var $error_config_default_file = false;
58 /**
59 * @var boolean
61 var $error_pma_uri = false;
63 /**
64 * @var array
66 var $default_server = array();
68 /**
69 * @var boolean whether init is done or not
70 * set this to false to force some initial checks
71 * like checking for required functions
73 var $done = false;
75 /**
76 * constructor
78 * @param string $source source to read config from
80 function __construct($source = null)
82 $this->settings = array();
84 // functions need to refresh in case of config file changed goes in
85 // PMA_Config::load()
86 $this->load($source);
88 // other settings, independent from config file, comes in
89 $this->checkSystem();
91 $this->checkIsHttps();
94 /**
95 * sets system and application settings
97 * @return nothing
99 function checkSystem()
101 $this->set('PMA_VERSION', '3.5.0-dev');
103 * @deprecated
105 $this->set('PMA_THEME_VERSION', 2);
107 * @deprecated
109 $this->set('PMA_THEME_GENERATION', 2);
111 $this->checkPhpVersion();
112 $this->checkWebServerOs();
113 $this->checkWebServer();
114 $this->checkGd2();
115 $this->checkClient();
116 $this->checkUpload();
117 $this->checkUploadSize();
118 $this->checkOutputCompression();
122 * whether to use gzip output compression or not
124 * @return nothing
126 function checkOutputCompression()
128 // If zlib output compression is set in the php configuration file, no
129 // output buffering should be run
130 if (@ini_get('zlib.output_compression')) {
131 $this->set('OBGzip', false);
134 // disable output-buffering (if set to 'auto') for IE6, else enable it.
135 if (strtolower($this->get('OBGzip')) == 'auto') {
136 if ($this->get('PMA_USR_BROWSER_AGENT') == 'IE'
137 && $this->get('PMA_USR_BROWSER_VER') >= 6
138 && $this->get('PMA_USR_BROWSER_VER') < 7
140 $this->set('OBGzip', false);
141 } else {
142 $this->set('OBGzip', true);
148 * Determines platform (OS), browser and version of the user
149 * Based on a phpBuilder article:
151 * @see http://www.phpbuilder.net/columns/tim20000821.php
153 * @return nothing
155 function checkClient()
157 if (PMA_getenv('HTTP_USER_AGENT')) {
158 $HTTP_USER_AGENT = PMA_getenv('HTTP_USER_AGENT');
159 } elseif (! isset($HTTP_USER_AGENT)) {
160 $HTTP_USER_AGENT = '';
163 // 1. Platform
164 if (strstr($HTTP_USER_AGENT, 'Win')) {
165 $this->set('PMA_USR_OS', 'Win');
166 } elseif (strstr($HTTP_USER_AGENT, 'Mac')) {
167 $this->set('PMA_USR_OS', 'Mac');
168 } elseif (strstr($HTTP_USER_AGENT, 'Linux')) {
169 $this->set('PMA_USR_OS', 'Linux');
170 } elseif (strstr($HTTP_USER_AGENT, 'Unix')) {
171 $this->set('PMA_USR_OS', 'Unix');
172 } elseif (strstr($HTTP_USER_AGENT, 'OS/2')) {
173 $this->set('PMA_USR_OS', 'OS/2');
174 } else {
175 $this->set('PMA_USR_OS', 'Other');
178 // 2. browser and version
179 // (must check everything else before Mozilla)
181 if (preg_match(
182 '@Opera(/| )([0-9].[0-9]{1,2})@',
183 $HTTP_USER_AGENT,
184 $log_version)
186 $this->set('PMA_USR_BROWSER_VER', $log_version[2]);
187 $this->set('PMA_USR_BROWSER_AGENT', 'OPERA');
188 } elseif (preg_match(
189 '@MSIE ([0-9].[0-9]{1,2})@',
190 $HTTP_USER_AGENT,
191 $log_version)
193 $this->set('PMA_USR_BROWSER_VER', $log_version[1]);
194 $this->set('PMA_USR_BROWSER_AGENT', 'IE');
195 } elseif (preg_match(
196 '@OmniWeb/([0-9].[0-9]{1,2})@',
197 $HTTP_USER_AGENT,
198 $log_version)
200 $this->set('PMA_USR_BROWSER_VER', $log_version[1]);
201 $this->set('PMA_USR_BROWSER_AGENT', 'OMNIWEB');
202 // Konqueror 2.2.2 says Konqueror/2.2.2
203 // Konqueror 3.0.3 says Konqueror/3
204 } elseif (preg_match(
205 '@(Konqueror/)(.*)(;)@',
206 $HTTP_USER_AGENT,
207 $log_version)
209 $this->set('PMA_USR_BROWSER_VER', $log_version[2]);
210 $this->set('PMA_USR_BROWSER_AGENT', 'KONQUEROR');
211 } elseif (preg_match(
212 '@Mozilla/([0-9].[0-9]{1,2})@',
213 $HTTP_USER_AGENT,
214 $log_version)
215 && preg_match('@Safari/([0-9]*)@', $HTTP_USER_AGENT, $log_version2)
217 $this->set('PMA_USR_BROWSER_VER', $log_version[1] . '.' . $log_version2[1]);
218 $this->set('PMA_USR_BROWSER_AGENT', 'SAFARI');
219 } elseif (preg_match('@rv:1.9(.*)Gecko@', $HTTP_USER_AGENT)) {
220 $this->set('PMA_USR_BROWSER_VER', '1.9');
221 $this->set('PMA_USR_BROWSER_AGENT', 'GECKO');
222 } elseif (
223 preg_match('@Mozilla/([0-9].[0-9]{1,2})@',
224 $HTTP_USER_AGENT,
225 $log_version)
227 $this->set('PMA_USR_BROWSER_VER', $log_version[1]);
228 $this->set('PMA_USR_BROWSER_AGENT', 'MOZILLA');
229 } else {
230 $this->set('PMA_USR_BROWSER_VER', 0);
231 $this->set('PMA_USR_BROWSER_AGENT', 'OTHER');
236 * Whether GD2 is present
238 * @return nothing
240 function checkGd2()
242 if ($this->get('GD2Available') == 'yes') {
243 $this->set('PMA_IS_GD2', 1);
244 } elseif ($this->get('GD2Available') == 'no') {
245 $this->set('PMA_IS_GD2', 0);
246 } else {
247 if (!@function_exists('imagecreatetruecolor')) {
248 $this->set('PMA_IS_GD2', 0);
249 } else {
250 if (@function_exists('gd_info')) {
251 $gd_nfo = gd_info();
252 if (strstr($gd_nfo["GD Version"], '2.')) {
253 $this->set('PMA_IS_GD2', 1);
254 } else {
255 $this->set('PMA_IS_GD2', 0);
257 } else {
258 /* We must do hard way... but almost no chance to execute this */
259 ob_start();
260 phpinfo(INFO_MODULES); /* Only modules */
261 $a = strip_tags(ob_get_contents());
262 ob_end_clean();
263 /* Get GD version string from phpinfo output */
264 if (preg_match('@GD Version[[:space:]]*\(.*\)@', $a, $v)) {
265 if (strstr($v, '2.')) {
266 $this->set('PMA_IS_GD2', 1);
267 } else {
268 $this->set('PMA_IS_GD2', 0);
270 } else {
271 $this->set('PMA_IS_GD2', 0);
279 * Whether the Web server php is running on is IIS
281 * @return nothing
283 function checkWebServer()
285 if (PMA_getenv('SERVER_SOFTWARE')
286 // some versions return Microsoft-IIS, some Microsoft/IIS
287 // we could use a preg_match() but it's slower
288 && stristr(PMA_getenv('SERVER_SOFTWARE'), 'Microsoft')
289 && stristr(PMA_getenv('SERVER_SOFTWARE'), 'IIS')
291 $this->set('PMA_IS_IIS', 1);
292 } else {
293 $this->set('PMA_IS_IIS', 0);
298 * Whether the os php is running on is windows or not
300 * @return nothing
302 function checkWebServerOs()
304 // Default to Unix or Equiv
305 $this->set('PMA_IS_WINDOWS', 0);
306 // If PHP_OS is defined then continue
307 if (defined('PHP_OS')) {
308 if (stristr(PHP_OS, 'win')) {
309 // Is it some version of Windows
310 $this->set('PMA_IS_WINDOWS', 1);
311 } elseif (stristr(PHP_OS, 'OS/2')) {
312 // Is it OS/2 (No file permissions like Windows)
313 $this->set('PMA_IS_WINDOWS', 1);
319 * detects PHP version
321 * @return nothing
323 function checkPhpVersion()
325 $match = array();
326 if (! preg_match(
327 '@([0-9]{1,2}).([0-9]{1,2}).([0-9]{1,2})@',
328 phpversion(),
329 $match)
331 preg_match(
332 '@([0-9]{1,2}).([0-9]{1,2})@',
333 phpversion(),
334 $match
337 if (isset($match) && ! empty($match[1])) {
338 if (! isset($match[2])) {
339 $match[2] = 0;
341 if (! isset($match[3])) {
342 $match[3] = 0;
344 $this->set(
345 'PMA_PHP_INT_VERSION',
346 (int) sprintf('%d%02d%02d', $match[1], $match[2], $match[3])
348 } else {
349 $this->set('PMA_PHP_INT_VERSION', 0);
351 $this->set('PMA_PHP_STR_VERSION', phpversion());
355 * loads default values from default source
357 * @return boolean success
359 function loadDefaults()
361 $cfg = array();
362 if (! file_exists($this->default_source)) {
363 $this->error_config_default_file = true;
364 return false;
366 include $this->default_source;
368 $this->default_source_mtime = filemtime($this->default_source);
370 $this->default_server = $cfg['Servers'][1];
371 unset($cfg['Servers']);
373 $this->default = $cfg;
374 $this->settings = PMA_array_merge_recursive($this->settings, $cfg);
376 $this->error_config_default_file = false;
378 return true;
382 * loads configuration from $source, usally the config file
383 * should be called on object creation
385 * @param string $source config file
387 * @return bool
389 function load($source = null)
391 $this->loadDefaults();
393 if (null !== $source) {
394 $this->setSource($source);
397 if (! $this->checkConfigSource()) {
398 return false;
401 $cfg = array();
404 * Parses the configuration file, the eval is used here to avoid
405 * problems with trailing whitespace, what is often a problem.
407 $old_error_reporting = error_reporting(0);
408 $eval_result = eval('?' . '>' . trim(file_get_contents($this->getSource())));
409 error_reporting($old_error_reporting);
411 if ($eval_result === false) {
412 $this->error_config_file = true;
413 } else {
414 $this->error_config_file = false;
415 $this->source_mtime = filemtime($this->getSource());
419 * Backward compatibility code
421 if (!empty($cfg['DefaultTabTable'])) {
422 $cfg['DefaultTabTable'] = str_replace(
423 '_properties',
425 str_replace(
426 'tbl_properties.php',
427 'tbl_sql.php',
428 $cfg['DefaultTabTable']
432 if (!empty($cfg['DefaultTabDatabase'])) {
433 $cfg['DefaultTabDatabase'] = str_replace(
434 '_details',
436 str_replace(
437 'db_details.php',
438 'db_sql.php',
439 $cfg['DefaultTabDatabase']
444 $this->settings = PMA_array_merge_recursive($this->settings, $cfg);
445 $this->checkPmaAbsoluteUri();
446 $this->checkFontsize();
448 $this->checkPermissions();
450 // Handling of the collation must be done after merging of $cfg
451 // (from config.inc.php) so that $cfg['DefaultConnectionCollation']
452 // can have an effect. Note that the presence of collation
453 // information in a cookie has priority over what is defined
454 // in the default or user's config files.
456 * @todo check validity of $_COOKIE['pma_collation_connection']
458 if (! empty($_COOKIE['pma_collation_connection'])) {
459 $this->set('collation_connection',
460 strip_tags($_COOKIE['pma_collation_connection']));
461 } else {
462 $this->set('collation_connection',
463 $this->get('DefaultConnectionCollation'));
465 // Now, a collation information could come from REQUEST
466 // (an example of this: the collation selector in main.php)
467 // so the following handles the setting of collation_connection
468 // and later, in common.inc.php, the cookie will be set
469 // according to this.
470 $this->checkCollationConnection();
472 return true;
476 * Loads user preferences and merges them with current config
477 * must be called after control connection has been estabilished
479 * @return boolean
481 function loadUserPreferences()
483 // index.php should load these settings, so that phpmyadmin.css.php
484 // will have everything avaiable in session cache
485 $server = isset($GLOBALS['server'])
486 ? $GLOBALS['server']
487 : (!empty($GLOBALS['cfg']['ServerDefault']) ? $GLOBALS['cfg']['ServerDefault'] : 0);
488 $cache_key = 'server_' . $server;
489 if ($server > 0 && !defined('PMA_MINIMUM_COMMON')) {
490 $config_mtime = max($this->default_source_mtime, $this->source_mtime);
491 // cache user preferences, use database only when needed
492 if (! isset($_SESSION['cache'][$cache_key]['userprefs'])
493 || $_SESSION['cache'][$cache_key]['config_mtime'] < $config_mtime
495 // load required libraries
496 include_once './libraries/user_preferences.lib.php';
497 $prefs = PMA_load_userprefs();
498 $_SESSION['cache'][$cache_key]['userprefs']
499 = PMA_apply_userprefs($prefs['config_data']);
500 $_SESSION['cache'][$cache_key]['userprefs_mtime'] = $prefs['mtime'];
501 $_SESSION['cache'][$cache_key]['userprefs_type'] = $prefs['type'];
502 $_SESSION['cache'][$cache_key]['config_mtime'] = $config_mtime;
504 } elseif ($server == 0
505 || ! isset($_SESSION['cache'][$cache_key]['userprefs'])
507 $this->set('user_preferences', false);
508 return;
510 $config_data = $_SESSION['cache'][$cache_key]['userprefs'];
511 // type is 'db' or 'session'
512 $this->set('user_preferences', $_SESSION['cache'][$cache_key]['userprefs_type']);
513 $this->set('user_preferences_mtime', $_SESSION['cache'][$cache_key]['userprefs_mtime']);
515 // backup some settings
516 $org_fontsize = $this->settings['fontsize'];
517 // load config array
518 $this->settings = PMA_array_merge_recursive($this->settings, $config_data);
519 $GLOBALS['cfg'] = PMA_array_merge_recursive($GLOBALS['cfg'], $config_data);
520 if (defined('PMA_MINIMUM_COMMON')) {
521 return;
524 // settings below start really working on next page load, but
525 // changes are made only in index.php so everything is set when
526 // in frames
528 // save theme
529 $tmanager = $_SESSION['PMA_Theme_Manager'];
530 if ($tmanager->getThemeCookie() || isset($_REQUEST['set_theme'])) {
531 if ((! isset($config_data['ThemeDefault'])
532 && $tmanager->theme->getId() != 'original')
533 || isset($config_data['ThemeDefault'])
534 && $config_data['ThemeDefault'] != $tmanager->theme->getId()
536 // new theme was set in common.inc.php
537 $this->setUserValue(
538 null,
539 'ThemeDefault',
540 $tmanager->theme->getId(),
541 'original'
544 } else {
545 // no cookie - read default from settings
546 if ($this->settings['ThemeDefault'] != $tmanager->theme->getId()
547 && $tmanager->checkTheme($this->settings['ThemeDefault'])
549 $tmanager->setActiveTheme($this->settings['ThemeDefault']);
550 $tmanager->setThemeCookie();
554 // save font size
555 if ((! isset($config_data['fontsize'])
556 && $org_fontsize != '82%')
557 || isset($config_data['fontsize'])
558 && $org_fontsize != $config_data['fontsize']
560 $this->setUserValue(null, 'fontsize', $org_fontsize, '82%');
563 // save language
564 if (isset($_COOKIE['pma_lang']) || isset($_POST['lang'])) {
565 if ((! isset($config_data['lang'])
566 && $GLOBALS['lang'] != 'en')
567 || isset($config_data['lang'])
568 && $GLOBALS['lang'] != $config_data['lang']
570 $this->setUserValue(null, 'lang', $GLOBALS['lang'], 'en');
572 } else {
573 // read language from settings
574 if (isset($config_data['lang']) && PMA_langSet($config_data['lang'])) {
575 $this->setCookie('pma_lang', $GLOBALS['lang']);
579 // save connection collation
580 if (isset($_COOKIE['pma_collation_connection'])
581 || isset($_POST['collation_connection'])
583 if ((! isset($config_data['collation_connection'])
584 && $GLOBALS['collation_connection'] != 'utf8_general_ci')
585 || isset($config_data['collation_connection'])
586 && $GLOBALS['collation_connection'] != $config_data['collation_connection']
588 $this->setUserValue(
589 null,
590 'collation_connection',
591 $GLOBALS['collation_connection'],
592 'utf8_general_ci'
595 } else {
596 // read collation from settings
597 if (isset($config_data['collation_connection'])) {
598 $GLOBALS['collation_connection']
599 = $config_data['collation_connection'];
600 $this->setCookie(
601 'pma_collation_connection',
602 $GLOBALS['collation_connection']
609 * Sets config value which is stored in user preferences (if available) or in a cookie.
611 * If user preferences are not yet initialized, option is applied to global config and
612 * added to a update queue, which is processed by {@link loadUserPreferences()}
614 * @param string $cookie_name can be null
615 * @param string $cfg_path
616 * @param mixed $new_cfg_value
617 * @param mixed $default_value
619 * @return nothing
621 function setUserValue($cookie_name, $cfg_path, $new_cfg_value, $default_value = null)
623 // use permanent user preferences if possible
624 $prefs_type = $this->get('user_preferences');
625 if ($prefs_type) {
626 include_once './libraries/user_preferences.lib.php';
627 if ($default_value === null) {
628 $default_value = PMA_array_read($cfg_path, $this->default);
630 PMA_persist_option($cfg_path, $new_cfg_value, $default_value);
632 if ($prefs_type != 'db' && $cookie_name) {
633 // fall back to cookies
634 if ($default_value === null) {
635 $default_value = PMA_array_read($cfg_path, $this->settings);
637 $this->setCookie($cookie_name, $new_cfg_value, $default_value);
639 PMA_array_write($cfg_path, $GLOBALS['cfg'], $new_cfg_value);
640 PMA_array_write($cfg_path, $this->settings, $new_cfg_value);
644 * Reads value stored by {@link setUserValue()}
646 * @param string $cookie_name
647 * @param mixed $cfg_value
649 * @return mixed
651 function getUserValue($cookie_name, $cfg_value)
653 $cookie_exists = isset($_COOKIE) && !empty($_COOKIE[$cookie_name]);
654 $prefs_type = $this->get('user_preferences');
655 if ($prefs_type == 'db') {
656 // permanent user preferences value exists, remove cookie
657 if ($cookie_exists) {
658 $this->removeCookie($cookie_name);
660 } else if ($cookie_exists) {
661 return $_COOKIE[$cookie_name];
663 // return value from $cfg array
664 return $cfg_value;
668 * set source
670 * @param string $source
672 * @return nothing
674 function setSource($source)
676 $this->source = trim($source);
680 * checks if the config folder still exists and terminates app if true
682 * @return nothing
684 function checkConfigFolder()
686 // Refuse to work while there still might be some world writable dir:
687 if (is_dir('./config')) {
688 die('Remove "./config" directory before using phpMyAdmin!');
693 * check config source
695 * @return boolean whether source is valid or not
697 function checkConfigSource()
699 if (! $this->getSource()) {
700 // no configuration file set at all
701 return false;
704 if (! file_exists($this->getSource())) {
705 $this->source_mtime = 0;
706 return false;
709 if (! is_readable($this->getSource())) {
710 $this->source_mtime = 0;
711 die(
712 'Existing configuration file ('
713 . $this->getSource() . ') is not readable.'
717 return true;
721 * verifies the permissions on config file (if asked by configuration)
722 * (must be called after config.inc.php has been merged)
724 * @return nothing
726 function checkPermissions()
728 // Check for permissions (on platforms that support it):
729 if ($this->get('CheckConfigurationPermissions')) {
730 $perms = @fileperms($this->getSource());
731 if (!($perms === false) && ($perms & 2)) {
732 // This check is normally done after loading configuration
733 $this->checkWebServerOs();
734 if ($this->get('PMA_IS_WINDOWS') == 0) {
735 $this->source_mtime = 0;
736 die('Wrong permissions on configuration file, should not be world writable!');
743 * returns specific config setting
745 * @param string $setting
747 * @return mixed value
749 function get($setting)
751 if (isset($this->settings[$setting])) {
752 return $this->settings[$setting];
754 return null;
758 * sets configuration variable
760 * @param string $setting configuration option
761 * @param string $value new value for configuration option
763 * @return nothing
765 function set($setting, $value)
767 if (! isset($this->settings[$setting])
768 || $this->settings[$setting] != $value
770 $this->settings[$setting] = $value;
771 $this->set_mtime = time();
776 * returns source for current config
778 * @return string config source
780 function getSource()
782 return $this->source;
786 * returns a unique value to force a CSS reload if either the config
787 * or the theme changes
788 * must also check the pma_fontsize cookie in case there is no
789 * config file
791 * @return int Summary of unix timestamps and fontsize,
792 * to be unique on theme parameters change
794 function getThemeUniqueValue()
796 if (null !== $this->get('fontsize')) {
797 $fontsize = intval($this->get('fontsize'));
798 } elseif (isset($_COOKIE['pma_fontsize'])) {
799 $fontsize = intval($_COOKIE['pma_fontsize']);
800 } else {
801 $fontsize = 0;
803 return (
804 $fontsize +
805 $this->source_mtime +
806 $this->default_source_mtime +
807 $this->get('user_preferences_mtime') +
808 $_SESSION['PMA_Theme']->mtime_info +
809 $_SESSION['PMA_Theme']->filesize_info);
813 * $cfg['PmaAbsoluteUri'] is a required directive else cookies won't be
814 * set properly and, depending on browsers, inserting or updating a
815 * record might fail
817 * @return bool
819 function checkPmaAbsoluteUri()
821 // Setup a default value to let the people and lazy sysadmins work anyway,
822 // they'll get an error if the autodetect code doesn't work
823 $pma_absolute_uri = $this->get('PmaAbsoluteUri');
824 $is_https = $this->detectHttps();
826 if (strlen($pma_absolute_uri) < 5) {
827 $url = array();
829 // If we don't have scheme, we didn't have full URL so we need to
830 // dig deeper
831 if (empty($url['scheme'])) {
832 // Scheme
833 if (PMA_getenv('HTTP_SCHEME')) {
834 $url['scheme'] = PMA_getenv('HTTP_SCHEME');
835 } else {
836 $url['scheme'] = PMA_getenv('HTTPS')
837 && strtolower(PMA_getenv('HTTPS')) != 'off'
838 ? 'https'
839 : 'http';
842 // Host and port
843 if (PMA_getenv('HTTP_HOST')) {
844 // Prepend the scheme before using parse_url() since this
845 // is not part of the RFC2616 Host request-header
846 $parsed_url = parse_url(
847 $url['scheme'] . '://' . PMA_getenv('HTTP_HOST')
849 if (!empty($parsed_url['host'])) {
850 $url = $parsed_url;
851 } else {
852 $url['host'] = PMA_getenv('HTTP_HOST');
854 } elseif (PMA_getenv('SERVER_NAME')) {
855 $url['host'] = PMA_getenv('SERVER_NAME');
856 } else {
857 $this->error_pma_uri = true;
858 return false;
861 // If we didn't set port yet...
862 if (empty($url['port']) && PMA_getenv('SERVER_PORT')) {
863 $url['port'] = PMA_getenv('SERVER_PORT');
866 // And finally the path could be already set from REQUEST_URI
867 if (empty($url['path'])) {
868 $path = parse_url($GLOBALS['PMA_PHP_SELF']);
869 $url['path'] = $path['path'];
873 // Make url from parts we have
874 $pma_absolute_uri = $url['scheme'] . '://';
875 // Was there user information?
876 if (!empty($url['user'])) {
877 $pma_absolute_uri .= $url['user'];
878 if (!empty($url['pass'])) {
879 $pma_absolute_uri .= ':' . $url['pass'];
881 $pma_absolute_uri .= '@';
883 // Add hostname
884 $pma_absolute_uri .= $url['host'];
885 // Add port, if it not the default one
886 if (! empty($url['port'])
887 && (($url['scheme'] == 'http' && $url['port'] != 80)
888 || ($url['scheme'] == 'https' && $url['port'] != 443))
890 $pma_absolute_uri .= ':' . $url['port'];
892 // And finally path, without script name, the 'a' is there not to
893 // strip our directory, when path is only /pmadir/ without filename.
894 // Backslashes returned by Windows have to be changed.
895 // Only replace backslashes by forward slashes if on Windows,
896 // as the backslash could be valid on a non-Windows system.
897 $this->checkWebServerOs();
898 if ($this->get('PMA_IS_WINDOWS') == 1) {
899 $path = str_replace("\\", "/", dirname($url['path'] . 'a'));
900 } else {
901 $path = dirname($url['path'] . 'a');
904 // To work correctly within transformations overview:
905 if (defined('PMA_PATH_TO_BASEDIR') && PMA_PATH_TO_BASEDIR == '../../') {
906 if ($this->get('PMA_IS_WINDOWS') == 1) {
907 $path = str_replace("\\", "/", dirname(dirname($path)));
908 } else {
909 $path = dirname(dirname($path));
913 // PHP's dirname function would have returned a dot
914 // when $path contains no slash
915 if ($path == '.') {
916 $path = '';
918 // in vhost situations, there could be already an ending slash
919 if (substr($path, -1) != '/') {
920 $path .= '/';
922 $pma_absolute_uri .= $path;
924 // We used to display a warning if PmaAbsoluteUri wasn't set, but now
925 // the autodetect code works well enough that we don't display the
926 // warning at all. The user can still set PmaAbsoluteUri manually.
927 // See
928 // http://sf.net/tracker/?func=detail&aid=1257134&group_id=23067&atid=377411
930 } else {
931 // The URI is specified, however users do often specify this
932 // wrongly, so we try to fix this.
934 // Adds a trailing slash et the end of the phpMyAdmin uri if it
935 // does not exist.
936 if (substr($pma_absolute_uri, -1) != '/') {
937 $pma_absolute_uri .= '/';
940 // If URI doesn't start with http:// or https://, we will add
941 // this.
942 if (substr($pma_absolute_uri, 0, 7) != 'http://'
943 && substr($pma_absolute_uri, 0, 8) != 'https://'
945 $pma_absolute_uri =
946 ($is_https ? 'https' : 'http')
947 . ':' . (substr($pma_absolute_uri, 0, 2) == '//' ? '' : '//')
948 . $pma_absolute_uri;
951 $this->set('PmaAbsoluteUri', $pma_absolute_uri);
955 * check selected collation_connection
957 * @todo check validity of $_REQUEST['collation_connection']
959 * @return nothing
961 function checkCollationConnection()
963 if (! empty($_REQUEST['collation_connection'])) {
964 $this->set(
965 'collation_connection',
966 strip_tags($_REQUEST['collation_connection'])
972 * checks for font size configuration, and sets font size as requested by user
974 * @return nothing
976 function checkFontsize()
978 $new_fontsize = '';
980 if (isset($_GET['set_fontsize'])) {
981 $new_fontsize = $_GET['set_fontsize'];
982 } elseif (isset($_POST['set_fontsize'])) {
983 $new_fontsize = $_POST['set_fontsize'];
984 } elseif (isset($_COOKIE['pma_fontsize'])) {
985 $new_fontsize = $_COOKIE['pma_fontsize'];
988 if (preg_match('/^[0-9.]+(px|em|pt|\%)$/', $new_fontsize)) {
989 $this->set('fontsize', $new_fontsize);
990 } elseif (! $this->get('fontsize')) {
991 // 80% would correspond to the default browser font size
992 // of 16, but use 82% to help read the monoface font
993 $this->set('fontsize', '82%');
996 $this->setCookie('pma_fontsize', $this->get('fontsize'), '82%');
1000 * checks if upload is enabled
1002 * @return nothing
1004 function checkUpload()
1006 if (ini_get('file_uploads')) {
1007 $this->set('enable_upload', true);
1008 // if set "php_admin_value file_uploads Off" in httpd.conf
1009 // ini_get() also returns the string "Off" in this case:
1010 if ('off' == strtolower(ini_get('file_uploads'))) {
1011 $this->set('enable_upload', false);
1013 } else {
1014 $this->set('enable_upload', false);
1019 * Maximum upload size as limited by PHP
1020 * Used with permission from Moodle (http://moodle.org) by Martin Dougiamas
1022 * this section generates $max_upload_size in bytes
1024 * @return nothing
1026 function checkUploadSize()
1028 if (! $filesize = ini_get('upload_max_filesize')) {
1029 $filesize = "5M";
1032 if ($postsize = ini_get('post_max_size')) {
1033 $this->set(
1034 'max_upload_size',
1035 min(PMA_get_real_size($filesize), PMA_get_real_size($postsize))
1037 } else {
1038 $this->set('max_upload_size', PMA_get_real_size($filesize));
1043 * check for https
1045 * @return nothing
1047 function checkIsHttps()
1049 $this->set('is_https', $this->isHttps());
1053 * @return bool
1055 public function isHttps()
1057 static $is_https = null;
1059 if (null !== $is_https) {
1060 return $is_https;
1063 $url = parse_url($this->get('PmaAbsoluteUri'));
1065 if (isset($url['scheme']) && $url['scheme'] == 'https') {
1066 $is_https = true;
1067 } else {
1068 $is_https = false;
1071 return $is_https;
1075 * Detects whether https appears to be used.
1077 * Please note that this just detects what we see, so
1078 * it completely ignores things like reverse proxies.
1080 * @return bool
1082 function detectHttps()
1084 $is_https = false;
1086 $url = array();
1088 // At first we try to parse REQUEST_URI, it might contain full URL,
1089 if (PMA_getenv('REQUEST_URI')) {
1090 // produces E_WARNING if it cannot get parsed, e.g. '/foobar:/'
1091 $url = @parse_url(PMA_getenv('REQUEST_URI'));
1092 if ($url === false) {
1093 $url = array();
1097 // If we don't have scheme, we didn't have full URL so we need to
1098 // dig deeper
1099 if (empty($url['scheme'])) {
1100 // Scheme
1101 if (PMA_getenv('HTTP_SCHEME')) {
1102 $url['scheme'] = PMA_getenv('HTTP_SCHEME');
1103 } else {
1104 $url['scheme'] =
1105 PMA_getenv('HTTPS') && strtolower(PMA_getenv('HTTPS')) != 'off'
1106 ? 'https'
1107 : 'http';
1111 if (isset($url['scheme']) && $url['scheme'] == 'https') {
1112 $is_https = true;
1113 } else {
1114 $is_https = false;
1117 return $is_https;
1121 * detect correct cookie path
1123 * @return nothing
1125 function checkCookiePath()
1127 $this->set('cookie_path', $this->getCookiePath());
1131 * @return string
1133 public function getCookiePath()
1135 static $cookie_path = null;
1137 if (null !== $cookie_path) {
1138 return $cookie_path;
1141 $parsed_url = parse_url($this->get('PmaAbsoluteUri'));
1143 $cookie_path = $parsed_url['path'];
1145 return $cookie_path;
1149 * enables backward compatibility
1151 * @return nothing
1153 function enableBc()
1155 $GLOBALS['cfg'] = $this->settings;
1156 $GLOBALS['default_server'] = $this->default_server;
1157 unset($this->default_server);
1158 $GLOBALS['collation_connection'] = $this->get('collation_connection');
1159 $GLOBALS['is_upload'] = $this->get('enable_upload');
1160 $GLOBALS['max_upload_size'] = $this->get('max_upload_size');
1161 $GLOBALS['cookie_path'] = $this->get('cookie_path');
1162 $GLOBALS['is_https'] = $this->get('is_https');
1164 $defines = array(
1165 'PMA_VERSION',
1166 'PMA_THEME_VERSION',
1167 'PMA_THEME_GENERATION',
1168 'PMA_PHP_STR_VERSION',
1169 'PMA_PHP_INT_VERSION',
1170 'PMA_IS_WINDOWS',
1171 'PMA_IS_IIS',
1172 'PMA_IS_GD2',
1173 'PMA_USR_OS',
1174 'PMA_USR_BROWSER_VER',
1175 'PMA_USR_BROWSER_AGENT'
1178 foreach ($defines as $define) {
1179 if (! defined($define)) {
1180 define($define, $this->get($define));
1186 * @todo finish
1188 * @return nothing
1190 function save()
1195 * returns options for font size selection
1197 * @static
1198 * @param string $current_size current selected font size with unit
1200 * @return array selectable font sizes
1202 static protected function _getFontsizeOptions($current_size = '82%')
1204 $unit = preg_replace('/[0-9.]*/', '', $current_size);
1205 $value = preg_replace('/[^0-9.]*/', '', $current_size);
1207 $factors = array();
1208 $options = array();
1209 $options["$value"] = $value . $unit;
1211 if ($unit === '%') {
1212 $factors[] = 1;
1213 $factors[] = 5;
1214 $factors[] = 10;
1215 } elseif ($unit === 'em') {
1216 $factors[] = 0.05;
1217 $factors[] = 0.2;
1218 $factors[] = 1;
1219 } elseif ($unit === 'pt') {
1220 $factors[] = 0.5;
1221 $factors[] = 2;
1222 } elseif ($unit === 'px') {
1223 $factors[] = 1;
1224 $factors[] = 5;
1225 $factors[] = 10;
1226 } else {
1227 //unknown font size unit
1228 $factors[] = 0.05;
1229 $factors[] = 0.2;
1230 $factors[] = 1;
1231 $factors[] = 5;
1232 $factors[] = 10;
1235 foreach ($factors as $key => $factor) {
1236 $option_inc = $value + $factor;
1237 $option_dec = $value - $factor;
1238 while (count($options) < 21) {
1239 $options["$option_inc"] = $option_inc . $unit;
1240 if ($option_dec > $factors[0]) {
1241 $options["$option_dec"] = $option_dec . $unit;
1243 $option_inc += $factor;
1244 $option_dec -= $factor;
1245 if (isset($factors[$key + 1])
1246 && $option_inc >= $value + $factors[$key + 1]
1248 break;
1252 ksort($options);
1253 return $options;
1257 * returns html selectbox for font sizes
1259 * @static
1260 * @param string $current_size currently slected font size with unit
1262 * @return string html selectbox
1264 static protected function _getFontsizeSelection()
1266 $current_size = $GLOBALS['PMA_Config']->get('fontsize');
1267 // for the case when there is no config file (this is supported)
1268 if (empty($current_size)) {
1269 if (isset($_COOKIE['pma_fontsize'])) {
1270 $current_size = $_COOKIE['pma_fontsize'];
1271 } else {
1272 $current_size = '82%';
1275 $options = PMA_Config::_getFontsizeOptions($current_size);
1277 $return = '<label for="select_fontsize">' . __('Font size') . ':</label>' . "\n";
1278 $return .= '<select name="set_fontsize" id="select_fontsize" class="autosubmit">' . "\n";
1279 foreach ($options as $option) {
1280 $return .= '<option value="' . $option . '"';
1281 if ($option == $current_size) {
1282 $return .= ' selected="selected"';
1284 $return .= '>' . $option . '</option>' . "\n";
1286 $return .= '</select>';
1288 return $return;
1292 * return complete font size selection form
1294 * @static
1295 * @param string $current_size currently slected font size with unit
1297 * @return string html selectbox
1299 static public function getFontsizeForm()
1301 return '<form name="form_fontsize_selection" id="form_fontsize_selection"'
1302 . ' method="post" action="index.php" target="_parent">' . "\n"
1303 . PMA_generate_common_hidden_inputs() . "\n"
1304 . PMA_Config::_getFontsizeSelection() . "\n"
1305 . '<noscript>' . "\n"
1306 . '<input type="submit" value="' . __('Go') . '" />' . "\n"
1307 . '</noscript>' . "\n"
1308 . '</form>';
1312 * removes cookie
1314 * @param string $cookie name of cookie to remove
1316 * @return boolean result of setcookie()
1318 function removeCookie($cookie)
1320 return setcookie(
1321 $cookie,
1323 time() - 3600,
1324 $this->getCookiePath(),
1326 $this->isHttps()
1331 * sets cookie if value is different from current cokkie value,
1332 * or removes if value is equal to default
1334 * @param string $cookie name of cookie to remove
1335 * @param mixed $value new cookie value
1336 * @param string $default default value
1337 * @param int $validity validity of cookie in seconds (default is one month)
1338 * @param bool $httponly whether cookie is only for HTTP (and not for scripts)
1340 * @return boolean result of setcookie()
1342 function setCookie($cookie, $value, $default = null, $validity = null, $httponly = true)
1344 if ($validity == null) {
1345 $validity = 2592000;
1347 if (strlen($value) && null !== $default && $value === $default) {
1348 // default value is used
1349 if (isset($_COOKIE[$cookie])) {
1350 // remove cookie
1351 return $this->removeCookie($cookie);
1353 return false;
1356 if (! strlen($value) && isset($_COOKIE[$cookie])) {
1357 // remove cookie, value is empty
1358 return $this->removeCookie($cookie);
1361 if (! isset($_COOKIE[$cookie]) || $_COOKIE[$cookie] !== $value) {
1362 // set cookie with new value
1363 /* Calculate cookie validity */
1364 if ($validity == 0) {
1365 $v = 0;
1366 } else {
1367 $v = time() + $validity;
1369 return setcookie(
1370 $cookie,
1371 $value,
1373 $this->getCookiePath(),
1375 $this->isHttps(),
1376 $httponly
1380 // cookie has already $value as value
1381 return true;