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;
12
13use FreeDSx\Ldap\Exception\UrlParseException;
14
15/**
16 * Represents a LDAP URL extension component. RFC 4516, Section 2.
17 *
18 * @author Chad Sikorra <Chad.Sikorra@gmail.com>
19 */
20class LdapUrlExtension
21{
22    use LdapUrlTrait;
23
24    /**
25     * @var string
26     */
27    protected $name;
28
29    /**
30     * @var null|string
31     */
32    protected $value;
33
34    /**
35     * @var bool
36     */
37    protected $isCritical = false;
38
39    /**
40     * @param string $name
41     * @param null|string $value
42     * @param bool $isCritical
43     */
44    public function __construct(string $name, ?string $value = null, bool $isCritical = false)
45    {
46        $this->name = $name;
47        $this->value = $value;
48        $this->isCritical = $isCritical;
49    }
50
51    /**
52     * @return string
53     */
54    public function getName(): string
55    {
56        return $this->name;
57    }
58
59    /**
60     * @param string $name
61     * @return $this
62     */
63    public function setName(string $name)
64    {
65        $this->name = $name;
66
67        return $this;
68    }
69
70    /**
71     * @return null|string
72     */
73    public function getValue(): ?string
74    {
75        return $this->value;
76    }
77
78    /**
79     * @param null|string $value
80     * @return $this
81     */
82    public function setValue(?string $value)
83    {
84        $this->value = $value;
85
86        return $this;
87    }
88
89    public function getIsCritical(): bool
90    {
91        return $this->isCritical;
92    }
93
94    /**
95     * @param bool $isCritical
96     * @return $this
97     */
98    public function setIsCritical(bool $isCritical)
99    {
100        $this->isCritical = $isCritical;
101
102        return $this;
103    }
104
105    /**
106     * @return string
107     */
108    public function toString(): string
109    {
110        $ext = ($this->isCritical ? '!' : '') . \str_replace(',', '%2c', self::encode($this->name));
111
112        if ($this->value !== null) {
113            $ext .= '=' . \str_replace(',', '%2c', self::encode($this->value));
114        }
115
116        return $ext;
117    }
118
119    /**
120     * @return string
121     */
122    public function __toString()
123    {
124        return $this->toString();
125    }
126
127    /**
128     * @param string $extension
129     * @return LdapUrlExtension
130     * @throws UrlParseException
131     */
132    public static function parse(string $extension): LdapUrlExtension
133    {
134        if (preg_match('/!?\w+(=.*)?/', $extension) !== 1) {
135            throw new UrlParseException(sprintf('The LDAP URL extension is malformed: %s', $extension));
136        }
137        $pieces = \explode('=', $extension, 2);
138
139        $isCritical = isset($pieces[0][0]) && $pieces[0][0] === '!';
140        if ($isCritical) {
141            $pieces[0] = \substr($pieces[0], 1);
142        }
143
144        $name = \str_ireplace('%2c', ',', self::decode($pieces[0]));
145        $value = isset($pieces[1]) ? \str_ireplace('%2c', ',', self::decode($pieces[1])) : null;
146
147        return new self($name, $value, $isCritical);
148    }
149}
150