annotate core/modules/jsonapi/src/Controller/EntryPoint.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\Controller;
Chris@18 4
Chris@18 5 use Drupal\Core\Cache\CacheableMetadata;
Chris@18 6 use Drupal\Core\Controller\ControllerBase;
Chris@18 7 use Drupal\Core\Session\AccountInterface;
Chris@18 8 use Drupal\Core\Url;
Chris@18 9 use Drupal\jsonapi\JsonApiResource\JsonApiDocumentTopLevel;
Chris@18 10 use Drupal\jsonapi\JsonApiResource\LinkCollection;
Chris@18 11 use Drupal\jsonapi\JsonApiResource\NullIncludedData;
Chris@18 12 use Drupal\jsonapi\JsonApiResource\Link;
Chris@18 13 use Drupal\jsonapi\JsonApiResource\ResourceObjectData;
Chris@18 14 use Drupal\jsonapi\ResourceResponse;
Chris@18 15 use Drupal\jsonapi\ResourceType\ResourceType;
Chris@18 16 use Drupal\jsonapi\ResourceType\ResourceTypeRepositoryInterface;
Chris@18 17 use Drupal\user\Entity\User;
Chris@18 18 use Symfony\Component\DependencyInjection\ContainerInterface;
Chris@18 19 use Symfony\Component\Routing\Exception\RouteNotFoundException;
Chris@18 20
Chris@18 21 /**
Chris@18 22 * Controller for the API entry point.
Chris@18 23 *
Chris@18 24 * @internal JSON:API maintains no PHP API. The API is the HTTP API. This class
Chris@18 25 * may change at any time and could break any dependencies on it.
Chris@18 26 *
Chris@18 27 * @see https://www.drupal.org/project/jsonapi/issues/3032787
Chris@18 28 * @see jsonapi.api.php
Chris@18 29 */
Chris@18 30 class EntryPoint extends ControllerBase {
Chris@18 31
Chris@18 32 /**
Chris@18 33 * The JSON:API resource type repository.
Chris@18 34 *
Chris@18 35 * @var \Drupal\jsonapi\ResourceType\ResourceTypeRepositoryInterface
Chris@18 36 */
Chris@18 37 protected $resourceTypeRepository;
Chris@18 38
Chris@18 39 /**
Chris@18 40 * The account object.
Chris@18 41 *
Chris@18 42 * @var \Drupal\Core\Session\AccountInterface
Chris@18 43 */
Chris@18 44 protected $user;
Chris@18 45
Chris@18 46 /**
Chris@18 47 * EntryPoint constructor.
Chris@18 48 *
Chris@18 49 * @param \Drupal\jsonapi\ResourceType\ResourceTypeRepositoryInterface $resource_type_repository
Chris@18 50 * The resource type repository.
Chris@18 51 * @param \Drupal\Core\Session\AccountInterface $user
Chris@18 52 * The current user.
Chris@18 53 */
Chris@18 54 public function __construct(ResourceTypeRepositoryInterface $resource_type_repository, AccountInterface $user) {
Chris@18 55 $this->resourceTypeRepository = $resource_type_repository;
Chris@18 56 $this->user = $user;
Chris@18 57 }
Chris@18 58
Chris@18 59 /**
Chris@18 60 * {@inheritdoc}
Chris@18 61 */
Chris@18 62 public static function create(ContainerInterface $container) {
Chris@18 63 return new static(
Chris@18 64 $container->get('jsonapi.resource_type.repository'),
Chris@18 65 $container->get('current_user')
Chris@18 66 );
Chris@18 67 }
Chris@18 68
Chris@18 69 /**
Chris@18 70 * Controller to list all the resources.
Chris@18 71 *
Chris@18 72 * @return \Drupal\jsonapi\ResourceResponse
Chris@18 73 * The response object.
Chris@18 74 */
Chris@18 75 public function index() {
Chris@18 76 $cacheability = (new CacheableMetadata())
Chris@18 77 ->addCacheContexts(['user.roles:authenticated'])
Chris@18 78 ->addCacheTags(['jsonapi_resource_types']);
Chris@18 79
Chris@18 80 // Only build URLs for exposed resources.
Chris@18 81 $resources = array_filter($this->resourceTypeRepository->all(), function ($resource) {
Chris@18 82 return !$resource->isInternal();
Chris@18 83 });
Chris@18 84
Chris@18 85 $self_link = new Link(new CacheableMetadata(), Url::fromRoute('jsonapi.resource_list'), ['self']);
Chris@18 86 $urls = array_reduce($resources, function (LinkCollection $carry, ResourceType $resource_type) {
Chris@18 87 if ($resource_type->isLocatable() || $resource_type->isMutable()) {
Chris@18 88 $route_suffix = $resource_type->isLocatable() ? 'collection' : 'collection.post';
Chris@18 89 $url = Url::fromRoute(sprintf('jsonapi.%s.%s', $resource_type->getTypeName(), $route_suffix))->setAbsolute();
Chris@18 90 // @todo: implement an extension relation type to signal that this is a primary collection resource.
Chris@18 91 $link_relation_types = [];
Chris@18 92 return $carry->withLink($resource_type->getTypeName(), new Link(new CacheableMetadata(), $url, $link_relation_types));
Chris@18 93 }
Chris@18 94 return $carry;
Chris@18 95 }, new LinkCollection(['self' => $self_link]));
Chris@18 96
Chris@18 97 $meta = [];
Chris@18 98 if ($this->user->isAuthenticated()) {
Chris@18 99 $current_user_uuid = User::load($this->user->id())->uuid();
Chris@18 100 $meta['links']['me'] = ['meta' => ['id' => $current_user_uuid]];
Chris@18 101 $cacheability->addCacheContexts(['user']);
Chris@18 102 try {
Chris@18 103 $me_url = Url::fromRoute(
Chris@18 104 'jsonapi.user--user.individual',
Chris@18 105 ['entity' => $current_user_uuid]
Chris@18 106 )
Chris@18 107 ->setAbsolute()
Chris@18 108 ->toString(TRUE);
Chris@18 109 $meta['links']['me']['href'] = $me_url->getGeneratedUrl();
Chris@18 110 // The cacheability of the `me` URL is the cacheability of that URL
Chris@18 111 // itself and the currently authenticated user.
Chris@18 112 $cacheability = $cacheability->merge($me_url);
Chris@18 113 }
Chris@18 114 catch (RouteNotFoundException $e) {
Chris@18 115 // Do not add the link if the route is disabled or marked as internal.
Chris@18 116 }
Chris@18 117 }
Chris@18 118
Chris@18 119 $response = new ResourceResponse(new JsonApiDocumentTopLevel(new ResourceObjectData([]), new NullIncludedData(), $urls, $meta));
Chris@18 120 return $response->addCacheableDependency($cacheability);
Chris@18 121 }
Chris@18 122
Chris@18 123 }