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\SequenceType;
20use FreeDSx\Ldap\Control\Control;
21use FreeDSx\Ldap\Exception\ProtocolException;
22use function count;
23
24/**
25 * Used to represent the Extended DN control.
26 *
27 * @see https://msdn.microsoft.com/en-us/library/cc223349.aspx
28 * @author Chad Sikorra <Chad.Sikorra@gmail.com>
29 */
30class ExtendedDnControl extends Control
31{
32    /**
33     * @var bool
34     */
35    protected $useHexFormat;
36
37    /**
38     * @param bool $useHexFormat
39     */
40    public function __construct(bool $useHexFormat = false)
41    {
42        $this->useHexFormat = $useHexFormat;
43        parent::__construct(self::OID_EXTENDED_DN);
44    }
45
46    /**
47     * @return bool
48     */
49    public function getUseHexFormat(): bool
50    {
51        return $this->useHexFormat;
52    }
53
54    /**
55     * @param bool $useHexFormat
56     * @return $this
57     */
58    public function setUseHexFormat(bool $useHexFormat)
59    {
60        $this->useHexFormat = $useHexFormat;
61
62        return $this;
63    }
64
65    /**
66     * {@inheritDoc}
67     * @return ExtendedDnControl
68     * @throws EncoderException
69     * @throws PartialPduException
70     */
71    public static function fromAsn1(AbstractType $type)
72    {
73        if (!$type instanceof SequenceType) {
74            throw new ProtocolException('The extended DN control is malformed.');
75        }
76        [0 => $oid, 1 => $criticality, 2 => $value] = self::parseAsn1ControlValues($type);
77
78        $useHexFormat = false;
79        if ($value !== null) {
80            $request = self::decodeEncodedValue($type);
81            if (!$request instanceof SequenceType) {
82                throw new ProtocolException('An ExtendedDn control value must be a sequence type.');
83            }
84            $useHexFormat = $request->getChild(0);
85            if (!$useHexFormat instanceof IntegerType) {
86                throw new ProtocolException('An ExtendedDn control value sequence 0 must be an integer type.');
87            }
88            $useHexFormat = ($useHexFormat->getValue() === 0);
89        }
90
91        $control = new self($useHexFormat);
92        $control->controlType = $oid;
93        $control->criticality = $criticality;
94
95        return $control;
96    }
97
98    /**
99     * {@inheritdoc}
100     */
101    public function toAsn1(): AbstractType
102    {
103        $useHexFormat = $this->useHexFormat ? 0 : 1;
104        $this->controlValue = Asn1::sequence(Asn1::integer($useHexFormat));
105
106        return parent::toAsn1();
107    }
108
109    /**
110     * @param AbstractType $type
111     * @throws ProtocolException
112     */
113    protected static function validate(AbstractType $type): void
114    {
115        if (!($type instanceof SequenceType && count($type) === 1)) {
116            throw new ProtocolException('An ExtendedDn control value must be a sequence type with 1 child.');
117        }
118        if (!$type->getChild(0) instanceof IntegerType) {
119            throw new ProtocolException('An ExtendedDn control value sequence 0 must be an integer type.');
120        }
121    }
122}
123