/**
  * Tests configuration renaming.
  */
 public function testConfigurationRename()
 {
     $content_type = entity_create('node_type', array('type' => Unicode::strtolower($this->randomName(16)), 'name' => $this->randomName()));
     $content_type->save();
     $staged_type = $content_type->type;
     $active = $this->container->get('config.storage');
     $staging = $this->container->get('config.storage.staging');
     $config_name = $content_type->getEntityType()->getConfigPrefix() . '.' . $content_type->id();
     // Emulate a staging operation.
     $this->copyConfig($active, $staging);
     // Change the machine name of the content type.
     $content_type->type = Unicode::strtolower($this->randomName(8));
     $content_type->save();
     $active_type = $content_type->type;
     $renamed_config_name = $content_type->getEntityType()->getConfigPrefix() . '.' . $content_type->id();
     $this->assertTrue($active->exists($renamed_config_name), 'The content type has the new name in the active store.');
     $this->assertFalse($active->exists($config_name), "The content type's old name does not exist active store.");
     $this->configImporter()->reset();
     $this->assertEqual(0, count($this->configImporter()->getUnprocessedConfiguration('create')), 'There are no configuration items to create.');
     $this->assertEqual(0, count($this->configImporter()->getUnprocessedConfiguration('delete')), 'There are no configuration items to delete.');
     $this->assertEqual(0, count($this->configImporter()->getUnprocessedConfiguration('update')), 'There are no configuration items to update.');
     // We expect that changing the machine name of the content type will
     // rename five configuration entities: the node type, the body field
     // instance, two entity form displays, and the entity view display.
     // @see \Drupal\node\Entity\NodeType::postSave()
     $expected = array('node.type.' . $active_type . '::node.type.' . $staged_type, 'entity.form_display.node.' . $active_type . '.default::entity.form_display.node.' . $staged_type . '.default', 'entity.view_display.node.' . $active_type . '.default::entity.view_display.node.' . $staged_type . '.default', 'entity.view_display.node.' . $active_type . '.teaser::entity.view_display.node.' . $staged_type . '.teaser', 'field.instance.node.' . $active_type . '.body::field.instance.node.' . $staged_type . '.body');
     $renames = $this->configImporter()->getUnprocessedConfiguration('rename');
     $this->assertIdentical($expected, $renames);
     $this->drupalGet('admin/config/development/configuration');
     foreach ($expected as $rename) {
         $names = $this->configImporter()->getStorageComparer()->extractRenameNames($rename);
         $this->assertText(String::format('!source_name to !target_name', array('!source_name' => $names['old_name'], '!target_name' => $names['new_name'])));
         // Test that the diff link is present for each renamed item.
         $href = \Drupal::urlGenerator()->getPathFromRoute('config.diff', array('source_name' => $names['old_name'], 'target_name' => $names['new_name']));
         $this->assertLinkByHref($href);
         $hrefs[$rename] = $href;
     }
     // Ensure that the diff works for each renamed item.
     foreach ($hrefs as $rename => $href) {
         $this->drupalGet($href);
         $names = $this->configImporter()->getStorageComparer()->extractRenameNames($rename);
         $config_entity_type = \Drupal::service('config.manager')->getEntityTypeIdByName($names['old_name']);
         $entity_type = \Drupal::entityManager()->getDefinition($config_entity_type);
         $old_id = ConfigEntityStorage::getIDFromConfigName($names['old_name'], $entity_type->getConfigPrefix());
         $new_id = ConfigEntityStorage::getIDFromConfigName($names['new_name'], $entity_type->getConfigPrefix());
         // Because table columns can be on multiple lines, need to assert a regex
         // pattern rather than normal text.
         $id_key = $entity_type->getKey('id');
         $text = "{$id_key}: {$old_id}";
         $this->assertTextPattern('/\\-\\s+' . preg_quote($text, '/') . '/', "'-{$text}' found.");
         $text = "{$id_key}: {$new_id}";
         $this->assertTextPattern('/\\+\\s+' . preg_quote($text, '/') . '/', "'+{$text}' found.");
     }
     // Run the import.
     $this->drupalPostForm('admin/config/development/configuration', array(), t('Import all'));
     $this->assertText(t('There are no configuration changes.'));
     $this->assertFalse(entity_load('node_type', $active_type), 'The content no longer exists with the old name.');
     $content_type = entity_load('node_type', $staged_type);
     $this->assertIdentical($staged_type, $content_type->type);
 }
