Completed
Push — master ( ca0a68...24aef7 )
by Jasper
04:58
created

LinksParser   A

Complexity

Total Complexity 16

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 16

3 Methods

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