Completed
Push — master ( cbb9ee...a654a8 )
by Jasper
05:35
created

DocumentFactory::itemCanBeIncluded()   A

Complexity

Conditions 4
Paths 5

Size

Total Lines 5
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 4

Importance

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