Passed
Push — master ( fced76...618096 )
by Thomas
02:41
created

EncryptedDBJson::getJsonMap()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 6
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 3
c 0
b 0
f 0
dl 0
loc 6
rs 10
cc 2
nc 2
nop 0
1
<?php
2
3
namespace LeKoala\Encrypt;
4
5
use SilverStripe\Forms\HiddenField;
6
use ParagonIE\CipherSweet\JsonFieldMap;
7
use ParagonIE\CipherSweet\EncryptedJsonField;
8
9
/**
10
 * A simple extension over EncryptedDBText that supports json
11
 * as a datastructure
12
 * The data is stored in a text field
13
 *
14
 * If you want to access array stuff, you need to use
15
 * $model->dbObject('myField')->toArray() or any other method
16
 *
17
 * This field is a great way to store serialized encrypted data
18
 */
19
class EncryptedDBJson extends EncryptedDBText
20
{
21
22
    /**
23
     * @return string
24
     */
25
    public function getJsonMap()
26
    {
27
        if (array_key_exists('map', $this->options)) {
28
            return $this->options['map'];
29
        }
30
        return null;
31
    }
32
33
    /**
34
     * We cannot search on json fields
35
     *
36
     * @param string $title
37
     * @return HiddenField
38
     */
39
    public function scaffoldSearchField($title = null)
40
    {
41
        return HiddenField::create($this->getName());
42
    }
43
44
    /**
45
     * Json data is not easily displayed
46
     *
47
     * @param string $title
48
     * @param string $params
49
     * @return HiddenField
50
     */
51
    public function scaffoldFormField($title = null, $params = null)
52
    {
53
        return HiddenField::create($this->getName());
54
    }
55
56
    /**
57
     * @return mixed
58
     */
59
    public function decode()
60
    {
61
        if (!$this->value) {
62
            return false;
63
        }
64
        return json_decode($this->value);
65
    }
66
67
    /**
68
     * @return array
69
     */
70
    public function decodeArray()
71
    {
72
        if (!$this->value) {
73
            return [];
74
        }
75
        return json_decode($this->value, JSON_OBJECT_AS_ARRAY);
0 ignored issues
show
Bug introduced by
LeKoala\Encrypt\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

75
        return json_decode($this->value, /** @scrutinizer ignore-type */ JSON_OBJECT_AS_ARRAY);
Loading history...
76
    }
77
78
    /**
79
     * @return array
80
     */
81
    public function toArray()
82
    {
83
        return $this->decodeArray();
84
    }
85
86
    /**
87
     * @return string
88
     */
89
    public function pretty()
90
    {
91
        return json_encode(json_decode($this->value), JSON_PRETTY_PRINT);
92
    }
93
94
    /**
95
     * @inheritDoc
96
     */
97
    public function saveInto($dataObject)
98
    {
99
        if ($this->value && is_array($this->value)) {
100
            $this->value = json_encode($this->value);
101
        }
102
        parent::saveInto($dataObject);
103
    }
104
105
    /**
106
     * Add a value
107
     *
108
     * @link https://stackoverflow.com/questions/7851590/array-set-value-using-dot-notation
109
     * @param string|array $key
110
     * @param string $value
111
     * @return $this
112
     */
113
    public function addValue($key, $value)
114
    {
115
        $currentValue = $this->decodeArray();
116
117
        if (!is_array($key)) {
118
            $key = [$key];
119
        }
120
        $arr = &$currentValue;
121
        foreach ($key as $idx) {
122
            if (!isset($arr[$idx])) {
123
                $arr[$idx] = [];
124
            }
125
            $arr = &$arr[$idx];
126
        }
127
        $arr = $value;
128
        return $this->setValue($currentValue);
129
    }
130
131
    /**
132
     * Internally, the value is always a json string
133
     *
134
     * @param mixed $value
135
     * @param DataObject $record
0 ignored issues
show
Bug introduced by
The type LeKoala\Encrypt\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...
136
     * @param boolean $markChanged
137
     * @return $this
138
     */
139
    public function setValue($value, $record = null, $markChanged = true)
140
    {
141
        // Return early if we keep encrypted value in memory
142
        if (!EncryptHelper::getAutomaticDecryption()) {
143
            $this->value = $value;
144
            return $this;
145
        }
146
147
        if ($this->getJsonMap() && $value && is_string($value)) {
148
            $this->value = $this->getEncryptedJsonField()->decryptJson($value);
149
            return $this;
150
        }
151
        if (is_array($value)) {
152
            if ($this->getJsonMap()) {
153
                $aad = $this->encryptionAad;
154
                $value = $this->getEncryptedJsonField()->encryptJson($value, $aad);
155
            } else {
156
                $value = json_encode($value);
157
            }
158
        }
159
160
        return parent::setValue($value, $record, $markChanged);
161
    }
162
163
    /**
164
     * @inheritDoc
165
     */
166
    public function prepValueForDB($value)
167
    {
168
        if (is_array($value)) {
169
            if ($this->getJsonMap()) {
170
                $aad = $this->encryptionAad;
171
                $value = $this->getEncryptedJsonField()->encryptJson($value, $aad);
172
                return $value;
173
            } else {
174
                $value = json_encode($value);
175
            }
176
        }
177
        return parent::prepValueForDB($value);
178
    }
179
180
    /**
181
     * We return false because we can accept array and convert it to string
182
     * @return boolean
183
     */
184
    public function scalarValueOnly()
185
    {
186
        return false;
187
    }
188
189
    /**
190
     * @param CipherSweet $engine
0 ignored issues
show
Bug introduced by
The type LeKoala\Encrypt\CipherSweet 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...
191
     * @param JsonFieldMap $map
192
     * @return EncryptedJsonField
193
     */
194
    public function getEncryptedJsonField($engine = null, $map = null)
195
    {
196
        if ($engine === null) {
197
            $engine = EncryptHelper::getCipherSweet();
198
        }
199
        if ($map === null) {
200
            $mapString = $this->getJsonMap();
201
            $map = JsonFieldMap::fromString($mapString);
202
        }
203
        $encryptedField = EncryptedJsonField::create($engine, $map, $this->tableName, $this->name);
204
        return $encryptedField;
205
    }
206
}
207