Passed
Push — master ( 50c0f4...5cee22 )
by Thomas
02:13
created

EncryptedNumberField::compositeDatabaseFields()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 1
c 1
b 0
f 0
dl 0
loc 3
rs 10
cc 1
nc 1
nop 0
1
<?php
2
3
namespace LeKoala\Encrypt;
4
5
use ParagonIE\CipherSweet\BlindIndex;
6
use ParagonIE\CipherSweet\EncryptedField;
7
use ParagonIE\CipherSweet\Transformation\LastFourDigits;
8
9
/**
10
 * Value will be set on parent record through built in getField
11
 * mechanisms for composite fields
12
 *
13
 * This can be useful to store phone numbers, national numbers...
14
 * We keep two indexes:
15
 * - One with the full record
16
 * - One with the last 4 numbers (so if your phone number is +00 471 123 456, it will be searchable with 3456)
17
 */
18
class EncryptedNumberField extends EncryptedDBField
19
{
20
    /**
21
     * @param array
22
     */
23
    private static $composite_db = array(
0 ignored issues
show
introduced by
The private property $composite_db is not used, and could be removed.
Loading history...
24
        "Value" => "Varchar(191)",
25
        "BlindIndex" => 'Varchar(32)',
26
        "LastFourBlindIndex" => 'Varchar(16)',
27
    );
28
29
    /**
30
     * @return string
31
     */
32
    public function getLastFourBlindIndexField()
33
    {
34
        return $this->getField('LastFourBlindIndex');
35
    }
36
37
    /**
38
     * @return $this
39
     */
40
    public function setLastFourBlindIndexField($value, $markChanged = true)
41
    {
42
        return $this->setField('LastFourBlindIndex', $value, $markChanged);
43
    }
44
45
    /**
46
     * @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...
47
     * @return EncryptedField
48
     */
49
    public function getEncryptedField($engine = null)
50
    {
51
        if ($engine === null) {
52
            $engine = EncryptHelper::getCipherSweet();
53
        }
54
        $encryptedField = (new EncryptedField($engine, $this->tableName, $this->name))
55
            // Add a blind index for the "last 4 of SSN":
56
            ->addBlindIndex(new BlindIndex($this->name . "LastFourBlindIndex", [new LastFourDigits()], 16))
57
            ->addBlindIndex(new BlindIndex($this->name . "BlindIndex", [], 32));
58
        return $encryptedField;
59
    }
60
61
    /**
62
     * This is not called anymore, we rely on saveInto for now
63
     * @link https://github.com/silverstripe/silverstripe-framework/issues/8800
64
     * @param array $manipulation
65
     * @return void
66
     */
67
    public function writeToManipulation(&$manipulation)
68
    {
69
        $encryptedField = $this->getEncryptedField();
70
71
        if ($this->value) {
72
            $dataForStorage = $encryptedField->prepareForStorage($this->value);
73
            $encryptedValue = $this->prepValueForDB($dataForStorage[0]);
74
            $blindIndexes = $dataForStorage[1];
75
        } else {
76
            $encryptedValue = null;
77
            $blindIndexes = [];
78
        }
79
80
        $manipulation['fields'][$this->name . 'Value'] = $encryptedValue;
81
        $manipulation['fields'][$this->name . 'BlindIndex'] = $blindIndexes[$this->name . 'BlindIndex'] ?? null;
82
        $manipulation['fields'][$this->name . 'LastFourBlindIndex'] = $blindIndexes[$this->name . 'LastFourBlindIndex'] ?? null;
83
    }
84
85
    public function saveInto($dataObject)
86
    {
87
        $encryptedField = $this->getEncryptedField();
88
89
        if ($this->value) {
90
            $dataForStorage = $encryptedField->prepareForStorage($this->value);
91
            $encryptedValue = $this->prepValueForDB($dataForStorage[0]);
92
            $blindIndexes = $dataForStorage[1];
93
        } else {
94
            $encryptedValue = null;
95
            $blindIndexes = [];
96
        }
97
98
        // Encrypt value
99
        $key = $this->getName() . 'Value';
100
        $dataObject->setField($key, $encryptedValue);
101
102
        // Build blind index
103
        $key = $this->getName() . 'BlindIndex';
104
        if (isset($blindIndexes[$key])) {
105
            $dataObject->setField($key, $blindIndexes[$key]);
106
        }
107
108
        // Build last four blind index
109
        $key = $this->getName() . 'LastFourBlindIndex';
110
        if (isset($blindIndexes[$key])) {
111
            $dataObject->setField($key, $blindIndexes[$key]);
112
        }
113
    }
114
115
    public function addToQuery(&$query)
116
    {
117
        parent::addToQuery($query);
118
        $query->selectField(sprintf('"%sValue"', $this->name));
119
        $query->selectField(sprintf('"%sBlindIndex"', $this->name));
120
        $query->selectField(sprintf('"%sLastFourBlindIndex"', $this->name));
121
    }
122
}
123