src/IncludeResolver.php | 5 ++++- src/JsonApiResource/EntityCollection.php | 27 +++++++++++++++++++++++++++ 2 files changed, 31 insertions(+), 1 deletion(-) diff --git a/src/IncludeResolver.php b/src/IncludeResolver.php index 25ccfd1..5fc259a 100644 --- a/src/IncludeResolver.php +++ b/src/IncludeResolver.php @@ -58,7 +58,10 @@ class IncludeResolver { // Map a single entity into an EntityCollection. $entity_collection = $data instanceof EntityInterface ? new EntityCollection([$data], 1) : $data; $include_tree = static::toIncludeTree($base_resource_type, $include_parameter, $related_field); - return EntityCollection::deduplicate($this->resolveIncludeTree($include_tree, $entity_collection)); + $result = EntityCollection::deduplicate($this->resolveIncludeTree($include_tree, $entity_collection)); + return $related_field !== NULL && $data instanceof EntityInterface + ? EntityCollection::without($result, new EntityCollection($data->get($related_field)->referencedEntities())) + : $result; } /** diff --git a/src/JsonApiResource/EntityCollection.php b/src/JsonApiResource/EntityCollection.php index dd7504e..0c1b820 100644 --- a/src/JsonApiResource/EntityCollection.php +++ b/src/JsonApiResource/EntityCollection.php @@ -186,4 +186,31 @@ class EntityCollection implements \IteratorAggregate, \Countable { return new static(array_values($deduplicated)); } + /** + * Returns a new EntityCollection without the specified needles. + * + * @param \Drupal\jsonapi\JsonApiResource\EntityCollection $collection + * The EntityCollection to filter. + * @param \Drupal\jsonapi\JsonApiResource\EntityCollection $needles + * The needles to filter away. + * + * @return \Drupal\jsonapi\JsonApiResource\EntityCollection + * A new EntityCollection object, containing a subset of $collection. + */ + public static function without(EntityCollection $collection, EntityCollection $needles) { + if (empty($needles)) { + return $collection; + } + + $resource_identifier_needles = array_map([ResourceIdentifier::class, 'fromEntity'], $needles->toArray()); + $without = []; + foreach ($collection->toArray() as $resource) { + $resource_identifier = ResourceIdentifier::fromEntity($resource); + if (empty(array_uintersect([$resource_identifier], $resource_identifier_needles, [ResourceIdentifier::class, 'compare']))) { + $without[] = $resource; + } + } + return new static($without); + } + }