HalLinker   A
last analyzed

Complexity

Total Complexity 14

Size/Duplication

Total Lines 76
Duplicated Lines 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
eloc 22
c 2
b 0
f 0
dl 0
loc 76
rs 10
wmc 14

5 Methods

Rating   Name   Duplication   Size   Complexity  
A addHalLink() 0 12 3
A __construct() 0 3 1
A linkAnnotation() 0 19 6
A getReverseLink() 0 3 1
A bodyLink() 0 15 3
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_array;
11
use function uri_template;
12
13
/**
14
 * @psalm-import-type Query from Types
15
 * @psalm-import-type Body from Types
16
 * @psalm-import-type HalLinks from Types
17
 * @psalm-import-type HalLinkData from Types
18
 */
19
final class HalLinker
20
{
21
    public function __construct(
22
        private readonly ReverseLinkerInterface $link,
23
    ) {
24
    }
25
26
    /** @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...
27
    public function getReverseLink(string $uri, array $query): string
28
    {
29
        return ($this->link)($uri, $query);
30
    }
31
32
    /**
33
     * @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...
34
     * @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...
35
     */
36
    public function addHalLink(array $body, array $methodAnnotations, Hal $hal): Hal
37
    {
38
        if (! empty($methodAnnotations)) {
39
            $hal = $this->linkAnnotation($body, $methodAnnotations, $hal);
40
        }
41
42
        if (isset($body['_links'])) {
43
            /** @var array{_links: HalLinks} $body */
44
            $hal = $this->bodyLink($body, $hal);
45
        }
46
47
        return $hal;
48
    }
49
50
    /**
51
     * @param Body                   $body
52
     * @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...
53
     */
54
    private function linkAnnotation(array $body, array $methodAnnotations, Hal $hal): Hal
55
    {
56
        foreach ($methodAnnotations as $annotation) {
57
            if (! $annotation instanceof Link) {
58
                continue;
59
            }
60
61
            $uri = uri_template($annotation->href, $body);
62
            $reverseUri = $this->getReverseLink($uri, []);
63
64
            if (isset($body['_links']) && is_array($body['_links']) && isset($body['_links'][$annotation->rel])) {
65
                // skip if already difined links in ResourceObject
66
                continue;
67
            }
68
69
            $hal->addLink($annotation->rel, $reverseUri);
70
        }
71
72
        return $hal;
73
    }
74
75
    /**
76
     * @param array{_links: HalLinks} $body
77
     *
78
     * User can set `_links` array as a `Links` annotation
79
     */
80
    private function bodyLink(array $body, Hal $hal): Hal
81
    {
82
        foreach ($body['_links'] as $rel => $link) {
83
            if (! isset($link['href'])) {
84
                // @codeCoverageIgnoreStart
85
                continue;
86
                // @codeCoverageIgnoreEnd
87
            }
88
89
            $attr = $link;
90
            unset($attr['href']);
91
            $hal->addLink($rel, $link['href'], $attr);
92
        }
93
94
        return $hal;
95
    }
96
}
97