+}
+
+/**
+ * Creates a batch for the config importer to process.
+ *
+ * @see install_tasks()
+ */
+function install_config_import_batch() {
+ // We need to manually trigger the installation of core-provided entity types,
+ // as those will not be handled by the module installer.
+ // @see install_profile_modules()
+ install_core_entity_type_definitions();
+
+ // Get the sync storage.
+ $sync = \Drupal::service('config.storage.sync');
+ // Match up the site UUIDs, the install_base_system install task will have
+ // installed the system module and created a new UUID.
+ $system_site = $sync->read('system.site');
+ \Drupal::configFactory()->getEditable('system.site')->set('uuid', $system_site['uuid'])->save();
+
+ // Create the storage comparer and the config importer.
+ $config_manager = \Drupal::service('config.manager');
+ $storage_comparer = new StorageComparer($sync, \Drupal::service('config.storage'), $config_manager);
+ $storage_comparer->createChangelist();
+ $config_importer = new ConfigImporter(
+ $storage_comparer,
+ \Drupal::service('event_dispatcher'),
+ $config_manager,
+ \Drupal::service('lock.persistent'),
+ \Drupal::service('config.typed'),
+ \Drupal::service('module_handler'),
+ \Drupal::service('module_installer'),
+ \Drupal::service('theme_handler'),
+ \Drupal::service('string_translation')
+ );
+
+ try {
+ $sync_steps = $config_importer->initialize();
+
+ $batch_builder = new BatchBuilder();
+ $batch_builder
+ ->setFinishCallback([ConfigImporterBatch::class, 'finish'])
+ ->setTitle(t('Importing configuration'))
+ ->setInitMessage(t('Starting configuration import.'))
+ ->setErrorMessage(t('Configuration import has encountered an error.'));
+
+ foreach ($sync_steps as $sync_step) {
+ $batch_builder->addOperation([ConfigImporterBatch::class, 'process'], [$config_importer, $sync_step]);
+ }
+
+ return $batch_builder->toArray();
+ }
+ catch (ConfigImporterException $e) {
+ global $install_state;
+ // There are validation errors.
+ $messenger = \Drupal::messenger();
+ $messenger->addError(t('The configuration synchronization failed validation.'));
+ foreach ($config_importer->getErrors() as $message) {
+ $messenger->addError($message);
+ }
+ install_display_output(['#title' => t('Configuration validation')], $install_state);
+ }
+}
+
+/**
+ * Replaces install_download_translation() during configuration installs.
+ *
+ * @param array $install_state
+ * An array of information about the current installation state.
+ *
+ * @return string
+ * A themed status report, or an exception if there are requirement errors.
+ * Upon successful download the page is reloaded and no output is returned.
+ *
+ * @see install_download_translation()
+ */
+function install_config_download_translations(&$install_state) {
+ $needs_download = isset($install_state['parameters']['langcode']) && !isset($install_state['translations'][$install_state['parameters']['langcode']]) && $install_state['parameters']['langcode'] !== 'en';
+ if ($needs_download) {
+ return install_download_translation($install_state);
+ }
+}
+
+/**
+ * Reverts configuration if hook_install() implementations have made changes.
+ *
+ * This step ensures that the final configuration matches the configuration
+ * provided to the installer.
+ */
+function install_config_revert_install_changes() {
+ global $install_state;
+
+ $config_manager = \Drupal::service('config.manager');
+ $storage_comparer = new StorageComparer(\Drupal::service('config.storage.sync'), \Drupal::service('config.storage'), $config_manager);
+ $storage_comparer->createChangelist();
+ if ($storage_comparer->hasChanges()) {
+ $config_importer = new ConfigImporter(
+ $storage_comparer,
+ \Drupal::service('event_dispatcher'),
+ $config_manager,
+ \Drupal::service('lock.persistent'),
+ \Drupal::service('config.typed'),
+ \Drupal::service('module_handler'),
+ \Drupal::service('module_installer'),
+ \Drupal::service('theme_handler'),
+ \Drupal::service('string_translation')
+ );
+ try {
+ $config_importer->import();
+ }
+ catch (ConfigImporterException $e) {
+ global $install_state;
+ $messenger = \Drupal::messenger();
+ // There are validation errors.
+ $messenger->addError(t('The configuration synchronization failed validation.'));
+ foreach ($config_importer->getErrors() as $message) {
+ $messenger->addError($message);
+ }
+ install_display_output(['#title' => t('Configuration validation')], $install_state);
+ }
+
+ // At this point the configuration should match completely.
+ if (\Drupal::moduleHandler()->moduleExists('language')) {
+ // If the English language exists at this point we need to ensure
+ // install_download_additional_translations_operations() does not delete
+ // it.
+ if (ConfigurableLanguage::load('en')) {
+ $install_state['profile_info']['keep_english'] = TRUE;
+ }
+ }