Completed
Push — master ( 24b486...2b6901 )
by Jasper
14s queued 10s
created

DocumentFactory::make()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 11
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 6
CRAP Score 3.0261

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 3
eloc 7
c 1
b 0
f 0
nc 3
nop 1
dl 0
loc 11
ccs 6
cts 7
cp 0.8571
crap 3.0261
rs 10
1
<?php
2
3
namespace Swis\JsonApi\Client;
4
5
use Swis\JsonApi\Client\Interfaces\DataInterface;
6
use Swis\JsonApi\Client\Interfaces\DocumentInterface;
7
use Swis\JsonApi\Client\Interfaces\ItemInterface;
8
9
class DocumentFactory
10
{
11
    /**
12
     * @param \Swis\JsonApi\Client\Interfaces\DataInterface $data
13
     *
14
     * @return \Swis\JsonApi\Client\Interfaces\DocumentInterface
15
     */
16 45
    public function make(DataInterface $data): DocumentInterface
17
    {
18 45
        if ($data instanceof ItemInterface) {
19 35
            $document = new ItemDocument();
20 10
        } elseif ($data instanceof Collection) {
21 10
            $document = new CollectionDocument();
22
        } else {
23
            throw new \InvalidArgumentException(sprintf('%s is not supported as input', get_class($data)));
24
        }
25
26 45
        return $document->setData($data)->setIncluded($this->getIncluded($data));
27
    }
28
29
    /**
30
     * @param \Swis\JsonApi\Client\Interfaces\DataInterface $data
31
     *
32
     * @return \Swis\JsonApi\Client\Collection
33
     */
34 45
    private function getIncluded(DataInterface $data): Collection
35
    {
36 45
        return Collection::wrap($data)
37 45
            ->flatMap(
38 18
                function (ItemInterface $item) {
39 45
                    return $this->getIncludedFromItem($item);
40 45
                }
41
            )
42 45
            ->unique(
43 18
                static function (ItemInterface $item) {
44 20
                    return sprintf('%s:%s', $item->getType(), $item->getId());
45 45
                }
46
            )
47 45
            ->values();
48
    }
49
50
    /**
51
     * @param \Swis\JsonApi\Client\Interfaces\ItemInterface $item
52
     *
53
     * @return \Swis\JsonApi\Client\Collection
54
     */
55 45
    private function getIncludedFromItem(ItemInterface $item): Collection
56
    {
57 45
        return Collection::make($item->getRelations())
58 45
            ->reject(
59 18
                static function ($relationship) {
60
                    /* @var \Swis\JsonApi\Client\Interfaces\OneRelationInterface|\Swis\JsonApi\Client\Interfaces\ManyRelationInterface $relationship */
61 35
                    return $relationship->shouldOmitIncluded() || !$relationship->hasIncluded();
62 45
                }
63
            )
64 45
            ->flatMap(
65 18
                static function ($relationship) {
66
                    /* @var \Swis\JsonApi\Client\Interfaces\OneRelationInterface|\Swis\JsonApi\Client\Interfaces\ManyRelationInterface $relationship */
67 35
                    return Collection::wrap($relationship->getIncluded());
68 45
                }
69
            )
70 45
            ->flatMap(
71 18
                function (ItemInterface $item) {
72 35
                    return Collection::wrap($item)->merge($this->getIncludedFromItem($item));
73 45
                }
74
            )
75 45
            ->filter(
76 18
                function (ItemInterface $item) {
77 35
                    return $this->itemCanBeIncluded($item);
78 45
                }
79
            );
80
    }
81
82
    /**
83
     * @param \Swis\JsonApi\Client\Interfaces\ItemInterface $item
84
     *
85
     * @return bool
86
     */
87 35
    private function itemCanBeIncluded(ItemInterface $item): bool
88
    {
89 35
        return $item->hasType()
90 35
            && $item->hasId()
91 35
            && ($item->hasAttributes() || $item->hasRelationships());
92
    }
93
}
94