Chris@18
|
1 <?php
|
Chris@18
|
2
|
Chris@18
|
3 namespace Drupal\jsonapi\Entity;
|
Chris@18
|
4
|
Chris@18
|
5 use Drupal\Core\Entity\EntityInterface;
|
Chris@18
|
6 use Drupal\Core\Entity\FieldableEntityInterface;
|
Chris@18
|
7 use Drupal\jsonapi\Exception\UnprocessableHttpEntityException;
|
Chris@18
|
8
|
Chris@18
|
9 /**
|
Chris@18
|
10 * Provides a method to validate an entity.
|
Chris@18
|
11 *
|
Chris@18
|
12 * @internal JSON:API maintains no PHP API. The API is the HTTP API. This class
|
Chris@18
|
13 * may change at any time and could break any dependencies on it.
|
Chris@18
|
14 *
|
Chris@18
|
15 * @see https://www.drupal.org/project/jsonapi/issues/3032787
|
Chris@18
|
16 * @see jsonapi.api.php
|
Chris@18
|
17 */
|
Chris@18
|
18 trait EntityValidationTrait {
|
Chris@18
|
19
|
Chris@18
|
20 /**
|
Chris@18
|
21 * Verifies that an entity does not violate any validation constraints.
|
Chris@18
|
22 *
|
Chris@18
|
23 * @param \Drupal\Core\Entity\EntityInterface $entity
|
Chris@18
|
24 * The entity object.
|
Chris@18
|
25 * @param string[] $field_names
|
Chris@18
|
26 * (optional) An array of field names. If specified, filters the violations
|
Chris@18
|
27 * list to include only this set of fields. Defaults to NULL,
|
Chris@18
|
28 * which means that all violations will be reported.
|
Chris@18
|
29 *
|
Chris@18
|
30 * @throws \Drupal\jsonapi\Exception\UnprocessableHttpEntityException
|
Chris@18
|
31 * Thrown when violations remain after filtering.
|
Chris@18
|
32 *
|
Chris@18
|
33 * @see \Drupal\rest\Plugin\rest\resource\EntityResourceValidationTrait::validate()
|
Chris@18
|
34 */
|
Chris@18
|
35 protected static function validate(EntityInterface $entity, array $field_names = NULL) {
|
Chris@18
|
36 if (!$entity instanceof FieldableEntityInterface) {
|
Chris@18
|
37 return;
|
Chris@18
|
38 }
|
Chris@18
|
39
|
Chris@18
|
40 $violations = $entity->validate();
|
Chris@18
|
41
|
Chris@18
|
42 // Remove violations of inaccessible fields as they cannot stem from our
|
Chris@18
|
43 // changes.
|
Chris@18
|
44 $violations->filterByFieldAccess();
|
Chris@18
|
45
|
Chris@18
|
46 // Filter violations based on the given fields.
|
Chris@18
|
47 if ($field_names !== NULL) {
|
Chris@18
|
48 $violations->filterByFields(
|
Chris@18
|
49 array_diff(array_keys($entity->getFieldDefinitions()), $field_names)
|
Chris@18
|
50 );
|
Chris@18
|
51 }
|
Chris@18
|
52
|
Chris@18
|
53 if (count($violations) > 0) {
|
Chris@18
|
54 // Instead of returning a generic 400 response we use the more specific
|
Chris@18
|
55 // 422 Unprocessable Entity code from RFC 4918. That way clients can
|
Chris@18
|
56 // distinguish between general syntax errors in bad serializations (code
|
Chris@18
|
57 // 400) and semantic errors in well-formed requests (code 422).
|
Chris@18
|
58 // @see \Drupal\jsonapi\Normalizer\UnprocessableHttpEntityExceptionNormalizer
|
Chris@18
|
59 $exception = new UnprocessableHttpEntityException();
|
Chris@18
|
60 $exception->setViolations($violations);
|
Chris@18
|
61 throw $exception;
|
Chris@18
|
62 }
|
Chris@18
|
63 }
|
Chris@18
|
64
|
Chris@18
|
65 }
|