Test Setup Failed
Push — master ( b50703...9d91c5 )
by Dominik
06:16
created

UrlEncodedDecoderType   A

Complexity

Total Complexity 15

Size/Duplication

Total Lines 90
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 0

Importance

Changes 0
Metric Value
dl 0
loc 90
c 0
b 0
f 0
wmc 15
lcom 1
cbo 0
rs 10

4 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 5 1
A getContentType() 0 4 1
A decode() 0 13 3
D cleanRawData() 0 32 10
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Chubbyphp\Deserialization\Decoder;
6
7
final class UrlEncodedDecoderType implements DecoderTypeInterface
8
{
9
    /**
10
     * @var string
11
     */
12
    private $numericPrefix;
13
14
    /**
15
     * @var string
16
     */
17
    private $argSeperator;
18
19
    /**
20
     * @param string $numericPrefix
21
     * @param string $argSeperator
22
     */
23
    public function __construct(string $numericPrefix = '', string $argSeperator = '&')
24
    {
25
        $this->numericPrefix = $numericPrefix;
26
        $this->argSeperator = $argSeperator;
27
    }
28
29
    /**
30
     * @return string
31
     */
32
    public function getContentType(): string
33
    {
34
        return 'application/x-www-form-urlencoded';
35
    }
36
37
    /**
38
     * @param string $data
39
     *
40
     * @return array
41
     *
42
     * @throws DecoderException
43
     */
44
    public function decode(string $data): array
45
    {
46
        $data = str_replace($this->argSeperator, '&', $data);
47
48
        $rawData = [];
49
        parse_str($data, $rawData);
50
51
        if ('' !== $data && [] === $rawData) {
52
            throw DecoderException::createNotParsable($this->getContentType());
53
        }
54
55
        return $this->cleanRawData($rawData, strlen($this->numericPrefix));
0 ignored issues
show
Bug introduced by
It seems like $rawData can also be of type null; however, Chubbyphp\Deserializatio...derType::cleanRawData() does only seem to accept array, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
56
    }
57
58
    /**
59
     * @param array $rawData
60
     * @param int   $numericPrefixLength
61
     *
62
     * @return array
63
     */
64
    private function cleanRawData(array $rawData, int $numericPrefixLength): array
65
    {
66
        $data = [];
67
        foreach ($rawData as $rawKey => $value) {
68
            if (0 !== $numericPrefixLength && 0 === strpos($rawKey, $this->numericPrefix)) {
69
                $rawSubKey = substr($rawKey, $numericPrefixLength);
70
                if (is_numeric($rawSubKey)) {
71
                    $rawKey = $rawSubKey;
72
                }
73
            }
74
75
            $key = is_numeric($rawKey) ? (int) $rawKey : $rawKey;
76
77
            if (is_array($value)) {
78
                $data[$key] = $this->cleanRawData($value, $numericPrefixLength);
79
            } else {
80
                if (is_numeric($value)) {
81
                    if ((string) (int) $value === $value) {
82
                        $value = (int) $value;
83
                    } else {
84
                        $value = (float) $value;
85
                    }
86
                } elseif ('' === $value) {
87
                    $value = null;
88
                }
89
90
                $data[$key] = $value;
91
            }
92
        }
93
94
        return $data;
95
    }
96
}
97