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\Control;
13
14use ArrayIterator;
15use Countable;
16use IteratorAggregate;
17use Traversable;
18use function array_search;
19use function count;
20use function is_string;
21
22/**
23 * Represents a set of controls.
24 *
25 * @author Chad Sikorra <Chad.Sikorra@gmail.com>
26 */
27class ControlBag implements IteratorAggregate, Countable
28{
29    /**
30     * @var Control[]
31     */
32    protected $controls;
33
34    /**
35     * ControlBag constructor.
36     * @param Control ...$controls
37     */
38    public function __construct(Control ...$controls)
39    {
40        $this->controls = $controls;
41    }
42
43    /**
44     * Check if a specific control exists by either the OID string or the Control object (strict check).
45     *
46     * @param string|Control $control
47     * @return bool
48     */
49    public function has($control): bool
50    {
51        if (is_string($control)) {
52            foreach ($this->controls as $ctrl) {
53                if ($ctrl->getTypeOid() === $control) {
54                    return true;
55                }
56            }
57
58            return false;
59        }
60
61        return array_search($control, $this->controls, true) !== false;
62    }
63
64    /**
65     * Get a control object by the string OID type. If none is found it will return null. Can check first with has.
66     *
67     * @param string $oid
68     * @return null|Control
69     */
70    public function get(string $oid): ?Control
71    {
72        foreach ($this->controls as $control) {
73            if ($oid === $control->getTypeOid()) {
74                return $control;
75            }
76        }
77
78        return null;
79    }
80
81    /**
82     * Add more controls.
83     *
84     * @param Control ...$controls
85     * @return $this
86     */
87    public function add(Control ...$controls)
88    {
89        foreach ($controls as $control) {
90            $this->controls[] = $control;
91        }
92
93        return $this;
94    }
95
96    /**
97     * Set the controls.
98     *
99     * @param Control ...$controls
100     * @return $this
101     */
102    public function set(Control ...$controls)
103    {
104        $this->controls = $controls;
105
106        return $this;
107    }
108
109    /**
110     * Remove controls by OID or Control object (strict check).
111     *
112     * @param Control|string ...$controls
113     * @return $this
114     */
115    public function remove(...$controls)
116    {
117        /** @var Control|string $control */
118        foreach ($controls as $control) {
119            if (is_string($control)) {
120                foreach ($this->controls as $i => $ctrl) {
121                    if ($ctrl->getTypeOid() === $control) {
122                        unset($this->controls[$i]);
123                    }
124                }
125            } else {
126                if (($i = array_search($control, $this->controls, true)) !== false) {
127                    unset($this->controls[$i]);
128                }
129            }
130        }
131
132        return $this;
133    }
134
135    /**
136     * Remove all of the controls.
137     *
138     * @return $this
139     */
140    public function reset()
141    {
142        $this->controls = [];
143
144        return $this;
145    }
146
147    /**
148     * Get the array of Control objects.
149     *
150     * @return Control[]
151     */
152    public function toArray(): array
153    {
154        return $this->controls;
155    }
156
157    /**
158     * @inheritDoc
159     */
160    public function count(): int
161    {
162        return count($this->controls);
163    }
164
165    /**
166     * @inheritDoc
167     * @psalm-return \ArrayIterator<array-key, Control>
168     */
169    public function getIterator(): Traversable
170    {
171        return new ArrayIterator($this->controls);
172    }
173}
174