Completed
Pull Request — master (#42)
by Jose Manuel
01:40
created

FilteredCollection   A

Complexity

Total Complexity 39

Size/Duplication

Total Lines 170
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 4

Test Coverage

Coverage 98.7%

Importance

Changes 0
Metric Value
wmc 39
lcom 1
cbo 4
dl 0
loc 170
ccs 76
cts 77
cp 0.987
rs 9.28
c 0
b 0
f 0

15 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 6 1
A __get() 0 9 2
A __unset() 0 6 2
A has() 0 10 3
A hasItem() 0 12 4
A set() 0 6 2
A getIterator() 0 4 1
A hasChildren() 0 10 3
A filter() 0 13 3
A areAllArgumentsCollections() 0 4 2
A filterItems() 0 14 3
A count() 0 13 4
A isEmpty() 0 4 1
A remove() 0 10 4
A jsonSerialize() 0 15 4
1
<?php
2
3
namespace Softonic\GraphQL\Mutation;
4
5
use Softonic\GraphQL\Mutation\Traits\MutationObjectHandler;
6
7
class FilteredCollection implements MutationObject, \IteratorAggregate, \JsonSerializable
8
{
9
    use MutationObjectHandler;
10
11
    /**
12
     * @var array<Item>
13
     */
14
    protected $arguments = [];
15
16
    /**
17
     * @var array
18
     */
19
    protected $config;
20
21
    /**
22
     * @var bool
23
     */
24
    protected $hasChanged = false;
25
26 84
    public function __construct(array $arguments = [], array $config = [], bool $hasChanged = false)
27
    {
28 84
        $this->arguments  = $arguments;
29 84
        $this->config     = $config;
30 84
        $this->hasChanged = $hasChanged;
31 84
    }
32
33 38
    public function __get(string $key): Collection
34
    {
35 38
        $items = [];
36 38
        foreach ($this->arguments as $argument) {
37 38
            $items[] = $argument->{$key};
38
        }
39
40 38
        return new Collection($items, $this->config[$key]->children);
41
    }
42
43 4
    public function __unset($key): void
44
    {
45 4
        foreach ($this->arguments as $argument) {
46 4
            unset($argument->{$key});
47
        }
48 4
    }
49
50 2
    public function has(string $key): bool
51
    {
52 2
        foreach ($this->arguments as $argument) {
53 2
            if ($argument->has($key)) {
54 2
                return true;
55
            }
56
        }
57
58 2
        return false;
59
    }
60
61 2
    public function hasItem(array $itemData): bool
62
    {
63 2
        foreach ($this->arguments as $argument) {
64 2
            $method = $argument instanceof FilteredCollection ? 'hasItem' : 'exists';
65
66 2
            if ($argument->$method($itemData)) {
67 2
                return true;
68
            }
69
        }
70
71 2
        return false;
72
    }
73
74 24
    public function set(array $data): void
75
    {
76 24
        foreach ($this->arguments as $argument) {
77 24
            $argument->set($data);
78
        }
79 24
    }
80
81 6
    public function getIterator(): \RecursiveIteratorIterator
82
    {
83 6
        return new \RecursiveIteratorIterator(new CollectionIterator($this->arguments));
84
    }
85
86 48
    public function hasChildren(): bool
87
    {
88 48
        foreach ($this->arguments as $argument) {
89 48
            if ($argument instanceof MutationObject) {
90 48
                return true;
91
            }
92
        }
93
94 4
        return false;
95
    }
96
97 22
    public function filter(array $filters): FilteredCollection
98
    {
99 22
        $filteredData = [];
100 22
        if ($this->areAllArgumentsCollections()) {
101 8
            foreach ($this->arguments as $argument) {
102 8
                $filteredData[] = $argument->filter($filters);
103
            }
104
        } else {
105 22
            $filteredData = $this->filterItems($this->arguments, $filters);
106
        }
107
108 22
        return new FilteredCollection($filteredData, $this->config);
109
    }
110
111 22
    private function areAllArgumentsCollections(): bool
112
    {
113 22
        return (!empty($this->arguments[0]) && $this->arguments[0] instanceof Collection);
114
    }
115
116
    private function filterItems(array $arguments, array $filters): array
117
    {
118 22
        $filteredItems = array_filter($arguments, function ($item) use ($filters) {
119 22
            foreach ($filters as $filterKey => $filterValue) {
120 22
                if (!($item->{$filterKey} == $filterValue)) {
121 22
                    return false;
122
                }
123
            }
124
125 22
            return true;
126 22
        });
127
128 22
        return array_values($filteredItems);
129
    }
130
131 6
    public function count(): int
132
    {
133 6
        $count = 0;
134 6
        foreach ($this->arguments as $argument) {
135 6
            if ($argument instanceof Collection) {
136 6
                $count += $argument->count();
137 4
            } elseif ($argument instanceof Item) {
138 5
                ++$count;
139
            }
140
        }
141
142 6
        return $count;
143
    }
144
145 4
    public function isEmpty(): bool
146
    {
147 4
        return $this->count() === 0;
148
    }
149
150 2
    public function remove(Item $item): void
151
    {
152 2
        foreach ($this->arguments as $key => $argument) {
153 2
            if ($argument instanceof Collection) {
154 2
                $argument->remove($item);
155 2
            } elseif ($argument === $item) {
156 2
                unset($this->arguments[$key]);
157
            }
158
        }
159 2
    }
160
161 44
    public function jsonSerialize(): array
162
    {
163 44
        if (!$this->hasChildren()) {
164
            return [];
165
        }
166
167 44
        $items = [];
168 44
        foreach ($this->arguments as $item) {
169 44
            if ($item->hasChanged()) {
170 44
                $items[] = $item->jsonSerialize();
171
            }
172
        }
173
174 44
        return $items;
175
    }
176
}
177