Completed
Pull Request — master (#52)
by Jasper
11:29
created

DocumentFactory::make()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 10
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

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