1<?php
2
3/**
4 * This file is part of the FreeDSx LDAP package.
5 *
6 * (c) Chad Sikorra <Chad.Sikorra@gmail.com>
7 *
8 * For the full copyright and license information, please view the LICENSE
9 * file that was distributed with this source code.
10 */
11
12namespace FreeDSx\Ldap\Entry;
13
14use ArrayIterator;
15use Countable;
16use IteratorAggregate;
17use Traversable;
18use function array_search;
19use function count;
20
21/**
22 * Represents a set of change objects.
23 *
24 * @author Chad Sikorra <Chad.Sikorra@gmail.com>
25 */
26class Changes implements Countable, IteratorAggregate
27{
28    /**
29     * @var Change[]
30     * @psalm-var list<Change>
31     */
32    protected $changes = [];
33
34    /**
35     * @param Change ...$changes
36     */
37    public function __construct(Change ...$changes)
38    {
39        $this->changes = $changes;
40    }
41
42    /**
43     * Add a change to the list.
44     *
45     * @param Change ...$changes
46     * @return $this
47     */
48    public function add(Change ...$changes)
49    {
50        foreach ($changes as $change) {
51            $this->changes[] = $change;
52        }
53
54        return $this;
55    }
56
57    /**
58     * Check if the change is in the change list.
59     *
60     * @param Change $change
61     * @return bool
62     */
63    public function has(Change $change)
64    {
65        return array_search($change, $this->changes, true) !== false;
66    }
67
68    /**
69     * Remove a change from the list.
70     *
71     * @param Change ...$changes
72     * @return $this
73     */
74    public function remove(Change ...$changes)
75    {
76        foreach ($changes as $change) {
77            if (($index = array_search($change, $this->changes, true)) !== false) {
78                unset($this->changes[$index]);
79            }
80        }
81
82        return $this;
83    }
84
85    /**
86     * Removes all changes from the list.
87     *
88     * @return $this
89     */
90    public function reset()
91    {
92        $this->changes = [];
93
94        return $this;
95    }
96
97    /**
98     * Set the change list to just these changes.
99     *
100     * @param Change ...$changes
101     * @return $this
102     */
103    public function set(Change ...$changes)
104    {
105        $this->changes = $changes;
106
107        return $this;
108    }
109
110    /**
111     * @return Change[]
112     */
113    public function toArray(): array
114    {
115        return $this->changes;
116    }
117
118    /**
119     * @inheritDoc
120     * @psalm-return 0|positive-int
121     */
122    public function count(): int
123    {
124        return count($this->changes);
125    }
126
127    /**
128     * @inheritDoc
129     * @psalm-return \ArrayIterator<int, Change>
130     */
131    public function getIterator(): Traversable
132    {
133        return new ArrayIterator($this->changes);
134    }
135}
136