Issue #2336247 by larowlan, andythorne: Make Relation and Type domain configurable based on context
parent
74db053104
commit
20add38187
|
@ -76,7 +76,7 @@ class ContentEntityNormalizer extends NormalizerBase {
|
|||
'href' => $this->getEntityUri($entity),
|
||||
),
|
||||
'type' => array(
|
||||
'href' => $this->linkManager->getTypeUri($entity->getEntityTypeId(), $entity->bundle()),
|
||||
'href' => $this->linkManager->getTypeUri($entity->getEntityTypeId(), $entity->bundle(), $context),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
@ -132,7 +132,7 @@ class ContentEntityNormalizer extends NormalizerBase {
|
|||
}
|
||||
|
||||
// Create the entity.
|
||||
$typed_data_ids = $this->getTypedDataIds($data['_links']['type']);
|
||||
$typed_data_ids = $this->getTypedDataIds($data['_links']['type'], $context);
|
||||
$entity_type = $this->entityManager->getDefinition($typed_data_ids['entity_type']);
|
||||
$langcode_key = $entity_type->getKey('langcode');
|
||||
$values = array();
|
||||
|
@ -210,13 +210,14 @@ class ContentEntityNormalizer extends NormalizerBase {
|
|||
*
|
||||
* @param array $types
|
||||
* The type array(s) (value of the 'type' attribute of the incoming data).
|
||||
* @param array $context
|
||||
* Context from the normalizer/serializer operation.
|
||||
*
|
||||
* @return array
|
||||
* The typed data IDs.
|
||||
*
|
||||
* @throws \Symfony\Component\Serializer\Exception\UnexpectedValueException
|
||||
*/
|
||||
protected function getTypedDataIds($types) {
|
||||
protected function getTypedDataIds($types, $context = array()) {
|
||||
// The 'type' can potentially contain an array of type objects. By default,
|
||||
// Drupal only uses a single type in serializing, but allows for multiple
|
||||
// types when deserializing.
|
||||
|
@ -231,7 +232,7 @@ class ContentEntityNormalizer extends NormalizerBase {
|
|||
$type_uri = $type['href'];
|
||||
// Check whether the URI corresponds to a known type on this site. Break
|
||||
// once one does.
|
||||
if ($typed_data_ids = $this->linkManager->getTypeInternalIds($type['href'])) {
|
||||
if ($typed_data_ids = $this->linkManager->getTypeInternalIds($type['href'], $context)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -85,7 +85,7 @@ class EntityReferenceItemNormalizer extends FieldItemNormalizer implements UuidR
|
|||
// objects.
|
||||
$field_name = $field_item->getParent()->getName();
|
||||
$entity = $field_item->getEntity();
|
||||
$field_uri = $this->linkManager->getRelationUri($entity->getEntityTypeId(), $entity->bundle(), $field_name);
|
||||
$field_uri = $this->linkManager->getRelationUri($entity->getEntityTypeId(), $entity->bundle(), $field_name, $context);
|
||||
return array(
|
||||
'_links' => array(
|
||||
$field_uri => array($link),
|
||||
|
|
|
@ -39,8 +39,7 @@ class FileNormalizeTest extends NormalizerTestBase {
|
|||
$this->installEntitySchema('file');
|
||||
|
||||
$entity_manager = \Drupal::entityManager();
|
||||
$url_assembler = \Drupal::service('unrouted_url_assembler');
|
||||
$link_manager = new LinkManager(new TypeLinkManager(new MemoryBackend('default'), $url_assembler), new RelationLinkManager(new MemoryBackend('default'), $entity_manager, $url_assembler));
|
||||
$link_manager = new LinkManager(new TypeLinkManager(new MemoryBackend('default'), \Drupal::moduleHandler(), \Drupal::service('config.factory'), \Drupal::service('request_stack')), new RelationLinkManager(new MemoryBackend('default'), $entity_manager, \Drupal::moduleHandler(), \Drupal::service('config.factory'), \Drupal::service('request_stack')));
|
||||
|
||||
// Set up the mock serializer.
|
||||
$normalizers = array(
|
||||
|
|
|
@ -83,6 +83,7 @@ abstract class NormalizerTestBase extends KernelTestBase {
|
|||
$class = get_parent_class($class);
|
||||
}
|
||||
$this->installConfig(array('field', 'language'));
|
||||
\Drupal::service('router.builder')->rebuild();
|
||||
|
||||
// Add German as a language.
|
||||
ConfigurableLanguage::create(array(
|
||||
|
@ -134,8 +135,7 @@ abstract class NormalizerTestBase extends KernelTestBase {
|
|||
))->save();
|
||||
|
||||
$entity_manager = \Drupal::entityManager();
|
||||
$url_assembler = \Drupal::service('unrouted_url_assembler');
|
||||
$link_manager = new LinkManager(new TypeLinkManager(new MemoryBackend('default'), $url_assembler), new RelationLinkManager(new MemoryBackend('default'), $entity_manager, $url_assembler));
|
||||
$link_manager = new LinkManager(new TypeLinkManager(new MemoryBackend('default'), \Drupal::moduleHandler(), \Drupal::service('config.factory'), \Drupal::service('request_stack')), new RelationLinkManager(new MemoryBackend('default'), $entity_manager, \Drupal::moduleHandler(), \Drupal::service('config.factory'), \Drupal::service('request_stack')));
|
||||
|
||||
$chain_resolver = new ChainEntityResolver(array(new UuidResolver($entity_manager), new TargetIdResolver()));
|
||||
|
||||
|
|
|
@ -44,3 +44,7 @@ resources:
|
|||
#
|
||||
# The full documentation is located at
|
||||
# https://drupal.org/documentation/modules/rest
|
||||
|
||||
# Set the domain for REST type and relation links.
|
||||
# If left blank, the site's domain will be used
|
||||
link_domain: ~
|
||||
|
|
|
@ -10,6 +10,9 @@ rest.settings:
|
|||
sequence:
|
||||
type: rest_resource
|
||||
label: 'Resource'
|
||||
link_domain:
|
||||
type: string
|
||||
label: 'Domain of the relation'
|
||||
|
||||
rest_resource:
|
||||
type: mapping
|
||||
|
|
|
@ -28,6 +28,53 @@ function hook_rest_resource_alter(&$definitions) {
|
|||
unset($definitions['entity:view']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Alter the REST type URI.
|
||||
*
|
||||
* Modules may wish to alter the type URI generated for a resource based on the
|
||||
* context of the serializer/normalizer operation.
|
||||
*
|
||||
* @param string $uri
|
||||
* The URI to alter.
|
||||
* @param array $context
|
||||
* The context from the serializer/normalizer operation.
|
||||
*
|
||||
* @see \Symfony\Component\Serializer\SerializerInterface::serialize()
|
||||
* @see \Symfony\Component\Serializer\SerializerInterface::deserialize()
|
||||
* @see \Symfony\Component\Serializer\NormalizerInterface::normalize()
|
||||
* @see \Symfony\Component\Serializer\DenormalizerInterface::denormalize()
|
||||
*/
|
||||
function hook_rest_type_uri_alter(&$uri, $context = array()) {
|
||||
if ($context['mymodule'] == TRUE) {
|
||||
$base = \Drupal::config('rest.settings')->get('link_domain');
|
||||
$uri = str_replace($base, 'http://mymodule.domain', $uri);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Alter the REST relation URI.
|
||||
*
|
||||
* Modules may wish to alter the relation URI generated for a resource based on
|
||||
* the context of the serializer/normalizer operation.
|
||||
*
|
||||
* @param string $uri
|
||||
* The URI to alter.
|
||||
* @param array $context
|
||||
* The context from the serializer/normalizer operation.
|
||||
*
|
||||
* @see \Symfony\Component\Serializer\SerializerInterface::serialize()
|
||||
* @see \Symfony\Component\Serializer\SerializerInterface::deserialize()
|
||||
* @see \Symfony\Component\Serializer\NormalizerInterface::normalize()
|
||||
* @see \Symfony\Component\Serializer\DenormalizerInterface::denormalize()
|
||||
*/
|
||||
function hook_rest_relation_uri_alter(&$uri, $context = array()) {
|
||||
if ($context['mymodule'] == TRUE) {
|
||||
$base = \Drupal::config('rest.settings')->get('link_domain');
|
||||
$uri = str_replace($base, 'http://mymodule.domain', $uri);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @} End of "addtogroup hooks".
|
||||
*/
|
||||
|
|
|
@ -19,10 +19,10 @@ services:
|
|||
arguments: ['@rest.link_manager.type', '@rest.link_manager.relation']
|
||||
rest.link_manager.type:
|
||||
class: Drupal\rest\LinkManager\TypeLinkManager
|
||||
arguments: ['@cache.default', '@unrouted_url_assembler']
|
||||
arguments: ['@cache.default', '@module_handler', '@config.factory', '@request_stack']
|
||||
rest.link_manager.relation:
|
||||
class: Drupal\rest\LinkManager\RelationLinkManager
|
||||
arguments: ['@cache.default', '@entity.manager', '@unrouted_url_assembler']
|
||||
arguments: ['@cache.default', '@entity.manager', '@module_handler', '@config.factory', '@request_stack']
|
||||
rest.resource_routes:
|
||||
class: Drupal\rest\Routing\ResourceRoutes
|
||||
arguments: ['@plugin.manager.rest', '@config.factory', '@logger.channel.rest']
|
||||
|
|
|
@ -0,0 +1,25 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Contains \Drupal\rest\LinkManager\ConfigurableLinkManagerInterface.
|
||||
*/
|
||||
|
||||
namespace Drupal\rest\LinkManager;
|
||||
|
||||
/**
|
||||
* Defines an interface for a link manager with a configurable domain.
|
||||
*/
|
||||
interface ConfigurableLinkManagerInterface {
|
||||
|
||||
/**
|
||||
* Sets the link domain used in constructing link URIs.
|
||||
*
|
||||
* @param string $domain
|
||||
* The link domain to use for constructing link URIs.
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setLinkDomain($domain);
|
||||
|
||||
}
|
|
@ -38,22 +38,22 @@ class LinkManager implements LinkManagerInterface {
|
|||
/**
|
||||
* Implements \Drupal\rest\LinkManager\TypeLinkManagerInterface::getTypeUri().
|
||||
*/
|
||||
public function getTypeUri($entity_type, $bundle) {
|
||||
return $this->typeLinkManager->getTypeUri($entity_type, $bundle);
|
||||
public function getTypeUri($entity_type, $bundle, $context = array()) {
|
||||
return $this->typeLinkManager->getTypeUri($entity_type, $bundle, $context);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements \Drupal\rest\LinkManager\TypeLinkManagerInterface::getTypeInternalIds().
|
||||
*/
|
||||
public function getTypeInternalIds($type_uri) {
|
||||
return $this->typeLinkManager->getTypeInternalIds($type_uri);
|
||||
public function getTypeInternalIds($type_uri, $context = array()) {
|
||||
return $this->typeLinkManager->getTypeInternalIds($type_uri, $context);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements \Drupal\rest\LinkManager\RelationLinkManagerInterface::getRelationUri().
|
||||
*/
|
||||
public function getRelationUri($entity_type, $bundle, $field_name) {
|
||||
return $this->relationLinkManager->getRelationUri($entity_type, $bundle, $field_name);
|
||||
public function getRelationUri($entity_type, $bundle, $field_name, $context = array()) {
|
||||
return $this->relationLinkManager->getRelationUri($entity_type, $bundle, $field_name, $context);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -63,4 +63,13 @@ class LinkManager implements LinkManagerInterface {
|
|||
return $this->relationLinkManager->getRelationInternalIds($relation_uri);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function setLinkDomain($domain) {
|
||||
$this->relationLinkManager->setLinkDomain($domain);
|
||||
$this->typeLinkManager->setLinkDomain($domain);
|
||||
return $this;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,64 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Contains \Drupal\rest\LinkManager\LinkManagerBase.
|
||||
*/
|
||||
|
||||
namespace Drupal\rest\LinkManager;
|
||||
use Drupal\Core\Url;
|
||||
|
||||
/**
|
||||
* Defines an abstract base-class for REST link manager objects.
|
||||
*/
|
||||
abstract class LinkManagerBase {
|
||||
|
||||
/**
|
||||
* Link domain used for type links URIs.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $linkDomain;
|
||||
|
||||
/**
|
||||
* Config factory service.
|
||||
*
|
||||
* @var \Drupal\Core\Config\ConfigFactoryInterface
|
||||
*/
|
||||
protected $configFactory;
|
||||
|
||||
/**
|
||||
* The request stack.
|
||||
*
|
||||
* @var \Symfony\Component\HttpFoundation\RequestStack
|
||||
*/
|
||||
protected $requestStack;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function setLinkDomain($domain) {
|
||||
$this->linkDomain = rtrim($domain, '/');
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the link domain.
|
||||
*
|
||||
* @return string
|
||||
* The link domain.
|
||||
*/
|
||||
protected function getLinkDomain() {
|
||||
if (empty($this->linkDomain)) {
|
||||
if ($domain = $this->configFactory->get('rest.settings')->get('link_domain')) {
|
||||
$this->linkDomain = rtrim($domain, '/');
|
||||
}
|
||||
else {
|
||||
$request = $this->requestStack->getCurrentRequest();
|
||||
$this->linkDomain = $request->getSchemeAndHttpHost() . $request->getBasePath();
|
||||
}
|
||||
}
|
||||
return $this->linkDomain;
|
||||
}
|
||||
|
||||
}
|
|
@ -9,11 +9,13 @@ namespace Drupal\rest\LinkManager;
|
|||
|
||||
use Drupal\Core\Cache\Cache;
|
||||
use Drupal\Core\Cache\CacheBackendInterface;
|
||||
use Drupal\Core\Config\ConfigFactoryInterface;
|
||||
use Drupal\Core\Entity\ContentEntityTypeInterface;
|
||||
use Drupal\Core\Entity\EntityManagerInterface;
|
||||
use Drupal\Core\Utility\UnroutedUrlAssemblerInterface;
|
||||
use Drupal\Core\Extension\ModuleHandlerInterface;
|
||||
use Symfony\Component\HttpFoundation\RequestStack;
|
||||
|
||||
class RelationLinkManager implements RelationLinkManagerInterface {
|
||||
class RelationLinkManager extends LinkManagerBase implements RelationLinkManagerInterface {
|
||||
|
||||
/**
|
||||
* @var \Drupal\Core\Cache\CacheBackendInterface;
|
||||
|
@ -28,11 +30,11 @@ class RelationLinkManager implements RelationLinkManagerInterface {
|
|||
protected $entityManager;
|
||||
|
||||
/**
|
||||
* The unrouted URL assembler.
|
||||
* Module handler service.
|
||||
*
|
||||
* @var \Drupal\Core\Utility\UnroutedUrlAssemblerInterface
|
||||
* @var \Drupal\Core\Extension\ModuleHandlerInterface
|
||||
*/
|
||||
protected $urlAssembler;
|
||||
protected $moduleHandler;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
|
@ -41,27 +43,35 @@ class RelationLinkManager implements RelationLinkManagerInterface {
|
|||
* The cache of relation URIs and their associated Typed Data IDs.
|
||||
* @param \Drupal\Core\Entity\EntityManagerInterface $entity_manager
|
||||
* The entity manager.
|
||||
* @param \Drupal\Core\Utility\UnroutedUrlAssemblerInterface $url_assembler
|
||||
* The unrouted URL assembler.
|
||||
* @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler
|
||||
* The module handler service.
|
||||
* @param \Drupal\Core\Config\ConfigFactoryInterface $config_factory
|
||||
* The config factory service.
|
||||
* @param \Symfony\Component\HttpFoundation\RequestStack $request_stack
|
||||
* The request stack.
|
||||
*/
|
||||
public function __construct(CacheBackendInterface $cache, EntityManagerInterface $entity_manager, UnroutedUrlAssemblerInterface $url_assembler) {
|
||||
public function __construct(CacheBackendInterface $cache, EntityManagerInterface $entity_manager, ModuleHandlerInterface $module_handler, ConfigFactoryInterface $config_factory, RequestStack $request_stack) {
|
||||
$this->cache = $cache;
|
||||
$this->entityManager = $entity_manager;
|
||||
$this->urlAssembler = $url_assembler;
|
||||
$this->configFactory = $config_factory;
|
||||
$this->moduleHandler = $module_handler;
|
||||
$this->requestStack = $request_stack;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getRelationUri($entity_type, $bundle, $field_name) {
|
||||
return $this->urlAssembler->assemble("base:rest/relation/$entity_type/$bundle/$field_name", array('absolute' => TRUE));
|
||||
public function getRelationUri($entity_type, $bundle, $field_name, $context = array()) {
|
||||
$uri = $this->getLinkDomain() . "/rest/relation/$entity_type/$bundle/$field_name";
|
||||
$this->moduleHandler->alter('rest_relation_uri', $uri, $context);
|
||||
return $uri;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getRelationInternalIds($relation_uri) {
|
||||
$relations = $this->getRelations();
|
||||
public function getRelationInternalIds($relation_uri, $context = array()) {
|
||||
$relations = $this->getRelations($context);
|
||||
if (isset($relations[$relation_uri])) {
|
||||
return $relations[$relation_uri];
|
||||
}
|
||||
|
@ -77,15 +87,18 @@ class RelationLinkManager implements RelationLinkManagerInterface {
|
|||
* even primitives, are given a relation URI. It is up to the caller to
|
||||
* determine which URIs to use.
|
||||
*
|
||||
* @param array $context
|
||||
* Context from the normalizer/serializer operation.
|
||||
*
|
||||
* @return array
|
||||
* An array of typed data ids (entity_type, bundle, and field name) keyed
|
||||
* by corresponding relation URI.
|
||||
*/
|
||||
protected function getRelations() {
|
||||
protected function getRelations($context = array()) {
|
||||
$cid = 'rest:links:relations';
|
||||
$cache = $this->cache->get($cid);
|
||||
if (!$cache) {
|
||||
$this->writeCache();
|
||||
$this->writeCache($context);
|
||||
$cache = $this->cache->get($cid);
|
||||
}
|
||||
return $cache->data;
|
||||
|
@ -93,15 +106,18 @@ class RelationLinkManager implements RelationLinkManagerInterface {
|
|||
|
||||
/**
|
||||
* Writes the cache of relation links.
|
||||
*
|
||||
* @param array $context
|
||||
* Context from the normalizer/serializer operation.
|
||||
*/
|
||||
protected function writeCache() {
|
||||
protected function writeCache($context = array()) {
|
||||
$data = array();
|
||||
|
||||
foreach ($this->entityManager->getDefinitions() as $entity_type) {
|
||||
if ($entity_type instanceof ContentEntityTypeInterface) {
|
||||
foreach ($this->entityManager->getBundleInfo($entity_type->id()) as $bundle => $bundle_info) {
|
||||
foreach ($this->entityManager->getFieldDefinitions($entity_type->id(), $bundle) as $field_definition) {
|
||||
$relation_uri = $this->getRelationUri($entity_type->id(), $bundle, $field_definition->getName());
|
||||
$relation_uri = $this->getRelationUri($entity_type->id(), $bundle, $field_definition->getName(), $context);
|
||||
$data[$relation_uri] = array(
|
||||
'entity_type' => $entity_type,
|
||||
'bundle' => $bundle,
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
|
||||
namespace Drupal\rest\LinkManager;
|
||||
|
||||
interface RelationLinkManagerInterface {
|
||||
interface RelationLinkManagerInterface extends ConfigurableLinkManagerInterface {
|
||||
|
||||
/**
|
||||
* Gets the URI that corresponds to a field.
|
||||
|
@ -18,11 +18,13 @@ interface RelationLinkManagerInterface {
|
|||
* The bundle name.
|
||||
* @param string $field_name
|
||||
* The field name.
|
||||
* @param array $context
|
||||
* (optional) Optional serializer/normalizer context.
|
||||
*
|
||||
* @return string
|
||||
* The corresponding URI for the field.
|
||||
*/
|
||||
public function getRelationUri($entity_type, $bundle, $field_name);
|
||||
public function getRelationUri($entity_type, $bundle, $field_name, $context = array());
|
||||
|
||||
/**
|
||||
* Translates a REST URI into internal IDs.
|
||||
|
|
|
@ -9,9 +9,11 @@ namespace Drupal\rest\LinkManager;
|
|||
|
||||
use Drupal\Core\Cache\Cache;
|
||||
use Drupal\Core\Cache\CacheBackendInterface;
|
||||
use Drupal\Core\Utility\UnroutedUrlAssemblerInterface;
|
||||
use Drupal\Core\Config\ConfigFactoryInterface;
|
||||
use Drupal\Core\Extension\ModuleHandlerInterface;
|
||||
use Symfony\Component\HttpFoundation\RequestStack;
|
||||
|
||||
class TypeLinkManager implements TypeLinkManagerInterface {
|
||||
class TypeLinkManager extends LinkManagerBase implements TypeLinkManagerInterface {
|
||||
|
||||
/**
|
||||
* Injected cache backend.
|
||||
|
@ -21,23 +23,29 @@ class TypeLinkManager implements TypeLinkManagerInterface {
|
|||
protected $cache;
|
||||
|
||||
/**
|
||||
* The unrouted URL assembler.
|
||||
* Module handler service.
|
||||
*
|
||||
* @var \Drupal\Core\Utility\UnroutedUrlAssemblerInterface
|
||||
* @var \Drupal\Core\Extension\ModuleHandlerInterface
|
||||
*/
|
||||
protected $urlAssembler;
|
||||
protected $moduleHandler;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param \Drupal\Core\Cache\CacheBackendInterface $cache
|
||||
* The injected cache backend for caching type URIs.
|
||||
* @param \Drupal\Core\Utility\UnroutedUrlAssemblerInterface $url_assembler
|
||||
* The unrouted URL assembler.
|
||||
* @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler
|
||||
* The module handler service.
|
||||
* @param \Drupal\Core\Config\ConfigFactoryInterface $config_factory
|
||||
* The config factory service.
|
||||
* @param \Symfony\Component\HttpFoundation\RequestStack $request_stack
|
||||
* The request stack.
|
||||
*/
|
||||
public function __construct(CacheBackendInterface $cache, UnroutedUrlAssemblerInterface $url_assembler) {
|
||||
public function __construct(CacheBackendInterface $cache, ModuleHandlerInterface $module_handler, ConfigFactoryInterface $config_factory, RequestStack $request_stack) {
|
||||
$this->cache = $cache;
|
||||
$this->urlAssembler = $url_assembler;
|
||||
$this->configFactory = $config_factory;
|
||||
$this->moduleHandler = $module_handler;
|
||||
$this->requestStack = $request_stack;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -47,20 +55,23 @@ class TypeLinkManager implements TypeLinkManagerInterface {
|
|||
* The bundle's entity type.
|
||||
* @param string $bundle
|
||||
* The name of the bundle.
|
||||
* @param array $context
|
||||
* Context of normalizer/serializer.
|
||||
*
|
||||
* @return array
|
||||
* @return string
|
||||
* The URI that identifies this bundle.
|
||||
*/
|
||||
public function getTypeUri($entity_type, $bundle) {
|
||||
// @todo Make the base path configurable.
|
||||
return $this->urlAssembler->assemble("base:rest/type/$entity_type/$bundle", array('absolute' => TRUE));
|
||||
public function getTypeUri($entity_type, $bundle, $context = array()) {
|
||||
$uri = $this->getLinkDomain() . "/rest/type/$entity_type/$bundle";
|
||||
$this->moduleHandler->alter('rest_type_uri', $uri, $context);
|
||||
return $uri;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements \Drupal\rest\LinkManager\TypeLinkManagerInterface::getTypeInternalIds().
|
||||
*/
|
||||
public function getTypeInternalIds($type_uri) {
|
||||
$types = $this->getTypes();
|
||||
public function getTypeInternalIds($type_uri, $context = array()) {
|
||||
$types = $this->getTypes($context);
|
||||
if (isset($types[$type_uri])) {
|
||||
return $types[$type_uri];
|
||||
}
|
||||
|
@ -70,15 +81,18 @@ class TypeLinkManager implements TypeLinkManagerInterface {
|
|||
/**
|
||||
* Get the array of type links.
|
||||
*
|
||||
* @param array $context
|
||||
* Context from the normalizer/serializer operation.
|
||||
*
|
||||
* @return array
|
||||
* An array of typed data ids (entity_type and bundle) keyed by
|
||||
* corresponding type URI.
|
||||
*/
|
||||
protected function getTypes() {
|
||||
protected function getTypes($context = array()) {
|
||||
$cid = 'rest:links:types';
|
||||
$cache = $this->cache->get($cid);
|
||||
if (!$cache) {
|
||||
$this->writeCache();
|
||||
$this->writeCache($context);
|
||||
$cache = $this->cache->get($cid);
|
||||
}
|
||||
return $cache->data;
|
||||
|
@ -86,8 +100,11 @@ class TypeLinkManager implements TypeLinkManagerInterface {
|
|||
|
||||
/**
|
||||
* Writes the cache of type links.
|
||||
*
|
||||
* @param array $context
|
||||
* Context from the normalizer/serializer operation.
|
||||
*/
|
||||
protected function writeCache() {
|
||||
protected function writeCache($context = array()) {
|
||||
$data = array();
|
||||
|
||||
// Type URIs correspond to bundles. Iterate through the bundles to get the
|
||||
|
@ -101,7 +118,7 @@ class TypeLinkManager implements TypeLinkManagerInterface {
|
|||
}
|
||||
foreach ($bundles as $bundle => $bundle_info) {
|
||||
// Get a type URI for the bundle.
|
||||
$bundle_uri = $this->getTypeUri($entity_type_id, $bundle);
|
||||
$bundle_uri = $this->getTypeUri($entity_type_id, $bundle, $context);
|
||||
$data[$bundle_uri] = array(
|
||||
'entity_type' => $entity_type_id,
|
||||
'bundle' => $bundle,
|
||||
|
@ -112,4 +129,5 @@ class TypeLinkManager implements TypeLinkManagerInterface {
|
|||
// and only clear it when entity_info is cleared.
|
||||
$this->cache->set('rest:links:types', $data, Cache::PERMANENT, array('entity_types'));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
|
||||
namespace Drupal\rest\LinkManager;
|
||||
|
||||
interface TypeLinkManagerInterface {
|
||||
interface TypeLinkManagerInterface extends ConfigurableLinkManagerInterface {
|
||||
|
||||
/**
|
||||
* Gets the URI that corresponds to a bundle.
|
||||
|
@ -20,21 +20,25 @@ interface TypeLinkManagerInterface {
|
|||
* The bundle's entity type.
|
||||
* @param $bundle
|
||||
* The bundle name.
|
||||
* @param array $context
|
||||
* (optional) Optional serializer/normalizer context.
|
||||
*
|
||||
* @return string
|
||||
* The corresponding URI for the bundle.
|
||||
*/
|
||||
public function getTypeUri($entity_type, $bundle);
|
||||
public function getTypeUri($entity_type, $bundle, $context = array());
|
||||
|
||||
/**
|
||||
* Get a bundle's Typed Data IDs based on a URI.
|
||||
*
|
||||
* @param string $type_uri
|
||||
* The type URI.
|
||||
* @param array $context
|
||||
* Context from the normalizer/serializer operation.
|
||||
*
|
||||
* @return array | boolean
|
||||
* If the URI matches a bundle, returns an array containing entity_type and
|
||||
* bundle. Otherwise, returns false.
|
||||
*/
|
||||
public function getTypeInternalIds($type_uri);
|
||||
public function getTypeInternalIds($type_uri, $context = array());
|
||||
}
|
||||
|
|
|
@ -0,0 +1,90 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Contains \Drupal\rest\Tests\RestLinkManagerTest.
|
||||
*/
|
||||
|
||||
namespace Drupal\rest\Tests;
|
||||
use Drupal\Core\Url;
|
||||
use Drupal\simpletest\KernelTestBase;
|
||||
|
||||
/**
|
||||
* Tests that REST type and relation link managers work as expected
|
||||
* @group rest
|
||||
*/
|
||||
class RestLinkManagerTest extends KernelTestBase {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static $modules = ['rest', 'rest_test', 'system'];
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
$this->installSchema('system', ['router']);
|
||||
\Drupal::service('router.builder')->rebuild();
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests that type hooks work as expected.
|
||||
*/
|
||||
public function testRestLinkManagers() {
|
||||
\Drupal::moduleHandler()->invoke('rest', 'install');
|
||||
/* @var \Drupal\rest\LinkManager\TypeLinkManagerInterface $type_manager */
|
||||
$type_manager = \Drupal::service('rest.link_manager.type');
|
||||
$base = Url::fromRoute('<front>', [], ['absolute' => TRUE])->toString();
|
||||
$link = $type_manager->getTypeUri('node', 'page');
|
||||
$this->assertEqual($link, $base . 'rest/type/node/page');
|
||||
// Now with optional context.
|
||||
$link = $type_manager->getTypeUri('node', 'page', ['rest_test' => TRUE]);
|
||||
$this->assertEqual($link, 'rest_test_type');
|
||||
|
||||
/* @var \Drupal\rest\LinkManager\RelationLinkManagerInterface $relation_manager */
|
||||
$relation_manager = \Drupal::service('rest.link_manager.relation');
|
||||
$link = $relation_manager->getRelationUri('node', 'page', 'field_ref');
|
||||
$this->assertEqual($link, $base . 'rest/relation/node/page/field_ref');
|
||||
// Now with optional context.
|
||||
$link = $relation_manager->getRelationUri('node', 'page', 'foobar', ['rest_test' => TRUE]);
|
||||
$this->assertEqual($link, 'rest_test_relation');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests that type hooks work as expected even without install hook.
|
||||
*/
|
||||
public function testRestLinkManagersNoInstallHook() {
|
||||
/* @var \Drupal\rest\LinkManager\TypeLinkManagerInterface $type_manager */
|
||||
$type_manager = \Drupal::service('rest.link_manager.type');
|
||||
$base = Url::fromRoute('<front>', [], ['absolute' => TRUE])->toString();
|
||||
$link = $type_manager->getTypeUri('node', 'page');
|
||||
$this->assertEqual($link, $base . 'rest/type/node/page');
|
||||
// Now with optional context.
|
||||
$link = $type_manager->getTypeUri('node', 'page', ['rest_test' => TRUE]);
|
||||
$this->assertEqual($link, 'rest_test_type');
|
||||
|
||||
/* @var \Drupal\rest\LinkManager\RelationLinkManagerInterface $relation_manager */
|
||||
$relation_manager = \Drupal::service('rest.link_manager.relation');
|
||||
$link = $relation_manager->getRelationUri('node', 'page', 'field_ref');
|
||||
$this->assertEqual($link, $base . 'rest/relation/node/page/field_ref');
|
||||
// Now with optional context.
|
||||
$link = $relation_manager->getRelationUri('node', 'page', 'foobar', ['rest_test' => TRUE]);
|
||||
$this->assertEqual($link, 'rest_test_relation');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests \Drupal\rest\LinkManager\LinkManager::setLinkDomain().
|
||||
*/
|
||||
public function testRestLinkManagersSetLinkDomain() {
|
||||
/* @var \Drupal\rest\LinkManager\LinkManager $link_manager */
|
||||
$link_manager = \Drupal::service('rest.link_manager');
|
||||
$link_manager->setLinkDomain('http://example.com/');
|
||||
$link = $link_manager->getTypeUri('node', 'page');
|
||||
$this->assertEqual($link, 'http://example.com/rest/type/node/page');
|
||||
$link = $link_manager->getRelationUri('node', 'page', 'field_ref');
|
||||
$this->assertEqual($link, 'http://example.com/rest/relation/node/page/field_ref');
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
name: 'REST test'
|
||||
type: module
|
||||
description: 'Provides test hooks for REST module.'
|
||||
package: Testing
|
||||
version: VERSION
|
||||
core: 8.x
|
||||
dependencies:
|
||||
- rest
|
|
@ -0,0 +1,24 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Contains hook implementations for testing REST module.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Implements hook_rest_type_uri_alter().
|
||||
*/
|
||||
function rest_test_rest_type_uri_alter(&$uri, $context = array()) {
|
||||
if (!empty($context['rest_test'])) {
|
||||
$uri = 'rest_test_type';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_rest_relation_uri_alter().
|
||||
*/
|
||||
function rest_test_rest_relation_uri_alter(&$uri, $context = array()) {
|
||||
if (!empty($context['rest_test'])) {
|
||||
$uri = 'rest_test_relation';
|
||||
}
|
||||
}
|
|
@ -32,7 +32,6 @@ class EntityResolverTest extends NormalizerTestBase {
|
|||
protected function setUp() {
|
||||
parent::setUp();
|
||||
|
||||
$this->installSchema('system', 'router');
|
||||
\Drupal::service('router.builder')->rebuild();
|
||||
|
||||
// Create the test field storage.
|
||||
|
|
|
@ -23,8 +23,10 @@ abstract class NormalizerTestBase extends KernelTestBase {
|
|||
|
||||
$this->installEntitySchema('entity_test_mulrev');
|
||||
$this->installEntitySchema('user');
|
||||
$this->installSchema('system', array('url_alias'));
|
||||
$this->installSchema('system', array('url_alias', 'router'));
|
||||
$this->installConfig(array('field'));
|
||||
\Drupal::service('router.builder')->rebuild();
|
||||
\Drupal::moduleHandler()->invoke('rest', 'install');
|
||||
|
||||
// Auto-create a field for testing.
|
||||
entity_create('field_storage_config', array(
|
||||
|
|
Loading…
Reference in New Issue