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