comparison core/modules/jsonapi/src/Revisions/VersionNegotiator.php @ 18:af1871eacc83

Update to Drupal core 8.7.1
author Chris Cannam
date Thu, 09 May 2019 15:33:08 +0100
parents
children
comparison
equal deleted inserted replaced
17:129ea1e6d783 18:af1871eacc83
1 <?php
2
3 namespace Drupal\jsonapi\Revisions;
4
5 use Drupal\Core\Cache\CacheableMetadata;
6 use Drupal\Core\Entity\EntityInterface;
7 use Drupal\Core\Http\Exception\CacheableBadRequestHttpException;
8 use Drupal\Core\Http\Exception\CacheableNotFoundHttpException;
9
10 /**
11 * Provides a version negotiator manager.
12 *
13 * @internal JSON:API maintains no PHP API since its API is the HTTP API. This
14 * class may change at any time and this will break any dependencies on it.
15 *
16 * @see https://www.drupal.org/project/jsonapi/issues/3032787
17 * @see jsonapi.api.php
18 *
19 * @see \Drupal\jsonapi\Revisions\VersionNegotiatorInterface
20 */
21 class VersionNegotiator {
22
23 /**
24 * The separator between the version negotiator name and the version argument.
25 *
26 * @var string
27 */
28 const SEPARATOR = ':';
29
30 /**
31 * An array of named version negotiators.
32 *
33 * @var \Drupal\jsonapi\Revisions\VersionNegotiatorInterface[]
34 */
35 protected $negotiators = [];
36
37 /**
38 * Adds a version negotiator.
39 *
40 * @param \Drupal\jsonapi\Revisions\VersionNegotiatorInterface $version_negotiator
41 * The version negotiator.
42 * @param string $negotiator_name
43 * The name of the negotiation strategy used by the version negotiator.
44 */
45 public function addVersionNegotiator(VersionNegotiatorInterface $version_negotiator, $negotiator_name) {
46 assert(strpos(get_class($version_negotiator), 'Drupal\\jsonapi\\') === 0, 'Version negotiators are not a public API.');
47 $this->negotiators[$negotiator_name] = $version_negotiator;
48 }
49
50 /**
51 * Gets a negotiated entity revision.
52 *
53 * @param \Drupal\Core\Entity\EntityInterface $entity
54 * The entity.
55 * @param string $resource_version_identifier
56 * A value used to derive a revision for the given entity.
57 *
58 * @return \Drupal\Core\Entity\EntityInterface
59 * The loaded revision.
60 *
61 * @throws \Drupal\Core\Http\Exception\CacheableNotFoundHttpException
62 * When the revision does not exist.
63 * @throws \Drupal\Core\Http\Exception\CacheableBadRequestHttpException
64 * When the revision ID cannot be negotiated.
65 */
66 public function getRevision(EntityInterface $entity, $resource_version_identifier) {
67 try {
68 list($version_negotiator_name, $version_argument) = explode(VersionNegotiator::SEPARATOR, $resource_version_identifier, 2);
69 if (!isset($this->negotiators[$version_negotiator_name])) {
70 static::throwBadRequestHttpException($resource_version_identifier);
71 }
72 return $this->negotiators[$version_negotiator_name]->getRevision($entity, $version_argument);
73 }
74 catch (VersionNotFoundException $exception) {
75 static::throwNotFoundHttpException($entity, $resource_version_identifier);
76 }
77 catch (InvalidVersionIdentifierException $exception) {
78 static::throwBadRequestHttpException($resource_version_identifier);
79 }
80 }
81
82 /**
83 * Throws a cacheable error exception.
84 *
85 * @param \Drupal\Core\Entity\EntityInterface $entity
86 * The entity for which a revision was requested.
87 * @param string $resource_version_identifier
88 * The user input for the revision negotiation.
89 *
90 * @throws \Drupal\Core\Http\Exception\CacheableNotFoundHttpException
91 */
92 protected static function throwNotFoundHttpException(EntityInterface $entity, $resource_version_identifier) {
93 $cacheability = CacheableMetadata::createFromObject($entity)->addCacheContexts(['url.path', 'url.query_args:' . ResourceVersionRouteEnhancer::RESOURCE_VERSION_QUERY_PARAMETER]);
94 $reason = sprintf('The requested version, identified by `%s`, could not be found.', $resource_version_identifier);
95 throw new CacheableNotFoundHttpException($cacheability, $reason);
96 }
97
98 /**
99 * Throws a cacheable error exception.
100 *
101 * @param string $resource_version_identifier
102 * The user input for the revision negotiation.
103 *
104 * @throws \Drupal\Core\Http\Exception\CacheableBadRequestHttpException
105 */
106 protected static function throwBadRequestHttpException($resource_version_identifier) {
107 $cacheability = (new CacheableMetadata())->addCacheContexts(['url.query_args:' . ResourceVersionRouteEnhancer::RESOURCE_VERSION_QUERY_PARAMETER]);
108 $message = sprintf('An invalid resource version identifier, `%s`, was provided.', $resource_version_identifier);
109 throw new CacheableBadRequestHttpException($cacheability, $message);
110 }
111
112 }