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