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\Vlv;
12
13use FreeDSx\Asn1\Asn1;
14use FreeDSx\Asn1\Type\AbstractType;
15use FreeDSx\Ldap\Control\Control;
16use FreeDSx\Ldap\Exception\RuntimeException;
17use FreeDSx\Ldap\Search\Filter\GreaterThanOrEqualFilter;
18
19/**
20 * Represents a VLV Request. draft-ietf-ldapext-ldapv3-vlv-09
21 *
22 * VirtualListViewRequest ::= SEQUENCE {
23 *     beforeCount    INTEGER (0..maxInt),
24 *     afterCount     INTEGER (0..maxInt),
25 *     target       CHOICE {
26 *         byOffset        [0] SEQUENCE {
27 *             offset          INTEGER (1 .. maxInt),
28 *             contentCount    INTEGER (0 .. maxInt) },
29 *         greaterThanOrEqual [1] AssertionValue },
30 *     contextID     OCTET STRING OPTIONAL }
31 *
32 * @author Chad Sikorra <Chad.Sikorra@gmail.com>
33 */
34class VlvControl extends Control
35{
36    use VlvTrait;
37
38    /**
39     * @var int
40     */
41    protected $after;
42
43    /**
44     * @var int
45     */
46    protected $before;
47
48    /**
49     * @var null|GreaterThanOrEqualFilter
50     */
51    protected $filter;
52
53    /**
54     * @param int $before
55     * @param int $after
56     * @param int $offset
57     * @param int $count
58     * @param GreaterThanOrEqualFilter|null $filter
59     * @param null|string $contextId
60     */
61    public function __construct(int $before, int $after, ?int $offset = null, ?int $count = null, GreaterThanOrEqualFilter $filter = null, ?string $contextId = null)
62    {
63        $this->before = $before;
64        $this->after = $after;
65        $this->offset = $offset;
66        $this->count = $count;
67        $this->filter = $filter;
68        $this->contextId = $contextId;
69        parent::__construct(self::OID_VLV);
70    }
71
72    /**
73     * @return int
74     */
75    public function getAfter(): int
76    {
77        return $this->after;
78    }
79
80    /**
81     * @param int $after
82     * @return $this
83     */
84    public function setAfter(int $after)
85    {
86        $this->after = $after;
87
88        return $this;
89    }
90
91    /**
92     * @return int
93     */
94    public function getBefore(): int
95    {
96        return $this->before;
97    }
98
99    /**
100     * @param int $before
101     * @return $this
102     */
103    public function setBefore(int $before)
104    {
105        $this->before = $before;
106
107        return $this;
108    }
109
110    /**
111     * @param int $count
112     * @return $this
113     */
114    public function setCount(?int $count)
115    {
116        $this->count = $count;
117
118        return $this;
119    }
120
121    /**
122     * @param string|null $contextId
123     * @return $this
124     */
125    public function setContextId($contextId)
126    {
127        $this->contextId = $contextId;
128
129        return $this;
130    }
131
132    /**
133     * @param int $offset
134     * @return $this
135     */
136    public function setOffset(?int $offset)
137    {
138        $this->offset = $offset;
139
140        return $this;
141    }
142
143    /**
144     * @return null|GreaterThanOrEqualFilter
145     */
146    public function getFilter(): ?GreaterThanOrEqualFilter
147    {
148        return $this->filter;
149    }
150
151    /**
152     * @param GreaterThanOrEqualFilter|null $filter
153     * @return $this
154     */
155    public function setFilter(GreaterThanOrEqualFilter $filter = null)
156    {
157        $this->filter = $filter;
158
159        return $this;
160    }
161
162    /**
163     * {@inheritdoc}
164     */
165    public function toAsn1(): AbstractType
166    {
167        $this->controlValue = Asn1::sequence(
168            Asn1::integer($this->before),
169            Asn1::integer($this->after)
170        );
171        if ($this->filter === null && ($this->count === null || $this->offset === null)) {
172            throw new RuntimeException('You must specify a filter or offset and count for a VLV request.');
173        }
174        if ($this->filter !== null) {
175            $this->controlValue->addChild(Asn1::context(1, $this->filter->toAsn1()));
176        } else {
177            $this->controlValue->addChild(Asn1::context(0, Asn1::sequence(
178                Asn1::integer((int) $this->offset),
179                Asn1::integer((int) $this->count)
180            )));
181        }
182
183        return parent::toAsn1();
184    }
185
186    /**
187     * {@inheritdoc}
188     */
189    public static function fromAsn1(AbstractType $type)
190    {
191        // TODO: Implement fromAsn1() method.
192    }
193}
194