Completed
Push — master ( 5a1f4e...aa9408 )
by ignace nyamagana
12:29
created

Query::withContent()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 8
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 2

Importance

Changes 0
Metric Value
cc 2
eloc 4
nc 2
nop 1
dl 0
loc 8
ccs 4
cts 4
cp 1
crap 2
rs 9.4285
c 0
b 0
f 0
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 League\Uri\Interfaces\Query as QueryInterface;
15
use League\Uri\QueryParser;
16
use League\Uri\Types\ImmutableCollectionTrait;
17
use League\Uri\Types\ImmutableComponentTrait;
18
19
/**
20
 * Value object representing a URI query component.
21
 *
22
 * @package League.uri
23
 * @author  Ignace Nyamagana Butera <[email protected]>
24
 * @since   1.0.0
25
 */
26
class Query implements QueryInterface
27
{
28
    use ImmutableComponentTrait;
29
30
    use ImmutableCollectionTrait;
31
32
    /**
33
     * Key/pair separator character
34
     *
35
     * @var string
36
     */
37
    protected static $separator = '&';
38
39
    /**
40
     * Preserve the delimiter
41
     *
42
     * @var bool
43
     */
44
    protected $preserveDelimiter = false;
45
46
    /**
47
     * DEPRECATION WARNING! This method will be removed in the next major point release
48
     *
49
     * @deprecated deprecated since version 4.2
50
     *
51
     * return a new instance from an array or a traversable object
52
     *
53
     * @param \Traversable|array $data
54
     *
55
     * @return static
56
     */
57
    public static function createFromArray($data)
58
    {
59
        return self::createFromPairs($data);
60
    }
61
62
    /**
63
     * return a new Query instance from an Array or a traversable object
64
     *
65
     * @param \Traversable|array $data
66
     *
67
     * @return static
68
     */
69 108
    public static function createFromPairs($data)
70
    {
71 108
        $data = static::validateIterator($data);
72 102
        if (empty($data)) {
73 27
            return new static();
74
        }
75
76 81
        $query = (new QueryParser())->build($data, static::$separator);
77
78 81
        return new static($query);
79
    }
80
81
    /**
82
     * a new instance
83
     *
84
     * @param string $data
85
     */
86 955
    public function __construct($data = null)
87
    {
88 955
        $this->data = $this->validate($data);
89 955
        $this->preserveDelimiter = null !== $data;
90 955
    }
91
92
    /**
93
     * sanitize the submitted data
94
     *
95
     * @param string $str
96
     *
97
     * @return array
98
     */
99 955
    protected function validate($str)
100
    {
101 955
        if (null === $str) {
102 462
            return [];
103
        }
104
105 754
        return (new QueryParser())
106 754
            ->parse($this->validateString($str), static::$separator, PHP_QUERY_RFC3986);
107
    }
108
109
    /**
110
     * @inheritdoc
111
     */
112 2
    public function __debugInfo()
113
    {
114 2
        return ['query' => $this->getContent()];
115
    }
116
117
    /**
118
     * @inheritdoc
119
     */
120 12
    public static function __set_state(array $properties)
121
    {
122 12
        $component = static::createFromPairs($properties['data']);
123 12
        $component->preserveDelimiter = $properties['preserveDelimiter'];
124
125 12
        return $component;
126
    }
127
128
    /**
129
     * Returns the component literal value.
130
     *
131
     * @return null|string
132
     */
133 862
    public function getContent()
134
    {
135 862
        if (!$this->preserveDelimiter) {
136 483
            return null;
137
        }
138
139 664
        return (new QueryParser())->build($this->data, static::$separator, PHP_QUERY_RFC3986);
140
    }
141
142
    /**
143
     * Returns the instance string representation; If the
144
     * instance is not defined an empty string is returned
145
     *
146
     * @return string
147
     */
148 850
    public function __toString()
149
    {
150 850
        return (string) $this->getContent();
151
    }
152
153
    /**
154
     * Returns the instance string representation
155
     * with its optional URI delimiters
156
     *
157
     * @return string
158
     */
159 800
    public function getUriComponent()
160
    {
161 800
        $query = $this->__toString();
162 800
        if ($this->preserveDelimiter) {
163 590
            return QueryInterface::DELIMITER.$query;
164
        }
165
166 459
        return $query;
167
    }
168
169
    /**
170
     * DEPRECATION WARNING! This method will be removed in the next major point release
171
     *
172
     * @deprecated deprecated since version 4.2
173
     *
174
     * Returns an array representation of the query
175
     *
176
     * @return array
177
     */
178
    public function toArray()
179
    {
180
        return $this->getPairs();
181
    }
182
183
    /**
184
     * Returns an array representation of the query
185
     *
186
     * @return array
187
     */
188 54
    public function getPairs()
189
    {
190 54
        return $this->data;
191
    }
192
193
    /**
194
     * Retrieves a single query parameter.
195
     *
196
     * Retrieves a single query parameter. If the parameter has not been set,
197
     * returns the default value provided.
198
     *
199
     * @param string $offset  the parameter name
200
     * @param mixed  $default Default value to return if the parameter does not exist.
201
     *
202
     * @return mixed
203
     */
204 9
    public function getValue($offset, $default = null)
205
    {
206 9
        $offset = $this->validateString($offset);
207 9
        $offset = $this->decodeComponent($offset);
208 9
        if (isset($this->data[$offset])) {
209 3
            return $this->data[$offset];
210
        }
211
212 6
        return $default;
213
    }
214
215
    /**
216
     * Returns an instance with the specified string
217
     *
218
     * This method MUST retain the state of the current instance, and return
219
     * an instance that contains the modified data
220
     *
221
     * @param string $value
222
     *
223
     * @return static
224
     */
225 240
    public function withContent($value = null)
226
    {
227 240
        if ($value === $this->getContent()) {
228 207
            return $this;
229
        }
230
231 33
        return new static($value);
232
    }
233
234
    /**
235
     * DEPRECATION WARNING! This method will be removed in the next major point release
236
     *
237
     * @deprecated deprecated since version 4.2
238
     *
239
     * @see withContent
240
     *
241
     * Returns an instance with the specified string
242
     *
243
     * This method MUST retain the state of the current instance, and return
244
     * an instance that contains the modified data
245
     *
246
     * @param string $value
247
     *
248
     * @return static
249
     */
250
    public function modify($value)
251
    {
252
        return $this->withContent($value);
253
    }
254
255
    /**
256
     * Returns an instance merge with the specified query
257
     *
258
     * This method MUST retain the state of the current instance, and return
259
     * an instance that contains the modified query
260
     *
261
     * @param QueryInterface|string $query the data to be merged
262
     *
263
     * @return static
264
     */
265 24
    public function merge($query)
266
    {
267 24
        $pairs = !$query instanceof QueryInterface ? $this->validate($query) : $query->getPairs();
268 24
        if ($this->data === $pairs) {
269 3
            return $this;
270
        }
271
272 21
        return static::createFromPairs(array_merge($this->data, $pairs));
273
    }
274
275
    /**
276
     * Sort the query string by offset, maintaining offset to data correlations.
277
     *
278
     * This method MUST retain the state of the current instance, and return
279
     * an instance that contains the modified query
280
     *
281
     * @param callable|int $sort a PHP sort flag constant or a comparaison function
282
     *                           which must return an integer less than, equal to,
283
     *                           or greater than zero if the first argument is
284
     *                           considered to be respectively less than, equal to,
285
     *                           or greater than the second.
286
     *
287
     * @return static
288
     */
289 57
    public function ksort($sort = SORT_REGULAR)
290
    {
291 57
        $func = is_callable($sort) ? 'uksort' : 'ksort';
292 57
        $data = $this->data;
293 57
        $func($data, $sort);
294 57
        if ($data === $this->data) {
295 45
            return $this;
296
        }
297
298 12
        return static::createFromPairs($data);
299
    }
300
301
    /**
302
     * @inheritdoc
303
     */
304 3
    public function hasKey($offset)
305
    {
306 3
        $offset = $this->validateString($offset);
307 3
        $offset = $this->decodeComponent($offset);
308
309 3
        return array_key_exists($offset, $this->data);
310
    }
311
312
    /**
313
     * @inheritdoc
314
     */
315 6
    public function keys()
316
    {
317 6
        if (0 === func_num_args()) {
318 3
            return array_keys($this->data);
319
        }
320
321 3
        return array_keys($this->data, $this->decodeComponent(func_get_arg(0)), true);
322
    }
323
324
    /**
325
     * @inheritdoc
326
     */
327 9
    public function without(array $offsets)
328
    {
329 9
        $data = $this->data;
330 9
        foreach ($offsets as $offset) {
331 9
            unset($data[$this->decodeComponent($offset)]);
332 6
        }
333
334 9
        return $this->newCollectionInstance($data);
335
    }
336
337
338
339
    /**
340
     * Return a new instance when needed
341
     *
342
     * @param array $data
343
     *
344
     * @return static
345
     */
346 42
    protected function newCollectionInstance(array $data)
347
    {
348 42
        if ($data === $this->data) {
349 15
            return $this;
350
        }
351
352 27
        return static::createFromPairs($data);
353
    }
354
}
355