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\OctetStringType;
17use FreeDSx\Asn1\Type\SequenceType;
18use FreeDSx\Ldap\Control\Control;
19use FreeDSx\Ldap\Exception\ProtocolException;
20
21/**
22 * Represents a DirSync Response. Defined in MS-ADTS 3.1.1.3.4.1.3. The control value response definition is:
23 *
24 * DirSyncResponseValue ::= SEQUENCE {
25 *     MoreResults     INTEGER
26 *     unused          INTEGER
27 *     CookieServer    OCTET STRING
28 * }
29 *
30 * @see https://msdn.microsoft.com/en-us/library/cc223347.aspx
31 * @author Chad Sikorra <Chad.Sikorra@gmail.com>
32 */
33class DirSyncResponseControl extends Control
34{
35    /**
36     * @var int
37     */
38    protected $moreResults;
39
40    /**
41     * @var int
42     */
43    protected $unused;
44
45    /**
46     * @var string
47     */
48    protected $cookie;
49
50    /**
51     * @param int $moreResults
52     * @param int $unused
53     * @param string $cookie
54     */
55    public function __construct(int $moreResults, int $unused = 0, string $cookie = '')
56    {
57        $this->moreResults = $moreResults;
58        $this->unused = $unused;
59        $this->cookie = $cookie;
60        parent::__construct(self::OID_DIR_SYNC);
61    }
62
63    /**
64     * @return int
65     */
66    public function getMoreResults(): int
67    {
68        return $this->moreResults;
69    }
70
71    /**
72     * @return bool
73     */
74    public function hasMoreResults(): bool
75    {
76        return $this->moreResults !== 0;
77    }
78
79    /**
80     * @return int
81     */
82    public function getUnused(): int
83    {
84        return $this->unused;
85    }
86
87    /**
88     * @return string
89     */
90    public function getCookie(): string
91    {
92        return $this->cookie;
93    }
94
95    /**
96     * {@inheritdoc}
97     */
98    public static function fromAsn1(AbstractType $type)
99    {
100        $response = self::decodeEncodedValue($type);
101        if (!$response instanceof SequenceType) {
102            throw new ProtocolException('A DirSyncResponse control value must be a sequence type with 3 children.');
103        }
104        $more = $response->getChild(0);
105        $unused = $response->getChild(1);
106        $cookie = $response->getChild(2);
107        if (!$more instanceof IntegerType) {
108            throw new ProtocolException('A DirSyncResponse control value sequence 0 must be an integer type.');
109        }
110        if (!$unused instanceof IntegerType) {
111            throw new ProtocolException('A DirSyncResponse control value sequence 1 must be an integer type.');
112        }
113        if (!$cookie instanceof OctetStringType) {
114            throw new ProtocolException('A DirSyncResponse control value sequence 2 must be an octet string type.');
115        }
116
117        /** @var SequenceType $request */
118        $control = new self(
119            $more->getValue(),
120            $unused->getValue(),
121            $cookie->getValue()
122        );
123
124        return self::mergeControlData($control, $type);
125    }
126
127    /**
128     * {@inheritdoc}
129     */
130    public function toAsn1(): AbstractType
131    {
132        $this->controlValue = Asn1::sequence(
133            Asn1::integer($this->moreResults),
134            Asn1::integer($this->unused),
135            Asn1::octetString($this->cookie)
136        );
137
138        return parent::toAsn1();
139    }
140}
141