1 bootstrap.inc | backdrop_settings_initialize() |
Sets the base URL, cookie domain, and session name from configuration.
File
- core/
includes/ bootstrap.inc, line 851 - Functions that need to be loaded on every Backdrop request.
Code
function backdrop_settings_initialize() {
global $base_url, $base_path, $base_root;
// Export these settings.php variables to the global namespace.
global $databases, $cookie_domain, $conf, $settings, $installed_profile, $is_https, $base_secure_url, $base_insecure_url, $config_directories, $config;
$conf = array();
$conf_path = conf_path();
if (file_exists($conf_path . '/settings.php')) {
require_once $conf_path . '/settings.php';
}
if (!empty($settings['backdrop_drupal_compatibility'])) {
require_once BACKDROP_ROOT . '/core/includes/drupal.inc';
}
$database_is_set = FALSE;
// The database connection can be specified in multiple formats:
// - $database as a string.
// - $database as an simple array.
// - $databases as a multi-level nested array.
// Both the simplified syntaxes are converted to the larger $databases array.
// First option: the database connection settings have been provided in the
// form of a connection string. This was the default format in versions prior
// to Backdrop 1.30.0:
if (!empty($database) && is_string($database)) {
$default_db_string = 'mysql://user:pass@localhost/database_name';
if ($database !== $default_db_string) {
// Convert simplified database settings string into the full databases
// array.
$database_parts = parse_url($database);
if (!$database_parts) {
trigger_error('The database setting could not be parsed. Please check the $database setting in settings.php.', E_USER_ERROR);
}
$databases['default']['default'] = array(
'driver' => $database_parts['scheme'],
// Remove leading slash.
'database' => rawurldecode(substr($database_parts['path'], 1)),
'username' => isset($database_parts['user']) ? rawurldecode($database_parts['user']) : '',
'password' => isset($database_parts['pass']) ? rawurldecode($database_parts['pass']) : '',
'host' => $database_parts['host'],
'port' => isset($database_parts['port']) ? $database_parts['port'] : NULL,
'prefix' => !empty($database_prefix) ? $database_prefix : '',
);
$database_is_set = TRUE;
}
}
// Second option: the database connection settings is a simplified array. This
// is the default format in version 1.30.0 and higher.
if (!empty($database) && is_array($database)) {
$default_db_array = array(
'database' => 'database_name',
'username' => 'user',
'password' => 'pass',
'host' => 'localhost',
);
if ($database != $default_db_array) {
// Specify default values.
$database += array(
'prefix' => '',
'driver' => 'mysql',
'port' => NULL,
'charset' => 'utf8mb4',
'collation' => 'utf8mb4_general_ci',
);
$databases['default']['default'] = $database;
$database_is_set = TRUE;
}
}
// If using one of the simplified syntaxes, verify all the necessary parts
// are specified.
if ($database_is_set) {
// Check that all required parts are included.
$required_parts = array('driver', 'database', 'username', 'host');
foreach ($required_parts as $key) {
if (!$databases['default']['default'][$key]) {
$missing_field = ($key == 'database') ? 'name' : $key;
trigger_error('Could not find a value for the database "' . $missing_field . '" setting. Please check the $database setting in settings.php.', E_USER_ERROR);
}
}
}
$is_https = backdrop_is_https();
// Load settings specified by the server, if present.
if (isset($_SERVER['BACKDROP_SETTINGS'])) {
$server_settings = @json_decode($_SERVER['BACKDROP_SETTINGS'], TRUE);
if (!is_array($server_settings)) {
trigger_error('The values in $_SERVER[BACKDROP_SETTINGS] could not be read. Ensure it is a valid JSON string with no spaces.', E_USER_ERROR);
}
else {
foreach ($server_settings as $key => $value) {
// One level of depth should be enough for $settings and $databases.
if ($key == 'settings') {
foreach ($value as $settings_key => $settings_value) {
$settings[$settings_key] = $settings_value;
}
}
elseif ($key == 'databases') {
// Protect default configuration but allow the specification of
// additional databases.
if (!isset($databases) || !is_array($databases)) {
$databases = array();
}
$databases = array_replace_recursive($databases, $value);
}
else {
$$key = $value;
}
}
}
}
// Pull in the database charset option if specified. This removes the need
// to use the long-form array and allows enabling ut8mb4 support even if the
// server provided options via $_SERVER['BACKDROP_SETTINGS'].
if (isset($database_charset) && isset($databases['default']['default']) && !isset($databases['default']['default']['charset'])) {
$databases['default']['default']['charset'] = $database_charset;
}
if (isset($base_url)) {
// Parse fixed base URL from settings.php.
$parts = parse_url($base_url);
if (!isset($parts['path'])) {
$parts['path'] = '';
}
$base_path = $parts['path'] . '/';
// Build $base_root (everything until first slash after "scheme://").
$base_root = substr($base_url, 0, strlen($base_url) - strlen($parts['path']));
}
else {
// Create base URL.
$http_protocol = $is_https ? 'https' : 'http';
$base_root = $http_protocol . '://' . $_SERVER['HTTP_HOST'];
$base_url = $base_root;
// $_SERVER['SCRIPT_NAME'] can, in contrast to $_SERVER['PHP_SELF'], not
// be modified by a visitor.
if ($dir = rtrim(dirname($_SERVER['SCRIPT_NAME']), '\/')) {
// Remove "core" directory if present, allowing install.php, update.php,
// cron.php and others to auto-detect a base path.
$core_position = strrpos($dir, '/core');
if ($core_position !== FALSE && strlen($dir) - 5 == $core_position) {
$base_path = substr($dir, 0, $core_position);
}
else {
$base_path = $dir;
}
$base_url .= $base_path;
$base_path .= '/';
}
else {
$base_path = '/';
}
}
$base_secure_url = str_replace('http://', 'https://', $base_url);
$base_insecure_url = str_replace('https://', 'http://', $base_url);
if ($cookie_domain) {
// If the user specifies the cookie domain, also use it for session name.
$session_name = $cookie_domain;
}
else {
// Otherwise use $base_url as session name, without the protocol
// to use the same session identifiers across HTTP and HTTPS.
list(, $session_name) = explode('://', $base_url, 2);
// HTTP_HOST can be modified by a visitor, but we already sanitized it
// in backdrop_settings_initialize().
if (!empty($_SERVER['HTTP_HOST'])) {
$cookie_domain = $_SERVER['HTTP_HOST'];
// Strip leading periods, www., and port numbers from cookie domain.
$cookie_domain = ltrim($cookie_domain, '.');
if (strpos($cookie_domain, 'www.') === 0) {
$cookie_domain = substr($cookie_domain, 4);
}
$cookie_domain = explode(':', $cookie_domain);
$cookie_domain = '.' . $cookie_domain[0];
}
}
// Per RFC 2109, cookie domains must contain at least one dot other than the
// first. For hosts such as 'localhost' or IP Addresses we don't set a cookie domain.
if (count(explode('.', $cookie_domain)) > 2 && !is_numeric(str_replace('.', '', $cookie_domain))) {
ini_set('session.cookie_domain', $cookie_domain);
}
// To prevent session cookies from being hijacked, a user can configure the
// SSL version of their website to only transfer session cookies via SSL by
// using PHP's session.cookie_secure setting. The browser will then use two
// separate session cookies for the HTTPS and HTTP versions of the site. So we
// must use different session identifiers for HTTPS and HTTP to prevent a
// cookie collision.
if ($is_https) {
ini_set('session.cookie_secure', TRUE);
}
$prefix = ini_get('session.cookie_secure') ? 'SSESS' : 'SESS';
session_name($prefix . substr(hash('sha256', $session_name), 0, 32));
}