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

DocumentFactory   A

Complexity

Total Complexity 10

Size/Duplication

Total Lines 83
Duplicated Lines 0 %

Test Coverage

Coverage 97.06%

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 32
dl 0
loc 83
ccs 33
cts 34
cp 0.9706
rs 10
c 1
b 0
f 0
wmc 10

4 Methods

Rating   Name   Duplication   Size   Complexity  
A make() 0 11 3
A itemCanBeIncluded() 0 5 4
A getIncluded() 0 14 1
A getIncludedFromItem() 0 23 2
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