diff --git a/core/includes/bootstrap.inc b/core/includes/bootstrap.inc index 72685a4..e32db3a 100644 --- a/core/includes/bootstrap.inc +++ b/core/includes/bootstrap.inc @@ -296,6 +296,20 @@ const DRUPAL_PHP_FUNCTION_PATTERN = '[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*'; /** + * $config_directories key for active directory. + * + * @see config_get_config_directory + */ +const CONFIG_ACTIVE_DIRECTORY = 'active'; + +/** + * $config_directories key for staging directory. + * + * @see config_get_config_directory + */ +const CONFIG_STAGING_DIRECTORY = 'staging'; + +/** * Starts the timer with the specified name. * * If you start and stop the same timer multiple times, the measured intervals @@ -469,23 +483,27 @@ function find_conf_path($http_host, $script_name, $require_settings = TRUE) { } /** - * Returns the path of the configuration directory. + * Returns the path of a configuration directory. + * + * @param string $type + * (optional) The type of config directory to return. Drupal core provides + * 'active' and 'staging'. Defaults to CONFIG_ACTIVE_DIRECTORY. * * @return string * The configuration directory path. */ -function config_get_config_directory() { - global $config_directory_name; +function config_get_config_directory($type = CONFIG_ACTIVE_DIRECTORY) { + global $config_directories; if ($test_prefix = drupal_valid_test_ua()) { // @see Drupal\simpletest\WebTestBase::setUp() - $path = conf_path() . '/files/simpletest/' . substr($test_prefix, 10) . '/config'; + $path = conf_path() . '/files/simpletest/' . substr($test_prefix, 10) . '/config_' . $type; } - elseif (!empty($config_directory_name)) { - $path = conf_path() . '/files/' . $config_directory_name; + elseif (!empty($config_directories[$type])) { + $path = conf_path() . '/files/' . $config_directories[$type]; } else { - throw new \Exception('Missing $config_directory_name.'); + throw new \Exception(format_string('The configuration directory type %type does not exist.', array('%type' => $type))); } return $path; } @@ -678,7 +696,7 @@ function drupal_settings_initialize() { global $base_url, $base_path, $base_root, $script_path; // Export these settings.php variables to the global namespace. - global $databases, $cookie_domain, $conf, $installed_profile, $update_free_access, $db_url, $db_prefix, $drupal_hash_salt, $is_https, $base_secure_url, $base_insecure_url, $config_directory_name; + global $databases, $cookie_domain, $conf, $installed_profile, $update_free_access, $db_url, $db_prefix, $drupal_hash_salt, $is_https, $base_secure_url, $base_insecure_url, $config_directories; $conf = array(); // Make conf_path() available as local variable in settings.php. @@ -1679,7 +1697,9 @@ function watchdog($type, $message, array $variables = array(), $severity = WATCH // It is possible that the error handling will itself trigger an error. In that case, we could // end up in an infinite loop. To avoid that, we implement a simple static semaphore. - if (!$in_error_state && function_exists('module_implements')) { + // During early bootstrap of the installer, module_implements() might be + // loaded already, but the module system might be initialized yet. + if (!$in_error_state && function_exists('module_implements') && module_load_all(NULL)) { $in_error_state = TRUE; // The user object may not exist in all conditions, so 0 is substituted if needed. @@ -2436,7 +2456,7 @@ function drupal_container(Container $new_container = NULL, $reset = FALSE) { // lowest of low level configuration. $container->setParameter('config.storage.options', array( 'Drupal\Core\Config\FileStorage' => array( - 'directory' => config_get_config_directory() . '/active', + 'directory' => config_get_config_directory(CONFIG_ACTIVE_DIRECTORY), ), 'Drupal\Core\Config\CacheStorage' => array( 'backend' => 'Drupal\Core\Cache\DatabaseBackend', @@ -2449,6 +2469,7 @@ function drupal_container(Container $new_container = NULL, $reset = FALSE) { $container->register('config.subscriber.globalconf', 'Drupal\Core\EventSubscriber\ConfigGlobalOverrideSubscriber'); $container->register('dispatcher', 'Symfony\Component\EventDispatcher\EventDispatcher') ->addMethodCall('addSubscriber', array(new Reference('config.subscriber.globalconf'))); + // Register configuration object factory. $container->register('config.factory', 'Drupal\Core\Config\ConfigFactory') ->addArgument(new Reference('config.storage')) @@ -2456,7 +2477,7 @@ function drupal_container(Container $new_container = NULL, $reset = FALSE) { // Register configuration state. $container->setParameter('config.state.options', array( - 'directory' => config_get_config_directory() . '/import', + 'directory' => config_get_config_directory(CONFIG_STAGING_DIRECTORY), )); $container->register('config.state', 'Drupal\Core\Config\FileStorage') ->addArgument('%config.state.options%'); diff --git a/core/includes/config.inc b/core/includes/config.inc index c4d6810..c2b0f29 100644 --- a/core/includes/config.inc +++ b/core/includes/config.inc @@ -135,7 +135,7 @@ function config_sync_changes(array $config_changes, StorageInterface $source_sto * synchronization error, or NULL if there are no changes to synchronize. */ function config_import() { - // Retrieve a list of differences between last known state and active store. + // Retrieve a list of differences between staging and the active store. $source_storage = drupal_container()->get('config.state'); $target_storage = drupal_container()->get('config.storage'); @@ -213,12 +213,12 @@ function config_import_invoke_owner(array $config_changes, StorageInterface $sou } /** - * Updates the last known state with the active store configuration. + * Updates staging store with the active store configuration. * * @todo config_export() is a misnomer now. Rename to config_state_update(). */ function config_export() { - // Retrieve a list of differences between active store and last known state. + // Retrieve a list of differences between the active store and staging. $source_storage = drupal_container()->get('config.storage'); $target_storage = drupal_container()->get('config.state'); diff --git a/core/includes/install.core.inc b/core/includes/install.core.inc index 3d8d823..cf3a605 100644 --- a/core/includes/install.core.inc +++ b/core/includes/install.core.inc @@ -279,7 +279,7 @@ function install_begin_request(&$install_state) { include_once DRUPAL_ROOT . '/core/includes/session.inc'; // Determine whether the configuration system is ready to operate. - $install_state['config_verified'] = install_verify_config_directory(); + $install_state['config_verified'] = install_verify_config_directory(CONFIG_ACTIVE_DIRECTORY) && install_verify_config_directory(CONFIG_STAGING_DIRECTORY); // If it is not, replace the configuration storage with the InstallStorage // implementation, for the following reasons: @@ -303,9 +303,13 @@ function install_begin_request(&$install_state) { // @todo Move this into a proper Drupal\Core\DependencyInjection\InstallContainerBuilder. if (!$install_state['config_verified']) { $container = new ContainerBuilder(); + + $container->register('dispatcher', 'Symfony\Component\EventDispatcher\EventDispatcher'); + $container->register('config.storage', 'Drupal\Core\Config\InstallStorage'); $container->register('config.factory', 'Drupal\Core\Config\ConfigFactory') - ->addArgument(new Reference('config.storage')); + ->addArgument(new Reference('config.storage')) + ->addArgument(new Reference('dispatcher')); drupal_container($container); } @@ -1086,8 +1090,8 @@ function install_settings_form_submit($form, &$form_state) { drupal_rewrite_settings($settings); - // Add the config directory to settings.php. - drupal_install_config_directory(); + // Add the config directories to settings.php. + drupal_install_config_directories(); // We have a valid configuration directory in settings.php. // Reset the service container, so the config.storage service will use the diff --git a/core/includes/install.inc b/core/includes/install.inc index 6602d36..de32df2 100644 --- a/core/includes/install.inc +++ b/core/includes/install.inc @@ -254,32 +254,37 @@ function drupal_rewrite_settings($settings = array()) { * @see install_settings_form_submit() * @see update_prepare_d8_bootstrap() */ -function drupal_install_config_directory() { - global $config_directory_name; +function drupal_install_config_directories() { + global $config_directories; // Add a randomized config directory name to settings.php, unless it was // manually defined in the existing already. - if (empty($config_directory_name)) { - $settings['config_directory_name'] = array( - 'value' => 'config_' . drupal_hash_base64(drupal_random_bytes(55)), + if (empty($config_directories)) { + $settings['config_directories'] = array( + 'value' => array( + CONFIG_ACTIVE_DIRECTORY => 'config/active_' . drupal_hash_base64(drupal_random_bytes(55)), + CONFIG_STAGING_DIRECTORY => 'config/staging_' . drupal_hash_base64(drupal_random_bytes(55)), + ), 'required' => TRUE, ); // Rewrite settings.php, which also sets the value as global variable. drupal_rewrite_settings($settings); } - // Ensure that the config directory exists or can be created, and is writable. - if (!install_ensure_config_directory()) { + // Ensure the config directories exist or can be created, and are writable. + foreach (array(CONFIG_ACTIVE_DIRECTORY, CONFIG_STAGING_DIRECTORY) as $config_type) { // This should never fail, since if the config directory was specified in // settings.php it will have already been created and verified earlier, and // if it wasn't specified in settings.php, it is created here inside the // public files directory, which has already been verified to be writable // itself. But if it somehow fails anyway, the installation cannot proceed. // Bail out using a similar error message as in system_requirements(). - throw new Exception(st('The directory %directory could not be created or could not be made writable. To proceed with the installation, either create the directory and modify its permissions manually or ensure that the installer has the permissions to create it automatically. For more information, see the online handbook.', array( - '%directory' => config_get_config_directory(), - '@handbook_url' => 'http://drupal.org/server-permissions', - ))); + if (!install_ensure_config_directory($config_type)) { + throw new Exception(st('The directory %directory could not be created or could not be made writable. To proceed with the installation, either create the directory and modify its permissions manually or ensure that the installer has the permissions to create it automatically. For more information, see the online handbook.', array( + '%directory' => config_get_config_directory($config_type), + '@handbook_url' => 'http://drupal.org/server-permissions', + ))); + } } } @@ -291,38 +296,51 @@ function drupal_install_config_directory() { * since the installer would create the config directory too early in the * installation process otherwise (e.g., when only visiting install.php when * there is a settings.php already, but not actually executing the installation). + * + * @param string $type + * Type of config directory to return. Drupal core provides 'active' and + * 'staging'. + * + * @return bool + * TRUE if the config directory exists and is writable. */ -function install_verify_config_directory() { - global $config_directory_name; - if (empty($config_directory_name)) { +function install_verify_config_directory($type) { + global $config_directories; + if (!isset($config_directories[$type])) { return FALSE; } - $config_directory = config_get_config_directory(); - if (is_dir($config_directory) && is_writable($config_directory)) { - return TRUE; + try { + $config_directory = config_get_config_directory($type); + if (is_dir($config_directory) && is_writable($config_directory)) { + return TRUE; + } + } + catch (\Exception $e) { } return FALSE; } /** * Ensures that the config directory exists and is writable, or can be made so. + * + * @param string $type + * Type of config directory to return. Drupal core provides 'active' and + * 'staging'. + * + * @return bool + * TRUE if the config directory exists and is writable. */ -function install_ensure_config_directory() { +function install_ensure_config_directory($type) { // The config directory must be defined in settings.php. - global $config_directory_name; - if (empty($config_directory_name)) { + global $config_directories; + if (!isset($config_directories[$type])) { return FALSE; } // The logic here is similar to that used by system_requirements() for other // directories that the installer creates. else { - $config_directory = config_get_config_directory(); - $success = file_prepare_directory($config_directory, FILE_CREATE_DIRECTORY | FILE_MODIFY_PERMISSIONS); - foreach (array('active', 'import') as $subdir) { - $subdir = $config_directory . '/' . $subdir; - $success = $success && file_prepare_directory($subdir, FILE_CREATE_DIRECTORY | FILE_MODIFY_PERMISSIONS); - } - return $success; + $config_directory = config_get_config_directory($type); + return file_prepare_directory($config_directory, FILE_CREATE_DIRECTORY | FILE_MODIFY_PERMISSIONS); } } diff --git a/core/includes/theme.maintenance.inc b/core/includes/theme.maintenance.inc index 12de2a7..4b3e80c 100644 --- a/core/includes/theme.maintenance.inc +++ b/core/includes/theme.maintenance.inc @@ -122,7 +122,7 @@ function theme_task_list($variables) { } else { $class = $done ? 'done' : ''; - $status = $done ? '(' . t('done') . ')' : ''; + $status = $done ? '(' . $t('done') . ')' : ''; } $output .= '