Skip to content
Snippets Groups Projects
Commit 436f42da authored by Pablo López's avatar Pablo López
Browse files

Issue #3316144 by plopesc, froboy, owenbush, erikaagp: Field cardinality is...

Issue #3316144 by plopesc, froboy, owenbush, erikaagp: Field cardinality is not preserved on inheritance
parent 11698fa5
No related branches found
No related tags found
1 merge request!22Issue #3316144: Field cardinality is not preserved on inheritance
Pipeline #518565 passed
......@@ -10,11 +10,14 @@ use Drupal\Core\Entity\EntityTypeInterface;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Extension\ModuleHandlerInterface;
use Drupal\Core\Field\BaseFieldDefinition;
use Drupal\Core\Field\FieldDefinitionInterface;
use Drupal\Core\Field\FieldStorageDefinitionInterface;
use Drupal\Core\Hook\Attribute\Hook;
use Drupal\Core\Routing\RouteMatchInterface;
use Drupal\Core\Session\AccountInterface;
use Drupal\Core\StringTranslation\StringTranslationTrait;
use Drupal\field\Entity\FieldConfig;
use Drupal\field_inheritance\Entity\FieldInheritanceInterface;
use Drupal\field_inheritance\EntityReferenceFieldInheritanceFactory;
use Drupal\field_inheritance\FieldInheritanceFactory;
use Drupal\field_inheritance\FieldStorageDefinition;
......@@ -68,6 +71,25 @@ class FieldInheritanceHooks {
return NULL;
}
/**
* Implements hook_entity_base_field_info().
*/
#[Hook('entity_base_field_info')]
public function entityBaseFieldInfo(EntityTypeInterface $entity_type): array {
$fields = [];
$entity_types = $this->configFactory->get('field_inheritance.config')->get('included_entities');
if (in_array($entity_type->id(), $entity_types ?? [])) {
$fields['field_inheritance'] = BaseFieldDefinition::create('map')
->setLabel($this->t('Field Inheritance'))
->setDescription($this->t('A serialized array of order options.'))
->setRevisionable($entity_type->isRevisionable())
->setDisplayConfigurable('form', TRUE);
}
return $fields;
}
/**
* Implements hook_entity_bundle_field_info_alter().
*/
......@@ -119,23 +141,13 @@ class FieldInheritanceHooks {
}
// Grab the configuration of the source field.
$source_field = FieldConfig::loadByName($field->sourceEntityType(), $field->sourceEntityBundle(), $field->sourceField());
if (!empty($source_field)) {
$settings = array_merge($settings, $source_field->getSettings());
$type = $source_field->getType();
}
else {
// This may be a base_field.
$base_fields = $this->entityFieldManager->getBaseFieldDefinitions($field->sourceEntityType());
if (!empty($base_fields[$field->sourceField()])) {
$source_field = $base_fields[$field->sourceField()];
$settings = array_merge($settings, $source_field->getSettings());
$type = $source_field->getType();
}
else {
continue;
}
$source_field = $this->getSourceFieldDefinition($field);
if (!$source_field) {
continue;
}
$settings = array_merge($settings, $source_field->getSettings());
$type = $source_field->getType();
$cardinality = $this->getComputedFieldCardinality($field);
// Set the factory class used to inherit the data from the source.
$class = $field->plugin() === 'entity_reference_inheritance' ?
......@@ -152,6 +164,7 @@ class FieldInheritanceHooks {
->setName($field->idWithoutTypeAndBundle())
->setDescription(t('The inherited field: @field', ['@field' => $field->label()]))
->setComputed(TRUE)
->setCardinality($cardinality)
->setClass($class)
->setSettings($settings)
->setTargetEntityTypeId($field->destinationEntityType())
......@@ -172,22 +185,80 @@ class FieldInheritanceHooks {
}
/**
* Implements hook_entity_base_field_info().
* Gets the source field definition for a given field inheritance.
*
* @param \Drupal\field_inheritance\Entity\FieldInheritanceInterface $field_inheritance
* The field inheritance.
*
* @return \Drupal\Core\Field\FieldDefinitionInterface|null
* The source field definition if available. NULL otherwise.
*/
#[Hook('entity_base_field_info')]
public function entityBaseFieldInfo(EntityTypeInterface $entity_type): array {
$fields = [];
$entity_types = $this->configFactory->get('field_inheritance.config')->get('included_entities');
protected function getSourceFieldDefinition(FieldInheritanceInterface $field_inheritance): ?FieldDefinitionInterface {
if (!$field_inheritance->sourceField()) {
return NULL;
}
if (in_array($entity_type->id(), $entity_types ?? [])) {
$fields['field_inheritance'] = BaseFieldDefinition::create('map')
->setLabel($this->t('Field Inheritance'))
->setDescription($this->t('A serialized array of order options.'))
->setRevisionable($entity_type->isRevisionable())
->setDisplayConfigurable('form', TRUE);
$field = FieldConfig::loadByName($field_inheritance->sourceEntityType(), $field_inheritance->sourceEntityBundle(), $field_inheritance->sourceField());
if (!empty($field)) {
return $field;
}
return $fields;
$fields = $this->entityFieldManager->getBaseFieldDefinitions($field_inheritance->sourceEntityType());
return $fields[$field_inheritance->sourceField()] ?? NULL;
}
/**
* Gets the destination field definition for a given field inheritance.
*
* @param \Drupal\field_inheritance\Entity\FieldInheritanceInterface $field_inheritance
* The field inheritance.
*
* @return \Drupal\Core\Field\FieldDefinitionInterface|null
* The destination field definition if available. NULL otherwise.
*/
protected function getDestinationFieldDefinition(FieldInheritanceInterface $field_inheritance): ?FieldDefinitionInterface {
if (!$field_inheritance->destinationField()) {
return NULL;
}
$field = FieldConfig::loadByName($field_inheritance->destinationEntityType(), $field_inheritance->destinationEntityBundle(), $field_inheritance->destinationField());
if (!empty($field)) {
return $field;
}
$fields = $this->entityFieldManager->getBaseFieldDefinitions($field_inheritance->destinationEntityType());
return $fields[$field_inheritance->destinationField()] ?? NULL;
}
/**
* Gets the computed cardinality for a given field inheritance.
*
* @param \Drupal\field_inheritance\Entity\FieldInheritanceInterface $field_inheritance
* The field inheritance.
*
* @return int
* The computed cardinality.
*/
protected function getComputedFieldCardinality(FieldInheritanceInterface $field_inheritance): int {
$source_field = $this->getSourceFieldDefinition($field_inheritance);
$source_cardinality = $source_field?->getFieldStorageDefinition()->getCardinality() ?? 1;
$destination_field = $this->getDestinationFieldDefinition($field_inheritance);
$destination_cardinality = $destination_field?->getFieldStorageDefinition()->getCardinality() ?? 1;
$unlimited = in_array(FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED, [
$source_cardinality,
$destination_cardinality,
]);
return match ($field_inheritance->type()) {
'prepend', 'append' => $unlimited ?
FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED :
$source_cardinality + $destination_cardinality,
'fallback' => $unlimited ?
FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED :
max($source_cardinality, $destination_cardinality),
default => $source_cardinality,
};
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment