Completed
Push — master ( c7eae7...1f65b1 )
by Jasper
05:14
created

LinksParser   A

Complexity

Total Complexity 17

Size/Duplication

Total Lines 85
Duplicated Lines 0 %

Test Coverage

Coverage 100%

Importance

Changes 0
Metric Value
eloc 33
dl 0
loc 85
ccs 29
cts 29
cp 1
rs 10
c 0
b 0
f 0
wmc 17

3 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 3 1
B buildLink() 0 22 9
B parse() 0 20 7
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 678
    public function __construct(MetaParser $metaParser)
37
    {
38 678
        $this->metaParser = $metaParser;
39 678
    }
40
41
    /**
42
     * @param mixed  $data
43
     * @param string $source
44
     *
45
     * @return \Swis\JsonApi\Client\Links
46
     */
47 168
    public function parse($data, string $source): Links
48
    {
49 168
        if (!is_object($data)) {
50 36
            throw new ValidationException(sprintf('Links has to be an object, "%s" given.', gettype($data)));
51
        }
52 132
        if ($source === self::SOURCE_ERROR && !property_exists($data, 'about')) {
53 6
            throw new ValidationException('Error links object MUST contain at least one of the following properties: `about`.');
54
        }
55 126
        if ($source === self::SOURCE_RELATIONSHIP && !property_exists($data, 'self') && !property_exists($data, 'related')) {
56 6
            throw new ValidationException('Relationship links object MUST contain at least one of the following properties: `self`, `related`.');
57
        }
58
59 120
        return new Links(
60 120
            Collection::wrap((array)$data)
61 120
                ->map(
62 40
                    function ($link, $name) {
63 120
                        return $this->buildLink($link, $name);
64 120
                    }
65
                )
66 78
                ->toArray()
67
        );
68
    }
69
70
    /**
71
     * @param mixed  $data
72
     * @param string $name
73
     *
74
     * @return \Swis\JsonApi\Client\Link
75
     */
76 120
    private function buildLink($data, string $name): ? Link
77
    {
78 120
        if (in_array($name, self::LINKS_THAT_MAY_NOT_BE_NULL_WHEN_PRESENT, true) && !is_string($data) && !is_object($data)) {
79 12
            throw new ValidationException(sprintf('Link "%s" has to be an object or string, "%s" given.', $name, gettype($data)));
80
        }
81
82 108
        if ($data === null) {
83 6
            return null;
84
        }
85
86 108
        if (is_string($data)) {
87 72
            return new Link($data);
88
        }
89
90 42
        if (!is_object($data)) {
91 24
            throw new ValidationException(sprintf('Link "%s" has to be an object, string or null, "%s" given.', $name, gettype($data)));
92
        }
93 18
        if (!property_exists($data, 'href')) {
94 6
            throw new ValidationException(sprintf('Link "%s" must have a "href" attribute.', $name));
95
        }
96
97 12
        return new Link($data->href, property_exists($data, 'meta') ? $this->metaParser->parse($data->meta) : null);
98
    }
99
}
100