Version 1
[yaffs-website] / web / core / modules / hal / src / LinkManager / TypeLinkManager.php
diff --git a/web/core/modules/hal/src/LinkManager/TypeLinkManager.php b/web/core/modules/hal/src/LinkManager/TypeLinkManager.php
new file mode 100644 (file)
index 0000000..c3a948f
--- /dev/null
@@ -0,0 +1,150 @@
+<?php
+
+namespace Drupal\hal\LinkManager;
+
+use Drupal\Core\Cache\Cache;
+use Drupal\Core\Cache\CacheBackendInterface;
+use Drupal\Core\Config\ConfigFactoryInterface;
+use Drupal\Core\Entity\EntityTypeBundleInfoInterface;
+use Drupal\Core\Extension\ModuleHandlerInterface;
+use Symfony\Component\HttpFoundation\RequestStack;
+
+class TypeLinkManager extends LinkManagerBase implements TypeLinkManagerInterface {
+
+  /**
+   * Injected cache backend.
+   *
+   * @var \Drupal\Core\Cache\CacheBackendInterface;
+   */
+  protected $cache;
+
+  /**
+   * Module handler service.
+   *
+   * @var \Drupal\Core\Extension\ModuleHandlerInterface
+   */
+  protected $moduleHandler;
+
+  /**
+   * The bundle info service.
+   *
+   * @var \Drupal\Core\Entity\EntityTypeBundleInfoInterface
+   */
+  protected $bundleInfoService;
+
+  /**
+   * Constructor.
+   *
+   * @param \Drupal\Core\Cache\CacheBackendInterface $cache
+   *   The injected cache backend for caching type URIs.
+   * @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 $bundle_info_service
+   *   The bundle info service.
+   */
+  public function __construct(CacheBackendInterface $cache, ModuleHandlerInterface $module_handler, ConfigFactoryInterface $config_factory, RequestStack $request_stack, EntityTypeBundleInfoInterface $bundle_info_service) {
+    $this->cache = $cache;
+    $this->configFactory = $config_factory;
+    $this->moduleHandler = $module_handler;
+    $this->requestStack = $request_stack;
+    $this->bundleInfoService = $bundle_info_service;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getTypeUri($entity_type, $bundle, $context = []) {
+    // Per the interface documentation of this method, the returned URI may
+    // optionally also serve as the URL of a documentation page about this
+    // bundle. 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 and
+    // bundle 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
+    // TypeLinkManager class/service to return the desired URL.
+    $uri = $this->getLinkDomain() . "/rest/type/$entity_type/$bundle";
+    $this->moduleHandler->alter('hal_type_uri', $uri, $context);
+    // @deprecated in Drupal 8.3.x and will be removed before Drupal 9.0.0. This
+    // hook is invoked to maintain backwards compatibility
+    $this->moduleHandler->alter('rest_type_uri', $uri, $context);
+    return $uri;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getTypeInternalIds($type_uri, $context = []) {
+    $types = $this->getTypes($context);
+    if (isset($types[$type_uri])) {
+      return $types[$type_uri];
+    }
+    return FALSE;
+  }
+
+  /**
+   * 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($context = []) {
+    $cid = 'hal:links:types';
+    $cache = $this->cache->get($cid);
+    if (!$cache) {
+      $data = $this->writeCache($context);
+    }
+    else {
+      $data = $cache->data;
+    }
+    return $data;
+  }
+
+  /**
+   * Writes the cache 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 writeCache($context = []) {
+    $data = [];
+
+    // Type URIs correspond to bundles. Iterate through the bundles to get the
+    // URI and data for them.
+    $entity_types = \Drupal::entityManager()->getDefinitions();
+    foreach ($this->bundleInfoService->getAllBundleInfo() as $entity_type_id => $bundles) {
+      // Only content entities are supported currently.
+      // @todo Consider supporting config entities.
+      if ($entity_types[$entity_type_id]->entityClassImplements(ConfigEntityInterface::class)) {
+        continue;
+      }
+      foreach ($bundles as $bundle => $bundle_info) {
+        // Get a type URI for the bundle.
+        $bundle_uri = $this->getTypeUri($entity_type_id, $bundle, $context);
+        $data[$bundle_uri] = [
+          'entity_type' => $entity_type_id,
+          'bundle' => $bundle,
+        ];
+      }
+    }
+    // These URIs only change when entity info changes, so cache it permanently
+    // and only clear it when entity_info is cleared.
+    $this->cache->set('hal:links:types', $data, Cache::PERMANENT, ['entity_types']);
+    return $data;
+  }
+
+}