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