Completed
Push — master ( 58f265...493087 )
by Beñat
01:57
created

Collection::removeElement()   B

Complexity

Conditions 5
Paths 5

Size

Total Lines 16
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 16
rs 8.8571
c 0
b 0
f 0
cc 5
eloc 9
nc 5
nop 1
1
<?php
2
3
/*
4
 * This file is part of the Shared Kernel library.
5
 *
6
 * Copyright (c) 2016-present LIN3S <[email protected]>
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11
12
declare(strict_types=1);
13
14
namespace LIN3S\SharedKernel\Domain\Model\Collection;
15
16
use Doctrine\Common\Collections\ArrayCollection;
17
use LIN3S\SharedKernel\Domain\Model\Identity\Id;
18
19
/**
20
 * @author Beñat Espiña <[email protected]>
21
 */
22
abstract class Collection extends ArrayCollection
23
{
24
    abstract protected function type();
25
26
    public function __construct(array $elements = [])
27
    {
28
        foreach ($elements as $element) {
29
            $this->validate($element);
30
        }
31
        parent::__construct($elements);
32
    }
33
34
    public function add($element) : void
35
    {
36
        $this->validate($element);
37
38
        if ($this->contains($element)) {
39
            throw new CollectionElementAlreadyAddedException();
40
        }
41
        parent::add($element);
42
    }
43
44
    public function removeElement($element) : void
45
    {
46
        if (!$this->contains($element)) {
47
            throw new CollectionElementAlreadyRemovedException();
48
        }
49
        if ($element instanceof Id) {
50
            foreach ($this->toArray() as $key => $el) {
51
                if ($element->equals($el)) {
52
                    $this->remove($key);
53
                }
54
            }
55
56
            return;
57
        }
58
        parent::removeElement($element);
59
    }
60
61
    public function contains($element) : bool
62
    {
63
        if ($element instanceof Id) {
64
            foreach ($this->toArray() as $el) {
65
                if ($element->equals($el)) {
66
                    return true;
67
                }
68
            }
69
70
            return false;
71
        }
72
73
        return parent::contains($element);
74
    }
75
76
    private function validate($element) : void
77
    {
78
        if (is_scalar($element)
79
            || false === (is_subclass_of($element, $this->type())
80
                || (get_class($element) === $this->type())
81
            )
82
        ) {
83
            throw new CollectionElementInvalidException();
84
        }
85
    }
86
}
87