Passed
Push — master ( 71d23f...5a582b )
by Thomas
02:20
created

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