<commit_before><?php
/**
 * This file is part of the LdapTools package.
 *
 * (c) <NAME> <<EMAIL>>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace LdapTools\AttributeConverter;

use LdapTools\Query\LdapQueryBuilder;
use LdapTools\Query\UserAccountControlFlags;

/**
 * Uses a User Account Control Mapping from the schema and the current attribute/last value context to properly convert
 * the boolean value to what LDAP or PHP expects it to be.
 *
 * @author <NAME> <<EMAIL>>
 */
class ConvertUserAccountControl implements AttributeConverterInterface
{
    use AttributeConverterTrait {
        getShouldAggregateValues as parentGetShouldAggregateValues;
    }

    public function __construct()
    {
        $this->options = [
            'uacMap' => [],
            'defaultValue' => UserAccountControlFlags::NORMAL_ACCOUNT,
        ];
    }

    /**
     * {@inheritdoc}
     */
    public function toLdap($value)
    {
        $this->validateCurrentAttribute();
        if (empty($this->getLastValue()) && $this->getOperationType() == self::TYPE_MODIFY) {
            $this->setLastValue($this->getCurrentUacValue());
        } elseif (empty($this->getLastValue()) && $this->getOperationType() == self::TYPE_CREATE) {
            $this->setLastValue($this->options['defaultValue']);
        }

        return $this->modifyUacValue((bool) $value);
    }

    /**
     * {@inheritdoc}
     */
    public function fromLdap($value)
    {
        $this->validateCurrentAttribute();

        return (bool) ((int) $value & (int) $this->getMappedValue($this->attribute));
    }

    /**
     * {@inheritdoc}
     */
    public function getShouldAggregateValues()
    {
        return ($this->getOperationType() == self::TYPE_MODIFY || $this->getOperationType() == self::TYPE_CREATE);
    }

    /**
     * If the context is a modification, then the current User Account Control value is needed to do the proper bitwise
     * value calculations so as to not squash other values within this attribute.
     *
     * @return string
     */
    protected function getCurrentUacValue()
    {
        if (!$this->getDn() || !$this->getLdapConnection()) {
            throw new \RuntimeException('Unable to query for the current userAccountControl attribute.');
        }

        $query = new LdapQueryBuilder($this->getLdapConnection());
        $result = $query->select('userAccountControl')
            ->where(['distinguishedName' => $this->getDn()])
            ->getLdapQuery()
            ->execute();

        if ($result->count() == 0) {
            throw new \RuntimeException(sprintf('Unable to find LDAP object: %s', $this->getDn()));
        }
        $object = $result->toArray()[0];

        return $object->getUserAccountControl();
    }

    /**
     * Given a bool value, do the needed bitwise comparison against the User Account Control value to either remove or
     * add the bit from the overall value.
     *
     * @param bool $value
     * @return int
     */
    protected function modifyUacValue($value)
    {
        $lastValue = is_array($this->getLastValue()) ? reset($this->getLastValue()) : $this->getLastValue();

        // If the bit we are expecting is already set how we want it, then do not attempt to modify it.
        if ($this->fromLdap($lastValue) === $value) {
            return $lastValue;
        }

        $mappedValue = $this->getMappedValue($this->attribute);
        if ($value) {
            $uac = (int) $lastValue | (int) $mappedValue;
        } else {
            $uac = (int) $lastValue ^ (int) $mappedValue;
        }

        return (string) $uac;
    }

    /**
     * If the current attribute does not exist in the map, then there is no way to determine how to do the calculation.
     */
    protected function validateCurrentAttribute()
    {
        if (!array_key_exists(strtolower($this->getAttribute()), array_change_key_case($this->options['uacMap']))) {
            throw new \RuntimeException(
                sprintf('You must first define "%s" in the options for this converter.', $this->attribute)
            );
        }
    }

