src/Normalizer/NullRelationshipItem.php | 49 ---------------------- src/Normalizer/Relationship.php | 4 +- src/Normalizer/RelationshipItem.php | 32 ++++++++++---- src/Normalizer/RelationshipNormalizer.php | 16 +++---- .../Value/NullRelationshipItemNormalizerValue.php | 35 ---------------- tests/src/Functional/TermTest.php | 10 ++++- 6 files changed, 38 insertions(+), 108 deletions(-) diff --git a/src/Normalizer/NullRelationshipItem.php b/src/Normalizer/NullRelationshipItem.php deleted file mode 100644 index 697d287..0000000 --- a/src/Normalizer/NullRelationshipItem.php +++ /dev/null @@ -1,49 +0,0 @@ -parent = $parent; - } - - /** - * Gets the relationship value. - * - * @return null - * The value of this relationship item. - */ - public function getValue() { - return NULL; - } - - /** - * Gets the relationship object that contains this relationship item. - * - * @return \Drupal\jsonapi\Normalizer\Relationship - * The parent relationship of this item. - */ - public function getParent() { - return $this->parent; - } - -} diff --git a/src/Normalizer/Relationship.php b/src/Normalizer/Relationship.php index c6fba39..57b3661 100644 --- a/src/Normalizer/Relationship.php +++ b/src/Normalizer/Relationship.php @@ -91,9 +91,7 @@ class Relationship implements AccessibleInterface, CacheableDependencyInterface $this->items = []; foreach ($entities as $key => $entity) { - $this->items[] = $entity === NULL - ? new NullRelationshipItem($this) - : new RelationshipItem( + $this->items[] = new RelationshipItem( $resource_type_repository, $entity, $this, diff --git a/src/Normalizer/RelationshipItem.php b/src/Normalizer/RelationshipItem.php index 3a7a9b9..918f2e4 100644 --- a/src/Normalizer/RelationshipItem.php +++ b/src/Normalizer/RelationshipItem.php @@ -52,8 +52,8 @@ class RelationshipItem { * * @param \Drupal\jsonapi\ResourceType\ResourceTypeRepositoryInterface $resource_type_repository * The JSON API resource type repository. - * @param \Drupal\Core\Entity\EntityInterface $target_entity - * The entity this relationship points to. + * @param \Drupal\Core\Entity\EntityInterface|null $target_entity + * The entity this relationship points to, if any. * @param \Drupal\jsonapi\Normalizer\Relationship $parent * The parent of this item. * @param string $target_key @@ -61,11 +61,25 @@ class RelationshipItem { * @param array $metadata * The list of metadata associated with this relationship item value. */ - public function __construct(ResourceTypeRepositoryInterface $resource_type_repository, EntityInterface $target_entity, Relationship $parent, $target_key = 'target_id', array $metadata = []) { - $this->targetResourceType = $resource_type_repository->get( - $target_entity->getEntityTypeId(), - $target_entity->bundle() - ); + public function __construct(ResourceTypeRepositoryInterface $resource_type_repository, $target_entity, Relationship $parent, $target_key = 'target_id', array $metadata = []) { + assert($target_entity === NULL || $target_entity instanceof EntityInterface); + if ($target_entity === NULL) { + $host_entity = $parent->getHostEntity(); + $relatable_resource_types = $resource_type_repository->get( + $host_entity->getEntityTypeId(), + $host_entity->bundle() + )->getRelatableResourceTypes()[$parent->getPropertyName()]; + if (count($relatable_resource_types) !== 1) { + throw new \RuntimeException('Relationships to virtual resources are possible only if a single resource type is relatable.'); + } + $this->targetResourceType = $relatable_resource_types[0]; + } + else { + $this->targetResourceType = $resource_type_repository->get( + $target_entity->getEntityTypeId(), + $target_entity->bundle() + ); + } $this->targetKey = $target_key; $this->targetEntity = $target_entity; $this->parent = $parent; @@ -102,7 +116,9 @@ class RelationshipItem { */ public function getValue() { return [ - 'target_uuid' => $this->getTargetEntity()->uuid(), + 'target_uuid' => ($this->targetEntity === NULL) + ? 'virtual' + : $this->getTargetEntity()->uuid(), 'meta' => $this->metadata, ]; } diff --git a/src/Normalizer/RelationshipNormalizer.php b/src/Normalizer/RelationshipNormalizer.php index f2a90ee..8698c4e 100644 --- a/src/Normalizer/RelationshipNormalizer.php +++ b/src/Normalizer/RelationshipNormalizer.php @@ -4,7 +4,6 @@ namespace Drupal\jsonapi\Normalizer; use Drupal\Core\Access\AccessResult; use Drupal\Core\Entity\EntityInterface; -use Drupal\jsonapi\Normalizer\Value\NullRelationshipItemNormalizerValue; use Drupal\jsonapi\Normalizer\Value\RelationshipNormalizerValue; use Drupal\jsonapi\ResourceType\ResourceTypeRepositoryInterface; use Drupal\jsonapi\LinkManager\LinkManager; @@ -78,17 +77,12 @@ class RelationshipNormalizer extends NormalizerBase { /* @var \Drupal\jsonapi\Normalizer\Relationship $relationship */ $normalizer_items = []; foreach ($relationship->getItems() as $relationship_item) { - if ($relationship_item instanceof NullRelationshipItem) { - $normalizer_items[] = new NullRelationshipItemNormalizerValue(); - } - else { - // If the relationship points to a disabled resource type, do not add - // the normalized relationship item. - if ($relationship_item->getTargetResourceType()->isInternal()) { - continue; - } - $normalizer_items[] = $this->serializer->normalize($relationship_item, $format, $context); + // If the relationship points to a disabled resource type, do not add the + // normalized relationship item. + if (!$relationship_item->getTargetResourceType()) { + continue; } + $normalizer_items[] = $this->serializer->normalize($relationship_item, $format, $context); } $cardinality = $relationship->getCardinality(); $link_context = [ diff --git a/src/Normalizer/Value/NullRelationshipItemNormalizerValue.php b/src/Normalizer/Value/NullRelationshipItemNormalizerValue.php deleted file mode 100644 index 35f9693..0000000 --- a/src/Normalizer/Value/NullRelationshipItemNormalizerValue.php +++ /dev/null @@ -1,35 +0,0 @@ - [ - NULL, + [ + 'id' => 'virtual', + 'type' => 'taxonomy_term--camelids', + ], ], 'links' => [ 'related' => $self_url . '/parent', @@ -153,7 +156,10 @@ class TermTest extends ResourceTestBase { case [0, 2]: $expected_parent_normalization = [ 'data' => [ - NULL, + [ + 'id' => 'virtual', + 'type' => 'taxonomy_term--camelids', + ], [ 'id' => Term::load(2)->uuid(), 'type' => 'taxonomy_term--camelids',