public function EntityResource::removeFromRelationshipData in Drupal 8
Same name and namespace in other branches
- 9 core/modules/jsonapi/src/Controller/EntityResource.php \Drupal\jsonapi\Controller\EntityResource::removeFromRelationshipData()
- 10 core/modules/jsonapi/src/Controller/EntityResource.php \Drupal\jsonapi\Controller\EntityResource::removeFromRelationshipData()
Deletes the relationship of an entity.
Parameters
\Drupal\jsonapi\ResourceType\ResourceType $resource_type: The base JSON:API resource type for the request to be served.
\Drupal\Core\Entity\EntityInterface $entity: The requested entity.
string $related: The related field name.
\Symfony\Component\HttpFoundation\Request $request: The request object.
Return value
\Drupal\jsonapi\ResourceResponse The response.
Throws
\Symfony\Component\HttpKernel\Exception\BadRequestHttpException Thrown when not body was provided for the DELETE operation.
\Symfony\Component\HttpKernel\Exception\ConflictHttpException Thrown when deleting a "to-one" relationship.
\Drupal\Core\Entity\EntityStorageException Thrown when the underlying entity cannot be saved.
File
- core/
modules/ jsonapi/ src/ Controller/ EntityResource.php, line 746
Class
- EntityResource
- Process all entity requests.
Namespace
Drupal\jsonapi\ControllerCode
public function removeFromRelationshipData(ResourceType $resource_type, EntityInterface $entity, $related, Request $request) {
$resource_identifiers = $this
->deserialize($resource_type, $request, ResourceIdentifier::class, $related);
$internal_relationship_field_name = $resource_type
->getInternalName($related);
/* @var \Drupal\Core\Field\EntityReferenceFieldItemListInterface $field_list */
$field_list = $entity->{$internal_relationship_field_name};
$is_multiple = $field_list
->getFieldDefinition()
->getFieldStorageDefinition()
->isMultiple();
if (!$is_multiple) {
throw new ConflictHttpException(sprintf('You can only DELETE from to-many relationships. %s is a to-one relationship.', $related));
}
// Compute the list of current values and remove the ones in the payload.
$original_resource_identifiers = ResourceIdentifier::toResourceIdentifiersWithArityRequired($field_list);
$removed_resource_identifiers = array_uintersect($resource_identifiers, $original_resource_identifiers, [
ResourceIdentifier::class,
'compare',
]);
$deltas_to_be_removed = [];
foreach ($removed_resource_identifiers as $removed_resource_identifier) {
foreach ($original_resource_identifiers as $delta => $existing_resource_identifier) {
// Identify the field item deltas which should be removed.
if (ResourceIdentifier::isDuplicate($removed_resource_identifier, $existing_resource_identifier)) {
$deltas_to_be_removed[] = $delta;
}
}
}
// Field item deltas are reset when an item is removed. This removes
// items in descending order so that the deltas yet to be removed will
// continue to exist.
rsort($deltas_to_be_removed);
foreach ($deltas_to_be_removed as $delta) {
$field_list
->removeItem($delta);
}
// Save the entity and return the response object.
static::validate($entity);
$entity
->save();
return $this
->getRelationship($resource_type, $entity, $related, $request, 204);
}