function _update_fix_missing_schema

Same name and namespace in other branches
  1. 9 core/includes/update.inc \_update_fix_missing_schema()
  2. 8.9.x core/includes/update.inc \_update_fix_missing_schema()
  3. 10 core/includes/update.inc \_update_fix_missing_schema()

Helper to detect and fix 'missing' schema information.

Repairs the case where a module has no schema version recorded. This has to be done prior to updates being run, otherwise the update system would detect and attempt to run all historical updates for a module.

@todo remove in a major version after https://www.drupal.org/project/drupal/issues/3130037 has been fixed.

1 call to _update_fix_missing_schema()
update_check_requirements in core/includes/update.inc
Checks update requirements and reports errors and (optionally) warnings.

File

core/includes/update.inc, line 71

Code

function _update_fix_missing_schema() {
    
    /** @var \Drupal\Core\Update\UpdateHookRegistry $update_registry */
    $update_registry = \Drupal::service('update.update_hook_registry');
    $versions = $update_registry->getAllInstalledVersions();
    $module_handler = \Drupal::moduleHandler();
    $enabled_modules = $module_handler->getModuleList();
    foreach (array_keys($enabled_modules) as $module) {
        // All modules should have a recorded schema version, but when they
        // don't, detect and fix the problem.
        if (!isset($versions[$module])) {
            // Ensure the .install file is loaded.
            $module_handler->loadInclude($module, 'install');
            $all_updates = $update_registry->getAvailableUpdates($module);
            // If the schema version of a module hasn't been recorded, we cannot
            // know the actual schema version a module is at, because
            // no updates will ever have been run on the site and it was not set
            // correctly when the module was installed, so instead set it to
            // the same as the last update. This means that updates will proceed
            // again the next time the module is updated and a new update is
            // added. Updates added in between the module being installed and the
            // schema version being fixed here (if any have been added) will never
            // be run, but we have no way to identify which updates these are.
            if ($all_updates) {
                $last_update = max($all_updates);
            }
            else {
                $last_update = \Drupal::CORE_MINIMUM_SCHEMA_VERSION;
            }
            // If the module implements hook_update_last_removed() use the
            // value of that if it's higher than the schema versions found so
            // far.
            if ($last_removed = $module_handler->invoke($module, 'update_last_removed')) {
                $last_update = max($last_update, $last_removed);
            }
            $update_registry->setInstalledVersion($module, $last_update);
            $args = [
                '%module' => $module,
                '%last_update_hook' => $module . '_update_' . $last_update . '()',
            ];
            \Drupal::messenger()->addWarning(t('Schema information for module %module was missing from the database. You should manually review the module updates and your database to check if any updates have been skipped up to, and including, %last_update_hook.', $args));
            \Drupal::logger('update')->warning('Schema information for module %module was missing from the database. You should manually review the module updates and your database to check if any updates have been skipped up to, and including, %last_update_hook.', $args);
        }
    }
}

Buggy or inaccurate documentation? Please file an issue. Need support? Need help programming? Connect with the Drupal community.