annotate core/modules/jsonapi/src/ParamConverter/EntityUuidConverter.php @ 19:fa3358dc1485 tip

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