Completed
Push — master ( 0a493e...a851a6 )
by ignace nyamagana
14:42
created

Formatter::setQuerySeparator()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

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