    /**
     * @param string $attribute
     */
    protected function getMappedValue($attribute)
    {
        return array_change_key_case($this->options['uacMap'])[strtolower($attribute)];
    }
}<commit_msg>Use the ConverterUtilitiesTrait in the user account control converter.<commit_after><?php
/**
 * This file is part of the LdapTools package.
 *
 * (c) <NAME> <<EMAIL>>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace LdapTools\AttributeConverter;

use LdapTools\Query\LdapQueryBuilder;
use LdapTools\Query\UserAccountControlFlags;

/**
 * Uses a User Account Control Mapping from the schema and the current attribute/last value context to properly convert
 * the boolean value to what LDAP or PHP expects it to be.
 *
 * @author <NAME> <<EMAIL>>
 */
class ConvertUserAccountControl implements AttributeConverterInterface
{
    use ConverterUtilitiesTrait;
    use AttributeConverterTrait {
        getShouldAggregateValues as parentGetShouldAggregateValues;
    }

    public function __construct()
    {
        $this->options = [
            'uacMap' => [],
            'defaultValue' => UserAccountControlFlags::NORMAL_ACCOUNT,
        ];
    }

    /**
     * {@inheritdoc}
     */
    public function toLdap($value)
    {
        $this->validateCurrentAttribute($this->options['uacMap']);
        if (empty($this->getLastValue()) && $this->getOperationType() == self::TYPE_MODIFY) {
            $this->setLastValue($this->getCurrentUacValue());
        } elseif (empty($this->getLastValue()) && $this->getOperationType() == self::TYPE_CREATE) {
            $this->setLastValue($this->options['defaultValue']);
        }

        return $this->modifyUacValue((bool) $value);
    }

    /**
     * {@inheritdoc}
     */
    public function fromLdap($value)
    {
        $this->validateCurrentAttribute($this->options['uacMap']);

        return (bool) ((int) $value & (int) $this->getArrayValue($this->options['uacMap'], $this->attribute));
    }

    /**
     * {@inheritdoc}
     */
    public function getShouldAggregateValues()
    {
        return ($this->getOperationType() == self::TYPE_MODIFY || $this->getOperationType() == self::TYPE_CREATE);
    }

    /**
     * If the context is a modification, then the current User Account Control value is needed to do the proper bitwise
     * value calculations so as to not squash other values within this attribute.
     *
     * @return string
     */
    protected function getCurrentUacValue()
    {
        if (!$this->getDn() || !$this->getLdapConnection()) {
            throw new \RuntimeException('Unable to query for the current userAccountControl attribute.');
        }

        $query = new LdapQueryBuilder($this->getLdapConnection());
        $result = $query->select('userAccountControl')
            ->where(['distinguishedName' => $this->getDn()])
            ->getLdapQuery()
            ->execute();

        if ($result->count() == 0) {
            throw new \RuntimeException(sprintf('Unable to find LDAP object: %s', $this->getDn()));
        }
        $object = $result->toArray()[0];

        return $object->getUserAccountControl();
    }

    /**
     * Given a bool value, do the needed bitwise comparison against the User Account Control value to either remove or
     * add the bit from the overall value.
     *
     * @param bool $value
     * @return int
     */
    protected function modifyUacValue($value)
    {
        $lastValue = is_array($this->getLastValue()) ? reset($this->getLastValue()) : $this->getLastValue();

        // If the bit we are expecting is already set how we want it, then do not attempt to modify it.
        if ($this->fromLdap($lastValue) === $value) {
            return $lastValue;
        }

        $mappedValue = $this->getArrayValue($this->options['uacMap'], $this->attribute);
        if ($value) {
            $uac = (int) $lastValue | (int) $mappedValue;
        } else {
            $uac = (int) $lastValue ^ (int) $mappedValue;
        }

        return (string) $uac;
    }
}
{'fraction_non_alphanumeric': 0.13098964603900795, 'fraction_numerical': 0.0004815795810257645, 'mean_word_length': 2.6772908366533863, 'pattern_counts': {'":': 0, '<': 17, '<?xml version=': 0, '>': 97, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2013679', 'n_tokens_mistral': 2305, 'n_tokens_neox': 2313, 'n_words': 623}