protected function DocumentExtractor::extractResourceObjectFromRequest in JSON:API Resources 8
Decodes and builds a resource object from a request body.
Parameters
\Symfony\Component\HttpFoundation\Request $request: The request.
Return value
\Drupal\jsonapi_resources\Unstable\Value\NewResourceObject A new resource object.
1 call to DocumentExtractor::extractResourceObjectFromRequest()
- DocumentExtractor::extractDocument in src/
Unstable/ DocumentExtractor.php - Extracts the JSON:API document from a request.
File
- src/
Unstable/ DocumentExtractor.php, line 114
Class
- DocumentExtractor
- Document extractor for requests.
Namespace
Drupal\jsonapi_resources\UnstableCode
protected function extractResourceObjectFromRequest(Request $request) {
$decoded = $this
->decodeRequestPayload($request);
$primary_data = $decoded['data'] ?? [];
if (isset($decoded['data'][0])) {
// The `data` member of a request document can only be an array if it is
// updating a relationship. If the objects in a data array are resource
// object, not resource identifiers, then it's because of a developer
// error.
if (!empty(array_intersect_key($decoded['data'][0], array_flip([
'attributes',
'relationships',
])))) {
throw new UnprocessableEntityHttpException("To add or update a resource object, the request document's primary data must not be an array.");
}
else {
throw new HttpException(501, 'The JSON:API Resources module does not yet support updating relationships.');
}
}
if (!isset($primary_data['type'])) {
throw new UnprocessableEntityHttpException("The document's primary data must have a `type` member.");
}
// Ensure that the client provided ID is a valid UUID.
if (isset($primary_data['id']) && !Uuid::isValid($primary_data['id'])) {
throw new UnprocessableEntityHttpException('IDs should be properly generated and formatted UUIDs as described in RFC 4122. See https://jsonapi.org/format/#crud-creating-client-ids.');
}
/** @var \Drupal\jsonapi\ResourceType\ResourceType[] $route_resource_types */
$route_resource_types = $request->attributes
->get('resource_types');
foreach ($route_resource_types as $route_resource_type) {
if ($primary_data['type'] === $route_resource_type
->getTypeName()) {
$resource_type = $route_resource_type;
}
}
if (!isset($resource_type)) {
$format = "The document's primary data contains a resource object with a type that cannot be created via this URL. Allowed resource types: `%s`";
$supported_resource_types = array_map(static function (ResourceType $resource_type) {
return $resource_type
->getTypeName();
}, $route_resource_types);
$message = sprintf($format, implode('`, `', $supported_resource_types));
throw new AccessDeniedHttpException($message);
}
// Ensure that no relationship fields are being set via the attributes
// resource object member.
if (isset($primary_data['attributes'])) {
$received_attribute_field_names = array_keys($primary_data['attributes']);
$relationship_field_names = array_keys($resource_type
->getRelatableResourceTypes());
if ($relationship_fields_sent_as_attributes = array_intersect($received_attribute_field_names, $relationship_field_names)) {
throw new UnprocessableEntityHttpException(sprintf('The following relationship fields were provided as attributes: [ %s ]', implode(', ', $relationship_fields_sent_as_attributes)));
}
}
if (isset($decoded['data']['relationships'])) {
$primary_data['relationships'] = $this
->handleRelationships($decoded['data']);
}
return NewResourceObject::createFromPrimaryData($resource_type, $primary_data);
}