HalLinker::__construct()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 0

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 0
c 1
b 0
f 0
nc 1
nop 1
dl 0
loc 3
rs 10
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
/**
14
 * @psalm-import-type Query from Types
15
 * @psalm-import-type Body from Types
16
 */
17
final class HalLinker
18
{
19
    public function __construct(
20
        private readonly ReverseLinkerInterface $link,
21
    ) {
22
    }
23
24
    /** @param Query $query */
0 ignored issues
show
Bug introduced by
The type BEAR\Resource\Query 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...
25
    public function getReverseLink(string $uri, array $query): string
26
    {
27
        return ($this->link)($uri, $query);
28
    }
29
30
    /**
31
     * @param Body         $body
0 ignored issues
show
Bug introduced by
The type BEAR\Resource\Body 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...
32
     * @param list<object> $methodAnnotations
0 ignored issues
show
Bug introduced by
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...
33
     */
34
    public function addHalLink(array $body, array $methodAnnotations, Hal $hal): Hal
35
    {
36
        if (! empty($methodAnnotations)) {
37
            $hal = $this->linkAnnotation($body, $methodAnnotations, $hal);
38
        }
39
40
        if (isset($body['_links'])) {
41
            /** @var array{_links: array<string, array{href: string}>} $body */
42
            $hal = $this->bodyLink($body, $hal);
43
        }
44
45
        return $hal;
46
    }
47
48
    /**
49
     * @param array<int|string, mixed>|array{_links: string} $body
50
     * @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...
51
     */
52
    private function linkAnnotation(array $body, array $methodAnnotations, Hal $hal): Hal
53
    {
54
        foreach ($methodAnnotations as $annotation) {
55
            if (! $annotation instanceof Link) {
56
                continue;
57
            }
58
59
            $uri = uri_template($annotation->href, $body);
60
            $reverseUri = $this->getReverseLink($uri, []);
61
62
            if (isset($body['_links'][$annotation->rel])) {
63
                // skip if already difined links in ResourceObject
64
                continue;
65
            }
66
67
            $hal->addLink($annotation->rel, $reverseUri);
68
        }
69
70
        return $hal;
71
    }
72
73
    /**
74
     * @param array{_links: array<array{href?: string}>} $body
75
     *
76
     * User can set `_links` array as a `Links` annotation
77
     */
78
    private function bodyLink(array $body, Hal $hal): Hal
79
    {
80
        foreach ($body['_links'] as $rel => $link) {
81
            if (! is_string($rel) || ! isset($link['href'])) {
82
                // @codeCoverageIgnoreStart
83
                continue;
84
                // @codeCoverageIgnoreEnd
85
            }
86
87
            $attr = $link;
88
            unset($attr['href']);
89
            $hal->addLink($rel, $link['href'], $attr);
90
        }
91
92
        return $hal;
93
    }
94
}
95