Passed
Push — 2.2 ( c9917f...37714b )
by Alexander
02:01 queued 17s
created

ArrayParser   A

Complexity

Total Complexity 20

Size/Duplication

Total Lines 91
Duplicated Lines 0 %

Test Coverage

Coverage 100%

Importance

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