class RelationLinkManager

Same name in other branches
  1. 8.9.x core/modules/rest/src/LinkManager/RelationLinkManager.php \Drupal\rest\LinkManager\RelationLinkManager
  2. 8.9.x core/modules/hal/src/LinkManager/RelationLinkManager.php \Drupal\hal\LinkManager\RelationLinkManager

Hierarchy

Expanded class hierarchy of RelationLinkManager

1 string reference to 'RelationLinkManager'
hal.services.yml in core/modules/hal/hal.services.yml
core/modules/hal/hal.services.yml
1 service uses RelationLinkManager
hal.link_manager.relation in core/modules/hal/hal.services.yml
Drupal\hal\LinkManager\RelationLinkManager

File

core/modules/hal/src/LinkManager/RelationLinkManager.php, line 15

Namespace

Drupal\hal\LinkManager
View source
class RelationLinkManager extends LinkManagerBase implements RelationLinkManagerInterface {
    
    /**
     * @var \Drupal\Core\Cache\CacheBackendInterface
     */
    protected $cache;
    
    /**
     * The entity field manager.
     *
     * @var \Drupal\Core\Entity\EntityFieldManagerInterface
     */
    protected $entityFieldManager;
    
    /**
     * The entity bundle info.
     *
     * @var \Drupal\Core\Entity\EntityTypeBundleInfoInterface
     */
    protected $entityTypeBundleInfo;
    
    /**
     * The entity type manager.
     *
     * @var \Drupal\Core\Entity\EntityTypeManagerInterface
     */
    protected $entityTypeManager;
    
    /**
     * Module handler service.
     *
     * @var \Drupal\Core\Extension\ModuleHandlerInterface
     */
    protected $moduleHandler;
    
    /**
     * Constructor.
     *
     * @param \Drupal\Core\Cache\CacheBackendInterface $cache
     *   The cache of relation URIs and their associated Typed Data IDs.
     * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
     *   The entity type manager.
     * @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.
     * @param \Drupal\Core\Entity\EntityTypeBundleInfoInterface $entity_type_bundle_info
     *   The entity type bundle info.
     * @param \Drupal\Core\Entity\EntityFieldManagerInterface $entity_field_manager
     *   The entity field manager.
     */
    public function __construct(CacheBackendInterface $cache, EntityTypeManagerInterface $entity_type_manager, ModuleHandlerInterface $module_handler, ConfigFactoryInterface $config_factory, RequestStack $request_stack, EntityTypeBundleInfoInterface $entity_type_bundle_info, EntityFieldManagerInterface $entity_field_manager) {
        $this->cache = $cache;
        $this->entityTypeManager = $entity_type_manager;
        $this->entityTypeBundleInfo = $entity_type_bundle_info;
        $this->entityFieldManager = $entity_field_manager;
        $this->configFactory = $config_factory;
        $this->moduleHandler = $module_handler;
        $this->requestStack = $request_stack;
    }
    
    /**
     * {@inheritdoc}
     */
    public function getRelationUri($entity_type, $bundle, $field_name, $context = []) {
        // Per the interface documentation of this method, the returned URI may
        // optionally also serve as the URL of a documentation page about this
        // field. However, Drupal does not currently implement such a documentation
        // page. Therefore, we return a URI assembled relative to the site's base
        // URL, which is sufficient to uniquely identify the site's entity type +
        // bundle + field for use in hypermedia formats, but we do not take into
        // account unclean URLs, language prefixing, or anything else that would be
        // required for Drupal to be able to respond with content at this URL. If a
        // module is installed that adds such content, but requires this URL to be
        // different (e.g., include a language prefix), then the module must also
        // override the RelationLinkManager class/service to return the desired URL.
        $uri = $this->getLinkDomain($context) . "/rest/relation/{$entity_type}/{$bundle}/{$field_name}";
        $this->moduleHandler
            ->alter('hal_relation_uri', $uri, $context);
        return $uri;
    }
    
