diff --git a/core/core.services.yml b/core/core.services.yml index f362a02..c56c778 100644 --- a/core/core.services.yml +++ b/core/core.services.yml @@ -1532,6 +1532,3 @@ services: arguments: ['@current_user', '@path.current', '@path.matcher', '@language_manager'] tags: - { name: event_subscriber } - entity_reference.finder: - class: Drupal\Core\Field\EntityReferenceFinder - arguments: ['@config.factory', '@plugin.manager.field.field_type'] diff --git a/core/lib/Drupal/Core/Entity/EntityManager.php b/core/lib/Drupal/Core/Entity/EntityManager.php index 24462d5..9d749fb 100644 --- a/core/lib/Drupal/Core/Entity/EntityManager.php +++ b/core/lib/Drupal/Core/Entity/EntityManager.php @@ -33,7 +33,6 @@ use Drupal\Core\StringTranslation\TranslationInterface; use Drupal\Core\TypedData\TranslatableInterface; use Drupal\Core\TypedData\TypedDataManager; -use Drupal\field\Entity\FieldConfig; use Symfony\Component\DependencyInjection\ContainerAwareInterface; use Symfony\Component\DependencyInjection\ContainerAwareTrait; use Symfony\Component\EventDispatcher\EventDispatcherInterface; diff --git a/core/lib/Drupal/Core/Field/EntityReferenceFinder.php b/core/lib/Drupal/Core/Field/EntityReferenceFinder.php deleted file mode 100644 index 1a15710..0000000 --- a/core/lib/Drupal/Core/Field/EntityReferenceFinder.php +++ /dev/null @@ -1,106 +0,0 @@ -configFactory = $config_factory; - $this->fieldTypeManager = $field_type_manager; - } - - /** - * {@inheritdoc} - */ - public static function create(ContainerInterface $container) { - return new static( - $container->get('config.factory'), - $container->get('plugin.manager.field.field_type') - ); - } - - /** - * {@inheritdoc} - */ - public function getFieldsReferencing($target_type, $target_bundle) { - if (!isset(static::$fieldsReferencing[$target_type][$target_bundle])) { - static::$fieldsReferencing[$target_type][$target_bundle] = []; - $ids = []; - - // Get a list of entity reference storage IDs. - foreach ($this->configFactory->loadMultiple($this->configFactory->listAll('field.storage.')) as $config) { - $class = $this->fieldTypeManager->getPluginClass($config->get('type')); - // Deal only with entity reference fields and descendants. - if ($class == static::ITEM_CLASS || is_subclass_of($class, static::ITEM_CLASS)) { - $id = $config->get('id'); - if (!$type = $config->get('settings.target_type')) { - throw new \LogicException(sprintf("Entity reference field '%s' without defined 'target_type'.", $id)); - } - $ids[] = $id; - } - } - - foreach ($this->configFactory->loadMultiple($this->configFactory->listAll('field.field.')) as $id => $config) { - list(,, $entity_type, , $field_name) = explode('.', $id); - // This field config doesn't belong to an entity reference field. - if (!in_array("$entity_type.$field_name", $ids)) { - continue; - } - - if ($bundles = $config->get('settings.handler_settings.target_bundles')) { - foreach ($bundles as $bundle) { - if ($bundle == $target_bundle) { - static::$fieldsReferencing[$target_type][$target_bundle][] = $config->get('id'); - break; - } - } - } - } - } - - return static::$fieldsReferencing[$target_type][$target_bundle]; - } - -} diff --git a/core/lib/Drupal/Core/Field/EntityReferenceFinderInterface.php b/core/lib/Drupal/Core/Field/EntityReferenceFinderInterface.php deleted file mode 100644 index c9abfb4..0000000 --- a/core/lib/Drupal/Core/Field/EntityReferenceFinderInterface.php +++ /dev/null @@ -1,36 +0,0 @@ -getDefinition($field_definition->getFieldStorageDefinition()->getSetting('target_type')); + + // Depend on default values entity types configurations. if ($default_value = $field_definition->getDefaultValueLiteral()) { - $target_entity_type = \Drupal::entityManager()->getDefinition($field_definition->getFieldStorageDefinition()->getSetting('target_type')); foreach ($default_value as $value) { if (is_array($value) && isset($value['target_uuid'])) { $entity = \Drupal::entityManager()->loadEntityByUuid($target_entity_type->id(), $value['target_uuid']); @@ -298,6 +301,19 @@ public static function calculateDependencies(FieldDefinitionInterface $field_def } } } + + // Depend on target bundle configurations. + $handler = $field_definition->getSetting('handler_settings'); + if (!empty($handler['target_bundles'])) { + if ($bundle_entity_type_id = $target_entity_type->getBundleEntityType()) { + if ($storage = $manager->getStorage($bundle_entity_type_id)) { + foreach ($storage->loadMultiple($handler['target_bundles']) as $bundle) { + $dependencies[$bundle->getConfigDependencyKey()][] = $bundle->getConfigDependencyName(); + } + } + } + } + return $dependencies; } @@ -305,12 +321,14 @@ public static function calculateDependencies(FieldDefinitionInterface $field_def * {@inheritdoc} */ public static function onDependencyRemoval(FieldDefinitionInterface $field_definition, array $dependencies) { - $changed = FALSE; + $changed = parent::calculateDependencies($field_definition, $dependencies); + $manager = \Drupal::entityManager(); + $target_entity_type = $manager->getDefinition($field_definition->getFieldStorageDefinition()->getSetting('target_type')); + if ($default_value = $field_definition->getDefaultValueLiteral()) { - $target_entity_type = \Drupal::entityManager()->getDefinition($field_definition->getFieldStorageDefinition()->getSetting('target_type')); foreach ($default_value as $key => $value) { if (is_array($value) && isset($value['target_uuid'])) { - $entity = \Drupal::entityManager()->loadEntityByUuid($target_entity_type->id(), $value['target_uuid']); + $entity = $manager->loadEntityByUuid($target_entity_type->id(), $value['target_uuid']); // @see \Drupal\Core\Field\EntityReferenceFieldItemList::processDefaultValue() if ($entity && isset($dependencies[$entity->getConfigDependencyKey()][$entity->getConfigDependencyName()])) { unset($default_value[$key]); @@ -322,6 +340,25 @@ public static function onDependencyRemoval(FieldDefinitionInterface $field_defin $field_definition->setDefaultValue($default_value); } } + $bundles_changed = FALSE; + $handler = $field_definition->getSetting('handler_settings'); + if (!empty($handler['target_bundles'])) { + if ($bundle_entity_type_id = $target_entity_type->getBundleEntityType()) { + if ($storage = $manager->getStorage($bundle_entity_type_id)) { + foreach ($storage->loadMultiple($handler['target_bundles']) as $bundle) { + if (isset($dependencies[$bundle->getConfigDependencyKey()][$bundle->getConfigDependencyName()])) { + unset($handler['target_bundles'][$bundle->id()]); + $bundles_changed = TRUE; + } + } + } + } + } + if ($bundles_changed) { + $field_definition->setSetting('handler_settings', $handler); + } + $changed |= $bundles_changed; + return $changed; } diff --git a/core/modules/entity_reference/entity_reference.module b/core/modules/entity_reference/entity_reference.module index 340aabf..a09a53c 100644 --- a/core/modules/entity_reference/entity_reference.module +++ b/core/modules/entity_reference/entity_reference.module @@ -213,42 +213,37 @@ function entity_reference_query_entity_reference_alter(AlterableInterface $query /** * Implements hook_entity_bundle_rename(). + * + * @todo Move this in an event subscriber once + * https://www.drupal.org/node/2553169 is in. */ function entity_reference_entity_bundle_rename($entity_type, $bundle_old, $bundle_new) { - entity_reference_sync_fields($entity_type, $bundle_old, $bundle_new); -} - -/** - * Implements hook_entity_bundle_delete(). - */ -function entity_reference_entity_bundle_delete($entity_type, $bundle) { - entity_reference_sync_fields($entity_type, $bundle); -} + $map = \Drupal::entityManager()->getFieldMapByFieldType('entity_reference'); + $ids = []; + foreach ($map as $type => $info) { + foreach ($info as $name => $data) { + foreach ($data['bundles'] as $bundle) { + $ids[] = "$type.$bundle.$name"; + } + } + } -/** - * Sync bundle settings of entity reference fields targeting a bundle that is - * about to change. - * - * @param string $entity_type - * The entity type of the bundle that is about to change. - * @param string $bundle - * The bundle that is about to change. - * @param string|null $bundle_new - * (optional) If provided the bundle has been renamed to this new name. If - * omitted, the bundle has been deleted. - */ -function entity_reference_sync_fields($entity_type, $bundle, $bundle_new = NULL) { - /** @var \Drupal\Core\Field\EntityReferenceFinder $finder */ - $finder = \Drupal::service('entity_reference.finder'); - $ids = $finder->getFieldsReferencing($entity_type, $bundle); - - foreach (FieldConfig::loadMultiple($ids) as $field_config) { - $handler_settings = $field_config->getSetting('handler_settings'); - if ($bundle_new) { - $handler_settings['target_bundles'][$bundle_new] = $bundle_new; + /** @var \Drupal\field\Entity\FieldConfig $config */ + foreach (FieldConfig::loadMultiple($ids) as $config) { + if ($config->getSetting('target_type') == $entity_type) { + $handler = $config->getSetting('handler_settings'); + $bundles = !empty($handler['target_bundles']) ? array_keys($handler['target_bundles']) : []; + foreach ($bundles as $bundle) { + if ($bundle == $bundle_old) { + $handler['target_bundles'][$bundle_new] = $bundle_new; + unset($handler['target_bundles'][$bundle_old]); + $config->setSetting('handler_settings', $handler); + $config->save(); + break; + } + } } - unset($handler_settings['target_bundles'][$bundle]); - $field_config->setSetting('handler_settings', $handler_settings); - $field_config->save(); } + // Release memory. + unset($map, $ids); }