Completed
Push — master ( 3089f7...b04f5d )
by ignace nyamagana
10s
created

Host::__set_state()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 8
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 5
CRAP Score 1

Importance

Changes 2
Bugs 1 Features 0
Metric Value
c 2
b 1
f 0
dl 0
loc 8
ccs 5
cts 5
cp 1
rs 9.4285
cc 1
eloc 5
nc 1
nop 1
crap 1
1
<?php
2
/**
3
 * League.Uri (http://uri.thephpleague.com)
4
 *
5
 * @package   League.uri
6
 * @author    Ignace Nyamagana Butera <[email protected]>
7
 * @copyright 2013-2015 Ignace Nyamagana Butera
8
 * @license   https://github.com/thephpleague/uri/blob/master/LICENSE (MIT License)
9
 * @version   4.2.0
10
 * @link      https://github.com/thephpleague/uri/
11
 */
12
namespace League\Uri\Components;
13
14
use InvalidArgumentException;
15
use League\Uri\Interfaces\Host as HostInterface;
16
17
/**
18
 * Value object representing a URI host component.
19
 *
20
 * @package League.uri
21
 * @author  Ignace Nyamagana Butera <[email protected]>
22
 * @since   1.0.0
23
 */
24
class Host extends AbstractHierarchicalComponent implements HostInterface
25
{
26
    use HostIpTrait;
27
28
    use HostnameInfoTrait;
29
30
    use HostnameTrait;
31
32
    /**
33
     * HierarchicalComponent delimiter
34
     *
35
     * @var string
36
     */
37
    protected static $separator = '.';
38
39
    /**
40
     * Host literal representation
41
     *
42
     * @var string
43
     */
44
    protected $host;
45
46
    /**
47
     * New instance
48
     *
49
     * @param null|string $host
50
     */
51 1016
    public function __construct($host = null)
52
    {
53 1016
        if (null !== $host) {
54 908
            $host = $this->validateString($host);
55 899
            $this->data = $this->validate($host);
56 842
            $this->setLiteral();
57 842
        }
58 950
    }
59
60
    /**
61
     * Returns whether or not the host is an IDN
62
     *
63
     * @return bool
64
     */
65 9
    public function isIdn()
66
    {
67 9
        return $this->isIdn;
68
    }
69
70
    /**
71
     * Returns whether or not the host is an IP address
72
     *
73
     * @return bool
74
     */
75 842
    public function isIp()
76
    {
77 842
        return $this->hostAsIpv4 || $this->hostAsIpv6;
78
    }
79
80
    /**
81
     * Returns whether or not the host is an IPv4 address
82
     *
83
     * @return bool
84
     */
85 36
    public function isIpv4()
86
    {
87 36
        return $this->hostAsIpv4;
88
    }
89
90
    /**
91
     * Returns whether or not the host is an IPv6 address
92
     *
93
     * @return bool
94
     */
95 36
    public function isIpv6()
96
    {
97 36
        return $this->hostAsIpv6;
98
    }
99
100
    /**
101
     * Returns whether or not the host has a ZoneIdentifier
102
     *
103
     * @return bool
104
     *
105
     * @see http://tools.ietf.org/html/rfc6874#section-4
106
     */
107 12
    public function hasZoneIdentifier()
108
    {
109 12
        return $this->hasZoneIdentifier;
110
    }
111
112
    /**
113
     * Host literal setter
114
     */
115 842
    protected function setLiteral()
116
    {
117 842
        $this->host = !$this->isIp() ? $this->__toString() : $this->data[0];
118 842
    }
119
120
    /**
121
     * Returns the instance literal representation
122
     * without encoding
123
     *
124
     * @return string
125
     */
126 21
    public function getLiteral()
127
    {
128 21
        return $this->host;
129
    }
130
131
    /**
132
     * validate the submitted data
133
     *
134
     * @param string $str
135
     *
136
     * @return array
137
     */
138 899
    protected function validate($str)
139
    {
140 899
        $res = $this->validateIpHost($str);
141 899
        if (!empty($res)) {
142 120
            return $res;
143
        }
144
145 812
        return $this->validateStringHost($str);
146
    }
147
148
    /**
149
     * Retrieves a single host label.
150
     *
151
     * Retrieves a single host label. If the label offset has not been set,
152
     * returns the default value provided.
153
     *
154
     * @param string $offset  the label offset
155
     * @param mixed  $default Default value to return if the offset does not exist.
156
     *
157
     * @return mixed
158
     */
159 3
    public function getLabel($offset, $default = null)
160
    {
161 3
        if (isset($this->data[$offset])) {
162 3
            return $this->isIdn ? $this->data[$offset] : idn_to_ascii($this->data[$offset]);
163
        }
164
165 3
        return $default;
166
    }
167
168
    /**
169
     * Returns an array representation of the host
170
     *
171
     * @return array
172
     */
173 746
    public function toArray()
174
    {
175 746
        return $this->convertToAscii($this->data, !$this->isIdn);
176
    }
177
178
    /**
179
     * @inheritdoc
180
     */
181 872
    public function getContent()
182
    {
183 872
        if ([] === $this->data) {
184 207
            return null;
185
        }
186
187 806
        if ($this->isIp()) {
188 75
            return $this->formatIp($this->data[0]);
189
        }
190
191 737
        return $this->formatComponentString($this->toArray(), $this->isAbsolute);
192
    }
193
194
    /**
195
     * @inheritdoc
196
     */
197 1
    public function __debugInfo()
198
    {
199 1
        return ['host' => $this->__toString()];
200
    }
201
202
    /**
203
     * @inheritdoc
204
     */
205 15
    public static function __set_state(array $properties)
206
    {
207 15
        $host = static::createFromArray($properties['data'], $properties['isAbsolute']);
208 15
        $host->hostnameInfoLoaded = $properties['hostnameInfoLoaded'];
209 15
        $host->hostnameInfo = $properties['hostnameInfo'];
210
211 15
        return $host;
212
    }
213
214
    /**
215
     * Returns a host in his punycode encoded form
216
     *
217
     * This method MUST retain the state of the current instance, and return
218
     * an instance with the host transcoded using to ascii the RFC 3492 rules
219
     *
220
     * @see http://tools.ietf.org/html/rfc3492
221
     *
222
     * @return static
223
     */
224 108
    public function toAscii()
225
    {
226 108
        if ($this->isIp() || !$this->isIdn) {
227 36
            return $this;
228
        }
229
230 75
        return $this->modify($this->formatComponentString(
231 75
            $this->convertToAscii($this->data, $this->isIdn),
232 75
            $this->isAbsolute
233 75
        ));
234
    }
235
236
    /**
237
     * Returns a host in his IDN form
238
     *
239
     * This method MUST retain the state of the current instance, and return
240
     * an instance with the host in its IDN form using RFC 3492 rules
241
     *
242
     * @see http://tools.ietf.org/html/rfc3492
243
     *
244
     * @return static
245
     */
246 84
    public function toUnicode()
247
    {
248 84
        if ($this->isIp() || $this->isIdn) {
249 69
            return $this;
250
        }
251
252 75
        return $this->modify($this->formatComponentString($this->data, $this->isAbsolute));
253
    }
254
255
    /**
256
     * @inheritdoc
257
     */
258 779
    protected static function formatComponentString($data, $type)
259
    {
260 779
        $hostname = implode(static::$separator, array_reverse(static::validateIterator($data)));
261 767
        if (self::IS_ABSOLUTE == $type) {
262 36
            return $hostname.static::$separator;
263
        }
264
265 743
        return $hostname;
266
    }
267
268
    /**
269
     * Return an host without its zone identifier according to RFC6874
270
     *
271
     * This method MUST retain the state of the current instance, and return
272
     * an instance without the host zone identifier according to RFC6874
273
     *
274
     * @see http://tools.ietf.org/html/rfc6874#section-4
275
     *
276
     * @return static
277
     */
278 18
    public function withoutZoneIdentifier()
279
    {
280 18
        if ($this->hasZoneIdentifier) {
281 9
            return $this->modify(substr($this->data[0], 0, strpos($this->data[0], '%')));
282
        }
283
284 9
        return $this;
285
    }
286
287
    /**
288
     * Validated the Host Label Count
289
     *
290
     * @param array $labels Host labels
291
     *
292
     * @throws InvalidArgumentException If the validation fails
293
     */
294 779
    protected function assertLabelsCount(array $labels)
295
    {
296 779
        if (127 <= count(array_merge($this->data, $labels))) {
297 3
            throw new InvalidArgumentException('Invalid Hostname, verify labels count');
298
        }
299 776
    }
300
301
    /**
302
     * set the FQDN property
303
     *
304
     * @param string $str
305
     *
306
     * @return string
307
     */
308 794
    protected function setIsAbsolute($str)
309
    {
310 794
        $this->isAbsolute = self::IS_RELATIVE;
311 794
        if ('.' == mb_substr($str, -1, 1, 'UTF-8')) {
312 42
            $this->isAbsolute = self::IS_ABSOLUTE;
313 42
            $str = mb_substr($str, 0, -1, 'UTF-8');
314 42
        }
315
316 794
        return $str;
317
    }
318
319
    /**
320
     * @inheritdoc
321
     */
322 60
    public function append($component)
323
    {
324 60
        return $this->newCollectionInstance(array_merge(
325 60
            $this->validateComponent($component)->toArray(),
326 60
            $this->toArray()
327 60
        ));
328
    }
329
}
330