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\Search\Filter;
13
14use FreeDSx\Asn1\Asn1;
15use FreeDSx\Asn1\Exception\EncoderException;
16use FreeDSx\Asn1\Type\AbstractType;
17use FreeDSx\Asn1\Type\IncompleteType;
18use FreeDSx\Asn1\Type\OctetStringType;
19use FreeDSx\Asn1\Type\SequenceType;
20use FreeDSx\Ldap\Entry\Attribute;
21use FreeDSx\Ldap\Exception\ProtocolException;
22use FreeDSx\Ldap\Exception\RuntimeException;
23use FreeDSx\Ldap\Protocol\LdapEncoder;
24
25/**
26 * Common methods for filters using attribute value assertions.
27 *
28 * @author Chad Sikorra <Chad.Sikorra@gmail.com>
29 */
30trait AttributeValueAssertionTrait
31{
32    use FilterAttributeTrait;
33
34    /**
35     * @var string
36     */
37    protected $value;
38
39    /**
40     * @param string $attribute
41     * @param string $value
42     */
43    public function __construct(string $attribute, string $value)
44    {
45        $this->attribute = $attribute;
46        $this->value = $value;
47    }
48
49    /**
50     * @param string $value
51     * @return $this
52     */
53    public function setValue(string $value)
54    {
55        $this->value = $value;
56
57        return $this;
58    }
59
60    /**
61     * @return string
62     */
63    public function getValue(): string
64    {
65        return $this->value;
66    }
67
68    /**
69     * {@inheritdoc}
70     */
71    public function toAsn1(): AbstractType
72    {
73        return Asn1::context(self::CHOICE_TAG, Asn1::sequence(
74            Asn1::octetString($this->attribute),
75            Asn1::octetString($this->value)
76        ));
77    }
78
79    /**
80     * {@inheritdoc}
81     */
82    public function toString(): string
83    {
84        return self::PAREN_LEFT
85            . $this->attribute
86            . self::FILTER_TYPE
87            . Attribute::escape($this->value)
88            . self::PAREN_RIGHT;
89    }
90
91    /**
92     * {@inheritDoc}
93     * @param AbstractType $type
94     * @return self
95     * @throws EncoderException
96     * @throws RuntimeException
97     * @throws ProtocolException
98     */
99    public static function fromAsn1(AbstractType $type)
100    {
101        $type = $type instanceof IncompleteType ? (new LdapEncoder())->complete($type, AbstractType::TAG_TYPE_SEQUENCE) : $type;
102        if (!($type instanceof SequenceType && count($type) === 2)) {
103            throw new ProtocolException('The attribute value assertion is malformed.');
104        }
105
106        $attribute = $type->getChild(0);
107        $value = $type->getChild(1);
108        if (!($attribute instanceof OctetStringType && $value instanceof OctetStringType)) {
109            throw new ProtocolException('The attribute value assertion is malformed.');
110        }
111
112        return new static($attribute->getValue(), $value->getValue());
113    }
114}
115