Issues (55)

src/HalLinker.php (2 issues)

1
<?php
2
3
declare(strict_types=1);
4
5
namespace BEAR\Resource;
6
7
use BEAR\Resource\Annotation\Link;
8
use Nocarrier\Hal;
9
10
use function is_string;
11
use function uri_template;
12
13
final class HalLinker
14
{
15
    public function __construct(
16
        private readonly ReverseLinkerInterface $link,
17
    ) {
18
    }
19
20
    /** @param array<string, mixed> $query */
21
    public function getReverseLink(string $uri, array $query): string
22
    {
23
        return ($this->link)($uri, $query);
24
    }
25
26
    /**
27
     * @param array<mixed> $body
28
     * @param list<object> $methodAnnotations
0 ignored issues
show
The type BEAR\Resource\list was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
29
     */
30
    public function addHalLink(array $body, array $methodAnnotations, Hal $hal): Hal
31
    {
32
        if (! empty($methodAnnotations)) {
33
            $hal = $this->linkAnnotation($body, $methodAnnotations, $hal);
34
        }
35
36
        if (isset($body['_links'])) {
37
            /** @var array{_links: array<string, array{href: string}>} $body */
38
            $hal = $this->bodyLink($body, $hal);
39
        }
40
41
        return $hal;
42
    }
43
44
    /**
45
     * @param array<int|string, mixed>|array{_links: string} $body
46
     * @param non-empty-list<object>                         $methodAnnotations
0 ignored issues
show
Documentation Bug introduced by
The doc comment non-empty-list<object> at position 0 could not be parsed: Unknown type name 'non-empty-list' at position 0 in non-empty-list<object>.
Loading history...
47
     */
48
    private function linkAnnotation(array $body, array $methodAnnotations, Hal $hal): Hal
49
    {
50
        foreach ($methodAnnotations as $annotation) {
51
            if (! $annotation instanceof Link) {
52
                continue;
53
            }
54
55
            $uri = uri_template($annotation->href, $body);
56
            $reverseUri = $this->getReverseLink($uri, []);
57
58
            if (isset($body['_links'][$annotation->rel])) {
59
                // skip if already difined links in ResourceObject
60
                continue;
61
            }
62
63
            $hal->addLink($annotation->rel, $reverseUri);
64
        }
65
66
        return $hal;
67
    }
68
69
    /**
70
     * @param array{_links: array<array{href?: string}>} $body
71
     *
72
     * User can set `_links` array as a `Links` annotation
73
     */
74
    private function bodyLink(array $body, Hal $hal): Hal
75
    {
76
        foreach ($body['_links'] as $rel => $link) {
77
            if (! is_string($rel) || ! isset($link['href'])) {
78
                // @codeCoverageIgnoreStart
79
                continue;
80
                // @codeCoverageIgnoreEnd
81
            }
82
83
            $attr = $link;
84
            unset($attr['href']);
85
            $hal->addLink($rel, $link['href'], $attr);
86
        }
87
88
        return $hal;
89
    }
90
}
91