You are here

public function EntityResource::createIndividual in JSON:API 8

Same name and namespace in other branches
  1. 8.2 src/Controller/EntityResource.php \Drupal\jsonapi\Controller\EntityResource::createIndividual()

Creates an individual entity.

Parameters

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

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

Return value

\Drupal\jsonapi\ResourceResponse The response.

Throws

\Drupal\Core\Entity\EntityStorageException

\Drupal\jsonapi\Exception\EntityAccessDeniedHttpException

\Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException

File

src/Controller/EntityResource.php, line 209

Class

EntityResource
Process all entity requests.

Namespace

Drupal\jsonapi\Controller

Code

public function createIndividual(EntityInterface $entity, Request $request) {
  $entity_access = $entity
    ->access('create', NULL, TRUE);
  if (!$entity_access
    ->isAllowed()) {
    throw new EntityAccessDeniedHttpException(NULL, $entity_access, '/data', 'The current user is not allowed to POST the selected resource.');
  }

  // Only check 'edit' permissions for fields that were actually submitted by
  // the user. Field access makes no difference between 'create' and 'update',
  // so the 'edit' operation is used here.
  $document = Json::decode($request
    ->getContent());
  if (isset($document['data']['attributes'])) {
    $received_attributes = array_keys($document['data']['attributes']);
    foreach ($received_attributes as $field_name) {
      $internal_field_name = $this->resourceType
        ->getInternalName($field_name);
      try {
        $field_access = $entity
          ->get($internal_field_name)
          ->access('edit', NULL, TRUE);
        if (!$field_access
          ->isAllowed()) {
          throw new EntityAccessDeniedHttpException(NULL, $field_access, '/data/attributes/' . $field_name, sprintf('The current user is not allowed to POST the selected field (%s).', $field_name));
        }
      } catch (\InvalidArgumentException $e) {
        throw new UnprocessableEntityHttpException(sprintf('The attribute %s does not exist on the %s resource type.', $internal_field_name, $this->resourceType
          ->getTypeName()));
      }
    }
  }
  if (isset($document['data']['relationships'])) {
    $received_relationships = array_keys($document['data']['relationships']);
    foreach ($received_relationships as $field_name) {
      $internal_field_name = $this->resourceType
        ->getInternalName($field_name);
      $field_access = $entity
        ->get($internal_field_name)
        ->access('edit', NULL, TRUE);
      if (!$field_access
        ->isAllowed()) {
        throw new EntityAccessDeniedHttpException(NULL, $field_access, '/data/relationships/' . $field_name, sprintf('The current user is not allowed to POST the selected field (%s).', $field_name));
      }
    }
  }
  $this
    ->validate($entity);

  // Return a 409 Conflict response in accordance with the JSON API spec. See
  // http://jsonapi.org/format/#crud-creating-responses-409.
  if ($this
    ->entityExists($entity)) {
    throw new ConflictHttpException('Conflict: Entity already exists.');
  }
  $entity
    ->save();

  // Build response object.
  $response = $this
    ->buildWrappedResponse($entity, 201);

  // According to JSON API specification, when a new entity was created
  // we should send "Location" header to the frontend.
  $entity_url = $this->linkManager
    ->getEntityLink($entity
    ->uuid(), $this->resourceType, [], 'individual');
  if ($entity_url) {
    $response->headers
      ->set('Location', $entity_url);
  }

  // Return response object with updated headers info.
  return $response;
}