| <?php |
| |
| namespace LdapRecord\Models; |
| |
| use InvalidArgumentException; |
| |
| class BatchModification |
| { |
| use DetectsResetIntegers; |
| |
| /** |
| * The array keys to be used in batch modifications. |
| */ |
| const KEY_ATTRIB = 'attrib'; |
| const KEY_MODTYPE = 'modtype'; |
| const KEY_VALUES = 'values'; |
| |
| /** |
| * The attribute of the modification. |
| * |
| * @var string|null |
| */ |
| protected $attribute; |
| |
| /** |
| * The original value of the attribute before modification. |
| * |
| * @var array |
| */ |
| protected $original = []; |
| |
| /** |
| * The values of the modification. |
| * |
| * @var array |
| */ |
| protected $values = []; |
| |
| /** |
| * The modtype integer of the batch modification. |
| * |
| * @var int|null |
| */ |
| protected $type; |
| |
| /** |
| * Constructor. |
| * |
| * @param string|null $attribute |
| * @param string|int|null $type |
| * @param array $values |
| */ |
| public function __construct($attribute = null, $type = null, array $values = []) |
| { |
| $this->setAttribute($attribute) |
| ->setType($type) |
| ->setValues($values); |
| } |
| |
| /** |
| * Set the original value of the attribute before modification. |
| * |
| * @param array|string $original |
| * |
| * @return $this |
| */ |
| public function setOriginal($original = []) |
| { |
| $this->original = $this->normalizeAttributeValues($original); |
| |
| return $this; |
| } |
| |
| /** |
| * Returns the original value of the attribute before modification. |
| * |
| * @return array |
| */ |
| public function getOriginal() |
| { |
| return $this->original; |
| } |
| |
| /** |
| * Set the attribute of the modification. |
| * |
| * @param string $attribute |
| * |
| * @return $this |
| */ |
| public function setAttribute($attribute) |
| { |
| $this->attribute = $attribute; |
| |
| return $this; |
| } |
| |
| /** |
| * Returns the attribute of the modification. |
| * |
| * @return string |
| */ |
| public function getAttribute() |
| { |
| return $this->attribute; |
| } |
| |
| /** |
| * Set the values of the modification. |
| * |
| * @param array $values |
| * |
| * @return $this |
| */ |
| public function setValues(array $values = []) |
| { |
| // Null and empty values must also not be added to a batch |
| // modification. Passing null or empty values will result |
| // in an exception when trying to save the modification. |
| $this->values = array_filter($this->normalizeAttributeValues($values), function ($value) { |
| return is_numeric($value) && $this->valueIsResetInteger((int) $value) ?: ! empty($value); |
| }); |
| |
| return $this; |
| } |
| |
| /** |
| * Normalize all of the attribute values. |
| * |
| * @param array|string $values |
| * |
| * @return array |
| */ |
| protected function normalizeAttributeValues($values = []) |
| { |
| // We must convert all of the values to strings. Only strings can |
| // be used in batch modifications, otherwise we will we will |
| // receive an LDAP exception while attempting to save. |
| return array_map('strval', (array) $values); |
| } |
| |
| /** |
| * Returns the values of the modification. |
| * |
| * @return array |
| */ |
| public function getValues() |
| { |
| return $this->values; |
| } |
| |
| /** |
| * Set the type of the modification. |
| * |
| * @param int|null $type |
| * |
| * @return $this |
| */ |
| public function setType($type = null) |
| { |
| if (is_null($type)) { |
| return $this; |
| } |
| |
| if (! $this->isValidType($type)) { |
| throw new InvalidArgumentException('Given batch modification type is invalid.'); |
| } |
| |
| $this->type = $type; |
| |
| return $this; |
| } |
| |
| /** |
| * Returns the type of the modification. |
| * |
| * @return int |
| */ |
| public function getType() |
| { |
| return $this->type; |
| } |
| |
| /** |
| * Determines if the batch modification is valid in its current state. |
| * |
| * @return bool |
| */ |
| public function isValid() |
| { |
| return ! is_null($this->get()); |
| } |
| |
| /** |
| * Builds the type of modification automatically |
| * based on the current and original values. |
| * |
| * @return $this |
| */ |
| public function build() |
| { |
| switch (true) { |
| case empty($this->original) && empty($this->values): |
| return $this; |
| case ! empty($this->original) && empty($this->values): |
| return $this->setType(LDAP_MODIFY_BATCH_REMOVE_ALL); |
| case empty($this->original) && ! empty($this->values): |
| return $this->setType(LDAP_MODIFY_BATCH_ADD); |
| default: |
| return $this->determineBatchTypeFromOriginal(); |
| } |
| } |
| |
| /** |
| * Determine the batch modification type from the original values. |
| * |
| * @return $this |
| */ |
| protected function determineBatchTypeFromOriginal() |
| { |
| $added = $this->getAddedValues(); |
| $removed = $this->getRemovedValues(); |
| |
| switch (true) { |
| case ! empty($added) && ! empty($removed): |
| return $this->setType(LDAP_MODIFY_BATCH_REPLACE); |
| case ! empty($added): |
| return $this->setValues($added)->setType(LDAP_MODIFY_BATCH_ADD); |
| case ! empty($removed): |
| return $this->setValues($removed)->setType(LDAP_MODIFY_BATCH_REMOVE); |
| default: |
| return $this; |
| } |
| } |
| |
| /** |
| * Get the values that were added to the attribute. |
| * |
| * @return array |
| */ |
| protected function getAddedValues() |
| { |
| return array_values( |
| array_diff($this->values, $this->original) |
| ); |
| } |
| |
| /** |
| * Get the values that were removed from the attribute. |
| * |
| * @return array |
| */ |
| protected function getRemovedValues() |
| { |
| return array_values( |
| array_diff($this->original, $this->values) |
| ); |
| } |
| |
| /** |
| * Returns the built batch modification array. |
| * |
| * @return array|null |
| */ |
| public function get() |
| { |
| switch ($this->type) { |
| case LDAP_MODIFY_BATCH_REMOVE_ALL: |
| // A values key cannot be provided when |
| // a remove all type is selected. |
| return [ |
| static::KEY_ATTRIB => $this->attribute, |
| static::KEY_MODTYPE => $this->type, |
| ]; |
| case LDAP_MODIFY_BATCH_REMOVE: |
| // Fallthrough. |
| case LDAP_MODIFY_BATCH_ADD: |
| // Fallthrough. |
| case LDAP_MODIFY_BATCH_REPLACE: |
| return [ |
| static::KEY_ATTRIB => $this->attribute, |
| static::KEY_MODTYPE => $this->type, |
| static::KEY_VALUES => $this->values, |
| ]; |
| default: |
| // If the modtype isn't recognized, we'll return null. |
| return; |
| } |
| } |
| |
| /** |
| * Determines if the given modtype is valid. |
| * |
| * @param int $type |
| * |
| * @return bool |
| */ |
| protected function isValidType($type) |
| { |
| return in_array($type, [ |
| LDAP_MODIFY_BATCH_REMOVE_ALL, |
| LDAP_MODIFY_BATCH_REMOVE, |
| LDAP_MODIFY_BATCH_REPLACE, |
| LDAP_MODIFY_BATCH_ADD, |
| ]); |
| } |
| } |