Completed
Pull Request — master (#45)
by Jose Manuel
02:24
created

AbstractCollection   A

Complexity

Total Complexity 29

Size/Duplication

Total Lines 124
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 4

Test Coverage

Coverage 100%

Importance

Changes 0
Metric Value
wmc 29
lcom 1
cbo 4
dl 0
loc 124
ccs 56
cts 56
cp 1
rs 10
c 0
b 0
f 0

12 Methods

Rating   Name   Duplication   Size   Complexity  
A has() 0 10 3
A getIterator() 0 4 1
A count() 0 13 4
A isEmpty() 0 4 1
A __get() 0 19 5
A hasItem() 0 12 4
A hasChildren() 0 10 3
A filter() 0 13 3
A areAllArgumentsCollections() 0 4 2
A filterItems() 0 17 3
buildFilteredCollection() 0 1 ?
buildSubCollection() 0 1 ?
1
<?php
2
3
namespace Softonic\GraphQL\DataObjects;
4
5
use IteratorAggregate;
6
use RecursiveIteratorIterator;
7
use Softonic\GraphQL\DataObjects\Mutation\MutationObject;
8
use Softonic\GraphQL\DataObjects\Query\Collection;
9
use Softonic\GraphQL\Exceptions\InaccessibleArgumentException;
10
use Softonic\GraphQL\Traits\CollectionArrayAccess;
11
12
abstract class AbstractCollection extends AbstractObject implements IteratorAggregate, \ArrayAccess
13
{
14
    use CollectionArrayAccess;
15
16 4
    public function has(string $key): bool
17
    {
18 4
        foreach ($this->arguments as $argument) {
19 4
            if ($argument->has($key)) {
20 4
                return true;
21
            }
22
        }
23
24 4
        return false;
25
    }
26
27 82
    public function getIterator(): RecursiveIteratorIterator
28
    {
29 82
        return new RecursiveIteratorIterator(new CollectionIterator($this->arguments));
30
    }
31
32 10
    public function count(): int
33
    {
34 10
        $count = 0;
35 10
        foreach ($this->arguments as $argument) {
36 8
            if ($argument instanceof AbstractCollection) {
37 6
                $count += $argument->count();
38 6
            } elseif ($argument instanceof AbstractItem) {
39 6
                ++$count;
40
            }
41
        }
42
43 10
        return $count;
44
    }
45
46 8
    public function isEmpty(): bool
47
    {
48 8
        return $this->count() === 0;
49
    }
50
51 52
    public function __get(string $key): AbstractCollection
52
    {
53 52
        if (empty($this->arguments)) {
54 2
            throw InaccessibleArgumentException::fromEmptyArguments($key);
55
        }
56
57 50
        $items = [];
58 50
        foreach ($this->arguments as $argument) {
59 50
            if ($argument->{$key} instanceof Collection) {
60 4
                foreach ($argument->{$key} as $item) {
61 4
                    $items[] = $item;
62
                }
63
            } else {
64 48
                $items[] = $argument->{$key};
65
            }
66
        }
67
68 50
        return $this->buildSubCollection($items, $key);
69
    }
70
71 4
    public function hasItem(array $itemData): bool
72
    {
73 4
        foreach ($this->arguments as $argument) {
74 4
            $method = $argument instanceof AbstractCollection ? 'hasItem' : 'equals';
75
76 4
            if ($argument->$method($itemData)) {
77 4
                return true;
78
            }
79
        }
80
81 4
        return false;
82
    }
83
84 48
    public function hasChildren(): bool
85
    {
86 48
        foreach ($this->arguments as $argument) {
87 48
            if ($argument instanceof MutationObject) {
88 48
                return true;
89
            }
90
        }
91
92 4
        return false;
93
    }
94
95 34
    public function filter(array $filters): AbstractCollection
96
    {
97 34
        $filteredData = [];
98 34
        if ($this->areAllArgumentsCollections()) {
99 8
            foreach ($this->arguments as $argument) {
100 8
                $filteredData[] = $argument->filter($filters);
101
            }
102
        } else {
103 34
            $filteredData = $this->filterItems($this->arguments, $filters);
104
        }
105
106 34
        return $this->buildFilteredCollection($filteredData);
107
    }
108
109 34
    private function areAllArgumentsCollections(): bool
110
    {
111 34
        return (!empty($this->arguments[0]) && $this->arguments[0] instanceof AbstractCollection);
112
    }
113
114 34
    private function filterItems(array $arguments, array $filters): array
115
    {
116 34
        $filteredItems = array_filter(
117 34
            $arguments,
118
            function ($item) use ($filters) {
119 34
                foreach ($filters as $filterKey => $filterValue) {
120 34
                    if (!($item->{$filterKey} == $filterValue)) {
121 34
                        return false;
122
                    }
123
                }
124
125 32
                return true;
126 34
            }
127
        );
128
129 34
        return array_values($filteredItems);
130
    }
131
132
    abstract protected function buildFilteredCollection($items);
133
134
    abstract protected function buildSubCollection(array $items, string $key);
135
}
136