diff -u b/core/modules/system/src/Controller/DbUpdateController.php b/core/modules/system/src/Controller/DbUpdateController.php --- b/core/modules/system/src/Controller/DbUpdateController.php +++ b/core/modules/system/src/Controller/DbUpdateController.php @@ -209,38 +209,6 @@ } /** - * Renders a list of available entity schema updates. - * - * @return array - * A render array. - */ - function entitySchema() { - $build = array('#title' => $this->t('Drupal entity schema updates')); - - // Build a summary of the entity schema changes. - $summary = \Drupal::service('entity.schema.manager')->getChangeSummary(); - if ($summary) { - $entity_manager = $this->entityManager(); - foreach ($summary as $entity_type_id => $items) { - $definition = $entity_manager->getDefinition($entity_type_id); - $build['summary'][$entity_type_id] = array( - '#type' => 'details', - '#title' => $definition->getLabel(), - ); - $build['summary'][$entity_type_id]['changes'] = array( - '#theme' => 'item_list', - '#items' => $items, - ); - } - } - else { - $build['summary'] = array('#markup' => $this->t('No entity schema changes available.')); - } - - return $build; - } - - /** * Renders a list of available database updates. * * @return array @@ -317,11 +285,21 @@ drupal_set_message($this->t('Some of the pending updates cannot be applied because their dependencies were not met.'), 'warning'); } - // If there are entity schema updates, display their information. - // @todo Improve UX. + // If there are entity schema updates, display their summary. if (\Drupal::service('entity.schema.manager')->hasChanges()) { - $build['start']['entity_schema'] = $this->entitySchema(); - $count += count(\Drupal::service('entity.schema.manager')->getChangeSummary()); + $entity_build = array(); + $summary = \Drupal::service('entity.schema.manager')->getChangeSummary(); + foreach ($summary as $entity_type_id => $items) { + $entity_update_key = 'entity_type_updates_' . $entity_type_id; + $entity_build[$entity_update_key] = array( + '#theme' => 'item_list', + '#items' => $items, + '#title' => $entity_type_id . ' entity type', + ); + $count++; + } + // Display these above the module updates, since they will be run first. + $build['start'] = $entity_build + $build['start']; } if (empty($count)) { @@ -540,16 +518,17 @@ $this->state->set('system.maintenance_mode', TRUE); } + $operations = array(); + // First of all perform entity schema updates, if needed, so that subsequent // updates work with a correct entity schema. - // @todo Incorporate this as a batch operation. if (\Drupal::service('entity.schema.manager')->hasChanges()) { - \Drupal::service('entity.schema.manager')->applyChanges(); + $operations[] = array('update_entity_schema', array('system', '0 - Update entity schema')); } - $start = $this->getModuleUpdates(); // Resolve any update dependencies to determine the actual updates that will // be run and the order they will be run in. + $start = $this->getModuleUpdates(); $updates = update_resolve_dependencies($start); // Store the dependencies for each update function in an array which the @@ -561,7 +540,7 @@ $dependency_map[$function] = !empty($update['reverse_paths']) ? array_keys($update['reverse_paths']) : array(); } - $operations = array(); + // Determine updates to be performed. foreach ($updates as $update) { if ($update['allowed']) { // Set the installed version of each module so updates will start at the only in patch2: unchanged: --- a/core/includes/update.inc +++ b/core/includes/update.inc @@ -10,14 +10,8 @@ use Drupal\Component\Graph\Graph; use Drupal\Component\Utility\String; -use Drupal\Core\Config\FileStorage; -use Drupal\Core\Config\ConfigException; -use Drupal\Core\DrupalKernel; -use Drupal\Core\Page\DefaultHtmlPageRenderer; +use Drupal\Core\Entity\EntityStorageException; use Drupal\Core\Utility\Error; -use Drupal\Component\Uuid\Uuid; -use Drupal\Component\Utility\NestedArray; -use Symfony\Component\HttpFoundation\Request; /** * Disables any extensions that are incompatible with the current core version. @@ -258,6 +252,33 @@ function update_do_one($module, $number, $dependency_map, &$context) { } /** + * Performs entity schema updates. + * + * @param $module + * The module whose update will be run. + * @param $number + * The update number to run. + * @param $context + * The batch context array. + */ +function update_entity_schema($module, $number, &$context) { + try { + \Drupal::service('entity.schema.manager')->applyChanges(); + } + catch (EntityStorageException $e) { + watchdog_exception('update', $e); + $variables = Error::decodeException($e); + unset($variables['backtrace']); + // The exception message is run through + // \Drupal\Component\Utility\String::checkPlain() by + // \Drupal\Core\Utility\Error::decodeException(). + $ret['#abort'] = array('success' => FALSE, 'query' => t('%type: !message in %function (line %line of %file).', $variables)); + $context['results'][$module][$number] = $ret; + $context['results']['#abort'][] = 'update_entity_schema'; + } +} + +/** * Returns a list of all the pending database updates. * * @return