EntityCollection::add()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 6
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
c 2
b 0
f 0
dl 0
loc 6
rs 9.4285
cc 1
eloc 3
nc 1
nop 1
1
<?php
2
3
namespace Analogue\ORM;
4
5
use Analogue\ORM\Exceptions\MappingException;
6
use Analogue\ORM\System\Manager;
7
use Analogue\ORM\System\Wrappers\Factory;
8
use Illuminate\Support\Collection;
9
use Illuminate\Support\Arr;
10
11
class EntityCollection extends Collection
12
{
13
    /**
14
     * Wrapper Factory
15
     *
16
     * @var \Analogue\ORM\System\Wrappers\Factory
17
     */
18
    protected $factory;
19
20
    /**
21
     * EntityCollection constructor.
22
     * @param array|null $entities
23
     */
24
    public function __construct(array $entities = null)
25
    {
26
        $this->factory = new Factory;
27
28
        parent::__construct($entities);
29
    }
30
31
    /**
32
     * Find an entity in the collection by key.
33
     *
34
     * @param  mixed $key
35
     * @param  mixed $default
36
     * @throws MappingException
37
     * @return \Analogue\ORM\Entity
38
     */
39
    public function find($key, $default = null)
40
    {
41
        if ($key instanceof Mappable) {
42
            $key = $this->getEntityKey($key);
43
        }
44
45
        return array_first($this->items, function ($itemKey, $entity) use ($key) {
46
            return $this->getEntityKey($entity) == $key;
47
        }, $default);
48
    }
49
50
    /**
51
     * Add an entity to the collection.
52
     *
53
     * @param  Mappable $entity
54
     * @return $this
55
     */
56
    public function add($entity)
57
    {
58
        $this->push($entity);
59
60
        return $this;
61
    }
62
63
    /**
64
     * Remove an entity from the collection
65
     *
66
     * @param $entity
67
     * @throws MappingException
68
     * @return mixed
69
     */
70
    public function remove($entity)
71
    {
72
        $key = $this->getEntityKey($entity);
73
74
        return $this->pull($key);
75
    }
76
77
    /**
78
     * Push an item onto the end of the collection.
79
     *
80
     * @param  mixed $value
81
     * @return void
82
     */
83
    public function push($value)
84
    {
85
        $this->offsetSet(null, $value);
86
    }
87
88
    /**
89
     * Put an item in the collection by key.
90
     *
91
     * @param  mixed $key
92
     * @param  mixed $value
93
     * @return void
94
     */
95
    public function put($key, $value)
96
    {
97
        $this->offsetSet($key, $value);
98
    }
99
100
    /**
101
     * Set the item at a given offset.
102
     *
103
     * @param  mixed $key
104
     * @param  mixed $value
105
     * @return void
106
     */
107
    public function offsetSet($key, $value)
108
    {
109
        if (is_null($key)) {
110
            $this->items[] = $value;
111
        } else {
112
            $this->items[$key] = $value;
113
        }
114
    }
115
116
    /**
117
     * Determine if a key exists in the collection.
118
     *
119
     * @param  mixed      $key
120
     * @param  mixed|null $value
121
     * @return bool
122
     */
123
    public function contains($key, $value = null)
124
    {
125
        if (func_num_args() == 2) {
126
            return !$this->where($key, $value)->isEmpty();
127
        }
128
129
        if ($this->useAsCallable($key)) {
130
            return !is_null($this->first($key));
131
        }
132
133
        return !is_null($this->find($key));
134
    }
135
136
    /**
137
     * Fetch a nested element of the collection.
138
     *
139
     * @param  string $key
140
     * @return self
141
     */
142
    public function fetch($key)
143
    {
144
        return new static(array_fetch($this->toArray(), $key));
145
    }
146
147
    /**
148
     * Generic function for returning class.key value pairs
149
     *
150
     * @throws MappingException
151
     * @return string
152
     */
153 View Code Duplication
    public function getEntityHashes()
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...
154
    {
155
        return array_map(function ($entity) {
156
            $class = get_class($entity);
157
158
            $mapper = Manager::getMapper($class);
159
160
            $keyName = $mapper->getEntityMap()->getKeyName();
161
162
            return $class . '.' . $entity->getEntityAttribute($keyName);
163
        },
164
        $this->items);
165
    }
166
167
    /**
168
     * Get a subset of the collection from entity hashes
169
     *
170
     * @param  array $hashes
171
     * @throws MappingException
172
     * @return array
173
     */
174
    public function getSubsetByHashes(array $hashes)
175
    {
176
        $subset = [];
177
178
        foreach ($this->items as $item) {
179
            $class = get_class($item);
180
181
            $mapper = Manager::getMapper($class);
182
183
            $keyName = $mapper->getEntityMap()->getKeyName();
184
185
            if (in_array($class . '.' . $item->$keyName, $hashes)) {
186
                $subset[] = $item;
187
            }
188
        }
189
190
        return $subset;
191
    }
192
193
    /**
194
     * Merge the collection with the given items.
195
     *
196
     * @param  array $items
197
     * @throws MappingException
198
     * @return self
199
     */
200
    public function merge($items)
201
    {
202
        $dictionary = $this->getDictionary();
203
204
        foreach ($items as $item) {
205
            $dictionary[$this->getEntityKey($item)] = $item;
206
        }
207
208
        return new static(array_values($dictionary));
209
    }
210
211
    /**
212
     * Diff the collection with the given items.
213
     *
214
     * @param  \ArrayAccess|array $items
215
     * @return self
216
     */
217 View Code Duplication
    public function diff($items)
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...
218
    {
219
        $diff = new static;
220
221
        $dictionary = $this->getDictionary($items);
222
223
        foreach ($this->items as $item) {
224
            if (!isset($dictionary[$this->getEntityKey($item)])) {
225
                $diff->add($item);
226
            }
227
        }
228
229
        return $diff;
230
    }
231
232
    /**
233
     * Intersect the collection with the given items.
234
     *
235
     * @param  \ArrayAccess|array $items
236
     * @throws MappingException
237
     * @return self
238
     */
239 View Code Duplication
    public function intersect($items)
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...
240
    {
241
        $intersect = new static;
242
243
        $dictionary = $this->getDictionary($items);
244
245
        foreach ($this->items as $item) {
246
            if (isset($dictionary[$this->getEntityKey($item)])) {
247
                $intersect->add($item);
248
            }
249
        }
250
251
        return $intersect;
252
    }
253
254
    /**
255
     * Returns only the models from the collection with the specified keys.
256
     *
257
     * @param  mixed $keys
258
     * @return self
259
     */
260
    public function only($keys)
261
    {
262
        $dictionary = array_only($this->getDictionary(), $keys);
263
264
        return new static(array_values($dictionary));
265
    }
266
267
    /**
268
     * Returns all models in the collection except the models with specified keys.
269
     *
270
     * @param  mixed $keys
271
     * @return self
272
     */
273
    public function except($keys)
274
    {
275
        $dictionary = array_except($this->getDictionary(), $keys);
276
277
        return new static(array_values($dictionary));
278
    }
279
280
    /**
281
     * Get a dictionary keyed by primary keys.
282
     *
283
     * @param  \ArrayAccess|array $items
284
     * @throws MappingException
285
     * @return array
286
     */
287
    public function getDictionary($items = null)
288
    {
289
        $items = is_null($items) ? $this->items : $items;
290
291
        $dictionary = [];
292
293
        foreach ($items as $value) {
294
            $dictionary[$this->getEntityKey($value)] = $value;
295
        }
296
297
        return $dictionary;
298
    }
299
300
    /**
301
     * @throws MappingException
302
     * @return array
303
     */
304
    public function getEntityKeys()
305
    {
306
        return array_keys($this->getDictionary());
307
    }
308
309
    /**
310
     * @param $entity
311
     * @throws MappingException
312
     * @return mixed
313
     */
314
    protected function getEntityKey($entity)
315
    {
316
        $keyName = Manager::getMapper($entity)->getEntityMap()->getKeyName();
317
318
        $wrapper = $this->factory->make($entity);
319
320
        return $wrapper->getEntityAttribute($keyName);
321
    }
322
323
    /**
324
     * Get the max value of a given key.
325
     *
326
     * @param  string|null $key
327
     * @throws MappingException
328
     * @return mixed
329
     */
330 View Code Duplication
    public function max($key = null)
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...
331
    {
332
        return $this->reduce(function ($result, $item) use ($key) {
333
            $wrapper = $this->factory->make($item);
334
335
            return (is_null($result) || $wrapper->getEntityAttribute($key) > $result) ?
336
                $wrapper->getEntityAttribute($key) : $result;
337
        });
338
    }
339
340
    /**
341
     * Get the min value of a given key.
342
     *
343
     * @param  string|null $key
344
     * @throws MappingException
345
     * @return mixed
346
     */
347 View Code Duplication
    public function min($key = null)
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...
348
    {
349
        return $this->reduce(function ($result, $item) use ($key) {
350
            $wrapper = $this->factory->make($item);
351
352
            return (is_null($result) || $wrapper->getEntityAttribute($key) < $result)
353
                ? $wrapper->getEntityAttribute($key) : $result;
354
        });
355
    }
356
357
    /**
358
     * Get an array with the values of a given key.
359
     *
360
     * @param  string $value
361
     * @param  string|null $key
362
     * @return self
363
     */
364
    public function pluck($value, $key = null)
365
    {
366
        return new Collection(Arr::pluck($this->items, $value, $key));
367
    }
368
369
    /**
370
     * Alias for the "pluck" method.
371
     *
372
     * @param  string $value
373
     * @param  string|null $key
374
     * @return self
375
     */
376
    public function lists($value, $key = null)
377
    {
378
        return $this->pluck($value, $key);
379
    }
380
381
    /**
382
     * Return only unique items from the collection.
383
     *
384
     * @param  string|null $key
385
     * @throws MappingException
386
     * @return self
387
     */
388
    public function unique($key = null)
389
    {
390
        $dictionary = $this->getDictionary();
391
392
        return new static(array_values($dictionary));
393
    }
394
395
    /**
396
     * Get a base Support collection instance from this collection.
397
     *
398
     * @return \Illuminate\Support\Collection
399
     */
400
    public function toBase()
401
    {
402
        return new Collection($this->items);
403
    }
404
}
405