You are here

protected function EntityCreationTrait::processEntityCreation in JSON:API Resources 8

Process the resource request.

Parameters

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

\Drupal\jsonapi\JsonApiResource\JsonApiDocumentTopLevel $request_document: The deserialized request document.

Return value

\Drupal\jsonapi\ResourceResponse The response.

Throws

\Symfony\Component\HttpKernel\Exception\ConflictHttpException Thrown when the entity to be created already exists.

\Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException Thrown if the storage handler couldn't be loaded.

\Drupal\Core\Entity\EntityStorageException Thrown if the entity could not be saved.

2 calls to EntityCreationTrait::processEntityCreation()
AddComment::process in tests/modules/jsonapi_resources_test/src/Resource/AddComment.php
Process the resource request.
AddReminder::process in tests/modules/jsonapi_resources_test/src/Resource/AddReminder.php
Process the resource request.

File

src/Unstable/Entity/EntityCreationTrait.php, line 46

Class

EntityCreationTrait
Provides methods for handling POST requests that should create an entity.

Namespace

Drupal\jsonapi_resources\Unstable\Entity

Code

protected function processEntityCreation(Request $request, JsonApiDocumentTopLevel $request_document) {
  $data = $request_document
    ->getData();
  if ($data
    ->getCardinality() !== 1) {
    throw new UnprocessableEntityHttpException("The request document's primary data must not be an array.");
  }
  $entity = $this->resourceObjectToEntityMapper
    ->createEntityFromResourceObject($data
    ->getIterator()
    ->current());

  // Allow the class using this trait to modfiy the created entity before it
  // is saved.
  $this
    ->modifyCreatedEntity($entity, $request);
  static::validate($entity);

  // Return a 409 Conflict response in accordance with the JSON:API spec. See
  // http://jsonapi.org/format/#crud-creating-responses-409.
  try {

    // @todo: remove the assignment of the entity type manager to a variable when an "Aware" interface is added.

    /** @var \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager */

    /** @var \Drupal\Core\Entity\EntityStorageInterface $entity_storage */
    $entity_type_manager = $this->entityTypeManager;
    $entity_storage = $entity_type_manager
      ->getStorage($entity
      ->getEntityTypeId());
  } catch (PluginNotFoundException $e) {
    assert(FALSE, "It is impossible to encounter this exception. An entity can't be created if its entity type ID does not exist.");
  }
  if (!empty($entity_storage
    ->loadByProperties([
    'uuid' => $entity
      ->uuid(),
  ]))) {
    throw new ConflictHttpException('Conflict: Entity already exists.');
  }
  $entity
    ->save();
  $data = $this
    ->createIndividualDataFromEntity($entity);
  $resource_object = $data
    ->getIterator()
    ->current();
  assert($resource_object instanceof ResourceObject);
  $response = $this
    ->createJsonapiResponse($data, $request, 201);

  // According to JSON:API specification, when a new entity was created
  // we should send "Location" header to the frontend.
  if ($resource_object
    ->getResourceType()
    ->isLocatable()) {
    $url = $resource_object
      ->toUrl()
      ->setAbsolute()
      ->toString(TRUE);
    $response->headers
      ->set('Location', $url
      ->getGeneratedUrl());
    if ($response instanceof CacheableResponseInterface) {
      $response
        ->addCacheableDependency($url);
    }
  }
  return $response;
}