From 36215a85b21b8231a871583f94ed1c44f1da05dd Mon Sep 17 00:00:00 2001 From: Mark Carver Date: Fri, 19 Jul 2013 00:57:22 -0500 Subject: Mark Carver: Generated with Drush iq --- core/includes/install.core.inc | 269 ++++++++++++--------- core/includes/install.inc | 64 +++-- core/lib/Drupal/Core/Config/DatabaseStorage.php | 2 +- core/lib/Drupal/Core/Config/FileStorage.php | 5 +- core/lib/Drupal/Core/Extension/ModuleHandler.php | 9 +- .../config/Tests/Storage/ConfigStorageTestBase.php | 6 +- core/modules/system/config/system.module.yml | 3 +- .../Tests/Upgrade/StateSystemUpgradePathTest.php | 8 + core/modules/system/system.install | 14 +- core/modules/system/system.module | 2 +- .../upgrade/drupal-7.state.system.database.php | 3 + 11 files changed, 226 insertions(+), 159 deletions(-) diff --git a/core/includes/install.core.inc b/core/includes/install.core.inc index eefe926..2517500 100644 --- a/core/includes/install.core.inc +++ b/core/includes/install.core.inc @@ -154,14 +154,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. + // TRUE when there are valid config directories. '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 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, // Whether a translation file for the selected language will be downloaded // from the translation server. 'download_translation' => FALSE, @@ -205,10 +206,6 @@ function install_state_defaults() { // Tokens in the pattern will be replaced by appropriate values for the // required translation file. 'server_pattern' => 'http://ftp.drupal.org/files/translations/%core/%project/%project-%version.%language.po', - // 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 @@ -308,23 +305,33 @@ function install_begin_request(&$install_state) { $languages[$install_state['parameters']['langcode']] = new Language($GLOBALS['conf']['language_default']); } - require_once __DIR__ . '/../modules/system/system.install'; - require_once __DIR__ . '/common.inc'; + // Load include files containing procedural service helpers. + require_once __DIR__ . '/cache.inc'; + require_once __DIR__ . '/database.inc'; + + // Required for module_list() override in early installer environment. require_once __DIR__ . '/file.inc'; + require_once __DIR__ . '/module.inc'; + + // Required for various installer operations. require_once __DIR__ . '/install.inc'; - require_once __DIR__ . '/schema.inc'; - require_once __DIR__ . '/../../' . settings()->get('path_inc', 'core/includes/path.inc'); - // Load module basics (needed for hook invokes). - include_once __DIR__ . '/module.inc'; - include_once __DIR__ . '/session.inc'; - require_once __DIR__ . '/entity.inc'; + // Required for running install tasks. + require_once __DIR__ . '/form.inc'; + require_once __DIR__ . '/ajax.inc'; + require_once __DIR__ . '/batch.inc'; - // Determine whether the configuration system is ready to operate. + // Determine bootstrap status. + if (!empty($install_state['parameters']['bootstrap'])) { + $install_state['parameters']['bootstrap'] = (int) $install_state['parameters']['bootstrap']; + $install_state['base_system_verified'] = TRUE; + } + + // 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); // Create a minimal container for t() to work. - // This container will be overriden but it needed for the very early + // This container will be overridden but it needed for the very early // installation process when database tasks run. $container = new ContainerBuilder(); // Register the translation services. @@ -335,44 +342,18 @@ function install_begin_request(&$install_state) { $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 and the - // database has been set up successfully. - // @see drupal_install_config_directories() - // @see install_settings_form_submit() - if ($install_state['settings_verified']) { - $kernel = new DrupalKernel('install', drupal_classloader(), FALSE); - $kernel->boot(); - $container = $kernel->getContainer(); - // Add the file translation service to the container. - $container->set('string_translator.file_translation', install_file_translation_service()); - $container->get('string_translation')->addTranslator($container->get('string_translator.file_translation')); - } - else { + // 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('event_dispatcher', 'Symfony\Component\EventDispatcher\EventDispatcher'); - $container->register('config.storage', 'Drupal\Core\Config\InstallStorage'); $container->register('config.context.factory', 'Drupal\Core\Config\Context\ConfigContextFactory') ->addArgument(new Reference('event_dispatcher')); @@ -385,6 +366,9 @@ function install_begin_request(&$install_state) { ->addArgument(new Reference('config.storage')) ->addArgument(new Reference('config.context')); + $container->register('state', 'Drupal\Core\KeyValueStore\MemoryStorage') + ->addArgument('state'); + // Register the 'language_manager' service. $container->register('language_manager', 'Drupal\Core\Language\LanguageManager'); @@ -397,14 +381,14 @@ function install_begin_request(&$install_state) { ->addArgument($bin); } - // 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['keyvalue_default'] = 'keyvalue.memory'; + $container + ->register('keyvalue', 'Drupal\Core\KeyValueStore\KeyValueFactory') + ->addArgument(new Reference('service_container')); + $container + ->register('keyvalue.memory', 'Drupal\Core\KeyValueStore\KeyValueMemoryFactory'); $container->register('lock', 'Drupal\Core\Lock\NullLockBackend'); + $conf['cache_classes'] = array('cache' => 'Drupal\Core\Cache\MemoryBackend'); // Register a module handler for managing enabled modules. $container @@ -436,12 +420,21 @@ function install_begin_request(&$install_state) { // Register the CSS and JavaScript asset collection renderers. $container->register('asset.css.collection_renderer', 'Drupal\Core\Asset\CssCollectionRenderer'); $container->register('asset.js.collection_renderer', 'Drupal\Core\Asset\JsCollectionRenderer'); - + } + // 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 { + $kernel = new DrupalKernel('install', drupal_classloader(), FALSE); + $kernel->boot(); + $container = $kernel->getContainer(); + // Add the file translation service to the container. + $container->set('string_translator.file_translation', install_file_translation_service()); + $container->get('string_translation')->addTranslator($container->get('string_translator.file_translation')); } // Set the request in the kernel to the new created Request above // so it is available to the rest of the installation process. $container->set('request', $request); - Drupal::setContainer($container); // Set up $language, so t() caller functions will still work. @@ -469,17 +462,7 @@ function install_begin_request(&$install_state) { // accessing the database before it is set up yet.) drupal_maintenance_theme(); - if ($install_state['database_verified']) { - // Initialize the database system. Note that the connection - // won't be initialized until it is actually requested. - require_once __DIR__ . '/database.inc'; - - // Verify the last completed task in the database, if there is one. - $task = install_verify_completed_task(); - } - else { - $task = NULL; - + if (!$install_state['database_verified']) { // Do not install over a configured settings.php. if (!empty($GLOBALS['databases'])) { throw new Exception(install_already_done_error()); @@ -497,8 +480,7 @@ function install_begin_request(&$install_state) { } // 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'); @@ -542,8 +524,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']) { + Drupal::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 @@ -571,7 +553,6 @@ function install_run_task($task, &$install_state) { $function = $task['function']; if ($task['type'] == 'form') { - require_once __DIR__ . '/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 @@ -616,7 +597,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 = Drupal::state()->get('system.install_current_batch'); if (!$install_state['interactive'] || !$current_batch) { $batch = $function($install_state); if (empty($batch)) { @@ -629,7 +610,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); + Drupal::state()->set('system.install_current_batch', $function); } else { $batch =& batch_get(); @@ -649,7 +630,6 @@ function install_run_task($task, &$install_state) { // If we are in the middle of processing this batch, keep sending back // any output from the batch process, until the task is complete. elseif ($current_batch == $function) { - include_once __DIR__ . '/batch.inc'; $output = _batch_page(); // Because Batch API now returns a JSON response for intermediary steps, // but the installer doesn't handle Response objects yet, just send the @@ -665,7 +645,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'); + Drupal::state()->delete('system.install_current_batch'); return; } else { @@ -769,11 +749,15 @@ 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_system_schema' => array( + 'run' => $install_state['base_system_verified'] ? INSTALL_TASK_SKIP : INSTALL_TASK_RUN_IF_NOT_COMPLETED, + ), + 'install_system_rebuild' => array( + 'run' => $install_state['base_system_verified'] ? INSTALL_TASK_SKIP : INSTALL_TASK_RUN_IF_NOT_COMPLETED, + ), + // All tasks below are executed in a regular, full Drupal environment. 'install_base_system' => array( ), - 'install_bootstrap_full' => array( - 'run' => INSTALL_TASK_RUN_IF_REACHED, - ), 'install_profile_modules' => array( 'display_name' => count($install_state['profiles']) == 1 ? t('Install site') : t('Installation profile'), 'type' => 'batch', @@ -973,15 +957,80 @@ function install_verify_requirements(&$install_state) { } /** + * Install task: Installs the System module schema. + */ +function install_system_schema(&$install_state) { + require_once __DIR__ . '/schema.inc'; + require_once dirname(__DIR__) . '/modules/system/system.install'; + // This task is the one that sets up persistent storage tables. Since this + // task is executed in the early installer environment, install_run_tasks() + // is not able to record that this task has been completed. Thus, the + // interactive installer invokes this task a second time and the fact that it + // completed can only be recorded after the second invocation. + $schema = drupal_get_schema_unprocessed('system'); + $table = key($schema); + if (!db_table_exists($table)) { + drupal_install_schema('system'); + } + + // 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, skipping + // install_system_rebuild(). + $install_state['parameters']['bootstrap'] = DRUPAL_BOOTSTRAP_VARIABLES; +} + +/** + * Install task: Performs a full bootstrap into the new environment. + */ +function install_system_rebuild(&$install_state) { + global $conf; + + // This phase is reached in the non-interactive installer only. + // We need to unset all overrides and rebuild all necessary facilities to get + // into a regular bootstrap state. + unset($conf['cache_classes']); + unset($conf['keyvalue_default']); + + // 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'; + } + + Drupal::moduleHandler()->reload(); + system_list_reset(); + Drupal::moduleHandler()->resetImplementations(); + + // Bootstrap, but avoid session initialization. + // @see install_begin_request() + drupal_bootstrap(DRUPAL_BOOTSTRAP_VARIABLES); + _drupal_bootstrap_code(); + $kernel = new DrupalKernel('prod', TRUE, drupal_classloader(), FALSE); + $kernel->boot(); + + $install_state['base_system_verified'] = TRUE; +} + +/** * 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 @@ -1004,7 +1053,13 @@ function install_base_system(&$install_state) { $modules[] = drupal_get_profile(); Drupal::state()->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); } /** @@ -1015,16 +1070,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 = Drupal::state()->get('system.install_task'); + if ($task) { if ($task == 'done') { throw new Exception(install_already_done_error()); } @@ -1233,18 +1280,13 @@ 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(); - // 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(); } /** @@ -1771,6 +1813,12 @@ function install_bootstrap_full() { * The batch definition. */ function install_profile_modules(&$install_state) { + // Batch API relies on drupal_get_token() and thus an initialized session. + // Up until now, the entire installation process happened without a user. + // Now that we are in a full environment, we need to enforce the session to be + // regenerated, so we have a new session ID and it is stored for the user. + drupal_session_regenerate(); + $modules = Drupal::state()->get('install_profile_modules') ?: array(); $files = system_rebuild_module_data(); Drupal::state()->delete('install_profile_modules'); @@ -1916,15 +1964,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); } @@ -2546,5 +2585,5 @@ function install_configure_form_submit($form, &$form_state) { user_login_finalize($account); // Record when this install ran. - variable_set('install_time', $_SERVER['REQUEST_TIME']); + Drupal::state()->set('system.install_time', $_SERVER['REQUEST_TIME']); } diff --git a/core/includes/install.inc b/core/includes/install.inc index e0e86cc..5d6cb38 100644 --- a/core/includes/install.inc +++ b/core/includes/install.inc @@ -608,41 +608,53 @@ 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 identical to module_enable(), with two exceptions: + * - System module's database schema has been installed in + * install_system_schema() already, as it is required for booting a kernel + * with regular services. module_enable() installs a module's database + * schema without a failsafe "IF NOT EXISTS" SQL condition, so it would bail + * out with database query errors. + * - The module entry for System module in the system.module:enabled + * configuration can only be written after the default configuration of + * System module has been installed, since the default config overwrites any + * potentially pre-existing config files. + * + * Therefore, this function performs the installation parts of module_enable() + * and then calls into module_enable() to enable the module. + * + * @see install_base_system() + * @see install_system_schema() */ function drupal_install_system() { - // Create tables. - drupal_install_schema('system'); + // Ensure that required files are loaded. + require_once DRUPAL_ROOT . '/core/modules/system/system.install'; + require_once __DIR__ . '/entity.inc'; + require_once __DIR__ . '/schema.inc'; - if (!drupal_container()->has('kernel')) { - // Immediately boot a kernel to have real services ready. - $kernel = new DrupalKernel('install', drupal_classloader(), FALSE); - $kernel->boot(); + $module = 'system'; + + // Mark the System database schema as installed to prevent module_enable() + // from attempting to install it. + $versions = drupal_get_schema_versions($module); + $version = $versions ? max($versions) : SCHEMA_INSTALLED; + if ($last_removed = Drupal::moduleHandler()->invoke($module, 'update_last_removed')) { + $version = max($version, $last_removed); } + drupal_set_installed_schema_version($module, $version); - $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::keyValue('system.schema')->set('system', $system_version); + // Install default configuration. + config_install_default_config('module', $module); - // 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) - ->save(); + // Allow the module to perform install tasks. + Drupal::moduleHandler()->invoke($module, 'install'); - // Update the module list to include it. - Drupal::moduleHandler()->setModuleList(array('system' => $system_path . '/system.module')); + // Record the fact that it was installed. + watchdog('system', '%module module installed.', array('%module' => $module), WATCHDOG_INFO); - config_install_default_config('module', 'system'); - - module_invoke('system', 'install'); + // Enable the module. + Drupal::moduleHandler()->enable(array($module)); } /** diff --git a/core/lib/Drupal/Core/Config/DatabaseStorage.php b/core/lib/Drupal/Core/Config/DatabaseStorage.php index 78e1629..65ea3c3 100644 --- a/core/lib/Drupal/Core/Config/DatabaseStorage.php +++ b/core/lib/Drupal/Core/Config/DatabaseStorage.php @@ -164,7 +164,7 @@ public function encode($data) { */ public function decode($raw) { $data = @unserialize($raw); - return is_array($data) ? $data : FALSE; + return is_array($data) ? $data : array(); } /** diff --git a/core/lib/Drupal/Core/Config/FileStorage.php b/core/lib/Drupal/Core/Config/FileStorage.php index 6e428b3..4bffe6c 100644 --- a/core/lib/Drupal/Core/Config/FileStorage.php +++ b/core/lib/Drupal/Core/Config/FileStorage.php @@ -186,9 +186,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/lib/Drupal/Core/Extension/ModuleHandler.php b/core/lib/Drupal/Core/Extension/ModuleHandler.php index c510192..a0ce2c7 100644 --- a/core/lib/Drupal/Core/Extension/ModuleHandler.php +++ b/core/lib/Drupal/Core/Extension/ModuleHandler.php @@ -640,14 +640,7 @@ public function enable($module_list, $enable_dependencies = TRUE) { system_list_reset(); // Update the kernel to include it. - // This reboots the kernel to register the module's bundle and its - // services in the service container. The $module_filenames argument is - // taken over as %container.modules% parameter, which is passed to a fresh - // ModuleHandler instance upon first retrieval. - // @todo install_begin_request() creates a container without a kernel. - if ($kernel = drupal_container()->get('kernel', ContainerInterface::NULL_ON_INVALID_REFERENCE)) { - $kernel->updateModules($module_filenames, $module_filenames); - } + drupal_container()->get('kernel')->updateModules(\Drupal::moduleHandler()->getModuleList(), $module_filenames); // Refresh the list of modules that implement bootstrap hooks. // @see bootstrap_hooks() diff --git a/core/modules/config/lib/Drupal/config/Tests/Storage/ConfigStorageTestBase.php b/core/modules/config/lib/Drupal/config/Tests/Storage/ConfigStorageTestBase.php index a2b3448..7a6f75b 100644 --- a/core/modules/config/lib/Drupal/config/Tests/Storage/ConfigStorageTestBase.php +++ b/core/modules/config/lib/Drupal/config/Tests/Storage/ConfigStorageTestBase.php @@ -39,14 +39,14 @@ function testCRUD() { $data = $this->storage->read($name); $this->assertIdentical($data, FALSE); - // Reading a name containing non-decodeable data returns FALSE. + // Reading a name containing non-decodeable data returns an array. $this->insert($name, ''); $data = $this->storage->read($name); - $this->assertIdentical($data, FALSE); + $this->assertIdentical($data, array()); $this->update($name, 'foo'); $data = $this->storage->read($name); - $this->assertIdentical($data, FALSE); + $this->assertIdentical($data, array()); $this->delete($name); diff --git a/core/modules/system/config/system.module.yml b/core/modules/system/config/system.module.yml index 696bedc..a1c31cc 100644 --- a/core/modules/system/config/system.module.yml +++ b/core/modules/system/config/system.module.yml @@ -1,2 +1 @@ -enabled: - system: '0' +enabled: { } 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 b9a97a5..ad92b97 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,14 @@ 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['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 d246507..17e013d 100644 --- a/core/modules/system/system.install +++ b/core/modules/system/system.install @@ -276,7 +276,7 @@ function system_requirements($phase) { // Determine when cron last ran. $cron_last = Drupal::state()->get('system.cron_last'); if (!is_numeric($cron_last)) { - $cron_last = variable_get('install_time', 0); + $cron_last = Drupal::state()->get('system.install_time') ?: 0; } // Determine severity based on time since cron last ran. @@ -1667,6 +1667,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', + )); +} + +/** * Clean up javascript_parsed variable. * * @ingroup system_upgrade diff --git a/core/modules/system/system.module b/core/modules/system/system.module index 72cb3bf..a2a400a 100644 --- a/core/modules/system/system.module +++ b/core/modules/system/system.module @@ -3367,7 +3367,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 && Drupal::state()->get('system.install_task') == 'done') { $cron_last = Drupal::state()->get('system.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 605ca5c..6f51325 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' => 'node_cron_views_scale')) ->fields(array('value' => serialize(1.0 / 2000))) ->execute(); -- 1.8.2