$cfg */
$cfg = [];
if (! @file_exists($this->defaultSource)) {
$this->errorConfigDefaultFile = true;
return false;
}
$canUseErrorReporting = Util::isErrorReportingAvailable();
$oldErrorReporting = null;
if ($canUseErrorReporting) {
$oldErrorReporting = error_reporting(0);
}
ob_start();
$isConfigLoading = true;
$eval_result = include $this->defaultSource;
$isConfigLoading = false;
ob_end_clean();
if ($canUseErrorReporting) {
error_reporting($oldErrorReporting);
}
if ($eval_result === false) {
$this->errorConfigDefaultFile = true;
return false;
}
$this->defaultSourceMtime = filemtime($this->defaultSource);
$this->defaultServer = $cfg['Servers'][1];
unset($cfg['Servers']);
$this->default = $cfg;
$this->settings = array_replace_recursive($this->settings, $cfg);
$this->errorConfigDefaultFile = false;
return true;
}
/**
* loads configuration from $source, usually the config file
* should be called on object creation
*
* @param string $source config file
*/
public function load(?string $source = null): bool
{
global $isConfigLoading;
$this->loadDefaults();
if ($source !== null) {
$this->setSource($source);
}
if (! $this->checkConfigSource()) {
return false;
}
$cfg = [];
/**
* Parses the configuration file, we throw away any errors or
* output.
*/
$canUseErrorReporting = Util::isErrorReportingAvailable();
$oldErrorReporting = null;
if ($canUseErrorReporting) {
$oldErrorReporting = error_reporting(0);
}
ob_start();
$isConfigLoading = true;
$eval_result = include $this->getSource();
$isConfigLoading = false;
ob_end_clean();
if ($canUseErrorReporting) {
error_reporting($oldErrorReporting);
}
if ($eval_result === false) {
$this->errorConfigFile = true;
} else {
$this->errorConfigFile = false;
$this->sourceMtime = filemtime($this->getSource());
}
/**
* Ignore keys with / as we do not use these
*
* These can be confusing for user configuration layer as it
* flatten array using / and thus don't see difference between
* $cfg['Export/method'] and $cfg['Export']['method'], while rest
* of the code uses the setting only in latter form.
*
* This could be removed once we consistently handle both values
* in the functional code as well.
*
* It could use array_filter(...ARRAY_FILTER_USE_KEY), but it's not
* supported on PHP 5.5 and HHVM.
*/
$matched_keys = array_filter(
array_keys($cfg),
static function ($key) {
return strpos($key, '/') === false;
}
);
$cfg = array_intersect_key($cfg, array_flip($matched_keys));
$this->settings = array_replace_recursive($this->settings, $cfg);
return true;
}
/**
* Sets the connection collation
*/
private function setConnectionCollation(): void
{
global $dbi;
$collation_connection = $this->get('DefaultConnectionCollation');
if (empty($collation_connection)
|| $collation_connection == $GLOBALS['collation_connection']
) {
return;
}
$dbi->setCollation($collation_connection);
}
/**
* Loads user preferences and merges them with current config
* must be called after control connection has been established
*/
public function loadUserPreferences(): void
{
$userPreferences = new UserPreferences();
// index.php should load these settings, so that phpmyadmin.css.php
// will have everything available in session cache
$server = $GLOBALS['server'] ?? (! empty($GLOBALS['cfg']['ServerDefault'])
? $GLOBALS['cfg']['ServerDefault']
: 0);
$cache_key = 'server_' . $server;
if ($server > 0 && ! defined('PMA_MINIMUM_COMMON')) {
$config_mtime = max($this->defaultSourceMtime, $this->sourceMtime);
// cache user preferences, use database only when needed
if (! isset($_SESSION['cache'][$cache_key]['userprefs'])
|| $_SESSION['cache'][$cache_key]['config_mtime'] < $config_mtime
) {
$prefs = $userPreferences->load();
$_SESSION['cache'][$cache_key]['userprefs']
= $userPreferences->apply($prefs['config_data']);
$_SESSION['cache'][$cache_key]['userprefs_mtime'] = $prefs['mtime'];
$_SESSION['cache'][$cache_key]['userprefs_type'] = $prefs['type'];
$_SESSION['cache'][$cache_key]['config_mtime'] = $config_mtime;
}
} elseif ($server == 0
|| ! isset($_SESSION['cache'][$cache_key]['userprefs'])
) {
$this->set('user_preferences', false);
return;
}
$config_data = $_SESSION['cache'][$cache_key]['userprefs'];
// type is 'db' or 'session'
$this->set(
'user_preferences',
$_SESSION['cache'][$cache_key]['userprefs_type']
);
$this->set(
'user_preferences_mtime',
$_SESSION['cache'][$cache_key]['userprefs_mtime']
);
// load config array
$this->settings = array_replace_recursive($this->settings, $config_data);
$GLOBALS['cfg'] = array_replace_recursive($GLOBALS['cfg'], $config_data);
if (defined('PMA_MINIMUM_COMMON')) {
return;
}
// settings below start really working on next page load, but
// changes are made only in index.php so everything is set when
// in frames
// save theme
/** @var ThemeManager $tmanager */
$tmanager = ThemeManager::getInstance();
if ($tmanager->getThemeCookie() || isset($_REQUEST['set_theme'])) {
if ((! isset($config_data['ThemeDefault'])
&& $tmanager->theme->getId() !== 'original')
|| isset($config_data['ThemeDefault'])
&& $config_data['ThemeDefault'] != $tmanager->theme->getId()
) {
// new theme was set in common.inc.php
$this->setUserValue(
null,
'ThemeDefault',
$tmanager->theme->getId(),
'original'
);
}
} else {
// no cookie - read default from settings
if ($tmanager->theme !== null
&& $this->settings['ThemeDefault'] != $tmanager->theme->getId()
&& $tmanager->checkTheme($this->settings['ThemeDefault'])
) {
$tmanager->setActiveTheme($this->settings['ThemeDefault']);
$tmanager->setThemeCookie();
}
}
// save language
if ($this->issetCookie('pma_lang') || isset($_POST['lang'])) {
if ((! isset($config_data['lang'])
&& $GLOBALS['lang'] !== 'en')
|| isset($config_data['lang'])
&& $GLOBALS['lang'] != $config_data['lang']
) {
$this->setUserValue(null, 'lang', $GLOBALS['lang'], 'en');
}
} else {
// read language from settings
if (isset($config_data['lang'])) {
$language = LanguageManager::getInstance()->getLanguage(
$config_data['lang']
);
if ($language !== false) {
$language->activate();
$this->setCookie('pma_lang', $language->getCode());
}
}
}
// set connection collation
$this->setConnectionCollation();
}
/**
* Sets config value which is stored in user preferences (if available)
* or in a cookie.
*
* If user preferences are not yet initialized, option is applied to
* global config and added to a update queue, which is processed
* by {@link loadUserPreferences()}
*
* @param string|null $cookie_name can be null
* @param string $cfg_path configuration path
* @param string $new_cfg_value new value
* @param string|null $default_value default value
*
* @return true|Message
*/
public function setUserValue(
?string $cookie_name,
string $cfg_path,
$new_cfg_value,
$default_value = null
) {
$userPreferences = new UserPreferences();
$result = true;
// use permanent user preferences if possible
$prefs_type = $this->get('user_preferences');
if ($prefs_type) {
if ($default_value === null) {
$default_value = Core::arrayRead($cfg_path, $this->default);
}
$result = $userPreferences->persistOption($cfg_path, $new_cfg_value, $default_value);
}
if ($prefs_type !== 'db' && $cookie_name) {
// fall back to cookies
if ($default_value === null) {
$default_value = Core::arrayRead($cfg_path, $this->settings);
}
$this->setCookie($cookie_name, $new_cfg_value, $default_value);
}
Core::arrayWrite($cfg_path, $GLOBALS['cfg'], $new_cfg_value);
Core::arrayWrite($cfg_path, $this->settings, $new_cfg_value);
return $result;
}
/**
* Reads value stored by {@link setUserValue()}
*
* @param string $cookie_name cookie name
* @param mixed $cfg_value config value
*
* @return mixed
*/
public function getUserValue(string $cookie_name, $cfg_value)
{
$cookie_exists = ! empty($this->getCookie($cookie_name));
$prefs_type = $this->get('user_preferences');
if ($prefs_type === 'db') {
// permanent user preferences value exists, remove cookie
if ($cookie_exists) {
$this->removeCookie($cookie_name);
}
} elseif ($cookie_exists) {
return $this->getCookie($cookie_name);
}
// return value from $cfg array
return $cfg_value;
}
/**
* set source
*
* @param string $source source
*/
public function setSource(string $source): void
{
$this->source = trim($source);
}
/**
* check config source
*
* @return bool whether source is valid or not
*/
public function checkConfigSource(): bool
{
if (! $this->getSource()) {
// no configuration file set at all
return false;
}
if (! @file_exists($this->getSource())) {
$this->sourceMtime = 0;
return false;
}
if (! @is_readable($this->getSource())) {
// manually check if file is readable
// might be bug #3059806 Supporting running from CIFS/Samba shares
$contents = false;
$handle = @fopen($this->getSource(), 'r');
if ($handle !== false) {
$contents = @fread($handle, 1); // reading 1 byte is enough to test
fclose($handle);
}
if ($contents === false) {
$this->sourceMtime = 0;
Core::fatalError(
sprintf(
function_exists('__')
? __('Existing configuration file (%s) is not readable.')
: 'Existing configuration file (%s) is not readable.',
$this->getSource()
)
);
return false;
}
}
return true;
}
/**
* verifies the permissions on config file (if asked by configuration)
* (must be called after config.inc.php has been merged)
*/
public function checkPermissions(): void
{
// Check for permissions (on platforms that support it):
if (! $this->get('CheckConfigurationPermissions') || ! @file_exists($this->getSource())) {
return;
}
$perms = @fileperms($this->getSource());
if ($perms === false || (! ($perms & 2))) {
return;
}
// This check is normally done after loading configuration
$this->checkWebServerOs();
if ($this->get('PMA_IS_WINDOWS') === true) {
return;
}
$this->sourceMtime = 0;
Core::fatalError(
__(
'Wrong permissions on configuration file, '
. 'should not be world writable!'
)
);
}
/**
* Checks for errors
* (must be called after config.inc.php has been merged)
*/
public function checkErrors(): void
{
if ($this->errorConfigDefaultFile) {
Core::fatalError(
sprintf(
__('Could not load default configuration from: %1$s'),
$this->defaultSource
)
);
}
if (! $this->errorConfigFile) {
return;
}
$error = '[strong]' . __('Failed to read configuration file!') . '[/strong]'
. '[br][br]'
. __(
'This usually means there is a syntax error in it, '
. 'please check any errors shown below.'
)
. '[br][br]'
. '[conferr]';
trigger_error($error, E_USER_ERROR);
}
/**
* returns specific config setting
*
* @param string $setting config setting
*
* @return mixed|null value
*/
public function get(string $setting)
{
if (isset($this->settings[$setting])) {
return $this->settings[$setting];
}
return null;
}
/**
* sets configuration variable
*
* @param string $setting configuration option
* @param mixed $value new value for configuration option
*/
public function set(string $setting, $value): void
{
if (isset($this->settings[$setting])
&& $this->settings[$setting] === $value
) {
return;
}
$this->settings[$setting] = $value;
$this->setMtime = time();
}
/**
* returns source for current config
*
* @return string config source
*/
public function getSource(): string
{
return $this->source;
}
/**
* returns a unique value to force a CSS reload if either the config
* or the theme changes
*
* @return int Summary of unix timestamps, to be unique on theme parameters
* change
*/
public function getThemeUniqueValue(): int
{
global $PMA_Theme;
return crc32(
$this->sourceMtime .
$this->defaultSourceMtime .
$this->get('user_preferences_mtime') .
($PMA_Theme->mtimeInfo ?? 0) .
($PMA_Theme->filesizeInfo ?? 0)
);
}
/**
* checks if upload is enabled
*/
public function checkUpload(): void
{
if (! ini_get('file_uploads')) {
$this->set('enable_upload', false);
return;
}
$this->set('enable_upload', true);
// if set "php_admin_value file_uploads Off" in httpd.conf
// ini_get() also returns the string "Off" in this case:
if (strtolower((string) ini_get('file_uploads')) !== 'off') {
return;
}
$this->set('enable_upload', false);
}
/**
* Maximum upload size as limited by PHP
* Used with permission from Moodle (https://moodle.org/) by Martin Dougiamas
*
* this section generates $max_upload_size in bytes
*/
public function checkUploadSize(): void
{
$fileSize = ini_get('upload_max_filesize');
if (! $fileSize) {
$fileSize = '5M';
}
$size = Core::getRealSize($fileSize);
$postSize = ini_get('post_max_size');
if ($postSize) {
$size = min($size, Core::getRealSize($postSize));
}
$this->set('max_upload_size', $size);
}
/**
* Checks if protocol is https
*
* This function checks if the https protocol on the active connection.
*/
public function isHttps(): bool
{
if ($this->get('is_https') !== null) {
return $this->get('is_https');
}
$url = $this->get('PmaAbsoluteUri');
$is_https = false;
if (! empty($url) && parse_url($url, PHP_URL_SCHEME) === 'https') {
$is_https = true;
} elseif (strtolower(Core::getenv('HTTP_SCHEME')) === 'https') {
$is_https = true;
} elseif (strtolower(Core::getenv('HTTPS')) === 'on') {
$is_https = true;
} elseif (strtolower(substr(Core::getenv('REQUEST_URI'), 0, 6)) === 'https:') {
$is_https = true;
} elseif (strtolower(Core::getenv('HTTP_HTTPS_FROM_LB')) === 'on') {
// A10 Networks load balancer
$is_https = true;
} elseif (strtolower(Core::getenv('HTTP_FRONT_END_HTTPS')) === 'on') {
$is_https = true;
} elseif (strtolower(Core::getenv('HTTP_X_FORWARDED_PROTO')) === 'https') {
$is_https = true;
} elseif (strtolower(Core::getenv('HTTP_CLOUDFRONT_FORWARDED_PROTO')) === 'https') {
// Amazon CloudFront, issue #15621
$is_https = true;
} elseif (Util::getProtoFromForwardedHeader(Core::getenv('HTTP_FORWARDED')) === 'https') {
// RFC 7239 Forwarded header
$is_https = true;
} elseif (Core::getenv('SERVER_PORT') == 443) {
$is_https = true;
}
$this->set('is_https', $is_https);
return $is_https;
}
/**
* Get phpMyAdmin root path
*/
public function getRootPath(): string
{
static $cookie_path = null;
if ($cookie_path !== null && ! defined('TESTSUITE')) {
return $cookie_path;
}
$url = $this->get('PmaAbsoluteUri');
if (! empty($url)) {
$path = parse_url($url, PHP_URL_PATH);
if (! empty($path)) {
if (substr($path, -1) !== '/') {
return $path . '/';
}
return $path;
}
}
$parsedUrlPath = parse_url($GLOBALS['PMA_PHP_SELF'], PHP_URL_PATH);
$parts = explode(
'/',
rtrim(str_replace('\\', '/', $parsedUrlPath), '/')
);
/* Remove filename */
if (substr($parts[count($parts) - 1], -4) === '.php') {
$parts = array_slice($parts, 0, count($parts) - 1);
}
/* Remove extra path from javascript calls */
if (defined('PMA_PATH_TO_BASEDIR')) {
$parts = array_slice($parts, 0, count($parts) - 1);
}
$parts[] = '';
return implode('/', $parts);
}
/**
* enables backward compatibility
*/
public function enableBc(): void
{
$GLOBALS['cfg'] = $this->settings;
$GLOBALS['default_server'] = $this->defaultServer;
unset($this->defaultServer);
$GLOBALS['is_upload'] = $this->get('enable_upload');
$GLOBALS['max_upload_size'] = $this->get('max_upload_size');
$GLOBALS['is_https'] = $this->get('is_https');
$defines = [
'PMA_VERSION',
'PMA_MAJOR_VERSION',
'PMA_THEME_VERSION',
'PMA_THEME_GENERATION',
'PMA_IS_WINDOWS',
'PMA_IS_GD2',
'PMA_USR_OS',
'PMA_USR_BROWSER_VER',
'PMA_USR_BROWSER_AGENT',
];
foreach ($defines as $define) {
if (defined($define)) {
continue;
}
define($define, $this->get($define));
}
}
/**
* removes cookie
*
* @param string $cookieName name of cookie to remove
*
* @return bool result of setcookie()
*/
public function removeCookie(string $cookieName): bool
{
$httpCookieName = $this->getCookieName($cookieName);
if ($this->issetCookie($cookieName)) {
unset($_COOKIE[$httpCookieName]);
}
if (defined('TESTSUITE')) {
return true;
}
return setcookie(
$httpCookieName,
'',
time() - 3600,
$this->getRootPath(),
'',
$this->isHttps()
);
}
/**
* sets cookie if value is different from current cookie value,
* or removes if value is equal to default
*
* @param string $cookie name of cookie to remove
* @param string $value new cookie value
* @param string $default default value
* @param int $validity validity of cookie in seconds (default is one month)
* @param bool $httponly whether cookie is only for HTTP (and not for scripts)
*
* @return bool result of setcookie()
*/
public function setCookie(
string $cookie,
string $value,
?string $default = null,
?int $validity = null,
bool $httponly = true
): bool {
global $cfg;
if (strlen($value) > 0 && $default !== null && $value === $default
) {
// default value is used
if ($this->issetCookie($cookie)) {
// remove cookie
return $this->removeCookie($cookie);
}
return false;
}
if (strlen($value) === 0 && $this->issetCookie($cookie)) {
// remove cookie, value is empty
return $this->removeCookie($cookie);
}
$httpCookieName = $this->getCookieName($cookie);
if (! $this->issetCookie($cookie) || $this->getCookie($cookie) !== $value) {
// set cookie with new value
/* Calculate cookie validity */
if ($validity === null) {
/* Valid for one month */
$validity = time() + 2592000;
} elseif ($validity == 0) {
/* Valid for session */
$validity = 0;
} else {
$validity = time() + $validity;
}
if (defined('TESTSUITE')) {
$_COOKIE[$httpCookieName] = $value;
return true;
}
if (PHP_VERSION_ID < 70300) {
return setcookie(
$httpCookieName,
$value,
$validity,
$this->getRootPath() . '; samesite=' . $cfg['CookieSameSite'],
'',
$this->isHttps(),
$httponly
);
}
$optionalParams = [
'expires' => $validity,
'path' => $this->getRootPath(),
'domain' => '',
'secure' => $this->isHttps(),
'httponly' => $httponly,
'samesite' => $cfg['CookieSameSite'],
];
return setcookie(
$httpCookieName,
$value,
$optionalParams
);
}
// cookie has already $value as value
return true;
}
/**
* get cookie
*
* @param string $cookieName The name of the cookie to get
*
* @return mixed|null result of getCookie()
*/
public function getCookie(string $cookieName)
{
if (isset($_COOKIE[$this->getCookieName($cookieName)])) {
return $_COOKIE[$this->getCookieName($cookieName)];
}
return null;
}
/**
* Get the real cookie name
*
* @param string $cookieName The name of the cookie
*/
public function getCookieName(string $cookieName): string
{
return $cookieName . ( $this->isHttps() ? '_https' : '' );
}
/**
* isset cookie
*
* @param string $cookieName The name of the cookie to check
*
* @return bool result of issetCookie()
*/
public function issetCookie(string $cookieName): bool
{
return isset($_COOKIE[$this->getCookieName($cookieName)]);
}
/**
* Error handler to catch fatal errors when loading configuration
* file
*/
public static function fatalErrorHandler(): void
{
global $isConfigLoading;
if (! isset($isConfigLoading) || ! $isConfigLoading) {
return;
}
$error = error_get_last();
if ($error === null) {
return;
}
Core::fatalError(
sprintf(
'Failed to load phpMyAdmin configuration (%s:%s): %s',
Error::relPath($error['file']),
$error['line'],
$error['message']
)
);
}
/**
* Wrapper for footer/header rendering
*
* @param string $filename File to check and render
* @param string $id Div ID
*/
private static function renderCustom(string $filename, string $id): string
{
$retval = '';
if (@file_exists($filename)) {
$retval .= '';
ob_start();
include $filename;
$retval .= ob_get_clean();
$retval .= '
';
}
return $retval;
}
/**
* Renders user configured footer
*/
public static function renderFooter(): string
{
return self::renderCustom(CUSTOM_FOOTER_FILE, 'pma_footer');
}
/**
* Renders user configured footer
*/
public static function renderHeader(): string
{
return self::renderCustom(CUSTOM_HEADER_FILE, 'pma_header');
}
/**
* Returns temporary dir path
*
* @param string $name Directory name
*/
public function getTempDir(string $name): ?string
{
static $temp_dir = [];
if (isset($temp_dir[$name]) && ! defined('TESTSUITE')) {
return $temp_dir[$name];
}
$path = $this->get('TempDir');
if (empty($path)) {
$path = null;
} else {
$path = rtrim($path, DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR . $name;
if (! @is_dir($path)) {
@mkdir($path, 0770, true);
}
if (! @is_dir($path) || ! @is_writable($path)) {
$path = null;
}
}
$temp_dir[$name] = $path;
return $path;
}
/**
* Returns temporary directory
*/
public function getUploadTempDir(): ?string
{
// First try configured temp dir
// Fallback to PHP upload_tmp_dir
$dirs = [
$this->getTempDir('upload'),
ini_get('upload_tmp_dir'),
sys_get_temp_dir(),
];
foreach ($dirs as $dir) {
if (! empty($dir) && @is_writable($dir)) {
return realpath($dir);
}
}
return null;
}
/**
* Selects server based on request parameters.
*/
public function selectServer(): int
{
$request = empty($_REQUEST['server']) ? 0 : $_REQUEST['server'];
/**
* Lookup server by name
* (see FAQ 4.8)
*/
if (! is_numeric($request)) {
foreach ($this->settings['Servers'] as $i => $server) {
$verboseToLower = mb_strtolower($server['verbose']);
$serverToLower = mb_strtolower($request);
if ($server['host'] == $request
|| $server['verbose'] == $request
|| $verboseToLower == $serverToLower
|| md5($verboseToLower) === $serverToLower
) {
$request = $i;
break;
}
}
if (is_string($request)) {
$request = 0;
}
}
/**
* If no server is selected, make sure that $this->settings['Server'] is empty (so
* that nothing will work), and skip server authentication.
* We do NOT exit here, but continue on without logging into any server.
* This way, the welcome page will still come up (with no server info) and
* present a choice of servers in the case that there are multiple servers
* and '$this->settings['ServerDefault'] = 0' is set.
*/
if (is_numeric($request) && ! empty($request) && ! empty($this->settings['Servers'][$request])) {
$server = $request;
$this->settings['Server'] = $this->settings['Servers'][$server];
} else {
if (! empty($this->settings['Servers'][$this->settings['ServerDefault']])) {
$server = $this->settings['ServerDefault'];
$this->settings['Server'] = $this->settings['Servers'][$server];
} else {
$server = 0;
$this->settings['Server'] = [];
}
}
return (int) $server;
}
/**
* Checks whether Servers configuration is valid and possibly apply fixups.
*/
public function checkServers(): void
{
// Do we have some server?
if (! isset($this->settings['Servers']) || count($this->settings['Servers']) === 0) {
// No server => create one with defaults
$this->settings['Servers'] = [1 => $this->defaultServer];
} else {
// We have server(s) => apply default configuration
$new_servers = [];
foreach ($this->settings['Servers'] as $server_index => $each_server) {
// Detect wrong configuration
if (! is_int($server_index) || $server_index < 1) {
trigger_error(
sprintf(__('Invalid server index: %s'), $server_index),
E_USER_ERROR
);
}
$each_server = array_merge($this->defaultServer, $each_server);
// Final solution to bug #582890
// If we are using a socket connection
// and there is nothing in the verbose server name
// or the host field, then generate a name for the server
// in the form of "Server 2", localized of course!
if (empty($each_server['host']) && empty($each_server['verbose'])) {
$each_server['verbose'] = sprintf(__('Server %d'), $server_index);
}
$new_servers[$server_index] = $each_server;
}
$this->settings['Servers'] = $new_servers;
}
}
/**
* Return connection parameters for the database server
*
* @param int $mode Connection mode on of CONNECT_USER, CONNECT_CONTROL
* or CONNECT_AUXILIARY.
* @param array|null $server Server information like host/port/socket/persistent
*
* @return array user, host and server settings array
*/
public static function getConnectionParams(int $mode, ?array $server = null): array
{
global $cfg;
$user = null;
$password = null;
if ($mode == DatabaseInterface::CONNECT_USER) {
$user = $cfg['Server']['user'];
$password = $cfg['Server']['password'];
$server = $cfg['Server'];
} elseif ($mode == DatabaseInterface::CONNECT_CONTROL) {
$user = $cfg['Server']['controluser'];
$password = $cfg['Server']['controlpass'];
$server = [];
if (! empty($cfg['Server']['controlhost'])) {
$server['host'] = $cfg['Server']['controlhost'];
} else {
$server['host'] = $cfg['Server']['host'];
}
// Share the settings if the host is same
if ($server['host'] == $cfg['Server']['host']) {
$shared = [
'port',
'socket',
'compress',
'ssl',
'ssl_key',
'ssl_cert',
'ssl_ca',
'ssl_ca_path',
'ssl_ciphers',
'ssl_verify',
];
foreach ($shared as $item) {
if (! isset($cfg['Server'][$item])) {
continue;
}
$server[$item] = $cfg['Server'][$item];
}
}
// Set configured port
if (! empty($cfg['Server']['controlport'])) {
$server['port'] = $cfg['Server']['controlport'];
}
// Set any configuration with control_ prefix
foreach ($cfg['Server'] as $key => $val) {
if (substr($key, 0, 8) !== 'control_') {
continue;
}
$server[substr($key, 8)] = $val;
}
} else {
if ($server === null) {
return [
null,
null,
null,
];
}
if (isset($server['user'])) {
$user = $server['user'];
}
if (isset($server['password'])) {
$password = $server['password'];
}
}
// Perform sanity checks on some variables
$server['port'] = empty($server['port']) ? 0 : (int) $server['port'];
if (empty($server['socket'])) {
$server['socket'] = null;
}
if (empty($server['host'])) {
$server['host'] = 'localhost';
}
if (! isset($server['ssl'])) {
$server['ssl'] = false;
}
if (! isset($server['compress'])) {
$server['compress'] = false;
}
return [
$user,
$password,
$server,
];
}
/**
* Get LoginCookieValidity from preferences cache.
*
* No generic solution for loading preferences from cache as some settings
* need to be kept for processing in loadUserPreferences().
*
* @see loadUserPreferences()
*/
public function getLoginCookieValidityFromCache(int $server): void
{
global $cfg;
$cacheKey = 'server_' . $server;
if (! isset($_SESSION['cache'][$cacheKey]['userprefs']['LoginCookieValidity'])) {
return;
}
$value = $_SESSION['cache'][$cacheKey]['userprefs']['LoginCookieValidity'];
$this->set('LoginCookieValidity', $value);
$cfg['LoginCookieValidity'] = $value;
}
}