Passed
Pull Request — 2.2 (#20357)
by Wilmer
13:33 queued 05:55
created

ArrayParser   A

Complexity

Total Complexity 20

Size/Duplication

Total Lines 91
Duplicated Lines 0 %

Test Coverage

Coverage 97.44%

Importance

Changes 0
Metric Value
eloc 39
dl 0
loc 91
ccs 38
cts 39
cp 0.9744
rs 10
c 0
b 0
f 0
wmc 20

3 Methods

Rating   Name   Duplication   Size   Complexity  
B parseString() 0 23 10
B parseArray() 0 25 7
A parse() 0 11 3
1
<?php
2
3
/**
4
 * @link https://www.yiiframework.com/
5
 * @copyright Copyright (c) 2008 Yii Software LLC
6
 * @license https://www.yiiframework.com/license/
7
 */
8
9
namespace yii\db\pgsql;
10
11
/**
12
 * The class converts PostgreSQL array representation to PHP array
13
 *
14
 * @author Sergei Tigrov <[email protected]>
15
 * @author Dmytro Naumenko <[email protected]>
16
 * @since 2.0.14
17
 * @phpcs:disable Squiz.NamingConventions.ValidVariableName.PrivateNoUnderscore
18
 */
19
class ArrayParser
20
{
21
    /**
22
     * @var string Character used in array
23
     */
24
    private $delimiter = ',';
25
26
27
    /**
28
     * Convert array from PostgreSQL to PHP
29
     *
30
     * @param string $value string to be converted
31
     * @return array|null
32
     */
33 11
    public function parse($value)
34
    {
35 11
        if ($value === null) {
0 ignored issues
show
introduced by
The condition $value === null is always false.
Loading history...
36
            return null;
37
        }
38
39 11
        if ($value === '{}') {
40 1
            return [];
41
        }
42
43 10
        return $this->parseArray($value);
44
    }
45
46
    /**
47
     * Pares PgSQL array encoded in string
48
     *
49
     * @param string $value
50
     * @param int $i parse starting position
51
     * @return array
52
     */
53 10
    private function parseArray($value, &$i = 0)
54
    {
55 10
        $result = [];
56 10
        $len = strlen($value);
57 10
        for (++$i; $i < $len; ++$i) {
58 10
            switch ($value[$i]) {
59 10
                case '{':
60 3
                    $result[] = $this->parseArray($value, $i);
61 3
                    break;
62 10
                case '}':
63 10
                    break 2;
64 10
                case $this->delimiter:
65 10
                    if (empty($result)) { // `{}` case
66 2
                        $result[] = null;
67
                    }
68 10
                    if (in_array($value[$i + 1], [$this->delimiter, '}'], true)) { // `{,}` case
69 5
                        $result[] = null;
70
                    }
71 10
                    break;
72
                default:
73 8
                    $result[] = $this->parseString($value, $i);
74
            }
75
        }
76
77 10
        return $result;
78
    }
79
80
    /**
81
     * Parses PgSQL encoded string
82
     *
83
     * @param string $value
84
     * @param int $i parse starting position
85
     * @return string|null
86
     */
87 8
    private function parseString($value, &$i)
88
    {
89 8
        $isQuoted = $value[$i] === '"';
90 8
        $stringEndChars = $isQuoted ? ['"'] : [$this->delimiter, '}'];
91 8
        $result = '';
92 8
        $len = strlen($value);
93 8
        for ($i += $isQuoted ? 1 : 0; $i < $len; ++$i) {
94 8
            if (in_array($value[$i], ['\\', '"'], true) && in_array($value[$i + 1], [$value[$i], '"'], true)) {
95 2
                ++$i;
96 8
            } elseif (in_array($value[$i], $stringEndChars, true)) {
97 8
                break;
98
            }
99
100 8
            $result .= $value[$i];
101
        }
102
103 8
        $i -= $isQuoted ? 0 : 1;
104
105 8
        if (!$isQuoted && $result === 'NULL') {
106 1
            $result = null;
107
        }
108
109 8
        return $result;
110
    }
111
}
112