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 function count;
15
16/**
17 * Represents an entry change.
18 *
19 * @author Chad Sikorra <Chad.Sikorra@gmail.com>
20 */
21class Change
22{
23    /**
24     * Add a value to an attribute.
25     */
26    public const TYPE_ADD = 0;
27
28    /**
29     * Delete a value, or values, from an attribute.
30     */
31    public const TYPE_DELETE = 1;
32
33    /**
34     * Replaces the current value of an attribute with a different one.
35     */
36    public const TYPE_REPLACE = 2;
37
38    /**
39     * @var int
40     */
41    protected $modType;
42
43    /**
44     * @var Attribute
45     */
46    protected $attribute;
47
48    /**
49     * @param int $modType
50     * @param string|Attribute $attribute
51     * @param string ...$values
52     */
53    public function __construct(int $modType, $attribute, ...$values)
54    {
55        $this->modType = $modType;
56        $this->attribute = $attribute instanceof Attribute ? $attribute : new Attribute($attribute, ...$values);
57    }
58
59    /**
60     * @return Attribute
61     */
62    public function getAttribute(): Attribute
63    {
64        return $this->attribute;
65    }
66
67    /**
68     * @param Attribute $attribute
69     * @return $this
70     */
71    public function setAttribute(Attribute $attribute)
72    {
73        $this->attribute = $attribute;
74
75        return $this;
76    }
77
78    /**
79     * @return int
80     */
81    public function getType(): int
82    {
83        return $this->modType;
84    }
85
86    /**
87     * @param int $modType
88     * @return $this
89     */
90    public function setType(int $modType)
91    {
92        $this->modType = $modType;
93
94        return $this;
95    }
96
97    /**
98     * @return bool
99     */
100    public function isAdd(): bool
101    {
102        return $this->modType === self::TYPE_ADD;
103    }
104
105    /**
106     * @return bool
107     */
108    public function isDelete(): bool
109    {
110        return $this->modType === self::TYPE_DELETE && count($this->attribute->getValues()) !== 0;
111    }
112
113    /**
114     * @return bool
115     */
116    public function isReplace(): bool
117    {
118        return $this->modType === self::TYPE_REPLACE;
119    }
120
121    /**
122     * @return bool
123     */
124    public function isReset(): bool
125    {
126        return $this->modType === self::TYPE_DELETE && count($this->attribute->getValues()) === 0;
127    }
128
129    /**
130     * Add the values contained in the attribute, creating the attribute if necessary.
131     *
132     * @param string|Attribute $attribute
133     * @param string ...$values
134     * @return Change
135     */
136    public static function add($attribute, ...$values): Change
137    {
138        $attribute = $attribute instanceof Attribute ? $attribute : new Attribute($attribute, ...$values);
139
140        return new self(self::TYPE_ADD, $attribute);
141    }
142
143    /**
144     * Delete values from the attribute. If no values are listed, or if all current values of the attribute are listed,
145     * the entire attribute is removed.
146     *
147     * @param Attribute|string $attribute
148     * @param string ...$values
149     * @return Change
150     */
151    public static function delete($attribute, ...$values): Change
152    {
153        $attribute = $attribute instanceof Attribute ? $attribute : new Attribute($attribute, ...$values);
154
155        return new self(self::TYPE_DELETE, $attribute);
156    }
157
158    /**
159     * Replace all existing values with the new values, creating the attribute if it did not already exist.  A replace
160     * with no value will delete the entire attribute if it exists, and it is ignored if the attribute does not exist.
161     *
162     * @param Attribute|string $attribute
163     * @param string ...$values
164     * @return Change
165     */
166    public static function replace($attribute, ...$values): Change
167    {
168        $attribute = $attribute instanceof Attribute ? $attribute : new Attribute($attribute, ...$values);
169
170        return new self(self::TYPE_REPLACE, $attribute);
171    }
172
173    /**
174     * Remove all values from an attribute, essentially un-setting/resetting it. This is the same type as delete when
175     * going to LDAP. The real difference being that no values are attached to the change.
176     *
177     * @param string|Attribute $attribute
178     * @return Change
179     */
180    public static function reset($attribute): Change
181    {
182        $attribute = $attribute instanceof Attribute ? new Attribute($attribute->getDescription()) : new Attribute($attribute);
183
184        return new self(self::TYPE_DELETE, $attribute);
185    }
186}
187