Loading field_fallback.services.yml +8 −3 Original line number Diff line number Diff line services: field_fallback.field_config_form: class: \Drupal\field_fallback\Form\FieldFallbackFieldConfigForm arguments: ['@entity_type.manager', '@plugin.manager.field_fallback_converter'] class: Drupal\field_fallback\Form\FieldFallbackFieldConfigForm arguments: ['@entity_field.manager', '@entity_type.manager', '@plugin.manager.field_fallback_converter'] field_fallback.service: class: \Drupal\field_fallback\FieldFallbackService class: Drupal\field_fallback\FieldFallbackService arguments: ['@entity_type.manager', '@plugin.manager.field_fallback_converter', '@language_manager'] plugin.manager.field_fallback_converter: class: Drupal\field_fallback\Plugin\FieldFallbackConverterManager arguments: ['@container.namespaces', '@cache.discovery', '@module_handler', '@entity_type.manager'] field_fallback.field_storage_subscriber: class: Drupal\field_fallback\EventSubscriber\FieldStorageSubscriber arguments: ['@field_fallback.service'] tags: - { name: event_subscriber } src/EventSubscriber/FieldStorageSubscriber.php 0 → 100644 +58 −0 Original line number Diff line number Diff line <?php namespace Drupal\field_fallback\EventSubscriber; use Drupal\Core\Field\FieldStorageDefinitionEvent; use Drupal\Core\Field\FieldStorageDefinitionEvents; use Drupal\field_fallback\FieldFallbackService; use Symfony\Component\EventDispatcher\EventSubscriberInterface; /** * Subscriber for field storage deletions. */ class FieldStorageSubscriber implements EventSubscriberInterface { /** * The field fallback service. * * @var \Drupal\field_fallback\FieldFallbackService */ protected $fieldFallbackService; /** * Constructs a FieldStorageSubscriber object. * * @param \Drupal\field_fallback\FieldFallbackService $field_fallback_service * The field fallback service. */ public function __construct(FieldFallbackService $field_fallback_service) { $this->fieldFallbackService = $field_fallback_service; } /** * Listens to field storage deletions. * * When a base field is deleted, we check the field_fallback configs that * depend on the base field and clean the config. * * @param \Drupal\Core\Field\FieldStorageDefinitionEvent $event * The triggered event. * * @throws \Drupal\Core\Entity\EntityStorageException */ public function onFieldStorageDeletion(FieldStorageDefinitionEvent $event): void { if ($event->getFieldStorageDefinition()->isBaseField()) { $this->fieldFallbackService->cleanupConfigBaseFields($event->getFieldStorageDefinition()); } } /** * {@inheritdoc} */ public static function getSubscribedEvents() { return [ FieldStorageDefinitionEvents::DELETE => 'onFieldStorageDeletion', ]; } } src/FieldFallbackService.php +53 −15 Original line number Diff line number Diff line Loading @@ -6,8 +6,9 @@ use Drupal\Core\Entity\EntityInterface; use Drupal\Core\Entity\EntityTypeManagerInterface; use Drupal\Core\Entity\FieldableEntityInterface; use Drupal\Core\Entity\TranslatableInterface; use Drupal\Core\Field\FieldDefinitionInterface; use Drupal\Core\Field\FieldStorageDefinitionInterface; use Drupal\Core\Language\LanguageManagerInterface; use Drupal\field\FieldConfigInterface; use Drupal\field_fallback\Plugin\FieldFallbackConverterManagerInterface; /** Loading Loading @@ -184,17 +185,49 @@ class FieldFallbackService { /** * Cleanup the config when a field is deleted. * * @param \Drupal\field\FieldConfigInterface $deleted_field_config * The field_config that's being deleted. * @param \Drupal\Core\Field\FieldDefinitionInterface $deleted_field * The field that's being deleted. * * @throws \Drupal\Core\Entity\EntityStorageException */ public function cleanupConfigFields(FieldConfigInterface $deleted_field_config): void { $field_config_ids = $this->getFieldConfigIdsWithFallback( $deleted_field_config->getTargetEntityTypeId(), $deleted_field_config->getTargetBundle() ?? $deleted_field_config->getTargetEntityTypeId() public function cleanupConfigFields(FieldDefinitionInterface $deleted_field): void { $this->doCleanupConfigOnDeletion( $deleted_field->getTargetEntityTypeId(), $deleted_field->getTargetBundle() ?? $deleted_field->getTargetEntityTypeId(), $deleted_field->getName() ); } /** * Cleanup the config when a base field is deleted. * * @param \Drupal\Core\Field\FieldStorageDefinitionInterface $deleted_base_field * The base field that's being deleted. * * @throws \Drupal\Core\Entity\EntityStorageException */ public function cleanupConfigBaseFields(FieldStorageDefinitionInterface $deleted_base_field): void { $this->doCleanupConfigOnDeletion( $deleted_base_field->getTargetEntityTypeId(), NULL, $deleted_base_field->getName() ); } /** * Method that does the actual cleanup of the field configs. * * @param string $entity_type_id * The entity type ID. * @param string|null $bundle_id * The bundle ID, when available. * @param string $deleted_field_name * The name of the field that's being deleted. * * @throws \Drupal\Core\Entity\EntityStorageException */ protected function doCleanupConfigOnDeletion(string $entity_type_id, ?string $bundle_id, string $deleted_field_name): void { $field_config_ids = $this->getFieldConfigIdsWithFallback($entity_type_id, $bundle_id); if (empty($field_config_ids)) { return; } Loading @@ -203,7 +236,7 @@ class FieldFallbackService { $field_configs = $this->fieldConfigStorage->loadMultiple($field_config_ids); foreach ($field_configs as $field_config) { if ($field_config->getThirdPartySetting('field_fallback', 'field') === $deleted_field_config->getName()) { if ($field_config->getThirdPartySetting('field_fallback', 'field') === $deleted_field_name) { $field_config->unsetThirdPartySetting('field_fallback', 'field'); $field_config->unsetThirdPartySetting('field_fallback', 'converter'); $field_config->save(); Loading @@ -216,18 +249,23 @@ class FieldFallbackService { * * @param string $entity_type_id * The entity type ID. * @param string $bundle * @param string|null $bundle * The bundle. * * @return array * An array of field config IDs. */ protected function getFieldConfigIdsWithFallback(string $entity_type_id, string $bundle): array { return $this->fieldConfigStorage->getQuery() ->condition('entity_type', $entity_type_id) ->condition('bundle', $bundle) ->condition('third_party_settings.field_fallback.field', NULL, 'IS NOT NULL') ->execute(); protected function getFieldConfigIdsWithFallback(string $entity_type_id, ?string $bundle): array { $query = $this->fieldConfigStorage->getQuery(); $query->condition('entity_type', $entity_type_id); if ($bundle !== NULL) { $query->condition('bundle', $bundle); } $query->condition('third_party_settings.field_fallback.field', NULL, 'IS NOT NULL'); $result = $query->execute(); return is_array($result) ? $result : []; } } src/Form/FieldFallbackFieldConfigForm.php +43 −15 Original line number Diff line number Diff line Loading @@ -3,9 +3,12 @@ namespace Drupal\field_fallback\Form; use Drupal\Component\Utility\NestedArray; use Drupal\Core\Config\Entity\ThirdPartySettingsInterface; use Drupal\Core\DependencyInjection\DependencySerializationTrait; use Drupal\Core\Entity\EntityFieldManagerInterface; use Drupal\Core\Entity\EntityFormInterface; use Drupal\Core\Entity\EntityTypeManagerInterface; use Drupal\Core\Field\FieldDefinitionInterface; use Drupal\Core\Form\FormState; use Drupal\Core\Form\FormStateInterface; use Drupal\Core\Render\Element; Loading @@ -21,6 +24,13 @@ class FieldFallbackFieldConfigForm { use DependencySerializationTrait; use StringTranslationTrait; /** * The entity field manager service. * * @var \Drupal\Core\Entity\EntityFieldManagerInterface */ protected $entityFieldManager; /** * The field config storage. * Loading @@ -38,6 +48,8 @@ class FieldFallbackFieldConfigForm { /** * FieldConfigForm constructor. * * @param \Drupal\Core\Entity\EntityFieldManagerInterface $entity_field_manager * The entity field manager service. * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager * The entity type manager. * @param \Drupal\field_fallback\Plugin\FieldFallbackConverterManagerInterface $field_fallback_converter_manager Loading @@ -46,7 +58,8 @@ class FieldFallbackFieldConfigForm { * @throws \Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException * @throws \Drupal\Component\Plugin\Exception\PluginNotFoundException */ public function __construct(EntityTypeManagerInterface $entity_type_manager, FieldFallbackConverterManagerInterface $field_fallback_converter_manager) { public function __construct(EntityFieldManagerInterface $entity_field_manager, EntityTypeManagerInterface $entity_type_manager, FieldFallbackConverterManagerInterface $field_fallback_converter_manager) { $this->entityFieldManager = $entity_field_manager; $this->fieldConfigStorage = $entity_type_manager->getStorage('field_config'); $this->fieldFallbackConverterManager = $field_fallback_converter_manager; } Loading Loading @@ -103,11 +116,9 @@ class FieldFallbackFieldConfigForm { $field_value = isset($user_input['third_party_settings']['field_fallback']['field']) ? $user_input['third_party_settings']['field_fallback']['field'] : ($settings['field'] ?? NULL); if (!empty($field_value)) { $fallback_field = $this->fieldConfigStorage->load($field_config->getTargetEntityTypeId() . '.' . $field_config->getTargetBundle() . '.' . $field_value); if ($fallback_field instanceof FieldConfigInterface) { $converter_options = $this->buildConverterOptions($field_config, $fallback_field); $converter_options = $this->buildConverterOptions($field_config, $field_value); if (!empty($converter_options)) { $default_converter = $settings['converter'] ?? NULL; if ($default_converter === NULL) { $default_converter = count($converter_options) === 1 ? key($converter_options) : NULL; Loading Loading @@ -270,6 +281,13 @@ class FieldFallbackFieldConfigForm { } } $base_field_definitions = $this->entityFieldManager->getBaseFieldDefinitions($configured_field->getTargetEntityTypeId()); foreach ($base_field_definitions as $base_field_definition) { if (in_array($base_field_definition->getType(), $source_field_types, TRUE) && $this->isFieldConfigApplicable($configured_field, $base_field_definition)) { $options[$base_field_definition->getName()] = $base_field_definition->getLabel(); } } natcasesort($options); return $options; Loading @@ -280,13 +298,24 @@ class FieldFallbackFieldConfigForm { * * @param \Drupal\field\FieldConfigInterface $target_field * The target field. * @param \Drupal\field\FieldConfigInterface $source_field * The source field on which the value will be based. * @param string $source_field_name * The name of the source field on which the value will be based. * * @return array * An option array containing field configs. */ protected function buildConverterOptions(FieldConfigInterface $target_field, FieldConfigInterface $source_field): array { protected function buildConverterOptions(FieldConfigInterface $target_field, string $source_field_name): array { $source_field = $this->fieldConfigStorage->load($target_field->getTargetEntityTypeId() . '.' . $target_field->getTargetBundle() . '.' . $source_field_name); if (!$source_field instanceof FieldConfigInterface) { $base_fields = $this->entityFieldManager->getBaseFieldDefinitions($target_field->getTargetEntityTypeId()); $source_field = $base_fields[$source_field_name] ?? NULL; } if ($source_field === NULL) { return []; } $converter_definitions = $this->fieldFallbackConverterManager->getDefinitionsBySourceAndTarget( $source_field->getType(), $target_field->getType() Loading @@ -303,30 +332,29 @@ class FieldFallbackFieldConfigForm { /** * Checks if a field can be configured as a fallback field. * * @param \Drupal\field\FieldConfigInterface $configured_field * @param \Drupal\Core\Field\FieldDefinitionInterface $configured_field * The currently configured field. * @param \Drupal\field\FieldConfigInterface $fallback_field * @param \Drupal\Core\Field\FieldDefinitionInterface $fallback_field * The fallback field. * * @return bool * True, when the field can be configured as a fallback field, else FALSE. */ protected function isFieldConfigApplicable(FieldConfigInterface $configured_field, FieldConfigInterface $fallback_field): bool { protected function isFieldConfigApplicable(FieldDefinitionInterface $configured_field, FieldDefinitionInterface $fallback_field): bool { // Chaining multiple fields is not supported right now. if ($fallback_field->getThirdPartySetting('field_fallback', 'field') !== NULL) { if ($fallback_field instanceof ThirdPartySettingsInterface && $fallback_field->getThirdPartySetting('field_fallback', 'field') !== NULL) { return FALSE; } // You can't use the same field as a fallback field. if ($configured_field->id() === $fallback_field->id()) { if ($configured_field->getName() === $fallback_field->getName()) { return FALSE; } // When a field has the current field configured as a fallback, you can't // use that field as a fallback field, since that would result in an // infinite loop. $fallback_field_value = (string) $fallback_field->getThirdPartySetting('field_fallback', 'field'); if ($fallback_field_value === $configured_field->getName()) { if ($fallback_field instanceof ThirdPartySettingsInterface && (string) $fallback_field->getThirdPartySetting('field_fallback', 'field') === $configured_field->getName()) { return FALSE; } Loading src/Plugin/FieldFallbackConverter/ParagraphsSummaryFieldFallbackConverter.php +4 −4 Original line number Diff line number Diff line Loading @@ -4,10 +4,10 @@ namespace Drupal\field_fallback\Plugin\FieldFallbackConverter; use Drupal\Core\Entity\EntityTypeManagerInterface; use Drupal\Core\Extension\ModuleHandlerInterface; use Drupal\Core\Field\FieldDefinitionInterface; use Drupal\Core\Field\FieldItemListInterface; use Drupal\Core\Form\FormStateInterface; use Drupal\Core\Plugin\ContainerFactoryPluginInterface; use Drupal\field\FieldConfigInterface; use Drupal\field_fallback\Plugin\FieldFallbackConverterBase; use Symfony\Component\DependencyInjection\ContainerInterface; Loading Loading @@ -75,7 +75,7 @@ class ParagraphsSummaryFieldFallbackConverter extends FieldFallbackConverterBase // formatter. 'value' => \Drupal::service('paragraphs_summary_token.text_summary_builder')->build($field, NULL, $configuration['format']), 'format' => $configuration['format'] ?? filter_default_format(), ] ], ]; } Loading Loading @@ -105,7 +105,7 @@ class ParagraphsSummaryFieldFallbackConverter extends FieldFallbackConverterBase $form['format'] = [ '#type' => 'select', '#title' => t('Text format'), '#title' => $this->t('Text format'), '#options' => $options, '#default_value' => $default_format, '#access' => count($options) >= 1, Loading Loading @@ -136,7 +136,7 @@ class ParagraphsSummaryFieldFallbackConverter extends FieldFallbackConverterBase /** * {@inheritdoc} */ public function isApplicable(FieldConfigInterface $target_field, FieldConfigInterface $source_field): bool { public function isApplicable(FieldDefinitionInterface $target_field, FieldDefinitionInterface $source_field): bool { return $source_field->getSetting('target_type') === 'paragraph' && $this->moduleHandler->moduleExists('paragraphs_summary_token'); } Loading Loading
field_fallback.services.yml +8 −3 Original line number Diff line number Diff line services: field_fallback.field_config_form: class: \Drupal\field_fallback\Form\FieldFallbackFieldConfigForm arguments: ['@entity_type.manager', '@plugin.manager.field_fallback_converter'] class: Drupal\field_fallback\Form\FieldFallbackFieldConfigForm arguments: ['@entity_field.manager', '@entity_type.manager', '@plugin.manager.field_fallback_converter'] field_fallback.service: class: \Drupal\field_fallback\FieldFallbackService class: Drupal\field_fallback\FieldFallbackService arguments: ['@entity_type.manager', '@plugin.manager.field_fallback_converter', '@language_manager'] plugin.manager.field_fallback_converter: class: Drupal\field_fallback\Plugin\FieldFallbackConverterManager arguments: ['@container.namespaces', '@cache.discovery', '@module_handler', '@entity_type.manager'] field_fallback.field_storage_subscriber: class: Drupal\field_fallback\EventSubscriber\FieldStorageSubscriber arguments: ['@field_fallback.service'] tags: - { name: event_subscriber }
src/EventSubscriber/FieldStorageSubscriber.php 0 → 100644 +58 −0 Original line number Diff line number Diff line <?php namespace Drupal\field_fallback\EventSubscriber; use Drupal\Core\Field\FieldStorageDefinitionEvent; use Drupal\Core\Field\FieldStorageDefinitionEvents; use Drupal\field_fallback\FieldFallbackService; use Symfony\Component\EventDispatcher\EventSubscriberInterface; /** * Subscriber for field storage deletions. */ class FieldStorageSubscriber implements EventSubscriberInterface { /** * The field fallback service. * * @var \Drupal\field_fallback\FieldFallbackService */ protected $fieldFallbackService; /** * Constructs a FieldStorageSubscriber object. * * @param \Drupal\field_fallback\FieldFallbackService $field_fallback_service * The field fallback service. */ public function __construct(FieldFallbackService $field_fallback_service) { $this->fieldFallbackService = $field_fallback_service; } /** * Listens to field storage deletions. * * When a base field is deleted, we check the field_fallback configs that * depend on the base field and clean the config. * * @param \Drupal\Core\Field\FieldStorageDefinitionEvent $event * The triggered event. * * @throws \Drupal\Core\Entity\EntityStorageException */ public function onFieldStorageDeletion(FieldStorageDefinitionEvent $event): void { if ($event->getFieldStorageDefinition()->isBaseField()) { $this->fieldFallbackService->cleanupConfigBaseFields($event->getFieldStorageDefinition()); } } /** * {@inheritdoc} */ public static function getSubscribedEvents() { return [ FieldStorageDefinitionEvents::DELETE => 'onFieldStorageDeletion', ]; } }
src/FieldFallbackService.php +53 −15 Original line number Diff line number Diff line Loading @@ -6,8 +6,9 @@ use Drupal\Core\Entity\EntityInterface; use Drupal\Core\Entity\EntityTypeManagerInterface; use Drupal\Core\Entity\FieldableEntityInterface; use Drupal\Core\Entity\TranslatableInterface; use Drupal\Core\Field\FieldDefinitionInterface; use Drupal\Core\Field\FieldStorageDefinitionInterface; use Drupal\Core\Language\LanguageManagerInterface; use Drupal\field\FieldConfigInterface; use Drupal\field_fallback\Plugin\FieldFallbackConverterManagerInterface; /** Loading Loading @@ -184,17 +185,49 @@ class FieldFallbackService { /** * Cleanup the config when a field is deleted. * * @param \Drupal\field\FieldConfigInterface $deleted_field_config * The field_config that's being deleted. * @param \Drupal\Core\Field\FieldDefinitionInterface $deleted_field * The field that's being deleted. * * @throws \Drupal\Core\Entity\EntityStorageException */ public function cleanupConfigFields(FieldConfigInterface $deleted_field_config): void { $field_config_ids = $this->getFieldConfigIdsWithFallback( $deleted_field_config->getTargetEntityTypeId(), $deleted_field_config->getTargetBundle() ?? $deleted_field_config->getTargetEntityTypeId() public function cleanupConfigFields(FieldDefinitionInterface $deleted_field): void { $this->doCleanupConfigOnDeletion( $deleted_field->getTargetEntityTypeId(), $deleted_field->getTargetBundle() ?? $deleted_field->getTargetEntityTypeId(), $deleted_field->getName() ); } /** * Cleanup the config when a base field is deleted. * * @param \Drupal\Core\Field\FieldStorageDefinitionInterface $deleted_base_field * The base field that's being deleted. * * @throws \Drupal\Core\Entity\EntityStorageException */ public function cleanupConfigBaseFields(FieldStorageDefinitionInterface $deleted_base_field): void { $this->doCleanupConfigOnDeletion( $deleted_base_field->getTargetEntityTypeId(), NULL, $deleted_base_field->getName() ); } /** * Method that does the actual cleanup of the field configs. * * @param string $entity_type_id * The entity type ID. * @param string|null $bundle_id * The bundle ID, when available. * @param string $deleted_field_name * The name of the field that's being deleted. * * @throws \Drupal\Core\Entity\EntityStorageException */ protected function doCleanupConfigOnDeletion(string $entity_type_id, ?string $bundle_id, string $deleted_field_name): void { $field_config_ids = $this->getFieldConfigIdsWithFallback($entity_type_id, $bundle_id); if (empty($field_config_ids)) { return; } Loading @@ -203,7 +236,7 @@ class FieldFallbackService { $field_configs = $this->fieldConfigStorage->loadMultiple($field_config_ids); foreach ($field_configs as $field_config) { if ($field_config->getThirdPartySetting('field_fallback', 'field') === $deleted_field_config->getName()) { if ($field_config->getThirdPartySetting('field_fallback', 'field') === $deleted_field_name) { $field_config->unsetThirdPartySetting('field_fallback', 'field'); $field_config->unsetThirdPartySetting('field_fallback', 'converter'); $field_config->save(); Loading @@ -216,18 +249,23 @@ class FieldFallbackService { * * @param string $entity_type_id * The entity type ID. * @param string $bundle * @param string|null $bundle * The bundle. * * @return array * An array of field config IDs. */ protected function getFieldConfigIdsWithFallback(string $entity_type_id, string $bundle): array { return $this->fieldConfigStorage->getQuery() ->condition('entity_type', $entity_type_id) ->condition('bundle', $bundle) ->condition('third_party_settings.field_fallback.field', NULL, 'IS NOT NULL') ->execute(); protected function getFieldConfigIdsWithFallback(string $entity_type_id, ?string $bundle): array { $query = $this->fieldConfigStorage->getQuery(); $query->condition('entity_type', $entity_type_id); if ($bundle !== NULL) { $query->condition('bundle', $bundle); } $query->condition('third_party_settings.field_fallback.field', NULL, 'IS NOT NULL'); $result = $query->execute(); return is_array($result) ? $result : []; } }
src/Form/FieldFallbackFieldConfigForm.php +43 −15 Original line number Diff line number Diff line Loading @@ -3,9 +3,12 @@ namespace Drupal\field_fallback\Form; use Drupal\Component\Utility\NestedArray; use Drupal\Core\Config\Entity\ThirdPartySettingsInterface; use Drupal\Core\DependencyInjection\DependencySerializationTrait; use Drupal\Core\Entity\EntityFieldManagerInterface; use Drupal\Core\Entity\EntityFormInterface; use Drupal\Core\Entity\EntityTypeManagerInterface; use Drupal\Core\Field\FieldDefinitionInterface; use Drupal\Core\Form\FormState; use Drupal\Core\Form\FormStateInterface; use Drupal\Core\Render\Element; Loading @@ -21,6 +24,13 @@ class FieldFallbackFieldConfigForm { use DependencySerializationTrait; use StringTranslationTrait; /** * The entity field manager service. * * @var \Drupal\Core\Entity\EntityFieldManagerInterface */ protected $entityFieldManager; /** * The field config storage. * Loading @@ -38,6 +48,8 @@ class FieldFallbackFieldConfigForm { /** * FieldConfigForm constructor. * * @param \Drupal\Core\Entity\EntityFieldManagerInterface $entity_field_manager * The entity field manager service. * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager * The entity type manager. * @param \Drupal\field_fallback\Plugin\FieldFallbackConverterManagerInterface $field_fallback_converter_manager Loading @@ -46,7 +58,8 @@ class FieldFallbackFieldConfigForm { * @throws \Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException * @throws \Drupal\Component\Plugin\Exception\PluginNotFoundException */ public function __construct(EntityTypeManagerInterface $entity_type_manager, FieldFallbackConverterManagerInterface $field_fallback_converter_manager) { public function __construct(EntityFieldManagerInterface $entity_field_manager, EntityTypeManagerInterface $entity_type_manager, FieldFallbackConverterManagerInterface $field_fallback_converter_manager) { $this->entityFieldManager = $entity_field_manager; $this->fieldConfigStorage = $entity_type_manager->getStorage('field_config'); $this->fieldFallbackConverterManager = $field_fallback_converter_manager; } Loading Loading @@ -103,11 +116,9 @@ class FieldFallbackFieldConfigForm { $field_value = isset($user_input['third_party_settings']['field_fallback']['field']) ? $user_input['third_party_settings']['field_fallback']['field'] : ($settings['field'] ?? NULL); if (!empty($field_value)) { $fallback_field = $this->fieldConfigStorage->load($field_config->getTargetEntityTypeId() . '.' . $field_config->getTargetBundle() . '.' . $field_value); if ($fallback_field instanceof FieldConfigInterface) { $converter_options = $this->buildConverterOptions($field_config, $fallback_field); $converter_options = $this->buildConverterOptions($field_config, $field_value); if (!empty($converter_options)) { $default_converter = $settings['converter'] ?? NULL; if ($default_converter === NULL) { $default_converter = count($converter_options) === 1 ? key($converter_options) : NULL; Loading Loading @@ -270,6 +281,13 @@ class FieldFallbackFieldConfigForm { } } $base_field_definitions = $this->entityFieldManager->getBaseFieldDefinitions($configured_field->getTargetEntityTypeId()); foreach ($base_field_definitions as $base_field_definition) { if (in_array($base_field_definition->getType(), $source_field_types, TRUE) && $this->isFieldConfigApplicable($configured_field, $base_field_definition)) { $options[$base_field_definition->getName()] = $base_field_definition->getLabel(); } } natcasesort($options); return $options; Loading @@ -280,13 +298,24 @@ class FieldFallbackFieldConfigForm { * * @param \Drupal\field\FieldConfigInterface $target_field * The target field. * @param \Drupal\field\FieldConfigInterface $source_field * The source field on which the value will be based. * @param string $source_field_name * The name of the source field on which the value will be based. * * @return array * An option array containing field configs. */ protected function buildConverterOptions(FieldConfigInterface $target_field, FieldConfigInterface $source_field): array { protected function buildConverterOptions(FieldConfigInterface $target_field, string $source_field_name): array { $source_field = $this->fieldConfigStorage->load($target_field->getTargetEntityTypeId() . '.' . $target_field->getTargetBundle() . '.' . $source_field_name); if (!$source_field instanceof FieldConfigInterface) { $base_fields = $this->entityFieldManager->getBaseFieldDefinitions($target_field->getTargetEntityTypeId()); $source_field = $base_fields[$source_field_name] ?? NULL; } if ($source_field === NULL) { return []; } $converter_definitions = $this->fieldFallbackConverterManager->getDefinitionsBySourceAndTarget( $source_field->getType(), $target_field->getType() Loading @@ -303,30 +332,29 @@ class FieldFallbackFieldConfigForm { /** * Checks if a field can be configured as a fallback field. * * @param \Drupal\field\FieldConfigInterface $configured_field * @param \Drupal\Core\Field\FieldDefinitionInterface $configured_field * The currently configured field. * @param \Drupal\field\FieldConfigInterface $fallback_field * @param \Drupal\Core\Field\FieldDefinitionInterface $fallback_field * The fallback field. * * @return bool * True, when the field can be configured as a fallback field, else FALSE. */ protected function isFieldConfigApplicable(FieldConfigInterface $configured_field, FieldConfigInterface $fallback_field): bool { protected function isFieldConfigApplicable(FieldDefinitionInterface $configured_field, FieldDefinitionInterface $fallback_field): bool { // Chaining multiple fields is not supported right now. if ($fallback_field->getThirdPartySetting('field_fallback', 'field') !== NULL) { if ($fallback_field instanceof ThirdPartySettingsInterface && $fallback_field->getThirdPartySetting('field_fallback', 'field') !== NULL) { return FALSE; } // You can't use the same field as a fallback field. if ($configured_field->id() === $fallback_field->id()) { if ($configured_field->getName() === $fallback_field->getName()) { return FALSE; } // When a field has the current field configured as a fallback, you can't // use that field as a fallback field, since that would result in an // infinite loop. $fallback_field_value = (string) $fallback_field->getThirdPartySetting('field_fallback', 'field'); if ($fallback_field_value === $configured_field->getName()) { if ($fallback_field instanceof ThirdPartySettingsInterface && (string) $fallback_field->getThirdPartySetting('field_fallback', 'field') === $configured_field->getName()) { return FALSE; } Loading
src/Plugin/FieldFallbackConverter/ParagraphsSummaryFieldFallbackConverter.php +4 −4 Original line number Diff line number Diff line Loading @@ -4,10 +4,10 @@ namespace Drupal\field_fallback\Plugin\FieldFallbackConverter; use Drupal\Core\Entity\EntityTypeManagerInterface; use Drupal\Core\Extension\ModuleHandlerInterface; use Drupal\Core\Field\FieldDefinitionInterface; use Drupal\Core\Field\FieldItemListInterface; use Drupal\Core\Form\FormStateInterface; use Drupal\Core\Plugin\ContainerFactoryPluginInterface; use Drupal\field\FieldConfigInterface; use Drupal\field_fallback\Plugin\FieldFallbackConverterBase; use Symfony\Component\DependencyInjection\ContainerInterface; Loading Loading @@ -75,7 +75,7 @@ class ParagraphsSummaryFieldFallbackConverter extends FieldFallbackConverterBase // formatter. 'value' => \Drupal::service('paragraphs_summary_token.text_summary_builder')->build($field, NULL, $configuration['format']), 'format' => $configuration['format'] ?? filter_default_format(), ] ], ]; } Loading Loading @@ -105,7 +105,7 @@ class ParagraphsSummaryFieldFallbackConverter extends FieldFallbackConverterBase $form['format'] = [ '#type' => 'select', '#title' => t('Text format'), '#title' => $this->t('Text format'), '#options' => $options, '#default_value' => $default_format, '#access' => count($options) >= 1, Loading Loading @@ -136,7 +136,7 @@ class ParagraphsSummaryFieldFallbackConverter extends FieldFallbackConverterBase /** * {@inheritdoc} */ public function isApplicable(FieldConfigInterface $target_field, FieldConfigInterface $source_field): bool { public function isApplicable(FieldDefinitionInterface $target_field, FieldDefinitionInterface $source_field): bool { return $source_field->getSetting('target_type') === 'paragraph' && $this->moduleHandler->moduleExists('paragraphs_summary_token'); } Loading