DBJson::decode()   A
last analyzed

Complexity

Conditions 2
Paths 2

Size

Total Lines 6
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 2
eloc 3
c 1
b 0
f 0
nc 2
nop 0
dl 0
loc 6
rs 10
1
<?php
2
3
namespace LeKoala\Blocks\FieldType;
4
5
use SilverStripe\ORM\DB;
6
use SilverStripe\Forms\HiddenField;
7
use SilverStripe\Core\Config\Config;
8
use SilverStripe\ORM\FieldType\DBString;
9
use SilverStripe\ORM\Connect\MySQLDatabase;
10
11
/**
12
 * Json storage
13
 *
14
 * Internally, the value is represented as a string (for consistency since we extend DBString)
15
 * TODO: investigate if it's worth it to use an array for internal state
16
 *
17
 * @link https://github.com/phptek/silverstripe-jsontext/blob/master/code/ORM/FieldType/JSONText.php
18
 * @link https://mariadb.com/resources/blog/json-mariadb-102
19
 */
20
class DBJson extends DBString
21
{
22
    /**
23
     * (non-PHPdoc)
24
     * @see DBField::requireField()
25
     */
26
    public function requireField()
27
    {
28
        $charset = Config::inst()->get(MySQLDatabase::class, 'charset');
29
        $collation = Config::inst()->get(MySQLDatabase::class, 'collation');
30
31
        $parts = [
32
            'datatype' => 'mediumtext',
33
            'character set' => $charset,
34
            'collate' => $collation,
35
            'arrayValue' => $this->arrayValue
36
        ];
37
38
        $values = [
39
            'type' => 'text',
40
            'parts' => $parts
41
        ];
42
43
        DB::require_field($this->tableName, $this->name, $values);
44
    }
45
46
    /**
47
     * @param string $title
48
     * @return \HiddenField
0 ignored issues
show
Bug introduced by
The type HiddenField was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
49
     */
50
    public function scaffoldSearchField($title = null)
51
    {
52
        return HiddenField::create($this->getName());
53
    }
54
    /**
55
     * @param string $title
56
     * @param string $params
57
     * @return \HiddenField
58
     */
59
    public function scaffoldFormField($title = null, $params = null)
60
    {
61
        return HiddenField::create($this->getName());
62
    }
63
64
    /**
65
     * @return mixed
66
     */
67
    public function decode()
68
    {
69
        if (!$this->value) {
70
            return false;
71
        }
72
        return json_decode($this->value);
73
    }
74
75
    /**
76
     * @return array
77
     */
78
    public function decodeArray()
79
    {
80
        if (!$this->value) {
81
            return [];
82
        }
83
        return json_decode($this->value, JSON_OBJECT_AS_ARRAY);
0 ignored issues
show
Bug introduced by
LeKoala\Blocks\FieldType\JSON_OBJECT_AS_ARRAY of type integer is incompatible with the type boolean|null expected by parameter $associative of json_decode(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

83
        return json_decode($this->value, /** @scrutinizer ignore-type */ JSON_OBJECT_AS_ARRAY);
Loading history...
84
    }
85
86
    /**
87
     * @return array
88
     */
89
    public function toArray()
90
    {
91
        return $this->decodeArray();
92
    }
93
94
    /**
95
     * @return string
96
     */
97
    public function pretty()
98
    {
99
        return json_encode(json_decode($this->value), JSON_PRETTY_PRINT);
100
    }
101
102
    public function saveInto($dataObject)
103
    {
104
        if ($this->value && is_array($this->value)) {
105
            $this->value = json_encode($this->value);
106
        }
107
        parent::saveInto($dataObject);
108
    }
109
110
    /**
111
     * Add a value
112
     *
113
     * @link https://stackoverflow.com/questions/7851590/array-set-value-using-dot-notation
114
     * @param string|array $key
115
     * @param string $value
116
     * @return $this
117
     */
118
    public function addValue($key, $value)
119
    {
120
        $currentValue = $this->decodeArray();
121
122
        if (!is_array($key)) {
123
            $key = [$key];
124
        }
125
        $arr = &$currentValue;
126
        foreach ($key as $idx) {
127
            if (!isset($arr[$idx])) {
128
                $arr[$idx] = [];
129
            }
130
            $arr = &$arr[$idx];
131
        }
132
        $arr = $value;
133
        return $this->setValue($currentValue);
134
    }
135
136
    /**
137
     * Internally, the value is always a json string
138
     *
139
     * @param mixed $value
140
     * @param DataObject $record
0 ignored issues
show
Bug introduced by
The type LeKoala\Blocks\FieldType\DataObject was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
141
     * @param boolean $markChanged
142
     * @return $this
143
     */
144
    public function setValue($value, $record = null, $markChanged = true)
145
    {
146
        if (is_array($value)) {
147
            $value = json_encode($value);
148
        }
149
        return parent::setValue($value, $record, $markChanged);
150
    }
151
152
    public function prepValueForDB($value)
153
    {
154
        if (is_array($value)) {
155
            $value = json_encode($value);
156
        }
157
        return parent::prepValueForDB($value);
158
    }
159
160
    /**
161
     * We return false because we can accept array and convert it to string
162
     * @return boolean
163
     */
164
    public function scalarValueOnly()
165
    {
166
        return false;
167
    }
168
169
    /**
170
     * Search multiple values in an array like store
171
     *
172
     * TODO: support proper json function if they are supported
173
     *
174
     * @param string $field
175
     * @param array $values
176
     * @return string
177
     */
178
    public static function sqlInArray($field, $values)
179
    {
180
        $gen = '';
181
        foreach ($values as $val) {
182
            $gen .= "(?=.*$val)";
183
        }
184
        $sql = "$field RLIKE '$gen'";
185
        return $sql;
186
    }
187
}
188