diff --git a/core/includes/update.inc b/core/includes/update.inc
index f956605..c628d3f 100644
--- a/core/includes/update.inc
+++ b/core/includes/update.inc
@@ -100,34 +100,31 @@ function update_settings_file_requirements() {
}
/**
- * Checks whether the minimum system schema version has been satisfied.
- *
- * Upgrading from a 7.x site database should block the update process.
- * Ensure that the site is running Drupal 8 before proceeding. Not that this
- * has to happen AFTER the database bootstraps because of
- * drupal_get_installed_schema_version().
+ * Returns whether the minimum schema requirement has been satisfied.
*
* @return array
* A requirements info array.
*/
-function update_migrate_requirements() {
+function update_system_schema_requirements() {
$requirements = array();
- try {
- $system_schema = drupal_get_installed_schema_version('system');
- }
- catch (\Exception $e) {
- $system_schema = db_query('SELECT schema_version FROM {system} WHERE name = :system', array(':system' => 'system'))->fetchField();
+
+ $system_schema = drupal_get_installed_schema_version('system');
+
+ $requirements['minimum schema']['title'] = 'Minimum schema version';
+ if ($system_schema >= \Drupal::CORE_MINIMUM_SCHEMA_VERSION) {
+ $requirements['minimum schema'] += array(
+ 'value' => 'The installed schema version meets the minimum.',
+ 'description' => 'Schema version: ' . $system_schema,
+ );
}
- if ($system_schema < \Drupal::CORE_MINIMUM_SCHEMA_VERSION) {
- $requirements = array(
- 'drupal 7 version' => array(
- 'title' => 'Drupal 7 version',
- 'value' => 'Your site database is from a Drupal 7 or earlier site.',
- 'severity' => REQUIREMENT_ERROR,
- 'description' => 'Migrate your Drupal 7 installation to a Drupal 8 installation using the Migrate module. Updating directly from Drupal 7 to Drupal 8 is not supported.',
- ),
+ else {
+ $requirements['minimum schema'] += array(
+ 'value' => 'The installed schema version does not meet the minimum.',
+ 'severity' => REQUIREMENT_ERROR,
+ 'description' => 'Your system schema version is ' . $system_schema . '. Updating directly from a schema version prior to 8000 is not supported. You must migrate your site to Drupal 8 first.',
);
}
+
return $requirements;
}
@@ -140,15 +137,10 @@ function update_migrate_requirements() {
* FALSE.
*/
function update_check_requirements($skip_warnings = FALSE) {
- // Upgrading from a 7.x site database should block the update process.
- $requirements = update_migrate_requirements();
- // If the user is not upgrading for a system schema prior to 8.x, gather
- // any additional extra requirements.
- if (empty($requirements)) {
- // Check requirements of all loaded modules.
- $requirements = \Drupal::moduleHandler()->invokeAll('requirements', array('update'));
- $requirements += update_settings_file_requirements();
- }
+ // Check requirements of all loaded modules.
+ $requirements = \Drupal::moduleHandler()->invokeAll('requirements', array('update'));
+ $requirements += update_system_schema_requirements();
+ $requirements += update_settings_file_requirements();
$severity = drupal_requirements_severity($requirements);
// If there are errors, always display them. If there are only warnings, skip
@@ -189,6 +181,25 @@ function update_prepare_d8_bootstrap() {
// Bootstrap to configuration.
drupal_bootstrap(DRUPAL_BOOTSTRAP_CONFIGURATION);
+ // Bootstrap the database.
+ require_once __DIR__ . '/database.inc';
+
+ // Updating from a site schema version prior to 8000 should block the update
+ // process. Ensure that the site is not attempting to update a database
+ // created in a previous version of Drupal.
+ try {
+ $system_schema = db_query('SELECT schema_version FROM {system} WHERE name = :system', array(':system' => 'system'))->fetchField();
+ }
+ catch (\Exception $e) {
+ // The schema_version does not exist in the system table, so continue
+ // for the moment assuming that this is a Drupal 8 database schema. Another
+ // check will be made later to verify this is the case.
+ }
+ if (isset($system_schema) && $system_schema < \Drupal::CORE_MINIMUM_SCHEMA_VERSION) {
+ print 'Your system schema version is ' . $system_schema . '. Updating directly from a schema version prior to 8000 is not supported. You must migrate your site to Drupal 8 first.';
+ exit;
+ }
+
// During the bootstrap to DRUPAL_BOOTSTRAP_PAGE_CACHE, code will try to read
// the cache but the cache tables are not compatible yet. Use the Null backend
// by default to avoid exceptions.
@@ -213,9 +224,6 @@ function update_prepare_d8_bootstrap() {
$kernel = new DrupalKernel('update', drupal_classloader(), FALSE);
$kernel->boot();
- // Bootstrap the database.
- require_once __DIR__ . '/database.inc';
-
// module.inc is not yet loaded but there are calls to module_config_sort()
// below.
require_once __DIR__ . '/module.inc';
diff --git a/core/modules/system/lib/Drupal/system/Tests/Update/UpdateScriptTest.php b/core/modules/system/lib/Drupal/system/Tests/Update/UpdateScriptTest.php
index 4158cea..ef2f136 100644
--- a/core/modules/system/lib/Drupal/system/Tests/Update/UpdateScriptTest.php
+++ b/core/modules/system/lib/Drupal/system/Tests/Update/UpdateScriptTest.php
@@ -41,6 +41,28 @@ function setUp() {
}
/**
+ * Tests that updates from schema versions prior to 8000 are prevented.
+ */
+ function testInvalidMigration() {
+ // Mock a D7 system table so that the schema value of the system module
+ // can be retrieved.
+ db_create_table('system', $this->getSystemSchema());
+ // Assert that the table exists.
+ $this->assertTrue(db_table_exists('system'), 'The table exists.');
+ // Insert a value for the system module.
+ db_insert('system')
+ ->fields(array(
+ 'name' => 'system',
+ 'schema_version' => 7000,
+ ))
+ ->execute();
+ $system_schema = db_query('SELECT schema_version FROM {system} WHERE name = :system', array(':system' => 'system'))->fetchField();
+ $this->drupalGet($this->update_url, array('external' => TRUE));
+ $text = 'Your system schema version is ' . $system_schema . '. Updating directly from a schema version prior to 8000 is not supported. You must migrate your site to Drupal 8 first.';
+ $this->assertRaw($text, 'Updates from schema versions prior to 8000 are prevented.');
+ }
+
+ /**
* Tests access to the update script.
*/
function testUpdateAccess() {
@@ -218,4 +240,78 @@ function testSuccessfulUpdateFunctionality() {
$this->clickLink('Administration pages');
$this->assertResponse(200);
}
+
+ /**
+ * Returns the Drupal 7 system table schema.
+ */
+ public function getSystemSchema() {
+ return array(
+ 'description' => "A list of all modules, themes, and theme engines that are or have been installed in Drupal's file system.",
+ 'fields' => array(
+ 'filename' => array(
+ 'description' => 'The path of the primary file for this item, relative to the Drupal root; e.g. modules/node/node.module.',
+ 'type' => 'varchar',
+ 'length' => 255,
+ 'not null' => TRUE,
+ 'default' => '',
+ ),
+ 'name' => array(
+ 'description' => 'The name of the item; e.g. node.',
+ 'type' => 'varchar',
+ 'length' => 255,
+ 'not null' => TRUE,
+ 'default' => '',
+ ),
+ 'type' => array(
+ 'description' => 'The type of the item, either module, theme, or theme_engine.',
+ 'type' => 'varchar',
+ 'length' => 12,
+ 'not null' => TRUE,
+ 'default' => '',
+ ),
+ 'owner' => array(
+ 'description' => "A theme's 'parent' . Can be either a theme or an engine.",
+ 'type' => 'varchar',
+ 'length' => 255,
+ 'not null' => TRUE,
+ 'default' => '',
+ ),
+ 'status' => array(
+ 'description' => 'Boolean indicating whether or not this item is enabled.',
+ 'type' => 'int',
+ 'not null' => TRUE,
+ 'default' => 0,
+ ),
+ 'bootstrap' => array(
+ 'description' => "Boolean indicating whether this module is loaded during Drupal's early bootstrapping phase (e.g. even before the page cache is consulted).",
+ 'type' => 'int',
+ 'not null' => TRUE,
+ 'default' => 0,
+ ),
+ 'schema_version' => array(
+ 'description' => "The module's database schema version number. -1 if the module is not installed (its tables do not exist); 0 or the largest N of the module's hook_update_N() function that has either been run or existed when the module was first installed.",
+ 'type' => 'int',
+ 'not null' => TRUE,
+ 'default' => -1,
+ 'size' => 'small',
+ ),
+ 'weight' => array(
+ 'description' => "The order in which this module's hooks should be invoked relative to other modules. Equal-weighted modules are ordered by name.",
+ 'type' => 'int',
+ 'not null' => TRUE,
+ 'default' => 0,
+ ),
+ 'info' => array(
+ 'description' => "A serialized array containing information from the module's .info file; keys can include name, description, package, version, core, dependencies, and php.",
+ 'type' => 'blob',
+ 'not null' => FALSE,
+ ),
+ ),
+ 'primary key' => array('filename'),
+ 'indexes' => array(
+ 'system_list' => array('status', 'bootstrap', 'type', 'weight', 'name'),
+ 'type_name' => array('type', 'name'),
+ ),
+ );
+ }
}