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