Completed
Pull Request — master (#3)
by Risan Bagja
02:02 queued 34s
created

BaseStringBuilder::buildQueryString()   B

Complexity

Conditions 5
Paths 10

Size

Total Lines 18
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 9
CRAP Score 5

Importance

Changes 0
Metric Value
dl 0
loc 18
ccs 9
cts 9
cp 1
rs 8.8571
c 0
b 0
f 0
cc 5
eloc 10
nc 10
nop 3
crap 5
1
<?php
2
3
namespace Risan\OAuth1\Signature;
4
5
use GuzzleHttp\Psr7\Uri;
6
use InvalidArgumentException;
7
use Psr\Http\Message\UriInterface;
8
9
class BaseStringBuilder implements BaseStringBuilderInterface
10
{
11
    /**
12
     * {@inheritDoc}
13
     */
14 4
    public function build($httpMethod, $uri, array $parameters = [])
15
    {
16 4
        $uri = $this->parseToPsrUri($uri);
17
18 4
        $components = [];
19
20 4
        $components[] = rawurlencode($this->buildMethodComponent($httpMethod));
21
22 4
        $components[] = rawurlencode($this->buildUriComponent($uri));
23
24 4
        parse_str($uri->getQuery(), $queryParameters);
25
26 4
        $components[] = rawurlencode($this->buildParametersComponent(array_merge($queryParameters, $parameters)));
27
28 4
        return implode('&', $components);
29
    }
30
31
    /**
32
     * {@inheritDoc}
33
     */
34 5
    public function buildMethodComponent($httpMethod)
35
    {
36 5
        return strtoupper($httpMethod);
37
    }
38
39
    /**
40
     * {@inheritDoc}
41
     */
42 7
    public function buildUriComponent($uri)
43
    {
44 7
        $uri = $this->parseToPsrUri($uri);
45
46 7
        return Uri::fromParts([
47 7
            'scheme' => $uri->getScheme(),
48 7
            'host' => $uri->getHost(),
49 7
            'port' => $uri->getPort(),
50 7
            'path' => $uri->getPath(),
51
        ]);
52
    }
53
54
    /**
55
     * {@inheritDoc}
56
     */
57 4
    public function buildParametersComponent(array $parameters)
58
    {
59 4
        $parameters = $this->normalizeParameters($parameters);
60
61 4
        return $this->buildQueryString($parameters);
62
    }
63
64
    /**
65
     * Normalize the given request parameters.
66
     *
67
     * @param  array  $parameters
68
     * @return array
69
     */
70 6
    public function normalizeParameters(array $parameters)
71
    {
72 6
        $normalized = [];
73
74
        // [1] Encode both the keys and values.
75
        // Decode it frist, in case the given data is already encoded.
76 6
        foreach ($parameters as $key => $value) {
77 6
            $key = rawurlencode(rawurldecode($key));
78
79 6
            if (is_array($value)) {
80 1
                $normalized[$key] = $this->normalizeParameters($value);
81
            } else {
82 6
                $normalized[$key] = rawurlencode(rawurldecode($value));
83
            }
84
        }
85
86
        // [2] Sort by the encoded key.
87 6
        ksort($normalized);
88
89 6
        return $normalized;
90
    }
91
92
    /**
93
     * Build query string from the given parameters.
94
     *
95
     * @param  array  $parameters
96
     * @param  array  $initialQueryParameters
97
     * @param  string $previousKey
98
     * @return string
99
     */
100 6
    public function buildQueryString(array $parameters, array $initialQueryParameters = [], $previousKey = null)
101
    {
102 6
        $queryParameters = $initialQueryParameters;
103
104 6
        foreach ($parameters as $key => $value) {
105 6
            if ($previousKey !== null) {
106 1
                $key = "{$previousKey}[{$key}]";
107
            }
108
109 6
            if (is_array($value)) {
110 1
                $queryParameters = $this->buildQueryString($value, $queryParameters, $key);
111
            } else {
112 6
                $queryParameters[] = "{$key}={$value}";
113
            }
114
        }
115
116 6
        return $previousKey !== null ? $queryParameters : implode('&', $queryParameters);
117
    }
118
119
    /**
120
     * Parse the given uri to the PSR URIInterface instance.
121
     *
122
     * @param  \Psr\Http\Message\UriInterface|string $uri
123
     * @return \Psr\Http\Message\UriInterface
124
     * @throws \InvalidArgumentException
125
     */
126 8
    public function parseToPsrUri($uri)
127
    {
128 8
        if ($uri instanceof UriInterface) {
129 6
            return $uri;
130 7
        } elseif (is_string($uri)) {
131 7
            return new Uri($uri);
132
        }
133
134 1
        throw new InvalidArgumentException('URI must be a string or an instance of \Psr\Http\Message\UriInterface');
135
    }
136
}
137