Completed
Pull Request — master (#47)
by ignace nyamagana
02:36
created

Formatter::setPort()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 1

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 4
ccs 3
cts 3
cp 1
rs 10
cc 1
eloc 2
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.1.1
10
 * @link      https://github.com/thephpleague/uri/
11
 */
12
namespace League\Uri;
13
14
use InvalidArgumentException;
15
use League\Uri\Components\Host;
16
use League\Uri\Components\Port;
17
use League\Uri\Components\Query;
18
use League\Uri\Interfaces\Host as HostInterface;
19
use League\Uri\Interfaces\Query as QueryInterface;
20
use League\Uri\Interfaces\Uri;
21
use League\Uri\Interfaces\UriPart;
22
use League\Uri\Schemes\Generic\UriBuilderTrait;
23
use Psr\Http\Message\UriInterface;
24
25
/**
26
 * A class to manipulate URI and URI components output
27
 *
28
 * @package League.uri
29
 * @author  Ignace Nyamagana Butera <[email protected]>
30
 * @since   4.0.0
31
 */
32
class Formatter
33
{
34
    use UriBuilderTrait;
35
36
    const HOST_AS_UNICODE = 1;
37
38
    const HOST_AS_ASCII   = 2;
39
40
    /**
41
     * host encoding property
42
     *
43
     * @var int
44
     */
45
    protected $hostEncoding = self::HOST_AS_UNICODE;
46
47
    /**
48
     * Port
49
     *
50
     * @var Port
51
     */
52
    protected $port;
53
54
    /**
55
     * query encoding property
56
     *
57
     * @var int
58
     */
59
    protected $queryEncoding = PHP_QUERY_RFC3986;
60
61
    /**
62
     * Query Parser object
63
     *
64
     * @var QueryParser
65
     */
66
    protected $queryParser;
67
68
    /**
69
     * query separator property
70
     *
71
     * @var string
72
     */
73
    protected $querySeparator = '&';
74
75
    /**
76
     * Should the query component be preserved
77
     *
78
     * @var bool
79
     */
80
    protected $preserveQuery = false;
81
82
    /**
83
     * Should the fragment component string be preserved
84
     *
85
     * @var bool
86
     */
87
    protected $preserveFragment = false;
88
89
    /**
90
     * New Instance
91
     */
92 54
    public function __construct()
93
    {
94 54
        $this->queryParser = new QueryParser();
95 54
    }
96
97
    /**
98
     * Host encoding setter
99
     *
100
     * @param int $encode a predefined constant value
101
     */
102 21
    public function setHostEncoding($encode)
103
    {
104 21
        if (!in_array($encode, [self::HOST_AS_UNICODE, self::HOST_AS_ASCII])) {
105 3
            throw new InvalidArgumentException('Unknown Host encoding rule');
106
        }
107 18
        $this->hostEncoding = $encode;
108 18
    }
109
110
    /**
111
     * Host encoding getter
112
     *
113
     * DEPRECATION WARNING! This method will be removed in the next major point release
114
     *
115
     * @deprecated deprecated since version 4.1
116
     *
117
     * @return int
118
     */
119
    public function getHostEncoding()
120
    {
121
        return $this->hostEncoding;
122
    }
123
124
    /**
125
     * Enforce Port presence
126
     *
127
     * @param null|int $port URI port value
128
     */
129 6
    public function setPort($port)
130
    {
131 6
        $this->port = new Port($port);
132 3
    }
133
134
    /**
135
     * Query encoding setter
136
     *
137
     * @param int $encode a predefined constant value
138
     */
139 9
    public function setQueryEncoding($encode)
140
    {
141 9
        if (!in_array($encode, [PHP_QUERY_RFC3986, PHP_QUERY_RFC1738])) {
142 3
            throw new InvalidArgumentException('Unknown Query encoding rule');
143
        }
144 6
        $this->queryEncoding = $encode;
145 6
    }
146
147
    /**
148
     * Query encoding getter
149
     *
150
     * DEPRECATION WARNING! This method will be removed in the next major point release
151
     *
152
     * @deprecated deprecated since version 4.1
153
     *
154
     * @return int
155
     */
156
    public function getQueryEncoding()
157
    {
158
        return $this->queryEncoding;
159
    }
160
161
    /**
162
     * Query separator setter
163
     *
164
     * @param string $separator
165
     */
166 15
    public function setQuerySeparator($separator)
167
    {
168 15
        $separator = filter_var($separator, FILTER_SANITIZE_STRING, FILTER_FLAG_STRIP_LOW);
169
170 15
        $this->querySeparator = trim($separator);
171 15
    }
172
173
    /**
174
     * Query separator getter
175
     *
176
     * DEPRECATION WARNING! This method will be removed in the next major point release
177
     *
178
     * @deprecated deprecated since version 4.1
179
     *
180
     * @return string
181
     */
182
    public function getQuerySeparator()
183
    {
184
        return $this->querySeparator;
185
    }
186
187
    /**
188
     * Whether we should preserve the Query component
189
     * regardless of its value.
190
     *
191
     * If set to true the query delimiter will be appended
192
     * to the URI regardless of the query string value
193
     *
194
     * @param bool $status
195
     */
196 3
    public function preserveQuery($status)
197
    {
198 3
        $this->preserveQuery = (bool) $status;
199 3
    }
200
201
    /**
202
     * Whether we should preserve the Fragment component
203
     * regardless of its value.
204
     *
205
     * If set to true the fragment delimiter will be appended
206
     * to the URI regardless of the query string value
207
     *
208
     * @param bool $status
209
     */
210 3
    public function preserveFragment($status)
211
    {
212 3
        $this->preserveFragment = (bool) $status;
213 3
    }
214
215
    /**
216
     * Format an object
217
     *
218
     * @see Formatter::format
219
     *
220
     * @param UriPart|Uri|UriInterface $input
221
     *
222
     * @return string
223
     */
224 42
    public function __invoke($input)
225
    {
226 42
        return $this->format($input);
227
    }
228
229
    /**
230
     * Format an object
231
     *
232
     * Format an object according to the formatter properties.
233
     * The object must implement one of the following interface:
234
     * <ul>
235
     * <li>League\Uri\Interfaces\Uri
236
     * <li>League\Uri\Interfaces\UriPart
237
     * <li>Psr\Http\Message\UriInterface
238
     * </ul>
239
     *
240
     * @param UriPart|Uri|UriInterface $input
241
     *
242
     * @return string
243
     */
244 45
    public function format($input)
245
    {
246 45
        if ($input instanceof UriPart) {
247 18
            return $this->formatUriPart($input);
248
        }
249
250 27
        if ($input instanceof Uri || $input instanceof UriInterface) {
251 24
            return $this->formatUri($input);
252
        }
253
254 3
        throw new InvalidArgumentException(
255 1
            'input must be an URI object or a League UriPart object'
256 2
        );
257
    }
258
259
    /**
260
     * Format a UriPart implemented object according to the Formatter properties
261
     *
262
     * @param UriPart $part
263
     *
264
     * @return string
265
     */
266 42
    protected function formatUriPart(UriPart $part)
267
    {
268 42
        if ($part instanceof QueryInterface) {
269 33
            return $this->queryParser->build($part->toArray(), $this->querySeparator, $this->queryEncoding);
270
        }
271
272 9
        if ($part instanceof HostInterface) {
273 6
            return $this->formatHost($part);
274
        }
275
276 3
        return $part->__toString();
277
    }
278
279
    /**
280
     * Format a Host according to the Formatter properties
281
     *
282
     * @param HostInterface $host
283
     *
284
     * @return string
285
     */
286 24
    protected function formatHost(HostInterface $host)
287
    {
288 24
        if (self::HOST_AS_ASCII == $this->hostEncoding) {
289 9
            return $host->toAscii()->__toString();
290
        }
291
292 15
        return $host->toUnicode()->__toString();
293
    }
294
295
    /**
296
     * Format an Uri according to the Formatter properties
297
     *
298
     * @param Uri|UriInterface $uri
299
     *
300
     * @return string
301
     */
302 24
    protected function formatUri($uri)
303
    {
304 24
        $scheme = $uri->getScheme();
305 24
        if ('' !== $scheme) {
306 21
            $scheme .= ':';
307 14
        }
308
309 24
        $auth = $this->formatAuthority($uri);
310
311 8
        return $scheme.$auth
312 24
            .$this->formatPath($uri->getPath(), $auth)
313 24
            .$this->formatQuery($uri)
314 24
            .$this->formatFragment($uri)
315 16
        ;
316
    }
317
318
    /**
319
     * Format a URI authority according to the Formatter properties
320
     *
321
     * @param Uri|UriInterface $uri
322
     *
323
     * @return string
324
     */
325 24
    protected function formatAuthority($uri)
326
    {
327 24
        if ('' == $uri->getHost()) {
328 6
            return '';
329
        }
330
331 18
        static $parser;
332 18
        if (!$parser) {
333 3
            $parser = new UriParser();
334 2
        }
335
336 18
        $components = $parser((string) $uri);
337
338
        return '//'
339 18
            .$this->buildUserInfo($components['user'], $components['pass'])
340 18
            .$this->formatHost(new Host($components['host']))
341 18
            .$this->formatPort($components['port'])
342 12
        ;
343
    }
344
345
    /**
346
     * Format a URI port component according to the Formatter properties
347
     *
348
     * @param null|int $port
349
     *
350
     * @return string
351
     */
352 18
    protected function formatPort($port)
353
    {
354 18
        if ($this->port instanceof Port) {
355 3
            return $this->port->getUriComponent();
356
        }
357
358 15
        if (null !== $port) {
359 3
            return ':'.$port;
360
        }
361
362 12
        return '';
363
    }
364
365
    /**
366
     * Format a URI Query component according to the Formatter properties
367
     *
368
     * @param Uri|UriInterface $uri
369
     *
370
     * @return string
371
     */
372 24
    protected function formatQuery($uri)
373
    {
374 24
        $query = $this->formatUriPart(new Query($uri->getQuery()));
375 24
        if ($this->preserveQuery || '' !== $query) {
376 15
            $query = '?'.$query;
377 10
        }
378
379 24
        return $query;
380
    }
381
382
    /**
383
     * Format a URI Fragment component according to the Formatter properties
384
     *
385
     * @param Uri|UriInterface $uri
386
     *
387
     * @return string
388
     */
389 24
    protected function formatFragment($uri)
390
    {
391 24
        $fragment = $uri->getFragment();
392 24
        if ($this->preserveFragment || '' != $fragment) {
393 15
            $fragment = '#'.$fragment;
394 10
        }
395
396 24
        return $fragment;
397
    }
398
}
399