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\Control\Ad;
13
14use FreeDSx\Asn1\Asn1;
15use FreeDSx\Asn1\Exception\EncoderException;
16use FreeDSx\Asn1\Exception\PartialPduException;
17use FreeDSx\Asn1\Type\AbstractType;
18use FreeDSx\Asn1\Type\IntegerType;
19use FreeDSx\Asn1\Type\SequenceType;
20use FreeDSx\Ldap\Control\Control;
21use FreeDSx\Ldap\Exception\ProtocolException;
22
23/**
24 * Represents an Expected Entry Count control. Defined in MS-ADTS 3.1.1.3.4.1.33. The control value request definition is:
25 *
26 *  ExpectedEntryCountRequestValue ::= SEQUENCE {
27 *      searchEntriesMin    INTEGER
28 *      searchEntriesMax    INTEGER
29 *  }
30 *
31 * @see https://msdn.microsoft.com/en-us/library/jj216720.aspx
32 * @author Chad Sikorra <Chad.Sikorra@gmail.com>
33 */
34class ExpectedEntryCountControl extends Control
35{
36    /**
37     * @var int
38     */
39    protected $minimum;
40
41    /**
42     * @var int
43     */
44    protected $maximum;
45
46    /**
47     * @param int $min
48     * @param int $max
49     */
50    public function __construct(int $min, int $max)
51    {
52        $this->minimum = $min;
53        $this->maximum = $max;
54        parent::__construct(self::OID_EXPECTED_ENTRY_COUNT, true);
55    }
56
57    /**
58     * @return int
59     */
60    public function getMaximum(): int
61    {
62        return $this->maximum;
63    }
64
65    /**
66     * @param int $max
67     * @return $this
68     */
69    public function setMaximum(int $max)
70    {
71        $this->maximum = $max;
72
73        return $this;
74    }
75
76    /**
77     * @return int
78     */
79    public function getMinimum(): int
80    {
81        return $this->minimum;
82    }
83
84    /**
85     * @param int $min
86     * @return $this
87     */
88    public function setMinimum(int $min)
89    {
90        $this->minimum = $min;
91
92        return $this;
93    }
94
95    /**
96     * {@inheritDoc}
97     * @return Control
98     * @throws EncoderException
99     * @throws PartialPduException
100     */
101    public static function fromAsn1(AbstractType $type)
102    {
103        $request = self::decodeEncodedValue($type);
104        if (!$request instanceof SequenceType) {
105            throw new ProtocolException('An ExpectedEntryCount control value must be a sequence type.');
106        }
107        $min = $request->getChild(0);
108        $max = $request->getChild(1);
109        if (!$min instanceof IntegerType) {
110            throw new ProtocolException('An ExpectedEntryCount control value sequence 0 must be an integer type.');
111        }
112        if (!$max instanceof IntegerType) {
113            throw new ProtocolException('An ExpectedEntryCount control value sequence 1 must be an integer type.');
114        }
115        $control = new self(
116            $min->getValue(),
117            $max->getValue()
118        );
119
120        return self::mergeControlData($control, $type);
121    }
122
123    /**
124     * {@inheritdoc}
125     */
126    public function toAsn1(): AbstractType
127    {
128        $this->controlValue = Asn1::sequence(
129            Asn1::integer($this->minimum),
130            Asn1::integer($this->maximum)
131        );
132
133        return parent::toAsn1();
134    }
135
136    /**
137     * @param AbstractType $type
138     * @throws ProtocolException
139     */
140    protected static function validate(AbstractType $type): void
141    {
142        if (!($type instanceof SequenceType && count($type) === 2)) {
143            throw new ProtocolException('An ExpectedEntryCount control value must be a sequence type with 2 children.');
144        }
145        if (!$type->getChild(0) instanceof IntegerType) {
146            throw new ProtocolException('An ExpectedEntryCount control value sequence 0 must be an integer type.');
147        }
148        if (!$type->getChild(1) instanceof IntegerType) {
149            throw new ProtocolException('An ExpectedEntryCount control value sequence 1 must be an integer type.');
150        }
151    }
152}
153