annotate core/modules/jsonapi/src/ParamConverter/EntityUuidConverter.php @ 5:12f9dff5fda9 tip

Update to Drupal core 8.7.1
author Chris Cannam
date Thu, 09 May 2019 15:34:47 +0100
parents
children
rev   line source
Chris@5 1 <?php
Chris@5 2
Chris@5 3 namespace Drupal\jsonapi\ParamConverter;
Chris@5 4
Chris@5 5 use Drupal\Core\Entity\EntityInterface;
Chris@5 6 use Drupal\Core\Language\LanguageInterface;
Chris@5 7 use Drupal\Core\Language\LanguageManagerInterface;
Chris@5 8 use Drupal\Core\ParamConverter\EntityConverter;
Chris@5 9 use Drupal\Core\TypedData\TranslatableInterface;
Chris@5 10 use Drupal\jsonapi\Routing\Routes;
Chris@5 11 use Symfony\Cmf\Component\Routing\RouteObjectInterface;
Chris@5 12 use Symfony\Component\HttpKernel\Exception\MethodNotAllowedHttpException;
Chris@5 13 use Symfony\Component\Routing\Route;
Chris@5 14
Chris@5 15 /**
Chris@5 16 * Parameter converter for upcasting entity UUIDs to full objects.
Chris@5 17 *
Chris@5 18 * @internal JSON:API maintains no PHP API since its API is the HTTP API. This
Chris@5 19 * class may change at any time and this will break any dependencies on it.
Chris@5 20 *
Chris@5 21 * @see https://www.drupal.org/project/jsonapi/issues/3032787
Chris@5 22 * @see jsonapi.api.php
Chris@5 23 *
Chris@5 24 * @see \Drupal\Core\ParamConverter\EntityConverter
Chris@5 25 *
Chris@5 26 * @todo Remove when https://www.drupal.org/node/2353611 lands.
Chris@5 27 */
Chris@5 28 class EntityUuidConverter extends EntityConverter {
Chris@5 29
Chris@5 30 /**
Chris@5 31 * The language manager.
Chris@5 32 *
Chris@5 33 * @var \Drupal\Core\Language\LanguageManagerInterface
Chris@5 34 */
Chris@5 35 protected $languageManager;
Chris@5 36
Chris@5 37 /**
Chris@5 38 * Injects the language manager.
Chris@5 39 *
Chris@5 40 * @param \Drupal\Core\Language\LanguageManagerInterface $language_manager
Chris@5 41 * The language manager to get the current content language.
Chris@5 42 */
Chris@5 43 public function setLanguageManager(LanguageManagerInterface $language_manager) {
Chris@5 44 $this->languageManager = $language_manager;
Chris@5 45 }
Chris@5 46
Chris@5 47 /**
Chris@5 48 * {@inheritdoc}
Chris@5 49 */
Chris@5 50 public function convert($value, $definition, $name, array $defaults) {
Chris@5 51 $entity_type_id = $this->getEntityTypeFromDefaults($definition, $name, $defaults);
Chris@5 52 // @see https://www.drupal.org/project/drupal/issues/2624770
Chris@5 53 $entity_type_manager = isset($this->entityTypeManager)
Chris@5 54 ? $this->entityTypeManager
Chris@5 55 : $this->entityManager;
Chris@5 56 $uuid_key = $entity_type_manager->getDefinition($entity_type_id)
Chris@5 57 ->getKey('uuid');
Chris@5 58 if ($storage = $entity_type_manager->getStorage($entity_type_id)) {
Chris@5 59 if (!$entities = $storage->loadByProperties([$uuid_key => $value])) {
Chris@5 60 return NULL;
Chris@5 61 }
Chris@5 62 $entity = reset($entities);
Chris@5 63 // If the entity type is translatable, ensure we return the proper
Chris@5 64 // translation object for the current context.
Chris@5 65 if ($entity instanceof EntityInterface && $entity instanceof TranslatableInterface) {
Chris@5 66 // @see https://www.drupal.org/project/drupal/issues/2624770
Chris@5 67 $entity_repository = isset($this->entityRepository) ? $this->entityRepository : $this->entityManager;
Chris@5 68 $entity = $entity_repository->getTranslationFromContext($entity, NULL, ['operation' => 'entity_upcast']);
Chris@5 69 // JSON:API always has only one method per route.
Chris@5 70 $method = $defaults[RouteObjectInterface::ROUTE_OBJECT]->getMethods()[0];
Chris@5 71 if (in_array($method, ['PATCH', 'DELETE'], TRUE)) {
Chris@5 72 $current_content_language = $this->languageManager->getCurrentLanguage(LanguageInterface::TYPE_CONTENT)->getId();
Chris@5 73 if ($method === 'DELETE' && (!$entity->isDefaultTranslation() || $entity->language()->getId() !== $current_content_language)) {
Chris@5 74 throw new MethodNotAllowedHttpException(['GET'], 'Deleting a resource object translation is not yet supported. See https://www.drupal.org/docs/8/modules/jsonapi/translations.');
Chris@5 75 }
Chris@5 76 if ($method === 'PATCH' && $entity->language()->getId() !== $current_content_language) {
Chris@5 77 $available_translations = implode(', ', array_keys($entity->getTranslationLanguages()));
Chris@5 78 throw new MethodNotAllowedHttpException(['GET'], sprintf('The requested translation of the resource object does not exist, instead modify one of the translations that do exist: %s.', $available_translations));
Chris@5 79 }
Chris@5 80 }
Chris@5 81 }
Chris@5 82 return $entity;
Chris@5 83 }
Chris@5 84 return NULL;
Chris@5 85 }
Chris@5 86
Chris@5 87 /**
Chris@5 88 * {@inheritdoc}
Chris@5 89 */
Chris@5 90 public function applies($definition, $name, Route $route) {
Chris@5 91 return (
Chris@5 92 (bool) Routes::getResourceTypeNameFromParameters($route->getDefaults()) &&
Chris@5 93 !empty($definition['type']) && strpos($definition['type'], 'entity') === 0
Chris@5 94 );
Chris@5 95 }
Chris@5 96
Chris@5 97 }