Completed
Pull Request — master (#40)
by ignace nyamagana
11:26
created

Query   A

Complexity

Total Complexity 19

Size/Duplication

Total Lines 185
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 3

Test Coverage

Coverage 100%

Importance

Changes 20
Bugs 1 Features 0
Metric Value
wmc 19
c 20
b 1
f 0
lcom 1
cbo 3
dl 0
loc 185
ccs 47
cts 47
cp 1
rs 10

10 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 6 2
A validate() 0 9 2
A createFromArray() 0 10 1
A __toString() 0 4 1
A getUriComponent() 0 9 2
A merge() 0 12 3
A ksort() 0 11 3
A newCollectionInstance() 0 8 2
A getValue() 0 9 2
A __set_state() 0 4 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.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
     * a new instance
42
     *
43
     * @param string $data
44
     */
45 484
    public function __construct($data = null)
46
    {
47 484
        if (null !== $data) {
48 386
            $this->data = $this->validate($data);
49 386
        }
50 484
    }
51
52
    /**
53
     * sanitize the submitted data
54
     *
55
     * @param string $str
56
     *
57
     * @throws InvalidArgumentException If reserved characters are used
58
     *
59
     * @return array
60
     */
61 386
    protected function validate($str)
62
    {
63 386
        $str = $this->validateString($str);
64 386
        if (strpos($str, '#') !== false) {
65 2
            throw new InvalidArgumentException('the query string must not contain a URI fragment');
66
        }
67
68 386
        return (new QueryParser())->parse($str, static::$separator, false);
69
    }
70
71
    /**
72
     * return a new Query instance from an Array or a traversable object
73
     *
74
     * @param \Traversable|array $data
75
     *
76
     * @return static
77
     */
78 60
    public static function createFromArray($data)
79
    {
80 60
        $query = (new QueryParser())->build(
81 60
            static::validateIterator($data),
82 56
            static::$separator,
83
            PHP_QUERY_RFC3986
84 56
        );
85
86 56
        return new static($query);
87
    }
88
89
    /**
90
     * Returns the instance string representation; If the
91
     * instance is not defined an empty string is returned
92 422
     *
93
     * @return string
94 422
     */
95
    public function __toString()
96
    {
97
        return (new QueryParser())->build($this->data, static::$separator, PHP_QUERY_RFC3986);
98
    }
99
100 390
    /**
101
     * Returns the instance string representation
102 390
     * with its optional URI delimiters
103 390
     *
104 286
     * @return string
105 286
     */
106
    public function getUriComponent()
107 390
    {
108
        $query = $this->__toString();
109
        if ('' !== $query) {
110
            $query = QueryInterface::DELIMITER.$query;
111
        }
112
113 6
        return $query;
114
    }
115 6
116 6
    /**
117 2
     * Retrieves a single query parameter.
118
     *
119
     * Retrieves a single query parameter. If the parameter has not been set,
120 4
     * returns the default value provided.
121
     *
122
     * @param string $offset  the parameter name
123
     * @param mixed  $default Default value to return if the parameter does not exist.
124
     *
125
     * @return mixed
126 16
     */
127
    public function getValue($offset, $default = null)
128 16
    {
129 4
        $offset = rawurldecode($offset);
130 4
        if (isset($this->data[$offset])) {
131
            return $this->data[$offset];
132 16
        }
133 2
134
        return $default;
135
    }
136 14
137
    /**
138
     * Returns an instance merge with the specified query
139
     *
140
     * This method MUST retain the state of the current instance, and return
141
     * an instance that contains the modified query
142 28
     *
143
     * @param Query|string $query the data to be merged query can be
144 28
     *                            - another Interfaces\Query object
145 28
     *                            - a string or a Stringable object
146 28
     *
147 28
     * @return static
148 20
     */
149
    public function merge($query)
150
    {
151 8
        if (!$query instanceof QueryInterface) {
152
            $query = static::createFromArray($this->validate($query));
153
        }
154
155
        if ($this->sameValueAs($query)) {
156
            return $this;
157
        }
158
159
        return static::createFromArray(array_merge($this->toArray(), $query->toArray()));
160
    }
161 28
162
    /**
163 28
     * Sort the query string by offset, maintaining offset to data correlations.
164 10
     *
165
     * This method MUST retain the state of the current instance, and return
166
     * an instance that contains the modified query
167 18
     *
168
     * @param callable|int $sort a PHP sort flag constant or a comparaison function
169
     *                           which must return an integer less than, equal to,
170
     *                           or greater than zero if the first argument is
171
     *                           considered to be respectively less than, equal to,
172
     *                           or greater than the second.
173
     *
174
     * @return static
175
     */
176
    public function ksort($sort = SORT_REGULAR)
177
    {
178
        $func = is_callable($sort) ? 'uksort' : 'ksort';
179
        $data = $this->data;
180
        $func($data, $sort);
181
        if ($data === $this->data) {
182
            return $this;
183
        }
184
185
        return static::createFromArray($data);
186
    }
187
188
    /**
189
     * Return a new instance when needed
190
     *
191
     * @param array $data
192
     *
193
     * @return static
194
     */
195
    protected function newCollectionInstance(array $data)
196
    {
197
        if ($data == $this->data) {
198
            return $this;
199
        }
200
201
        return static::createFromArray($data);
202
    }
203
204
    /**
205
     * @inheritdoc
206
     */
207
    public static function __set_state(array $properties)
208
    {
209
        return static::createFromArray($properties['data']);
210
    }
211
}
212