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\Operation\Request;
13
14use FreeDSx\Asn1\Asn1;
15use FreeDSx\Asn1\Exception\EncoderException;
16use FreeDSx\Asn1\Type\AbstractType;
17use FreeDSx\Asn1\Type\OctetStringType;
18use FreeDSx\Asn1\Type\SequenceType;
19use FreeDSx\Ldap\Entry\Dn;
20use FreeDSx\Ldap\Exception\ProtocolException;
21use FreeDSx\Ldap\Exception\RuntimeException;
22use FreeDSx\Ldap\Search\Filter\EqualityFilter;
23
24/**
25 * An attribute-value comparison request. RFC 4511, 4.10.
26 *
27 * CompareRequest ::= [APPLICATION 14] SEQUENCE {
28 *     entry           LDAPDN,
29 *     ava             AttributeValueAssertion }
30 *
31 * @author Chad Sikorra <Chad.Sikorra@gmail.com>
32 */
33class CompareRequest implements RequestInterface, DnRequestInterface
34{
35    protected const APP_TAG = 14;
36
37    /**
38     * @var Dn
39     */
40    protected $dn;
41
42    /**
43     * @var EqualityFilter
44     */
45    protected $filter;
46
47    /**
48     * @param string|Dn $dn
49     * @param EqualityFilter $filter
50     */
51    public function __construct($dn, EqualityFilter $filter)
52    {
53        $this->setDn($dn);
54        $this->filter = $filter;
55    }
56
57    /**
58     * @return Dn
59     */
60    public function getDn(): Dn
61    {
62        return $this->dn;
63    }
64
65    /**
66     * @param string|Dn $dn
67     * @return $this
68     */
69    public function setDn($dn)
70    {
71        $this->dn = $dn instanceof Dn ? $dn : new Dn($dn);
72
73        return $this;
74    }
75
76    /**
77     * @return EqualityFilter
78     */
79    public function getFilter(): EqualityFilter
80    {
81        return $this->filter;
82    }
83
84    /**
85     * @param EqualityFilter $filter
86     * @return $this
87     */
88    public function setFilter(EqualityFilter $filter)
89    {
90        $this->filter = $filter;
91
92        return $this;
93    }
94
95    /**
96     * {@inheritDoc}
97     * @return self
98     * @throws EncoderException
99     * @throws RuntimeException
100     */
101    public static function fromAsn1(AbstractType $type)
102    {
103        if (!($type instanceof SequenceType && count($type->getChildren()) === 2)) {
104            throw new ProtocolException('The compare request is malformed');
105        }
106        $dn = $type->getChild(0);
107        $ava = $type->getChild(1);
108
109        if (!$dn instanceof OctetStringType || $ava === null) {
110            throw new ProtocolException('The compare request is malformed.');
111        }
112
113        return new self($dn->getValue(), EqualityFilter::fromAsn1($ava));
114    }
115
116    /**
117     * {@inheritdoc}
118     */
119    public function toAsn1(): AbstractType
120    {
121        return Asn1::application(self::APP_TAG, Asn1::sequence(
122            Asn1::octetString($this->dn->toString()),
123            Asn1::universal(AbstractType::TAG_TYPE_SEQUENCE, $this->filter->toAsn1())
124        ));
125    }
126}
127