You are here

public function EntityResource::deleteRelationship in JSON:API 8

Deletes the relationship of an entity.

Parameters

\Drupal\Core\Entity\EntityInterface $entity: The requested entity.

string $related_field: The related field name.

mixed $parsed_field_list: The entity reference field list of items to add, or a response object in case of error.

\Symfony\Component\HttpFoundation\Request $request: The request object.

Return value

\Drupal\jsonapi\ResourceResponse The response.

File

src/Controller/EntityResource.php, line 754

Class

EntityResource
Process all entity requests.

Namespace

Drupal\jsonapi\Controller

Code

public function deleteRelationship(EntityInterface $entity, $related_field, $parsed_field_list, Request $request = NULL) {
  if ($parsed_field_list instanceof Response) {

    // This usually means that there was an error, so there is no point on
    // processing further.
    return $parsed_field_list;
  }
  if ($parsed_field_list instanceof Request) {

    // This usually means that there was not body provided.
    throw new BadRequestHttpException(sprintf('You need to provide a body for DELETE operations on a relationship (%s).', $related_field));
  }

  /* @var \Drupal\Core\Field\EntityReferenceFieldItemListInterface $parsed_field_list */
  $this
    ->relationshipAccess($entity, 'update', $related_field);
  $field_name = $parsed_field_list
    ->getName();
  $field_access = $parsed_field_list
    ->access('edit', NULL, TRUE);
  if (!$field_access
    ->isAllowed()) {
    throw new EntityAccessDeniedHttpException($entity, $field_access, '/data/relationships/' . $field_name, sprintf('The current user is not allowed to PATCH the selected field (%s).', $field_name));
  }

  /* @var \Drupal\Core\Field\EntityReferenceFieldItemListInterface $field_list */
  $field_list = $entity->{$related_field};
  $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_field));
  }

  // Compute the list of current values and remove the ones in the payload.
  $current_values = $field_list
    ->getValue();
  $deleted_values = $parsed_field_list
    ->getValue();
  $keep_values = array_udiff($current_values, $deleted_values, function ($first, $second) {
    return reset($first) - reset($second);
  });

  // Replace the existing field with one containing the relationships to keep.
  $entity->{$related_field} = $this->pluginManager
    ->createFieldItemList($entity, $related_field, $keep_values);

  // Save the entity and return the response object.
  $this
    ->validate($entity);
  $entity
    ->save();
  return $this
    ->getRelationship($entity, $related_field, $request, 204);
}