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

Query::getValue()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 9
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 5
CRAP Score 2

Importance

Changes 2
Bugs 0 Features 0
Metric Value
c 2
b 0
f 0
dl 0
loc 9
ccs 5
cts 5
cp 1
rs 9.6666
cc 2
eloc 5
nc 2
nop 2
crap 2
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\Query as QueryInterface;
16
use League\Uri\QueryParser;
17
use League\Uri\Types\ImmutableCollectionTrait;
18
use League\Uri\Types\ImmutableComponentTrait;
19
20
/**
21
 * Value object representing a URI query component.
22
 *
23
 * @package League.uri
24
 * @author  Ignace Nyamagana Butera <[email protected]>
25
 * @since   1.0.0
26
 */
27
class Query implements QueryInterface
28
{
29
    use ImmutableComponentTrait;
30
31
    use ImmutableCollectionTrait;
32
33
    /**
34
     * Key/pair separator character
35
     *
36
     * @var string
37
     */
38
    protected static $separator = '&';
39
40
    /**
41
     * Preserve the delimiter
42
     *
43
     * @var string
44
     */
45
    protected $preserveDelimiter = false;
46
47
    /**
48
     * a new instance
49
     *
50
     * @param string $data
51
     */
52 767
    public function __construct($data = null)
53
    {
54 767
        if (null !== $data) {
55 611
            $this->preserveDelimiter = true;
0 ignored issues
show
Documentation Bug introduced by
The property $preserveDelimiter was declared of type string, but true is of type boolean. Maybe add a type cast?

This check looks for assignments to scalar types that may be of the wrong type.

To ensure the code behaves as expected, it may be a good idea to add an explicit type cast.

$answer = 42;

$correct = false;

$correct = (bool) $answer;
Loading history...
56 611
            $this->data = $this->validate($data);
57 611
        }
58 767
    }
59
60
    /**
61
     * sanitize the submitted data
62
     *
63
     * @param string $str
64
     *
65
     * @throws InvalidArgumentException If reserved characters are used
66
     *
67
     * @return array
68
     */
69 611
    protected function validate($str)
70
    {
71 611
        $str = $this->validateString($str);
72 611
        if (strpos($str, '#') !== false) {
73 3
            throw new InvalidArgumentException('the query string must not contain a URI fragment');
74
        }
75
76 611
        return (new QueryParser())->parse($str, static::$separator, false);
77
    }
78
79
    /**
80
     * return a new Query instance from an Array or a traversable object
81
     *
82
     * @param \Traversable|array $data
83
     *
84
     * @return static
85
     */
86 102
    public static function createFromArray($data)
87
    {
88 102
        $query = null;
89 102
        $data = static::validateIterator($data);
90 96
        if (!empty($data)) {
91 78
            $query = (new QueryParser())->build($data, static::$separator, PHP_QUERY_RFC3986);
92 78
        }
93
94 96
        return new static($query);
95
    }
96
97
    /**
98
     * @inheritdoc
99
     */
100 1
    public function __debugInfo()
101
    {
102 1
        return ['query' => $this->getContent()];
103
    }
104
105
    /**
106
     * @inheritdoc
107
     */
108 12
    public static function __set_state(array $properties)
109
    {
110 12
        $component = static::createFromArray($properties['data']);
111 12
        $component->preserveDelimiter = $properties['preserveDelimiter'];
112
113 12
        return $component;
114
    }
115
116
    /**
117
     * Returns the component literal value. The return type can be
118
     * <ul>
119
     * <li> null: If the component is not defined
120
     * <li> string: Otherwise
121
     * </ul>
122
     *
123
     * @return string|int|null
124
     */
125 674
    public function getContent()
126
    {
127 674
        if ([] === $this->data && false === $this->preserveDelimiter) {
128 345
            return null;
129
        }
130
131 521
        return (new QueryParser())->build($this->data, static::$separator, PHP_QUERY_RFC3986);
132
    }
133
134
    /**
135
     * Returns the instance string representation; If the
136
     * instance is not defined an empty string is returned
137
     *
138
     * @return string
139
     */
140 674
    public function __toString()
141
    {
142 674
        return (string) $this->getContent();
143
    }
144
145
    /**
146
     * Returns the instance string representation
147
     * with its optional URI delimiters
148
     *
149
     * @return string
150
     */
151 625
    public function getUriComponent()
152
    {
153 625
        $query = $this->__toString();
154 625
        if ($this->preserveDelimiter) {
155 454
            return QueryInterface::DELIMITER.$query;
156
        }
157
158 333
        return $query;
159
    }
160
161
    /**
162
     * Returns an instance with the specified string
163
     *
164
     * This method MUST retain the state of the current instance, and return
165
     * an instance that contains the modified data
166
     *
167
     * @param string $value
168
     *
169
     * @return static
170
     */
171 162
    public function modify($value)
172
    {
173 162
        if (null === $value && $value === $this->getContent()) {
174 117
            return $this;
175
        }
176
177 45
        if ($value === $this->__toString()) {
178 18
            return $this;
179
        }
180
181 27
        return new static($value);
182
    }
183
184
    /**
185
     * Retrieves a single query parameter.
186
     *
187
     * Retrieves a single query parameter. If the parameter has not been set,
188
     * returns the default value provided.
189
     *
190
     * @param string $offset  the parameter name
191
     * @param mixed  $default Default value to return if the parameter does not exist.
192
     *
193
     * @return mixed
194
     */
195 9
    public function getValue($offset, $default = null)
196
    {
197 9
        $offset = rawurldecode($offset);
198 9
        if (isset($this->data[$offset])) {
199 3
            return $this->data[$offset];
200
        }
201
202 6
        return $default;
203
    }
204
205
    /**
206
     * Returns an instance merge with the specified query
207
     *
208
     * This method MUST retain the state of the current instance, and return
209
     * an instance that contains the modified query
210
     *
211
     * @param Query|string $query the data to be merged query can be
212
     *                            - another Interfaces\Query object
213
     *                            - a string or a Stringable object
214
     *
215
     * @return static
216
     */
217 24
    public function merge($query)
218
    {
219 24
        if (!$query instanceof QueryInterface) {
220 6
            $query = static::createFromArray($this->validate($query));
221 6
        }
222
223 24
        if ($this->sameValueAs($query)) {
224 3
            return $this;
225
        }
226
227 21
        return static::createFromArray(array_merge($this->toArray(), $query->toArray()));
228
    }
229
230
    /**
231
     * Sort the query string by offset, maintaining offset to data correlations.
232
     *
233
     * This method MUST retain the state of the current instance, and return
234
     * an instance that contains the modified query
235
     *
236
     * @param callable|int $sort a PHP sort flag constant or a comparaison function
237
     *                           which must return an integer less than, equal to,
238
     *                           or greater than zero if the first argument is
239
     *                           considered to be respectively less than, equal to,
240
     *                           or greater than the second.
241
     *
242
     * @return static
243
     */
244 45
    public function ksort($sort = SORT_REGULAR)
245
    {
246 45
        $func = is_callable($sort) ? 'uksort' : 'ksort';
247 45
        $data = $this->data;
248 45
        $func($data, $sort);
249 45
        if ($data === $this->data) {
250 33
            return $this;
251
        }
252
253 12
        return static::createFromArray($data);
254
    }
255
256
    /**
257
     * Return a new instance when needed
258
     *
259
     * @param array $data
260
     *
261
     * @return static
262
     */
263 42
    protected function newCollectionInstance(array $data)
264
    {
265 42
        if ($data == $this->data) {
266 15
            return $this;
267
        }
268
269 27
        return static::createFromArray($data);
270
    }
271
}
272