Completed
Push — master ( c60dc8...c69317 )
by Jasper
19s queued 10s
created

LinksParser::parse()   A

Complexity

Conditions 6
Paths 3

Size

Total Lines 17
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 9
CRAP Score 6

Importance

Changes 0
Metric Value
cc 6
eloc 10
nc 3
nop 2
dl 0
loc 17
ccs 9
cts 9
cp 1
crap 6
rs 9.2222
c 0
b 0
f 0
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 618
23
    private const LINKS_THAT_MAY_NOT_BE_NULL_WHEN_PRESENT = [
24 618
        'self',
25 618
        'related',
26
    ];
27
28
    /**
29
     * @var \Swis\JsonApi\Client\Parsers\MetaParser
30
     */
31
    private $metaParser;
32 108
33
    /**
34 108
     * @param \Swis\JsonApi\Client\Parsers\MetaParser $metaParser
35 108
     */
36 36
    public function __construct(MetaParser $metaParser)
37 108
    {
38 108
        $this->metaParser = $metaParser;
39 108
    }
40
41
    /**
42
     * @param mixed  $data
43
     * @param string $source
44
     *
45
     * @return \Swis\JsonApi\Client\Links
46
     */
47
    public function parse($data, string $source): Links
48
    {
49 108
        if ($source === self::SOURCE_ERROR && !property_exists($data, 'about')) {
50
            throw new ValidationException('Error links object MUST contain at least one of the following properties: `about`.');
51 108
        }
52 6
        if ($source === self::SOURCE_RELATIONSHIP && !property_exists($data, 'self') && !property_exists($data, 'related')) {
53
            throw new ValidationException('Relationship links object MUST contain at least one of the following properties: `self`, `related`.');
54
        }
55 108
56 72
        return new Links(
57
            Collection::wrap((array)$data)
58
                ->map(
59 42
                    function ($link, $name) {
60 24
                        return $this->buildLink($link, $name);
61
                    }
62 18
                )
63 6
                ->toArray()
64
        );
65
    }
66 12
67
    /**
68
     * @param mixed  $data
69
     * @param string $name
70
     *
71
     * @return \Swis\JsonApi\Client\Link
72
     */
73
    private function buildLink($data, string $name): ? Link
74
    {
75
        if (in_array($name, self::LINKS_THAT_MAY_NOT_BE_NULL_WHEN_PRESENT, true) && !is_string($data) && !is_object($data)) {
76
            throw new ValidationException(sprintf('Link "%s" has to be an object or string, "%s" given.', $name, gettype($data)));
77
        }
78
79
        if ($data === null) {
80
            return null;
81
        }
82
83
        if (is_string($data)) {
84
            return new Link($data);
85
        }
86
87
        if (!is_object($data)) {
88
            throw new ValidationException(sprintf('Link "%s" has to be an object, string or null, "%s" given.', $name, gettype($data)));
89
        }
90
        if (!property_exists($data, 'href')) {
91
            throw new ValidationException(sprintf('Link "%s" must have a "href" attribute.', $name));
92
        }
93
94
        return new Link($data->href, property_exists($data, 'meta') ? $this->metaParser->parse($data->meta) : null);
95
    }
96
}
97