Skip to content
Snippets Groups Projects
Select Git revision
  • 11.x
  • 11.2.x protected
  • 10.5.x protected
  • 10.6.x protected
  • 11.1.x protected
  • 10.4.x protected
  • 11.0.x protected
  • 10.3.x protected
  • 7.x protected
  • 10.2.x protected
  • 10.1.x protected
  • 9.5.x protected
  • 10.0.x protected
  • 9.4.x protected
  • 9.3.x protected
  • 9.2.x protected
  • 9.1.x protected
  • 8.9.x protected
  • 9.0.x protected
  • 8.8.x protected
  • 10.5.2 protected
  • 11.2.3 protected
  • 10.5.1 protected
  • 11.2.2 protected
  • 11.2.1 protected
  • 11.2.0 protected
  • 10.5.0 protected
  • 11.2.0-rc2 protected
  • 10.5.0-rc1 protected
  • 11.2.0-rc1 protected
  • 10.4.8 protected
  • 11.1.8 protected
  • 10.5.0-beta1 protected
  • 11.2.0-beta1 protected
  • 11.2.0-alpha1 protected
  • 10.4.7 protected
  • 11.1.7 protected
  • 10.4.6 protected
  • 11.1.6 protected
  • 10.3.14 protected
40 results

Link.php

Blame
  • quietone's avatar
    Issue #3386058 by welly, bbrala: Update PhpDoc type for Drupal\jsonapi\JsonApiResource\Link::$rel
    quietone authored
    dff46835
    History
    Code owners
    Assign users and groups as approvers for specific file changes. Learn more.
    Link.php 5.04 KiB
    <?php
    
    namespace Drupal\jsonapi\JsonApiResource;
    
    use Drupal\Component\Assertion\Inspector;
    use Drupal\Component\Utility\DiffArray;
    use Drupal\Core\Cache\CacheableDependencyInterface;
    use Drupal\Core\Cache\CacheableDependencyTrait;
    use Drupal\Core\Cache\CacheableMetadata;
    use Drupal\Core\Url;
    
    /**
     * Represents an RFC8288 based link.
     *
     * @internal JSON:API maintains no PHP API. The API is the HTTP API. This class
     *   may change at any time and could break any dependencies on it.
     *
     * @see https://www.drupal.org/project/drupal/issues/3032787
     * @see jsonapi.api.php
     *
     * @see https://tools.ietf.org/html/rfc8288
     */
    final class Link implements CacheableDependencyInterface {
    
      use CacheableDependencyTrait;
    
      /**
       * The link URI.
       *
       * @var \Drupal\Core\Url
       */
      protected $uri;
    
      /**
       * The URI, as a string.
       *
       * @var string
       */
      protected $href;
    
      /**
       * The link relation type.
       *
       * @var string
       */
      protected $rel;
    
      /**
       * The link target attributes.
       *
       * @var string[]
       *   An associative array where the keys are the attribute keys and values are
       *   either string or an array of strings.
       */
      protected $attributes;
    
      /**
       * JSON:API Link constructor.
       *
       * @param \Drupal\Core\Cache\CacheableMetadata $cacheability
       *   Any cacheability metadata associated with the link. For example, a
       *   'call-to-action' link might reference a registration resource if an event
       *   has vacancies or a wait-list resource otherwise. Therefore, the link's
       *   cacheability might be depend on a certain entity's values other than the
       *   entity on which the link will appear.
       * @param \Drupal\Core\Url $url
       *   The Url object for the link.
       * @param string $link_relation_type
       *   An array of registered or extension RFC8288 link relation types.
       * @param array $target_attributes
       *   An associative array of target attributes for the link.
       *
       * @see https://tools.ietf.org/html/rfc8288#section-2.1
       */
      public function __construct(CacheableMetadata $cacheability, Url $url, string $link_relation_type, array $target_attributes = []) {
        assert(Inspector::assertAllStrings(array_keys($target_attributes)));
        assert(Inspector::assertAll(function ($target_attribute_value) {
          return is_string($target_attribute_value) || is_array($target_attribute_value);
        }, array_values($target_attributes)));
        $generated_url = $url->setAbsolute()->toString(TRUE);
        $this->href = $generated_url->getGeneratedUrl();
        $this->uri = $url;
        $this->rel = $link_relation_type;
        $this->attributes = $target_attributes;
        $this->setCacheability($cacheability->addCacheableDependency($generated_url));
      }
    
      /**
       * Gets the link's URI.
       *
       * @return \Drupal\Core\Url
       *   The link's URI as a Url object.
       */
      public function getUri() {
        return $this->uri;
      }
    
      /**
       * Gets the link's URI as a string.
       *
       * @return string
       *   The link's URI as a string.
       */
      public function getHref() {
        return $this->href;
      }
    
      /**
       * Gets the link's relation type.
       *
       * @return string
       *   The link's relation type.
       */
      public function getLinkRelationType() {
        return $this->rel;
      }
    
      /**
       * Gets the link's target attributes.
       *
       * @return string[]
       *   The link's target attributes.
       */
      public function getTargetAttributes() {
        return $this->attributes;
      }
    
      /**
       * Compares two links.
       *
       * @param \Drupal\jsonapi\JsonApiResource\Link $a
       *   The first link.
       * @param \Drupal\jsonapi\JsonApiResource\Link $b
       *   The second link.
       *
       * @return int
       *   0 if the links can be considered identical, an integer greater than or
       *   less than 0 otherwise.
       */
      public static function compare(Link $a, Link $b) {
        // Any string concatenation would work, but a Link header-like format makes
        // it clear what is being compared.
        $a_string = sprintf('<%s>;rel="%s"', $a->getHref(), $a->rel);
        $b_string = sprintf('<%s>;rel="%s"', $b->getHref(), $b->rel);
        $cmp = strcmp($a_string, $b_string);
        // If the `href` or `rel` of the links are not equivalent, it's not
        // necessary to compare target attributes.
        if ($cmp === 0) {
          return (int) !empty(DiffArray::diffAssocRecursive($a->getTargetAttributes(), $b->getTargetAttributes()));
        }
        return $cmp;
      }
    
      /**
       * Merges two equivalent links into one link with the merged cacheability.
       *
       * The links must share the same URI, link relation type and attributes.
       *
       * @param \Drupal\jsonapi\JsonApiResource\Link $a
       *   The first link.
       * @param \Drupal\jsonapi\JsonApiResource\Link $b
       *   The second link.
       *
       * @return static
       *   A new JSON:API Link object with the cacheability of both links merged.
       */
      public static function merge(Link $a, Link $b) {
        assert(static::compare($a, $b) === 0, 'Only equivalent links can be merged.');
        $merged_cacheability = (new CacheableMetadata())->addCacheableDependency($a)->addCacheableDependency($b);
        return new static($merged_cacheability, $a->getUri(), $a->getLinkRelationType(), $a->getTargetAttributes());
      }
    
    }