Ejemplo n.º 2
0
 /**
  * Ensures bundles that will be deleted are not in use.
  *
  * @param \Drupal\Core\Config\ConfigImporterEvent $event
  *   The config import event.
  */
 public function onConfigImporterValidate(ConfigImporterEvent $event)
 {
     foreach ($event->getChangelist('delete') as $config_name) {
         // Get the config entity type ID. This also ensure we are dealing with a
         // configuration entity.
         if ($entity_type_id = $this->configManager->getEntityTypeIdByName($config_name)) {
             $entity_type = $this->entityManager->getDefinition($entity_type_id);
             // Does this entity type define a bundle of another entity type.
             if ($bundle_of = $entity_type->getBundleOf()) {
                 // Work out if there are entities with this bundle.
                 $bundle_of_entity_type = $this->entityManager->getDefinition($bundle_of);
                 $bundle_id = ConfigEntityStorage::getIDFromConfigName($config_name, $entity_type->getConfigPrefix());
                 $entity_query = $this->entityManager->getStorage($bundle_of)->getQuery();
                 $entity_ids = $entity_query->condition($bundle_of_entity_type->getKey('bundle'), $bundle_id)->accessCheck(FALSE)->range(0, 1)->execute();
                 if (!empty($entity_ids)) {
                     $entity = $this->entityManager->getStorage($entity_type_id)->load($bundle_id);
                     $event->getConfigImporter()->logError($this->t('Entities exist of type %entity_type and %bundle_label %bundle. These entities need to be deleted before importing.', array('%entity_type' => $bundle_of_entity_type->getLabel(), '%bundle_label' => $bundle_of_entity_type->getBundleLabel(), '%bundle' => $entity->label())));
                 }
             }
         }
     }
 }
Ejemplo n.º 3
0
 /**
  * Gets the list of fields to purge before configuration synchronization.
  *
  * If, during a configuration synchronization, a field is being deleted and
  * the module that provides the field type is being uninstalled then the field
  * data must be purged before the module is uninstalled. Also, if deleted
  * fields exist whose field types are provided by modules that are being
  * uninstalled their data need to be purged too.
  *
  * @param array $extensions
  *   The list of extensions that will be enabled after the configuration
  *   synchronization has finished.
  * @param array $deletes
  *   The configuration that will be deleted by the configuration
  *   synchronization.
  *
  * @return \Drupal\field\Entity\FieldStorageConfig[]
  *   An array of field storages that need purging before configuration can be
  *   synchronized.
  */
 public static function getFieldStoragesToPurge(array $extensions, array $deletes)
 {
     $providers = array_keys($extensions['module']);
     $providers[] = 'core';
     $storages_to_delete = array();
     // Gather fields that will be deleted during configuration synchronization
     // where the module that provides the field type is also being uninstalled.
     $field_storage_ids = array();
     foreach ($deletes as $config_name) {
         $field_storage_config_prefix = \Drupal::entityManager()->getDefinition('field_storage_config')->getConfigPrefix();
         if (strpos($config_name, $field_storage_config_prefix . '.') === 0) {
             $field_storage_ids[] = ConfigEntityStorage::getIDFromConfigName($config_name, $field_storage_config_prefix);
         }
     }
     if (!empty($field_storage_ids)) {
         $field_storages = \Drupal::entityQuery('field_storage_config')->condition('id', $field_storage_ids, 'IN')->condition('module', $providers, 'NOT IN')->execute();
         if (!empty($field_storages)) {
             $storages_to_delete = FieldStorageConfig::loadMultiple($field_storages);
         }
     }
     // Gather deleted fields from modules that are being uninstalled.
     /** @var \Drupal\field\FieldStorageConfigInterface[] $field_storages */
     $field_storages = entity_load_multiple_by_properties('field_storage_config', array('deleted' => TRUE, 'include_deleted' => TRUE));
     foreach ($field_storages as $field_storage) {
         if (!in_array($field_storage->getTypeProvider(), $providers)) {
             $storages_to_delete[$field_storage->id()] = $field_storage;
         }
     }
     return $storages_to_delete;
 }