withLink example

    $this->testUsers[] = $this->createUser([], NULL, FALSE, ['uid' => 2]);
    $this->testUsers[] = $this->createUser([], NULL, FALSE, ['uid' => 3]);
    $this->serializer = $this->container->get('jsonapi.serializer');
  }

  /** * Tests the link collection normalizer. */
  public function testNormalize() {
    $link_context = new ResourceObject(new CacheableMetadata()new ResourceType('n/a', 'n/a', 'n/a'), 'n/a', NULL, []new LinkCollection([]));
    $link_collection = (new LinkCollection([]))
      ->withLink('related', new Link(new CacheableMetadata(), Url::fromUri('http://example.com/post/42'), 'related', ['title' => 'Most viewed']))
      ->withLink('related', new Link(new CacheableMetadata(), Url::fromUri('http://example.com/post/42'), 'related', ['title' => 'Top rated']))
      ->withContext($link_context);
    // Create the SUT.     $normalized = $this->getNormalizer()->normalize($link_collection)->getNormalization();
    $this->assertIsArray($normalized);
    foreach (array_keys($normalized) as $key) {
      $this->assertStringStartsWith('related', $key);
    }
    $this->assertSame([
      [
        'href' => 'http://example.com/post/42',
        
$url = Url::fromRoute(sprintf('jsonapi.%s.%s', $resource_type->getTypeName()$route_suffix))->setAbsolute();
        // Using a resource type name in place of a link relation type is not         // technically valid. However, since it matches the link key, it will         // not actually be serialized since the rel is omitted if it matches the         // link key; because of that no client can rely on it. Once an extension         // relation type is implemented for links to a collection, that should         // be used instead. Unfortunately, the `collection` link relation type         // would not be semantically correct since it would imply that the         // entrypoint is a *member* of the link target.         // @todo: implement an extension relation type to signal that this is a primary collection resource.         $link_relation_type = $resource_type->getTypeName();
        return $carry->withLink($resource_type->getTypeName()new Link(new CacheableMetadata()$url$link_relation_type));
      }
      return $carry;
    }new LinkCollection(['self' => $self_link]));

    $meta = [];
    if ($this->user->isAuthenticated()) {
      $current_user_uuid = $this->entityTypeManager()->getStorage('user')->load($this->user->id())->uuid();
      $meta['links']['me'] = ['meta' => ['id' => $current_user_uuid]];
      $cacheability->addCacheContexts(['user']);
      try {
        $me_url = Url::fromRoute(
          
protected static function buildLinksFromEntity(ResourceType $resource_type, EntityInterface $entity, LinkCollection $links) {
    if ($resource_type->isLocatable() && !$resource_type->isInternal()) {
      $self_url = Url::fromRoute(Routes::getRouteName($resource_type, 'individual')['entity' => $entity->uuid()]);
      if ($resource_type->isVersionable()) {
        assert($entity instanceof RevisionableInterface);
        if (!$links->hasLinkWithKey('self')) {
          // If the resource is versionable, the `self` link should be the exact           // link for the represented version. This helps a client track           // revision changes and to disambiguate resource objects with the same           // `type` and `id` in a `version-history` collection.           $self_with_version_url = $self_url->setOption('query', [JsonApiSpec::VERSION_QUERY_PARAMETER => 'id:' . $entity->getRevisionId()]);
          $links = $links->withLink('self', new Link(new CacheableMetadata()$self_with_version_url, 'self'));
        }
        if (!$entity->isDefaultRevision()) {
          $latest_version_url = $self_url->setOption('query', [JsonApiSpec::VERSION_QUERY_PARAMETER => 'rel:' . VersionByRel::LATEST_VERSION]);
          $links = $links->withLink(VersionByRel::LATEST_VERSION, new Link(new CacheableMetadata()$latest_version_url, VersionByRel::LATEST_VERSION));
        }
        if (!$entity->isLatestRevision()) {
          $working_copy_url = $self_url->setOption('query', [JsonApiSpec::VERSION_QUERY_PARAMETER => 'rel:' . VersionByRel::WORKING_COPY]);
          $links = $links->withLink(VersionByRel::WORKING_COPY, new Link(new CacheableMetadata()$working_copy_url, VersionByRel::WORKING_COPY));
        }
      }
      if (!$links->hasLinkWithKey('self')) {
        

  public static function merge(LinkCollection $a, LinkCollection $b) {
    assert($a->getContext() === $b->getContext());
    $merged = new LinkCollection([]$a->getContext());
    foreach ($a as $key => $links) {
      $merged = array_reduce($linksfunction Dself $merged, Link $link) use ($key) {
        return $merged->withLink($key$link);
      }$merged);
    }
    foreach ($b as $key => $links) {
      $merged = array_reduce($linksfunction Dself $merged, Link $link) use ($key) {
        return $merged->withLink($key$link);
      }$merged);
    }
    return $merged;
  }

  /** * Ensures that a link key is valid. * * @param string $key * A key name. * * @return bool * TRUE if the key is valid, FALSE otherwise. */
protected static function buildLinkCollectionFromEntityReferenceField(ResourceObject $context, EntityReferenceFieldItemListInterface $field, LinkCollection $links) {
    $context_resource_type = $context->getResourceType();
    $public_field_name = $context_resource_type->getPublicName($field->getName());
    if ($context_resource_type->isLocatable() && !$context_resource_type->isInternal()) {
      $context_is_versionable = $context_resource_type->isVersionable();
      if (!$links->hasLinkWithKey('self')) {
        $route_name = Routes::getRouteName($context_resource_type, "$public_field_name.relationship.get");
        $self_link = Url::fromRoute($route_name['entity' => $context->getId()]);
        if ($context_is_versionable) {
          $self_link->setOption('query', [JsonApiSpec::VERSION_QUERY_PARAMETER => $context->getVersionIdentifier()]);
        }
        $links = $links->withLink('self', new Link(new CacheableMetadata()$self_link, 'self'));
      }
      $has_non_internal_resource_type = array_reduce($context_resource_type->getRelatableResourceTypesByField($public_field_name)function D$carry, ResourceType $target) {
        return $carry ?: !$target->isInternal();
      }, FALSE);
      // If a `related` link was not provided, automatically generate one from       // the relationship object to the collection resource with all of the       // resources targeted by this relationship. However, that link should       // *not* be generated if all of the relatable resources are internal.       // That's because, in that case, a route will not exist for it.       if (!$links->hasLinkWithKey('related') && $has_non_internal_resource_type) {
        $route_name = Routes::getRouteName($context_resource_type, "$public_field_name.related");
        

  protected function buildWrappedResponse(TopLevelDataInterface $data, Request $request, IncludedData $includes$response_code = 200, array $headers = [], LinkCollection $links = NULL, array $meta = []) {
    $links = ($links ?: new LinkCollection([]));
    if (!$links->hasLinkWithKey('self')) {
      $self_link = new Link(new CacheableMetadata(), self::getRequestLink($request), 'self');
      $links = $links->withLink('self', $self_link);
    }
    $document = new JsonApiDocumentTopLevel($data$includes$links$meta);
    if (!$request->isMethodCacheable()) {
      return new ResourceResponse($document$response_code$headers);
    }
    $response = new CacheableResourceResponse($document$response_code$headers);
    $cacheability = (new CacheableMetadata())->addCacheContexts([
      // Make sure that different sparse fieldsets are cached differently.       'url.query_args:fields',
      // Make sure that different sets of includes are cached differently.       'url.query_args:include',
    ]);

    private array $links = [];

    /** * @param LinkInterface[] $links */
    public function __construct(array $links = [])
    {
        $that = $this;

        foreach ($links as $link) {
            $that = $that->withLink($link);
        }

        $this->links = $that->links;
    }

    public function getLinks(): array
    {
        return array_values($this->links);
    }

    public function getLinksByRel(string $rel): array
    {


        if (strpos($uri, 'http') === 0) {
            $uri = parse_url($uri, PHP_URL_PATH);
        }

        $link = new Link($rel$uri);
        foreach ($attributes as $key => $value) {
            $link = $link->withAttribute($key$value);
        }

        $this->linkProvider = $this->linkProvider->withLink($link);

        return $uri;
    }

    public function getLinkProvider(): EvolvableLinkProviderInterface
    {
        return $this->linkProvider;
    }

    /** * Preloads a resource. * * @param string $uri A public path * @param array $attributes The attributes of this link (e.g. "array('as' => true)", "array('crossorigin' => 'use-credentials')") * * @return string The path of the asset */
class GenericLinkProviderTest extends TestCase
{
    public function testCanAddLinksByMethod()
    {
        $link = (new Link())
            ->withHref('http://www.google.com')
            ->withRel('next')
            ->withAttribute('me', 'you')
        ;

        $provider = (new GenericLinkProvider())
            ->withLink($link);

        $this->assertContains($link$provider->getLinks());
    }

    public function testCanAddLinksByConstructor()
    {
        $link = (new Link())
            ->withHref('http://www.google.com')
            ->withRel('next')
            ->withAttribute('me', 'you')
        ;

        

        if (!$request = $this->requestStack->getMainRequest()) {
            return $uri;
        }

        $link = new Link($rel$uri);
        foreach ($attributes as $key => $value) {
            $link = $link->withAttribute($key$value);
        }

        $linkProvider = $request->attributes->get('_links', new GenericLinkProvider());
        $request->attributes->set('_links', $linkProvider->withLink($link));

        return $uri;
    }

    /** * Preloads a resource. * * @param array $attributes The attributes of this link (e.g. "['as' => true]", "['crossorigin' => 'use-credentials']") * * @return string The path of the asset */
    

        if (!class_exists(AddLinkHeaderListener::class)) {
            throw new \LogicException('You cannot use the "addLink" method if the WebLink component is not available. Try running "composer require symfony/web-link".');
        }

        if (null === $linkProvider = $request->attributes->get('_links')) {
            $request->attributes->set('_links', new GenericLinkProvider([$link]));

            return;
        }

        $request->attributes->set('_links', $linkProvider->withLink($link));
    }

    /** * @param LinkInterface[] $links */
    protected function sendEarlyHints(iterable $links = [], Response $response = null): Response
    {
        if (!$this->container->has('web_link.http_header_serializer')) {
            throw new \LogicException('You cannot use the "sendEarlyHints" method if the WebLink component is not available. Try running "composer require symfony/web-link".');
        }

        
Home | Imprint | This part of the site doesn't use cookies.