Completed
Push — master ( b031f2...59e749 )
by Dominik
02:40
created

LazyModelCollection::count()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 6
rs 9.4285
c 0
b 0
f 0
cc 1
eloc 3
nc 1
nop 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Chubbyphp\Model\Collection;
6
7
use Chubbyphp\Model\ModelInterface;
8
use Chubbyphp\Model\ResolverInterface;
9
use Chubbyphp\Model\ModelSortTrait;
10
11
final class LazyModelCollection implements ModelCollectionInterface
12
{
13
    use ModelSortTrait;
14
15
    /**
16
     * @var ResolverInterface
17
     */
18
    private $resolver;
19
20
    /**
21
     * @var string
22
     */
23
    private $modelClass;
24
25
    /**
26
     * @var string
27
     */
28
    private $foreignField;
29
30
    /**
31
     * @var string
32
     */
33
    private $foreignId;
34
35
    /**
36
     * @var array|null
37
     */
38
    private $orderBy;
39
40
    /**
41
     * @var bool
42
     */
43
    private $resolved = false;
44
45
    /**
46
     * @var ModelInterface[]|array
47
     */
48
    private $initialModels;
49
50
    /**
51
     * @var ModelInterface[]|array
52
     */
53
    private $models;
54
55
    /**
56
     * @var \ReflectionProperty
57
     */
58
    private $propertyReflection;
59
60
    /**
61
     * @param ResolverInterface $resolver
62
     * @param string $modelClass
63
     * @param string $foreignField
64
     * @param string $foreignId
65
     * @param array|null $orderBy
66
     */
67 View Code Duplication
    public function __construct(
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
68
        ResolverInterface $resolver,
69
        string $modelClass,
70
        string $foreignField,
71
        string $foreignId,
72
        array $orderBy = null
73
    ) {
74
        $this->resolver = $resolver;
75
        $this->modelClass = $modelClass;
76
        $this->foreignField = $foreignField;
77
        $this->foreignId = $foreignId;
78
        $this->orderBy = $orderBy;
79
80
        $this->propertyReflection = new \ReflectionProperty($this->modelClass, $this->foreignField);
81
        $this->propertyReflection->setAccessible(true);
82
    }
83
84
    private function resolveModels()
85
    {
86
        if ($this->resolved) {
87
            return;
88
        }
89
90
        $this->resolved = true;
91
92
        $criteria = [$this->foreignField => $this->foreignId];
93
94
        $models = [];
95
        foreach ($this->resolver->findBy($this->modelClass, $criteria, $this->orderBy) as $model) {
96
            $models[$model->getId()] = $model;
97
        }
98
99
        $this->initialModels = $models;
100
        $this->models = $models;
101
    }
102
103
    /**
104
     * @param ModelInterface $model
105
     *
106
     * @return ModelCollectionInterface
107
     */
108
    public function addModel(ModelInterface $model): ModelCollectionInterface
109
    {
110
        $this->resolveModels();
111
112
        $this->propertyReflection->setValue($model, $this->foreignId);
113
114
        $this->models[$model->getId()] = $model;
115
116
        return $this;
117
    }
118
119
    /**
120
     * @param ModelInterface $model
121
     *
122
     * @return ModelCollectionInterface
123
     */
124 View Code Duplication
    public function removeModel(ModelInterface $model): ModelCollectionInterface
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
125
    {
126
        $this->resolveModels();
127
128
        if (isset($this->models[$model->getId()])) {
129
            $this->propertyReflection->setValue($model, null);
130
131
            unset($this->models[$model->getId()]);
132
        }
133
134
        return $this;
135
    }
136
137
    /**
138
     * @param ModelInterface[]|array $models
139
     *
140
     * @return ModelCollectionInterface
141
     */
142
    public function setModels(array $models): ModelCollectionInterface
143
    {
144
        $this->resolveModels();
145
146
        $this->models = [];
147
        foreach ($models as $model) {
148
            $this->addModel($model);
149
        }
150
151
        return $this;
152
    }
153
154
    /**
155
     * @return ModelInterface[]|array
156
     */
157
    public function getModels(): array
158
    {
159
        $this->resolveModels();
160
161
        return $this->sort($this->modelClass, array_values($this->models), $this->orderBy);
162
    }
163
164
    /**
165
     * @return ModelInterface[]|array
166
     */
167
    public function getInitialModels(): array
168
    {
169
        $this->resolveModels();
170
171
        return array_values($this->initialModels);
172
    }
173
174
    /**
175
     * @return \ArrayIterator
176
     */
177
    public function getIterator()
178
    {
179
        $this->resolveModels();
180
181
        return new \ArrayIterator($this->getModels());
182
    }
183
184
    /**
185
     * @return int
186
     */
187
    public function count()
188
    {
189
        $this->resolveModels();
190
191
        return count($this->getModels());
192
    }
193
194
    /**
195
     * @return array
196
     */
197
    public function jsonSerialize(): array
198
    {
199
        $this->resolveModels();
200
201
        $serializedModels = [];
202
        foreach ($this->getModels() as $model) {
203
            $serializedModels[] = $model->jsonSerialize();
204
        }
205
206
        return $serializedModels;
207
    }
208
209
    /**
210
     * @return string
211
     */
212
    public function getForeignField(): string
213
    {
214
        return $this->foreignField;
215
    }
216
217
    /**
218
     * @return string
219
     */
220
    public function getForeignId(): string
221
    {
222
        return $this->foreignId;
223
    }
224
}
225