From 4baeb8d8c5f798b6f59a63973ca6628db5d49a65 Mon Sep 17 00:00:00 2001
From: Dries <dries@buytaert.net>
Date: Wed, 9 Jul 2014 11:18:34 -0400
Subject: [PATCH] Issue #2234159 by alexpott: Fixed config importing through
 the UI and change ConfigImportAll test using the UI.

---
 .../lib/Drupal/Core/Config/ConfigImporter.php | 15 +++++++
 .../Drupal/Core/Config/DatabaseStorage.php    |  2 +
 core/modules/config/config.services.yml       |  5 +++
 core/modules/config/src/ConfigSubscriber.php  | 42 +++++++++++++++++++
 .../config/src/Tests/ConfigImportAllTest.php  | 12 +++++-
 .../config/src/Tests/ConfigImportUITest.php   | 15 +++++++
 core/modules/migrate/src/Entity/Migration.php | 21 ++++------
 .../src/Form/SimpletestResultsForm.php        |  7 ++++
 8 files changed, 104 insertions(+), 15 deletions(-)
 create mode 100644 core/modules/config/config.services.yml
 create mode 100644 core/modules/config/src/ConfigSubscriber.php

diff --git a/core/lib/Drupal/Core/Config/ConfigImporter.php b/core/lib/Drupal/Core/Config/ConfigImporter.php
index dbf340f12b06..e060cdf7046f 100644
--- a/core/lib/Drupal/Core/Config/ConfigImporter.php
+++ b/core/lib/Drupal/Core/Config/ConfigImporter.php
@@ -540,6 +540,7 @@ public function initialize() {
     // We have extensions to process.
     if ($this->totalExtensionsToProcess > 0) {
       $sync_steps[] = 'processExtensions';
+      $sync_steps[] = 'flush';
     }
     $sync_steps[] = 'processConfigurations';
 
@@ -549,6 +550,20 @@ public function initialize() {
     return $sync_steps;
   }
 
+  /**
+   * Flushes Drupal's caches.
+   */
+  public function flush(array &$context) {
+    // Rebuild the container and flush Drupal's caches. If the container is not
+    // rebuilt first the entity types are not discovered correctly due to using
+    // an entity manager that has the incorrect container namespaces injected.
+    \Drupal::service('kernel')->rebuildContainer(TRUE);
+    drupal_flush_all_caches();
+    $this->reInjectMe();
+    $context['message'] = $this->t('Flushed all caches.');
+    $context['finished'] = 1;
+  }
+
   /**
    * Processes extensions as a batch operation.
    *
diff --git a/core/lib/Drupal/Core/Config/DatabaseStorage.php b/core/lib/Drupal/Core/Config/DatabaseStorage.php
index 64214ae8e035..20e5f1b9bef0 100644
--- a/core/lib/Drupal/Core/Config/DatabaseStorage.php
+++ b/core/lib/Drupal/Core/Config/DatabaseStorage.php
@@ -10,11 +10,13 @@
 use Drupal\Core\Database\Database;
 use Drupal\Core\Database\Connection;
 use Drupal\Core\Database\SchemaObjectExistsException;
+use Drupal\Core\DependencyInjection\DependencySerializationTrait;
 
 /**
  * Defines the Database storage.
  */
 class DatabaseStorage implements StorageInterface {
+  use DependencySerializationTrait;
 
   /**
    * The database connection.
diff --git a/core/modules/config/config.services.yml b/core/modules/config/config.services.yml
new file mode 100644
index 000000000000..5ce2696f936c
--- /dev/null
+++ b/core/modules/config/config.services.yml
@@ -0,0 +1,5 @@
+services:
+  config.config_subscriber:
+    class: Drupal\config\ConfigSubscriber
+    tags:
+      - { name: event_subscriber }
diff --git a/core/modules/config/src/ConfigSubscriber.php b/core/modules/config/src/ConfigSubscriber.php
new file mode 100644
index 000000000000..9da0233f8cd2
--- /dev/null
+++ b/core/modules/config/src/ConfigSubscriber.php
@@ -0,0 +1,42 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\config\ConfigSubscriber.
+ */
+
+namespace Drupal\config;
+
+use Drupal\Core\Config\ConfigEvents;
+use Drupal\Core\Config\ConfigImporterEvent;
+use Drupal\Core\Config\ConfigImporterException;
+use Drupal\Core\Config\ConfigImportValidateEventSubscriberBase;
+
+
+/**
+ * Config subscriber.
+ */
+class ConfigSubscriber extends ConfigImportValidateEventSubscriberBase {
+
+  /**
+   * Checks that the Configuration module is not being uninstalled.
+   *
+   * @param ConfigImporterEvent $event
+   *   The config import event.
+   */
+  public function onConfigImporterValidate(ConfigImporterEvent $event) {
+    $importer = $event->getConfigImporter();
+    $core_extension = $importer->getStorageComparer()->getSourceStorage()->read('core.extension');
+    if (!isset($core_extension['module']['config'])) {
+      $importer->logError($this->t('Can not uninstall the Configuration module as part of a configuration synchronization through the user interface.'));
+    }
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  static function getSubscribedEvents() {
+    $events[ConfigEvents::IMPORT_VALIDATE][] = array('onConfigImporterValidate', 20);
+    return $events;
+  }
+}
diff --git a/core/modules/config/src/Tests/ConfigImportAllTest.php b/core/modules/config/src/Tests/ConfigImportAllTest.php
index 1624211de1a4..83100f33d1e1 100644
--- a/core/modules/config/src/Tests/ConfigImportAllTest.php
+++ b/core/modules/config/src/Tests/ConfigImportAllTest.php
@@ -32,6 +32,13 @@ public static function getInfo() {
     );
   }
 
+  public function setUp() {
+    parent::setUp();
+
+    $this->web_user = $this->drupalCreateUser(array('synchronize configuration'));
+    $this->drupalLogin($this->web_user);
+  }
+
   /**
    * Tests that a fixed set of modules can be installed and uninstalled.
    */
@@ -82,6 +89,9 @@ public function testInstallUninstall() {
       return TRUE;
     });
 
+    // Can not uninstall config and use admin/config/development/configuration!
+    unset($modules_to_uninstall['config']);
+
     $this->assertTrue(isset($modules_to_uninstall['comment']), 'The comment module will be disabled');
 
     // Uninstall all modules that can be uninstalled.
@@ -94,7 +104,7 @@ public function testInstallUninstall() {
     }
 
     // Import the configuration thereby re-installing all the modules.
-    $this->configImporter()->import();
+    $this->drupalPostForm('admin/config/development/configuration', array(), t('Import all'));
 
     // Check that there are no errors.
     $this->assertIdentical($this->configImporter()->getErrors(), array());
diff --git a/core/modules/config/src/Tests/ConfigImportUITest.php b/core/modules/config/src/Tests/ConfigImportUITest.php
index 6f3bb2c5a48a..62a28ed5c1e0 100644
--- a/core/modules/config/src/Tests/ConfigImportUITest.php
+++ b/core/modules/config/src/Tests/ConfigImportUITest.php
@@ -331,6 +331,21 @@ public function testImportValidation() {
     $this->assertNotEqual($new_site_name, \Drupal::config('system.site')->get('name'));
   }
 
+  public function testConfigUninstallConfigException() {
+    $staging = $this->container->get('config.storage.staging');
+
+    $core_extension = \Drupal::config('core.extension')->get();
+    unset($core_extension['module']['config']);
+    $staging->write('core.extension', $core_extension);
+
+    $this->drupalGet('admin/config/development/configuration');
+    $this->assertText('core.extension');
+
+    // Import and verify that both do not appear anymore.
+    $this->drupalPostForm(NULL, array(), t('Import all'));
+    $this->assertText('Can not uninstall the Configuration module as part of a configuration synchronization through the user interface.');
+  }
+
   function prepareSiteNameUpdate($new_site_name) {
     $staging = $this->container->get('config.storage.staging');
     // Create updated configuration object.
diff --git a/core/modules/migrate/src/Entity/Migration.php b/core/modules/migrate/src/Entity/Migration.php
index c892ccb5fe22..da71c0be56e3 100644
--- a/core/modules/migrate/src/Entity/Migration.php
+++ b/core/modules/migrate/src/Entity/Migration.php
@@ -78,6 +78,13 @@ class Migration extends ConfigEntityBase implements MigrationInterface, Requirem
    */
   public $process;
 
+  /**
+   * The configuration describing the load plugins.
+   *
+   * @var array
+   */
+  public $load;
+
   /**
    * The cached process plugins.
    *
@@ -339,18 +346,4 @@ public function checkRequirements() {
     return TRUE;
   }
 
-  /**
-   * {@inheritdoc}
-   */
-  public function toArray() {
-    // @todo Remove once migration config entities have schema
-    //   https://drupal.org/node/2183957.
-    $class_info = new \ReflectionClass($this);
-    foreach ($class_info->getProperties(\ReflectionProperty::IS_PUBLIC) as $property) {
-      $name = $property->getName();
-      $properties[$name] = $this->get($name);
-    }
-    return $properties;
-  }
-
 }
diff --git a/core/modules/simpletest/src/Form/SimpletestResultsForm.php b/core/modules/simpletest/src/Form/SimpletestResultsForm.php
index 299f3051cde2..7c55197e5595 100644
--- a/core/modules/simpletest/src/Form/SimpletestResultsForm.php
+++ b/core/modules/simpletest/src/Form/SimpletestResultsForm.php
@@ -48,6 +48,12 @@ public static function create(ContainerInterface $container) {
    */
   public function __construct(Connection $database) {
     $this->database = $database;
+  }
+
+  /**
+   * Builds the status image map.
+   */
+  protected function buildStatusImageMap() {
     // Initialize image mapping property.
     $image_pass = array(
       '#theme' => 'image',
@@ -96,6 +102,7 @@ public function getFormId() {
    * {@inheritdoc}
    */
   public function buildForm(array $form, array &$form_state, $test_id = NULL) {
+    $this->buildStatusImageMap();
     // Make sure there are test results to display and a re-run is not being
     // performed.
     $results = array();
-- 
GitLab