Query   A
last analyzed

Complexity

Total Complexity 27

Size/Duplication

Total Lines 139
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 0

Test Coverage

Coverage 81.36%

Importance

Changes 0
Metric Value
wmc 27
lcom 1
cbo 0
dl 0
loc 139
ccs 48
cts 59
cp 0.8136
rs 10
c 0
b 0
f 0

11 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 4 1
A __toString() 0 4 1
A import() 0 6 1
A reset() 0 6 1
A getvar() 0 4 1
A putvar() 0 4 1
A compile() 0 9 2
A parse() 0 13 5
B parseQueryString() 0 25 6
A parseQueryStringEntry() 0 12 3
A encodeValue() 0 16 5
1
<?php
2
3
/*
4
 * This file is part of the Ariadne Component Library.
5
 *
6
 * (c) Muze <[email protected]>
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11
12
namespace arc\url;
13
14
/**
15
 *  Query parses any valid url query part and generates array accessible values for it
16
 *  - you can use the same name multiple times -- ?name=value1&name=value2
17
 *    this will result in name becoming an array, similarly arrays will not be encoded with trailing [] behind the name
18
 *  - you can use names without values -- ?name&name2&name3
19
 *  - names may include any valid character -- ?valid+name
20
 *
21
 */
22
class Query extends \ArrayObject implements QueryInterface
23
{
24 48
    public function __construct($query = '')
25
    {
26 48
        parent::__construct( $this->parse( $query ), \ArrayObject::ARRAY_AS_PROPS );
27 48
    }
28
29 42
    public function __toString()
30
	{
31 42
        return $this->compile( (array) $this );
32
    }
33
34
    /**
35
     *	Import a query string or an array of key => value pairs into the UrlQuery.
36
     *
37
     *	Usage:
38
     *		$query->import( 'foo=bar&bar=1' );
39
     *		$query->import( array( 'foo' => 'bar', 'bar' => 1 ) );
40
     *
41
     *	@param string|array $values query string or array of values to import into this query
42
     */
43 48
    public function import($values)
44
    {
45 48
        $this->exchangeArray( $this->parse( $values ) + $this->getArrayCopy() );
46
47 48
        return $this;
48
    }
49
50
    /**
51
     * Removes all current query parameters.
52
     * @return $this
53
     */
54
    public function reset()
55
    {
56
        $this->exchangeArray( [] );
57
58
        return $this;
59
    }
60
61
    // === \arc\KeyValueStoreInterface ===
62
63
    /**
64
     *	@param string $name name of the query parameter
65
     *	@return mixed The named query parameter
66
     */
67
    public function getvar($name)
68
    {
69
        return $this->offsetGet($name);
70
    }
71
72
    /**
73
     *	@param string $name name for the query parameter
74
     *	@param mixed $value value of the query parameter
75
     */
76
    public function putvar($name, $value)
77
    {
78
        $this->offsetSet($name, $value);
79
    }
80
81 4
    protected function compile($values)
82
    {
83 4
        $result = array();
84 4
        foreach ($values as $name => $value) {
85 4
            $result[] = $this->encodeValue( $name, $value );
86
        }
87
88 4
        return implode( '&', $result );
89
    }
90
91 48
    protected function parse($values)
92
    {
93 48
        $result = array();
94 48
        if (is_array( $values ) || ( $values instanceof \Traversable )) {
95
            foreach ($values as $name => $value) {
96
                $result[$name] = $value;
97
            }
98 48
        } elseif (is_string( $values )) {
99 48
            $result = $this->parseQueryString( $values );
100
        }
101
102 48
        return $result;
103
    }
104
105 16
    protected function parseQueryString($queryString)
106
    {
107 16
        $result = array();
108 16
        if ($queryString) {
109 6
            $values = preg_split( '/[\&\;]/', $queryString );
110 6
            foreach ($values as $queryStringEntry) {
111 6
                list( $name, $value ) = $this->parseQueryStringEntry( $queryStringEntry );
112 6
                if (!isset($value)) {
113
                    // no '=' in query entry  e.g: ?name&...
114 4
                    $result[] = $name;
115 4
                } elseif (!isset( $result[$name] )) {
116
                    // a new entry e.g: ?name=1&...
117 4
                    $result[ $name ] = $value;
118 2
                } elseif (!is_array( $result[$name] )) {
119
                    // entry with same name exists already but is not an array yet => ?name=1&name=2&...
120 2
                    $result[ $name ] = array( $result[$name], $value );
121
                } else {
122
                    // entry with same name exists and is an array => ?name=1&name=2&name=3&...
123
                    $result[ $name ][] = $value;
124
                }
125
            }
126
        }
127
128 16
        return $result;
129
    }
130
131 6
    private function parseQueryStringEntry($queryStringEntry)
132
    {
133 6
        $result = explode( '=', $queryStringEntry, 2 ) + array( 1 => null ); // value may be null if no '=' is found in the query string
134 6
        foreach ($result as $key => $value) {
135 6
            if (isset($value)) {
136 6
                $value = urldecode( $value );
137
            }
138 6
            $result[$key] = $value;
139
        }
140
141 6
        return $result;
142
    }
143
144 4
    private function encodeValue($name, $value = null)
145
    {
146 4
        if (is_array( $value )) {
147 2
            $result = array();
148 2
            foreach ($value as $val) {
149 2
                $result[] = $this->encodeValue( $name, $val );
150
            }
151
152 2
            return implode( '&', $result );
153
        } else {
154 4
            return ( is_numeric( $name )
155 4
                ? RawUrlEncode( $value )
156 4
                : RawUrlEncode( $name ) . ( isset( $value ) ? '=' . RawUrlEncode( (string) $value ) : '' )
157
            );
158
        }
159
    }
160
}
161