Completed
Push — master ( 911e66...bf8335 )
by Jasper
17s queued 13s
created

LinksParser   A

Complexity

Total Complexity 15

Size/Duplication

Total Lines 82
Duplicated Lines 0 %

Test Coverage

Coverage 100%

Importance

Changes 0
Metric Value
eloc 31
dl 0
loc 82
ccs 27
cts 27
cp 1
rs 10
c 0
b 0
f 0
wmc 15

3 Methods

Rating   Name   Duplication   Size   Complexity  
B buildLink() 0 22 9
A __construct() 0 3 1
A parse() 0 17 5
1
<?php
2
3
namespace Swis\JsonApi\Client\Parsers;
4
5
use Swis\JsonApi\Client\Collection;
6
use Swis\JsonApi\Client\Exceptions\ValidationException;
7
use Swis\JsonApi\Client\Link;
8
use Swis\JsonApi\Client\Links;
9
10
/**
11
 * @internal
12
 */
13
class LinksParser
14
{
15
    public const SOURCE_DOCUMENT = 'document';
16
17
    public const SOURCE_ERROR = 'error';
18
19
    public const SOURCE_ITEM = 'item';
20
21
    public const SOURCE_RELATIONSHIP = 'relationship';
22
23
    private const LINKS_THAT_MAY_NOT_BE_NULL_WHEN_PRESENT = [
24
        'self',
25
        'related',
26
    ];
27
28
    /**
29
     * @var \Swis\JsonApi\Client\Parsers\MetaParser
30
     */
31
    private $metaParser;
32
33
    /**
34
     * @param \Swis\JsonApi\Client\Parsers\MetaParser $metaParser
35
     */
36 840
    public function __construct(MetaParser $metaParser)
37
    {
38 840
        $this->metaParser = $metaParser;
39 840
    }
40
41
    /**
42
     * @param mixed  $data
43
     * @param string $source
44
     *
45
     * @return \Swis\JsonApi\Client\Links
46
     */
47 189
    public function parse($data, string $source): Links
48
    {
49 189
        if (!is_object($data)) {
50 42
            throw new ValidationException(sprintf('Links MUST be an object, "%s" given.', gettype($data)));
51
        }
52 147
        if ($source === self::SOURCE_RELATIONSHIP && !property_exists($data, 'self') && !property_exists($data, 'related')) {
53 7
            throw new ValidationException('Relationship links object MUST contain at least one of the following properties: `self`, `related`.');
54
        }
55
56 140
        return new Links(
57 140
            Collection::wrap((array) $data)
58 140
                ->map(
59 40
                    function ($link, $name) {
60 140
                        return $this->buildLink($link, $name);
61 140
                    }
62
                )
63 91
                ->toArray()
64
        );
65
    }
66
67
    /**
68
     * @param mixed  $data
69
     * @param string $name
70
     *
71
     * @return \Swis\JsonApi\Client\Link
72
     */
73 140
    private function buildLink($data, string $name): ? Link
74
    {
75 140
        if (in_array($name, self::LINKS_THAT_MAY_NOT_BE_NULL_WHEN_PRESENT, true) && !is_string($data) && !is_object($data)) {
76 14
            throw new ValidationException(sprintf('Link "%s" MUST be an object or string, "%s" given.', $name, gettype($data)));
77
        }
78
79 126
        if ($data === null) {
80 7
            return null;
81
        }
82
83 126
        if (is_string($data)) {
84 84
            return new Link($data);
85
        }
86
87 49
        if (!is_object($data)) {
88 28
            throw new ValidationException(sprintf('Link "%s" MUST be an object, string or null, "%s" given.', $name, gettype($data)));
89
        }
90 21
        if (!property_exists($data, 'href')) {
91 7
            throw new ValidationException(sprintf('Link "%s" MUST have a "href" attribute.', $name));
92
        }
93
94 14
        return new Link($data->href, property_exists($data, 'meta') ? $this->metaParser->parse($data->meta) : null);
95
    }
96
}
97