diff --git a/core/includes/bootstrap.inc b/core/includes/bootstrap.inc index eac2f97..f1c3a64 100644 --- a/core/includes/bootstrap.inc +++ b/core/includes/bootstrap.inc @@ -2234,6 +2234,8 @@ function _drupal_exception_handler($exception) { * Sets up the script environment and loads settings.php. */ function _drupal_bootstrap_configuration() { + // Load the procedural configuration system helper functions. + require_once DRUPAL_ROOT . '/core/includes/config.inc'; // Set the Drupal custom error handler. set_error_handler('_drupal_error_handler'); set_exception_handler('_drupal_exception_handler'); @@ -2249,9 +2251,6 @@ function _drupal_bootstrap_configuration() { // Activate the class loader. drupal_classloader(); - - // Load the procedural configuration system helper functions. - require_once DRUPAL_ROOT . '/core/includes/config.inc'; } /** diff --git a/core/includes/install.core.inc b/core/includes/install.core.inc index 50fb9b6..c067328 100644 --- a/core/includes/install.core.inc +++ b/core/includes/install.core.inc @@ -146,14 +146,15 @@ function install_state_defaults() { // The last task that was completed during the previous installation // request. 'completed_task' => NULL, - // This becomes TRUE only when a valid config directory is created or - // detected. - 'config_verified' => FALSE, - // This becomes TRUE only when Drupal's system module is installed. - 'database_tables_exist' => FALSE, - // This becomes TRUE only when a valid database connection can be - // established. + // TRUE when there is a valid database connection. 'database_verified' => FALSE, + // TRUE when there are valid config directories. + 'config_verified' => FALSE, + // TRUE when a valid settings.php exists (containing both database + // connection information and config directory names). + 'settings_verified' => FALSE, + // TRUE when the base system is ready to operate. + 'base_system_verified' => FALSE, // An array of forms to be programmatically submitted during the // installation. The keys of each element indicate the name of the // installation task that the form submission is for, and the values are @@ -192,10 +193,6 @@ function install_state_defaults() { // $_SERVER array via drupal_override_server_variables(). Used by // non-interactive installations only. 'server' => array(), - // This becomes TRUE only when a valid settings.php file is written - // (containing both valid database connection information and a valid - // config directory). - 'settings_verified' => FALSE, // Installation tasks can set this to TRUE to force the page request to // end (even if there is no themable output), in the case of an interactive // installation. This is needed only rarely; for example, it would be used @@ -275,87 +272,88 @@ function install_begin_request(&$install_state) { global $conf; require_once DRUPAL_ROOT . '/core/modules/system/system.install'; + require_once DRUPAL_ROOT . '/core/includes/ajax.inc'; + require_once DRUPAL_ROOT . '/core/includes/cache.inc'; require_once DRUPAL_ROOT . '/core/includes/common.inc'; + require_once DRUPAL_ROOT . '/core/includes/database.inc'; require_once DRUPAL_ROOT . '/core/includes/file.inc'; + require_once DRUPAL_ROOT . '/core/includes/form.inc'; require_once DRUPAL_ROOT . '/core/includes/install.inc'; require_once DRUPAL_ROOT . '/core/includes/schema.inc'; require_once DRUPAL_ROOT . '/' . variable_get('path_inc', 'core/includes/path.inc'); - - // Load module basics (needed for hook invokes). include_once DRUPAL_ROOT . '/core/includes/module.inc'; include_once DRUPAL_ROOT . '/core/includes/session.inc'; require_once DRUPAL_ROOT . '/core/includes/entity.inc'; - // Determine whether the configuration system is ready to operate. + // Determine bootstrap status. + if (!empty($install_state['parameters']['bootstrap'])) { + $install_state['base_system_verified'] = (int) $install_state['parameters']['bootstrap']; + } + + // Determine whether base system services are ready to operate. $install_state['config_verified'] = install_verify_config_directory(CONFIG_ACTIVE_DIRECTORY) && install_verify_config_directory(CONFIG_STAGING_DIRECTORY); + $install_state['database_verified'] = install_verify_database_settings(); + $install_state['settings_verified'] = $install_state['config_verified'] && $install_state['database_verified']; - // If it is not, replace the configuration storage with the InstallStorage - // implementation, for the following reasons: - // - The first call into drupal_container() will try to set up the regular - // runtime configuration storage, using the CachedStorage by default. It - // calls config_get_config_directory() to retrieve the config directory to - // use, but that throws an exception, since $config_directories is not - // defined since there is no settings.php yet. If there is a prepared - // settings.php already, then the returned directory still cannot be used, - // because it does not necessarily exist. The installer ensures that it - // exists and is writeable in a later step. - // - The installer outputs maintenance theme pages and performs many other - // operations, which try to load configuration. Since there is no active - // configuration yet, and because the configuration system does not have a - // notion of default values at runtime, data is missing in many places. The - // lack of data does not trigger errors, but results in a broken user - // interface (e.g., missing page title, etc). - // - The actual configuration data to read during installation is essentially - // the default configuration provided by the installation profile and - // modules (most notably System module). The InstallStorage therefore reads - // from the default configuration directories of extensions. - // This override is reverted as soon as the config directory has been set up - // successfully. - // @see drupal_install_config_directories() - if (!$install_state['config_verified']) { + // If they are not, replace services with in-memory implementations and + // specialized installer implementations. This override is reverted as soon as + // the install_system_rebuild() phase is reached. + if (!$install_state['base_system_verified']) { // @todo Move into a proper Drupal\Core\DependencyInjection\InstallContainerBuilder. $container = new ContainerBuilder(); + // The actual configuration data to read during installation is essentially + // the default configuration provided by the installation profile and + // modules (most notably System module). The InstallStorage therefore reads + // from the default configuration directories of extensions. $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('dispatcher')); - drupal_container($container); - } - // Set up $language, so t() caller functions will still work. - drupal_language_initialize(); + $conf['keyvalue_default'] = 'keyvalue.memory'; + $container + ->register('keyvalue', 'Drupal\Core\KeyValueStore\KeyValueFactory') + ->addArgument(new Reference('service_container')); + $container + ->register('keyvalue.memory', 'Drupal\Core\KeyValueStore\KeyValueMemoryFactory'); - require_once DRUPAL_ROOT . '/core/includes/ajax.inc'; - // Override the module list with a minimal set of modules. - $module_list['system']['filename'] = 'core/modules/system/system.module'; - $module_list['user']['filename'] = 'core/modules/user/user.module'; - module_list(NULL, $module_list); - drupal_load('module', 'system'); - drupal_load('module', 'user'); - - // Load the cache infrastructure using a "fake" cache implementation that - // does not attempt to write to the database. We need this during the initial - // part of the installer because the database is not available yet. We - // continue to use it even when the database does become available, in order - // to preserve consistency between interactive and command-line installations - // (the latter complete in one page request and therefore are forced to - // continue using the cache implementation they started with) and also - // because any data put in the cache during the installer is inherently - // suspect, due to the fact that Drupal is not fully set up yet. - require_once DRUPAL_ROOT . '/core/includes/cache.inc'; - $conf['cache_classes'] = array('cache' => 'Drupal\Core\Cache\InstallBackend'); + $conf['cache_classes'] = array('cache' => 'Drupal\Core\Cache\InstallBackend'); + $conf['lock_backend'] = 'Drupal\Core\Lock\NullLockBackend'; + + drupal_container($container); - // The install process cannot use the database lock backend since the database - // is not fully up, so we use a null backend implementation during the - // installation process. This will also speed up the installation process. - // The site being installed will use the real lock backend when doing AJAX - // requests but, except for a WSOD, there is no chance for a a lock to stall - // (as opposed to the cache backend) so we can afford having a null - // implementation here. - $conf['lock_backend'] = 'Drupal\Core\Lock\NullLockBackend'; + // Override the module list with a minimal set of modules. + $module_list['system']['filename'] = 'core/modules/system/system.module'; + $module_list['user']['filename'] = 'core/modules/user/user.module'; + module_list(NULL, $module_list); + drupal_load('module', 'system'); + drupal_load('module', 'user'); + + // Set up $language, so t() caller functions will still work. + drupal_language_initialize(); + } + // We have reached the install_system_rebuild() install task and need to + // install System module as well as all the rest of the system in a full + // environment. + else { + // DRUPAL_BOOTSTRAP_SESSION is incompatible with the installer, as it tries + // to read and write sessions before the {users} table has been installed. + // Therefore, the install_base_system() task needs a custom bootstrap that + // avoids session initialization but is otherwise still a full environment. + // @todo Convert session handling into a swappable service. + // @see http://drupal.org/node/335411 + if ($install_state['parameters']['bootstrap'] == DRUPAL_BOOTSTRAP_VARIABLES) { + drupal_bootstrap(DRUPAL_BOOTSTRAP_VARIABLES); + _drupal_bootstrap_code(); + } + else { + drupal_bootstrap(DRUPAL_BOOTSTRAP_CODE); + } + $kernel = new DrupalKernel('prod', TRUE, NULL); + $kernel->boot(); + } // Prepare for themed output. We need to run this at the beginning of the // page request to avoid a different theme accidentally getting set. (We also @@ -364,34 +362,8 @@ function install_begin_request(&$install_state) { // accessing the database before it is set up yet.) drupal_maintenance_theme(); - // Check existing settings.php. - $install_state['database_verified'] = install_verify_database_settings(); - $install_state['settings_verified'] = $install_state['config_verified'] && $install_state['database_verified']; - - if ($install_state['database_verified']) { - // Initialize the database system. Note that the connection - // won't be initialized until it is actually requested. - require_once DRUPAL_ROOT . '/core/includes/database.inc'; - - // Verify the last completed task in the database, if there is one. - $task = install_verify_completed_task(); - } - else { - $task = NULL; - - // Since previous versions of Drupal stored database connection information - // in the 'db_url' variable, we should never let an installation proceed if - // this variable is defined and the settings file was not verified above - // (otherwise we risk installing over an existing site whose settings file - // has not yet been updated). - if (!empty($GLOBALS['db_url'])) { - throw new Exception(install_already_done_error()); - } - } - // Modify the installation state as appropriate. - $install_state['completed_task'] = $task; - $install_state['database_tables_exist'] = !empty($task); + $install_state['completed_task'] = install_verify_completed_task(); // Add the list of available profiles to the installation state. $install_state['profiles'] += drupal_system_listing('/^' . DRUPAL_PHP_FUNCTION_PATTERN . '\.profile$/', 'profiles'); @@ -435,8 +407,8 @@ function install_run_tasks(&$install_state) { if (!$install_state['task_not_complete']) { $install_state['tasks_performed'][] = $task_name; $install_state['installation_finished'] = empty($tasks_to_perform); - if ($install_state['database_tables_exist'] && ($task['run'] == INSTALL_TASK_RUN_IF_NOT_COMPLETED || $install_state['installation_finished'])) { - variable_set('install_task', $install_state['installation_finished'] ? 'done' : $task_name); + if ($task['run'] == INSTALL_TASK_RUN_IF_NOT_COMPLETED || $install_state['installation_finished']) { + state()->set('system.install_task', $install_state['installation_finished'] ? 'done' : $task_name); } } // Stop when there are no tasks left. In the case of an interactive @@ -464,7 +436,6 @@ function install_run_task($task, &$install_state) { $function = $task['function']; if ($task['type'] == 'form') { - require_once DRUPAL_ROOT . '/core/includes/form.inc'; if ($install_state['interactive']) { // For interactive forms, build the form and ensure that it will not // redirect, since the installer handles its own redirection only after @@ -509,7 +480,7 @@ function install_run_task($task, &$install_state) { elseif ($task['type'] == 'batch') { // Start a new batch based on the task function, if one is not running // already. - $current_batch = variable_get('install_current_batch'); + $current_batch = state()->get('system.install_current_batch'); if (!$install_state['interactive'] || !$current_batch) { $batch = $function($install_state); if (empty($batch)) { @@ -522,7 +493,7 @@ function install_run_task($task, &$install_state) { // task is currently running. Otherwise, we need to make sure the batch // will complete in one page request. if ($install_state['interactive']) { - variable_set('install_current_batch', $function); + state()->set('system.install_current_batch', $function); } else { $batch =& batch_get(); @@ -551,7 +522,7 @@ function install_run_task($task, &$install_state) { // longer requesting a batch ID. if ($output === FALSE) { // Return nothing so the next task will run in the same request. - variable_del('install_current_batch'); + state()->delete('system.install_current_batch'); return; } else { @@ -646,10 +617,13 @@ function install_tasks($install_state) { // since the form submit handler is where settings.php is rewritten. 'run' => $install_state['settings_verified'] ? INSTALL_TASK_SKIP : INSTALL_TASK_RUN_IF_NOT_COMPLETED, ), - 'install_base_system' => array( + 'install_system_schema' => array( + 'run' => $install_state['base_system_verified'] ? INSTALL_TASK_SKIP : INSTALL_TASK_RUN_IF_NOT_COMPLETED, ), - 'install_bootstrap_full' => array( - 'run' => INSTALL_TASK_RUN_IF_REACHED, + 'install_system_rebuild' => array( + ), + // All tasks below are executed in a regular, full Drupal environment. + 'install_base_system' => array( ), 'install_profile_modules' => array( 'display_name' => count($install_state['profiles']) == 1 ? st('Install site') : st('Installation profile'), @@ -876,15 +850,86 @@ function install_verify_requirements(&$install_state) { } /** + * Install task: Installs the System module schema. + */ +function install_system_schema(&$install_state) { + // Create base system tables if they do not exist yet. + // The try/catch is not necessary under normal circumstances, but helps a lot + // when debugging the installer, since this install task has to be executed + // unconditionally until the install_system_rebuild() install task is reached, + // as we cannot determine whether system tables have been installed already. + try { + drupal_install_schema('system'); + } + catch (\Exception $e) { + } +} + +/** + * Install task: Performs a full bootstrap into the new environment. + */ +function install_system_rebuild(&$install_state) { + global $conf; + + // If we are in the interactive installer, all we need to do is to set the + // 'bootstrap' parameter. Doing so will trigger a redirect and the next page + // request will perform a full boostrap into the new environment. + $install_state['base_system_verified'] = TRUE; + $install_state['parameters']['bootstrap'] = DRUPAL_BOOTSTRAP_VARIABLES; + if ($install_state['interactive']) { + return; + } + + // Otherwise, this phase is reached within the early-installer environment. + // We need to unset all overrides and rebuild all necessary facilities to get + // into a regular bootstrap state. + // Remove the service overrides. + unset($conf['cache_classes']); + unset($conf['keyvalue_default']); + unset($conf['lock_backend']); + + // Ensure that custom service definitions in a prepared settings.php are + // applied. This effectively allows to install Drupal with custom Cache, + // KeyValue, and Lock backends in the non-interactive installer. + $conf_path = conf_path(); + if (is_readable(DRUPAL_ROOT . '/' . $conf_path . '/settings.php')) { + include DRUPAL_ROOT . '/' . $conf_path . '/settings.php'; + } + + // Rebuild and replace the container with working service implementations. + drupal_container(NULL, TRUE); + + // Clear out module list and hook implementation statics. + module_list_reset(); + module_load_all(FALSE, TRUE); + system_list_reset(); + module_implements_reset(); + + // Bootstrap, but avoid session initialization. + // @see install_begin_request() + drupal_bootstrap(DRUPAL_BOOTSTRAP_VARIABLES); + _drupal_bootstrap_code(); + $kernel = new DrupalKernel('prod', TRUE, NULL); + $kernel->boot(); +} + +/** * Installation task; install the base functionality Drupal needs to bootstrap. * * @param $install_state * An array of information about the current installation state. */ function install_base_system(&$install_state) { - // Install system.module. + // Install System module. + // This cannot use module_enable(), since System module's database tables have + // to be created separately in install_system_schema(), so we are able to + // switch to a full Drupal environment in install_system_rebuild(). drupal_install_system(); + // Something in the installer bootstrap primes file_get_stream_wrappers() too + // early. Resetting that static alone doesn't resolve it. + drupal_static_reset(); + // Call file_ensure_htaccess() to ensure that all of Drupal's standard // directories (e.g., the public files directory and config directory) have // appropriate .htaccess files. These directories will have already been @@ -901,13 +946,17 @@ function install_base_system(&$install_state) { // Save the list of other modules to install for the upcoming tasks. // variable_set() can be used now that system.module is installed. $modules = $install_state['profile_info']['dependencies']; - // The installation profile is also a module, which needs to be installed // after all the dependencies have been installed. $modules[] = drupal_get_profile(); - variable_set('install_profile_modules', array_diff($modules, array('system'))); - $install_state['database_tables_exist'] = TRUE; + + // Now that the {users} table exists, the session can be initialized. + $install_state['parameters']['bootstrap'] = DRUPAL_BOOTSTRAP_CODE; + if ($install_state['interactive']) { + return; + } + drupal_bootstrap(DRUPAL_BOOTSTRAP_CODE); } /** @@ -918,16 +967,8 @@ function install_base_system(&$install_state) { * is already installed. */ function install_verify_completed_task() { - try { - if ($result = db_query("SELECT value FROM {variable} WHERE name = :name", array('name' => 'install_task'))) { - $task = unserialize($result->fetchField()); - } - } - // Do not trigger an error if the database query fails, since the database - // might not be set up yet. - catch (Exception $e) { - } - if (isset($task)) { + $task = state()->get('system.install_task'); + if ($task) { if ($task == 'done') { throw new Exception(install_already_done_error()); } @@ -1103,23 +1144,12 @@ function install_settings_form_submit($form, &$form_state) { ); drupal_rewrite_settings($settings); + $install_state['database_verified'] = TRUE; + $install_state['settings_verified'] = TRUE; // Add the config directories to settings.php. drupal_install_config_directories(); - - // We have valid configuration directories in settings.php. - // Reset the service container, so the config.storage service will use the - // actual active storage for installing configuration. - drupal_container(NULL, TRUE); - - // Indicate that the settings file has been verified, and check the database - // for the last completed task, now that we have a valid connection. This - // last step is important since we want to trigger an error if the new - // database already has Drupal installed. - $install_state['settings_verified'] = TRUE; $install_state['config_verified'] = TRUE; - $install_state['database_verified'] = TRUE; - $install_state['completed_task'] = install_verify_completed_task(); } /** @@ -1494,23 +1524,6 @@ function install_load_profile(&$install_state) { } /** - * Performs a full bootstrap of Drupal during installation. - * - * @param $install_state - * An array of information about the current installation state. - */ -function install_bootstrap_full(&$install_state) { - // Clear the module list that was overriden earlier in the process. - // This will allow all freshly installed modules to be loaded. - module_list_reset(); - - // Instantiate the kernel. - $kernel = new DrupalKernel('prod', FALSE, NULL); - $kernel->boot(); - drupal_bootstrap(DRUPAL_BOOTSTRAP_FULL); -} - -/** * Installs required modules via a batch process. * * @param $install_state @@ -1643,15 +1656,6 @@ function install_configure_form($form, &$form_state, &$install_state) { // work during installation. drupal_add_js(array('copyFieldValue' => array('edit-site-mail' => array('edit-account-mail'))), 'setting'); - // Cache a fully-built schema. This is necessary for any invocation of - // index.php because: (1) setting cache table entries requires schema - // information, (2) that occurs during bootstrap before any module are - // loaded, so (3) if there is no cached schema, drupal_get_schema() will - // try to generate one but with no loaded modules will return nothing. - // - // @todo Move this to the 'install_finished' task? - drupal_get_schema(NULL, TRUE); - // Return the form. return _install_configure_form($form, $form_state, $install_state); } @@ -1695,6 +1699,7 @@ function install_finished(&$install_state) { // Flush all caches to ensure that any full bootstraps during the installer // do not leave stale cached data, and that any content types or other items // registered by the installation profile are registered correctly. + // @todo This appears to be unnecessary. drupal_flush_all_caches(); drupal_set_title(st('@drupal installation complete', array('@drupal' => drupal_install_profile_distribution_name())), PASS_THROUGH); @@ -1730,6 +1735,7 @@ function _install_module_batch($module, $module_name, &$context) { function _install_profile_modules_finished($success, $results, $operations) { // Flush all caches to complete the module installation process. Subsequent // installation tasks will now have full access to the profile's modules. + // @todo This appears to be unnecessary. drupal_flush_all_caches(); } @@ -2040,5 +2046,5 @@ function install_configure_form_submit($form, &$form_state) { user_login_finalize(); // Record when this install ran. - variable_set('install_time', $_SERVER['REQUEST_TIME']); + state()->set('system.install_time', $_SERVER['REQUEST_TIME']); } diff --git a/core/includes/install.inc b/core/includes/install.inc index ee501ba..bb21175 100644 --- a/core/includes/install.inc +++ b/core/includes/install.inc @@ -7,6 +7,7 @@ use Drupal\Core\Database\Database; use Drupal\locale\Gettext; +use Symfony\Component\DependencyInjection\ContainerInterface; /** * Requirement severity -- Informational message only. @@ -413,40 +414,68 @@ function drupal_verify_profile($install_state) { } /** - * Installs the system module. + * Installs the System module. * - * Separated from the installation of other modules so core system - * functions can be made available while other modules are installed. + * This is the exact same procedure as in module_enable(). The only difference + * is that System module's database schema has been installed in + * install_system_schema() already. Due to that, module_enable() can no longer + * be used. + * + * @see install_base_system() + * @see install_system_schema() */ function drupal_install_system() { - // Create tables. - drupal_install_schema('system'); - - $system_path = drupal_get_path('module', 'system'); - require_once DRUPAL_ROOT . '/' . $system_path . '/system.install'; - $system_versions = drupal_get_schema_versions('system'); - $system_version = $system_versions ? max($system_versions) : SCHEMA_INSTALLED; - drupal_container() - ->get('keyvalue') - ->get('system.schema') - ->set('system', $system_version); - - // System module needs to be enabled and the system/module lists need to be - // reset first in order to allow config_install_default_config() to invoke - // config import callbacks. - // @todo Installation profiles may override the system.module config object. - config('system.module') - ->set('enabled.system', 0) + $module = 'system'; + + $schema_store = drupal_container()->get('keyvalue')->get('system.schema'); + $module_config = config('system.module'); + $disabled_config = config('system.module.disabled'); + + $module_config + ->set("enabled.$module", 0) ->save(); + $disabled_config + ->clear($module) + ->save(); + // Load the module's code. + drupal_load('module', $module); - // Clear out module list and hook implementation statics. + // Refresh the module list to include it. system_list_reset(); - module_list_reset(); module_implements_reset(); + _system_update_bootstrap_status(); + // Update the kernel to include it. + // @todo The if statement is here because install_begin_request() creates + // a container without a kernel. It probably shouldn't. + if ($kernel = drupal_container()->get('kernel', ContainerInterface::NULL_ON_INVALID_REFERENCE)) { + $kernel->updateModules(module_list()); + } + + // Refresh the schema to include it. + drupal_get_schema(NULL, TRUE); + // Update the theme registry to include it. + drupal_theme_rebuild(); + + // Clear the entity info cache before importing new configuration. + entity_info_cache_clear(); + + // Install default configuration of the module. + config_install_default_config('module', $module); + + // Set the schema version to the number of the last update provided. + $versions = drupal_get_schema_versions($module); + $version = $versions ? max($versions) : SCHEMA_INSTALLED; + $schema_store->set($module, $version); + + // Allow the module to perform install tasks. + module_invoke($module, 'install'); + + watchdog('system', '%module module installed.', array('%module' => $module), WATCHDOG_INFO); - config_install_default_config('module', 'system'); + entity_info_cache_clear(); - module_invoke('system', 'install'); + // Enable the module. + module_invoke($module, 'enable'); } /** diff --git a/core/lib/Drupal/Core/Config/FileStorage.php b/core/lib/Drupal/Core/Config/FileStorage.php index 1e22fdc..11c6dac 100644 --- a/core/lib/Drupal/Core/Config/FileStorage.php +++ b/core/lib/Drupal/Core/Config/FileStorage.php @@ -173,9 +173,10 @@ public function encode($data) { */ public function decode($raw) { $data = $this->getParser()->parse($raw); - // A simple string is valid YAML for any reason. + // A simple string is valid YAML for any reason. Also, a config file may + // exist but can be empty, in which case $data is NULL. if (!is_array($data)) { - return FALSE; + return array(); } return $data; } diff --git a/core/modules/system/config/system.module.disabled.yml b/core/modules/system/config/system.module.disabled.yml new file mode 100644 index 0000000..e69de29 diff --git a/core/modules/system/config/system.module.yml b/core/modules/system/config/system.module.yml index 696bedc..dc71340 100644 --- a/core/modules/system/config/system.module.yml +++ b/core/modules/system/config/system.module.yml @@ -1,2 +1,6 @@ enabled: + # @todo config_install_default_config() overwrites existing config. + # In case of System module, the installer needs to write this config file, + # before it can install default config. Therefore, system module MUST be + # contained in here already. system: '0' diff --git a/core/modules/system/lib/Drupal/system/Tests/Upgrade/StateSystemUpgradePathTest.php b/core/modules/system/lib/Drupal/system/Tests/Upgrade/StateSystemUpgradePathTest.php index fbd754f..04dfc1d 100644 --- a/core/modules/system/lib/Drupal/system/Tests/Upgrade/StateSystemUpgradePathTest.php +++ b/core/modules/system/lib/Drupal/system/Tests/Upgrade/StateSystemUpgradePathTest.php @@ -35,6 +35,19 @@ public function testSystemVariableUpgrade() { $expected_state = array(); + $expected_state['system.install_time'] = array( + 'value' => 1304208000, + 'variable_name' => 'install_time', + ); + $expected_state['system.install_task'] = array( + 'value' => 'done', + 'variable_name' => 'install_task', + ); + $expected_state['system.path_alias_whitelist'] = array( + 'value' => array( + ), + 'variable_name' => 'path_alias_whitelist', + ); $expected_state['node.node_access_needs_rebuild'] = array( 'value' => TRUE, 'variable_name' => 'node_access_needs_rebuild', diff --git a/core/modules/system/system.install b/core/modules/system/system.install index 5a96500..9855e68 100644 --- a/core/modules/system/system.install +++ b/core/modules/system/system.install @@ -274,7 +274,7 @@ function system_requirements($phase) { // Determine when cron last ran. $cron_last = variable_get('cron_last'); if (!is_numeric($cron_last)) { - $cron_last = variable_get('install_time', 0); + $cron_last = state()->get('system.install_time') ?: 0; } // Determine severity based on time since cron last ran. @@ -2120,6 +2120,18 @@ function system_update_8025() { } /** + * Migrates install_task and install_time variables to State API. + * + * @ingroup config_upgrade + */ +function system_update_8026() { + update_variables_to_state(array( + 'install_task' => 'system.install_task', + 'install_time' => 'system.install_time', + )); +} + +/** * Cleans up javascript_parsed variable. * * @ingroup system_upgrade diff --git a/core/modules/system/system.module b/core/modules/system/system.module index 4670f88..c24fbdc 100644 --- a/core/modules/system/system.module +++ b/core/modules/system/system.module @@ -3701,7 +3701,7 @@ function system_run_automated_cron() { // If the site is not fully installed, suppress the automated cron run. // Otherwise it could be triggered prematurely by Ajax requests during // installation. - if (($threshold = config('system.cron')->get('threshold.autorun')) > 0 && variable_get('install_task') == 'done') { + if (($threshold = config('system.cron')->get('threshold.autorun')) > 0 && state()->get('system.install_task') == 'done') { $cron_last = variable_get('cron_last', NULL); if (!isset($cron_last) || (REQUEST_TIME - $cron_last > $threshold)) { drupal_cron_run(); diff --git a/core/modules/system/tests/upgrade/drupal-7.state.system.database.php b/core/modules/system/tests/upgrade/drupal-7.state.system.database.php index 47c86f2..eb47ade 100644 --- a/core/modules/system/tests/upgrade/drupal-7.state.system.database.php +++ b/core/modules/system/tests/upgrade/drupal-7.state.system.database.php @@ -12,6 +12,9 @@ // Update system settings to known values. db_merge('variable') + ->key(array('name' => 'install_time'))->fields(array('value' => serialize(1304208000))) + ->execute(); +db_merge('variable') ->key(array('name' => 'update_last_check')) ->fields(array('value' => serialize(1304208000))) ->execute();