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