Completed
Push — master ( 9db984...9898c1 )
by ignace nyamagana
02:48
created

Query::getPairs()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 2
c 1
b 0
f 0
nc 1
nop 0
dl 0
loc 4
ccs 2
cts 2
cp 1
crap 1
rs 10
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 907
    public function __construct($data = null)
87
    {
88 907
        $this->data = $this->validate($data);
89 907
        $this->preserveDelimiter = null !== $data;
90 907
    }
91
92
    /**
93
     * sanitize the submitted data
94
     *
95
     * @param string $str
96
     *
97
     * @return array
98
     */
99 907
    protected function validate($str)
100
    {
101 907
        if (null === $str) {
102 414
            return [];
103
        }
104
105 748
        return (new QueryParser())
106 748
            ->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 814
    public function getContent()
134
    {
135 814
        if (!$this->preserveDelimiter) {
136 429
            return null;
137
        }
138
139 658
        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 802
    public function __toString()
149
    {
150 802
        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 752
    public function getUriComponent()
160
    {
161 752
        $query = $this->__toString();
162 752
        if ($this->preserveDelimiter) {
163 590
            return QueryInterface::DELIMITER.$query;
164
        }
165
166 405
        return $query;
167
    }
168
169
    /**
170
     * Returns an instance with the specified string
171
     *
172
     * This method MUST retain the state of the current instance, and return
173
     * an instance that contains the modified data
174
     *
175
     * @param string $value
176
     *
177
     * @return static
178
     */
179 204
    public function modify($value)
180
    {
181 204
        if ($value === $this->getContent()) {
182 177
            return $this;
183
        }
184
185 27
        return new static($value);
186
    }
187
188
    /**
189
     * Returns an array representation of the query
190
     *
191
     * @return array
192
     */
193 54
    public function getPairs()
194
    {
195 54
        return $this->data;
196
    }
197
198
    /**
199
     * DEPRECATION WARNING! This method will be removed in the next major point release
200
     *
201
     * @deprecated deprecated since version 4.2
202
     *
203
     * Returns an array representation of the query
204
     *
205
     * @return array
206
     */
207
    public function toArray()
208
    {
209
        return $this->getPairs();
210
    }
211
212
    /**
213
     * Retrieves a single query parameter.
214
     *
215
     * Retrieves a single query parameter. If the parameter has not been set,
216
     * returns the default value provided.
217
     *
218
     * @param string $offset  the parameter name
219
     * @param mixed  $default Default value to return if the parameter does not exist.
220
     *
221
     * @return mixed
222
     */
223 9
    public function getValue($offset, $default = null)
224
    {
225 9
        $offset = $this->validateString($offset);
226 9
        $offset = $this->decodeComponent($offset);
227 9
        if (isset($this->data[$offset])) {
228 3
            return $this->data[$offset];
229
        }
230
231 6
        return $default;
232
    }
233
234
    /**
235
     * Returns an instance merge with the specified query
236
     *
237
     * This method MUST retain the state of the current instance, and return
238
     * an instance that contains the modified query
239
     *
240
     * @param QueryInterface|string $query the data to be merged
241
     *
242
     * @return static
243
     */
244 24
    public function merge($query)
245
    {
246 24
        $pairs = !$query instanceof QueryInterface ? $this->validate($query) : $query->getPairs();
247 24
        if ($this->data === $pairs) {
248 3
            return $this;
249
        }
250
251 21
        return static::createFromPairs(array_merge($this->data, $pairs));
252
    }
253
254
    /**
255
     * Sort the query string by offset, maintaining offset to data correlations.
256
     *
257
     * This method MUST retain the state of the current instance, and return
258
     * an instance that contains the modified query
259
     *
260
     * @param callable|int $sort a PHP sort flag constant or a comparaison function
261
     *                           which must return an integer less than, equal to,
262
     *                           or greater than zero if the first argument is
263
     *                           considered to be respectively less than, equal to,
264
     *                           or greater than the second.
265
     *
266
     * @return static
267
     */
268 51
    public function ksort($sort = SORT_REGULAR)
269
    {
270 51
        $func = is_callable($sort) ? 'uksort' : 'ksort';
271 51
        $data = $this->data;
272 51
        $func($data, $sort);
273 51
        if ($data === $this->data) {
274 39
            return $this;
275
        }
276
277 12
        return static::createFromPairs($data);
278
    }
279
280
    /**
281
     * @inheritdoc
282
     */
283 3
    public function hasKey($offset)
284
    {
285 3
        $offset = $this->validateString($offset);
286 3
        $offset = $this->decodeComponent($offset);
287
288 3
        return array_key_exists($offset, $this->data);
289
    }
290
291
    /**
292
     * @inheritdoc
293
     */
294 6
    public function keys()
295
    {
296 6
        if (0 === func_num_args()) {
297 3
            return array_keys($this->data);
298
        }
299
300 3
        return array_keys($this->data, $this->decodeComponent(func_get_arg(0)), true);
301
    }
302
303
    /**
304
     * @inheritdoc
305
     */
306 9
    public function without(array $offsets)
307
    {
308 9
        $data = $this->data;
309 9
        foreach ($offsets as $offset) {
310 9
            unset($data[$this->decodeComponent($offset)]);
311 6
        }
312
313 9
        return $this->newCollectionInstance($data);
314
    }
315
316
317
318
    /**
319
     * Return a new instance when needed
320
     *
321
     * @param array $data
322
     *
323
     * @return static
324
     */
325 42
    protected function newCollectionInstance(array $data)
326
    {
327 42
        if ($data === $this->data) {
328 15
            return $this;
329
        }
330
331 27
        return static::createFromPairs($data);
332
    }
333
}
334