Mercurial > hg > isophonics-drupal-site
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 } |