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;
12
13use FreeDSx\Asn1\Asn1;
14use FreeDSx\Asn1\Type\AbstractType;
15use FreeDSx\Asn1\Type\IntegerType;
16use FreeDSx\Asn1\Type\OctetStringType;
17use FreeDSx\Asn1\Type\SequenceType;
18use FreeDSx\Ldap\Exception\ProtocolException;
19
20/**
21 * Represents a paged results control request value. RFC 2696.
22 *
23 * realSearchControlValue ::= SEQUENCE {
24 *     size            INTEGER (0..maxInt),
25 *                          -- requested page size from client
26 *                          -- result set size estimate from server
27 *     cookie          OCTET STRING }
28 *
29 * @author Chad Sikorra <Chad.Sikorra@gmail.com>
30 */
31class PagingControl extends Control
32{
33    /**
34     * @var string
35     */
36    protected $cookie;
37
38    /**
39     * @var int
40     */
41    protected $size;
42
43    /**
44     * @param int $size
45     * @param string $cookie
46     */
47    public function __construct(int $size, string $cookie = '')
48    {
49        $this->size = $size;
50        $this->cookie = $cookie;
51        parent::__construct(self::OID_PAGING);
52    }
53
54    /**
55     * @return string
56     */
57    public function getCookie(): string
58    {
59        return $this->cookie;
60    }
61
62    /**
63     * @return int
64     */
65    public function getSize(): int
66    {
67        return $this->size;
68    }
69
70    /**
71     * @param string $cookie
72     * @return $this
73     */
74    public function setCookie(string $cookie)
75    {
76        $this->cookie = $cookie;
77
78        return $this;
79    }
80
81    /**
82     * @param int $size
83     * @return $this
84     */
85    public function setSize(int $size)
86    {
87        $this->size = $size;
88
89        return $this;
90    }
91
92    /**
93     * {@inheritdoc}
94     */
95    public static function fromAsn1(AbstractType $type)
96    {
97        $paging = self::decodeEncodedValue($type);
98        if (!$paging instanceof SequenceType) {
99            throw new ProtocolException('A paged control value must be a sequence type with 2 children.');
100        }
101        $count = $paging->getChild(0);
102        $cookie = $paging->getChild(1);
103        if (!$count instanceof IntegerType) {
104            throw new ProtocolException('A paged control value sequence 0 must be an integer type.');
105        }
106        if (!$cookie instanceof OctetStringType) {
107            throw new ProtocolException('A paged control value sequence 1 must be an octet string type.');
108        }
109        $control = new self($count->getValue(), $cookie->getValue());
110
111        return self::mergeControlData($control, $type);
112    }
113
114    /**
115     * {@inheritdoc}
116     */
117    public function toAsn1(): AbstractType
118    {
119        $this->controlValue = Asn1::sequence(
120            Asn1::integer($this->size),
121            Asn1::octetString($this->cookie)
122        );
123
124        return parent::toAsn1();
125    }
126}
127