Passed
Push — master ( 244aa0...c1114e )
by Wilmer
27:09 queued 12:07
created

ColumnSchema::phpTypecast()   A

Complexity

Conditions 5
Paths 7

Size

Total Lines 18
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 5
eloc 10
nc 7
nop 1
dl 0
loc 18
rs 9.6111
c 0
b 0
f 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Yiisoft\Db\Pgsql;
6
7
use Yiisoft\Db\Expression\ArrayExpression;
8
use Yiisoft\Db\Expression\ExpressionInterface;
9
use Yiisoft\Db\Expression\JsonExpression;
10
use Yiisoft\Db\Schema\ColumnSchema as AbstractColumnSchema;
11
12
use function array_walk_recursive;
13
use function in_array;
14
use function is_array;
15
use function is_string;
16
use function json_decode;
17
use function strtolower;
18
19
final class ColumnSchema extends AbstractColumnSchema
20
{
21
    /**
22
     * @var int the dimension of array. Defaults to 0, means this column is not an array.
23
     */
24
    private int $dimension = 0;
25
26
    /**
27
     * @var string name of associated sequence if column is auto-incremental.
28
     */
29
    private ?string $sequenceName = null;
30
31
    /**
32
     * Converts the input value according to {@see type} and {@see dbType} for use in a db query.
33
     *
34
     * If the value is null or an {@see Expression}, it will not be converted.
35
     *
36
     * @param mixed $value input value
37
     *
38
     * @return mixed converted value. This may also be an array containing the value as the first element and the PDO
39
     * type as the second element.
40
     */
41
    public function dbTypecast($value)
42
    {
43
        if ($value === null) {
44
            return $value;
45
        }
46
47
        if ($value instanceof ExpressionInterface) {
48
            return $value;
49
        }
50
51
        if ($this->dimension > 0) {
52
            return new ArrayExpression($value, $this->getDbType(), $this->dimension);
53
        }
54
55
        if (in_array($this->getDbType(), [Schema::TYPE_JSON, Schema::TYPE_JSONB], true)) {
56
            return new JsonExpression($value, $this->getDbType());
57
        }
58
59
        return $this->typecast($value);
60
    }
61
62
    /**
63
     * Converts the input value according to {@see phpType} after retrieval from the database.
64
     *
65
     * If the value is null or an {@see Expression}, it will not be converted.
66
     *
67
     * @param mixed $value input value
68
     *
69
     * @return mixed converted value
70
     */
71
    public function phpTypecast($value)
72
    {
73
        if ($this->dimension > 0) {
74
            if (!is_array($value)) {
75
                $value = $this->getArrayParser()->parse($value);
76
            }
77
            if (is_array($value)) {
78
                array_walk_recursive($value, function (&$val) {
79
                    $val = $this->phpTypecastValue($val);
80
                });
81
            } elseif ($value === null) {
0 ignored issues
show
introduced by
The condition $value === null is always true.
Loading history...
82
                return null;
83
            }
84
85
            return $value;
86
        }
87
88
        return $this->phpTypecastValue($value);
89
    }
90
91
    /**
92
     * Casts $value after retrieving from the DBMS to PHP representation.
93
     *
94
     * @param string|int|null $value
95
     *
96
     * @return bool|mixed|null
97
     */
98
    protected function phpTypecastValue($value)
99
    {
100
        if ($value === null) {
101
            return null;
102
        }
103
104
        switch ($this->getType()) {
105
            case Schema::TYPE_BOOLEAN:
106
                $value = is_string($value) ? strtolower($value) : $value;
107
108
                switch ($value) {
109
                    case 't':
110
                    case 'true':
111
                        return true;
112
                    case 'f':
113
                    case 'false':
114
                        return false;
115
                }
116
117
                return (bool) $value;
118
            case Schema::TYPE_JSON:
119
                return json_decode($value, true, 512, JSON_THROW_ON_ERROR);
120
        }
121
122
        return parent::phpTypecast($value);
123
    }
124
125
    /**
126
     * Creates instance of ArrayParser.
127
     *
128
     * @return ArrayParser
129
     */
130
    protected function getArrayParser(): ArrayParser
131
    {
132
        static $parser = null;
133
134
        if ($parser === null) {
135
            $parser = new ArrayParser();
136
        }
137
138
        return $parser;
139
    }
140
141
    public function getDimension(): int
142
    {
143
        return $this->dimension;
144
    }
145
146
    public function getSequenceName(): ?string
147
    {
148
        return $this->sequenceName;
149
    }
150
151
    public function dimension(int $dimension): void
152
    {
153
        $this->dimension = $dimension;
154
    }
155
156
    public function sequenceName(?string $sequenceName): void
157
    {
158
        $this->sequenceName = $sequenceName;
159
    }
160
}
161