Passed
Push — master ( 45a3bb...2cf7c0 )
by Thomas
03:37
created

EncryptedNumberField::setLastFourBlindIndexField()   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 2
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(
24
        "Value" => "Varchar(191)",
25
        "BlindIndex" => 'Varchar(32)',
26
        "LastFourBlindIndex" => 'Varchar(16)',
27
    );
28
29
    public function compositeDatabaseFields()
30
    {
31
        return self::$composite_db;
32
    }
33
34
    /**
35
     * @return string
36
     */
37
    public function getLastFourBlindIndexField()
38
    {
39
        return $this->getField('LastFourBlindIndex');
40
    }
41
42
    /**
43
     * @return $this
44
     */
45
    public function setLastFourBlindIndexField($value, $markChanged = true)
46
    {
47
        return $this->setField('LastFourBlindIndex', $value, $markChanged);
48
    }
49
50
    /**
51
     * @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...
52
     * @return EncryptedField
53
     */
54
    public function getEncryptedField($engine = null)
55
    {
56
        if ($engine === null) {
57
            $engine = EncryptHelper::getCipherSweet();
58
        }
59
        $encryptedField = (new EncryptedField($engine, $this->tableName, $this->name))
60
            // Add a blind index for the "last 4 of SSN":
61
            ->addBlindIndex(new BlindIndex($this->name . "LastFourBlindIndex", [new LastFourDigits()], 16))
62
            ->addBlindIndex(new BlindIndex($this->name . "BlindIndex", [], 32));
63
        return $encryptedField;
64
    }
65
66
    /**
67
     * This is not called anymore, we rely on saveInto for now
68
     * @link https://github.com/silverstripe/silverstripe-framework/issues/8800
69
     * @param array $manipulation
70
     * @return void
71
     */
72
    public function writeToManipulation(&$manipulation)
73
    {
74
        $encryptedField = $this->getEncryptedField();
75
76
        if ($this->value) {
77
            $dataForStorage = $encryptedField->prepareForStorage($this->value);
78
            $encryptedValue = $this->prepValueForDB($dataForStorage[0]);
79
            $blindIndexes = $dataForStorage[1];
80
        } else {
81
            $encryptedValue = null;
82
            $blindIndexes = [];
83
        }
84
85
        $manipulation['fields'][$this->name . 'Value'] = $encryptedValue;
86
        $manipulation['fields'][$this->name . 'BlindIndex'] = $blindIndexes[$this->name . 'BlindIndex'] ?? null;
87
        $manipulation['fields'][$this->name . 'LastFourBlindIndex'] = $blindIndexes[$this->name . 'LastFourBlindIndex'] ?? null;
88
    }
89
90
    public function saveInto($dataObject)
91
    {
92
        $encryptedField = $this->getEncryptedField();
93
94
        if ($this->value) {
95
            $dataForStorage = $encryptedField->prepareForStorage($this->value);
96
            $encryptedValue = $this->prepValueForDB($dataForStorage[0]);
97
            $blindIndexes = $dataForStorage[1];
98
        } else {
99
            $encryptedValue = null;
100
            $blindIndexes = [];
101
        }
102
103
        // Encrypt value
104
        $key = $this->getName() . 'Value';
105
        $dataObject->setField($key, $encryptedValue);
106
107
        // Build blind index
108
        $key = $this->getName() . 'BlindIndex';
109
        if (isset($blindIndexes[$key])) {
110
            $dataObject->setField($key, $blindIndexes[$key]);
111
        }
112
113
        // Build last four blind index
114
        $key = $this->getName() . 'LastFourBlindIndex';
115
        if (isset($blindIndexes[$key])) {
116
            $dataObject->setField($key, $blindIndexes[$key]);
117
        }
118
    }
119
120
    public function addToQuery(&$query)
121
    {
122
        parent::addToQuery($query);
123
        $query->selectField(sprintf('"%sValue"', $this->name));
124
        $query->selectField(sprintf('"%sBlindIndex"', $this->name));
125
        $query->selectField(sprintf('"%sLastFourBlindIndex"', $this->name));
126
    }
127
}
128