    /**
     * {@inheritdoc}
     */
    public function getRelationInternalIds($relation_uri, $context = []) {
        $relations = $this->getRelations($context);
        if (isset($relations[$relation_uri])) {
            return $relations[$relation_uri];
        }
        return FALSE;
    }
    
    /**
     * Get the array of relation links.
     *
     * Any field can be handled as a relation simply by changing how it is
     * normalized. Therefore, there is no prior knowledge that can be used here
     * to determine which fields to assign relation URIs. Instead, each field,
     * 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 keyed by corresponding relation URI. The keys
     *   are:
     *   - 'entity_type_id'
     *   - 'bundle'
     *   - 'field_name'
     *   The values for 'entity_type_id', 'bundle' and 'field_name' are strings.
     *
     * @see https://www.drupal.org/node/2877608
     */
    protected function getRelations($context = []) {
        $cid = 'hal:links:relations:' . $this->getLinkDomain($context);
        $cache = $this->cache
            ->get($cid);
        if (!$cache) {
            $data = $this->writeCache($context);
        }
        else {
            $data = $cache->data;
        }
        return $data;
    }
    
    /**
     * Writes the cache of relation links.
     *
     * @param array $context
     *   Context from the normalizer/serializer operation.
     *
     * @return array
     *   An array of typed data IDs keyed by corresponding relation URI. The keys
     *   are:
     *   - 'entity_type_id'
     *   - 'bundle'
     *   - 'field_name'
     *   The values for 'entity_type_id', 'bundle' and 'field_name' are strings.
     */
    protected function writeCache($context = []) {
        $data = [];
        foreach ($this->entityTypeManager
            ->getDefinitions() as $entity_type) {
            if ($entity_type instanceof ContentEntityTypeInterface) {
                foreach ($this->entityTypeBundleInfo
                    ->getBundleInfo($entity_type->id()) as $bundle => $bundle_info) {
                    foreach ($this->entityFieldManager
                        ->getFieldDefinitions($entity_type->id(), $bundle) as $field_definition) {
                        $relation_uri = $this->getRelationUri($entity_type->id(), $bundle, $field_definition->getName(), $context);
                        $data[$relation_uri] = [
                            'entity_type_id' => $entity_type->id(),
                            'bundle' => $bundle,
                            'field_name' => $field_definition->getName(),
                        ];
                    }
                }
            }
        }
        // These URIs only change when field info changes, so cache it permanently
        // and only clear it when the fields cache is cleared.
        $this->cache
            ->set('hal:links:relations:' . $this->getLinkDomain($context), $data, Cache::PERMANENT, [
            'entity_field_info',
        ]);
        return $data;
    }

}

Members

Title Sort descending Modifiers Object type Summary Overriden Title
LinkManagerBase::$configFactory protected property Config factory service.
LinkManagerBase::$linkDomain protected property Link domain used for type links URIs.
LinkManagerBase::$requestStack protected property The request stack.
LinkManagerBase::getLinkDomain protected function Gets the link domain.
LinkManagerBase::setLinkDomain public function
RelationLinkManager::$cache protected property
RelationLinkManager::$entityFieldManager protected property The entity field manager.
RelationLinkManager::$entityTypeBundleInfo protected property The entity bundle info.
RelationLinkManager::$entityTypeManager protected property The entity type manager.
RelationLinkManager::$moduleHandler protected property Module handler service.
RelationLinkManager::getRelationInternalIds public function Translates a REST URI into internal IDs. Overrides RelationLinkManagerInterface::getRelationInternalIds
RelationLinkManager::getRelations protected function Get the array of relation links.
RelationLinkManager::getRelationUri public function Gets the URI that corresponds to a field. Overrides RelationLinkManagerInterface::getRelationUri
RelationLinkManager::writeCache protected function Writes the cache of relation links.
RelationLinkManager::__construct public function Constructor.

Buggy or inaccurate documentation? Please file an issue. Need support? Need help programming? Connect with the Drupal community.