Completed
Push — master ( f0d93b...12af13 )
by Emmanuel
04:54
created

AbstractAnonymizer   A

Complexity

Total Complexity 19

Size/Duplication

Total Lines 188
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 3

Test Coverage

Coverage 94.44%

Importance

Changes 0
Metric Value
wmc 19
lcom 1
cbo 3
dl 0
loc 188
rs 10
c 0
b 0
f 0
ccs 51
cts 54
cp 0.9444

7 Methods

Rating   Name   Duplication   Size   Complexity  
processEntity() 0 6 ?
A setConfiguration() 0 5 1
B whatToDoWithEntity() 0 24 6
A getWhereConditionInConfig() 0 10 2
B generateFakeData() 0 31 5
A checkEntityIsInConfig() 0 13 3
A checkColIsInEntity() 0 6 2
1
<?php
2
/**
3
 * neuralyzer : Data Anonymization Library and CLI Tool
4
 *
5
 * PHP Version 7.1
6
 *
7
 * @author Emmanuel Dyan
8
 * @author Rémi Sauvat
9
 * @copyright 2018 Emmanuel Dyan
10
 *
11
 * @package edyan/neuralyzer
12
 *
13
 * @license GNU General Public License v2.0
14
 *
15
 * @link https://github.com/edyan/neuralyzer
16
 */
17
18
namespace Edyan\Neuralyzer\Anonymizer;
19
20
use Edyan\Neuralyzer\Configuration\Reader;
21
use Edyan\Neuralyzer\Exception\NeuralizerConfigurationException;
22
23
/**
24
 * Abstract Anonymizer, that can be implemented as DB Anonymizer for example
25
 * Its goal is only to anonymize any data, from a simple array
26
 * not to write or read it from anywhere
27
 *
28
 */
29
abstract class AbstractAnonymizer
30
{
31
    /**
32
     * Truncate table
33
     */
34
    const TRUNCATE_TABLE = 1;
35
36
    /**
37
     * Update data into table
38
     */
39
    const UPDATE_TABLE = 2;
40
41
    /**
42
     * Insert data into table
43
     */
44
    const INSERT_TABLE = 4;
45
46
    /**
47
     * Contain the configuration object
48
     *
49
     * @var Reader
50
     */
51
    protected $configuration;
52
53
    /**
54
     * Configuration of entities
55
     *
56
     * @var array
57
     */
58
    protected $configEntites = [];
59
60
    /**
61
     * Current table (entity) to process
62
     * @var string
63
     */
64
    protected $entity;
65
66
    /**
67
     * Current table (entity) Columns
68
     * @var array
69
     */
70
    protected $entityCols;
71
72
73
    /**
74
     * Process the entity according to the anonymizer type
75
     *
76
     * @param string        $entity         Entity's name
77
     * @param callable|null $callback       Callback function with current row num as parameter
78
     * @param bool          $pretend        Simulate update
79
     * @param bool          $returnRes      Return queries
80
     */
81
    abstract public function processEntity(
82
        string $entity,
83
        callable $callback = null,
84
        bool $pretend = true,
85
        bool $returnRes = false
86
    ): array;
87
88
89
    /**
90
     * Set the configuration
91
     *
92
     * @param Reader $configuration
93
     */
94 17
    public function setConfiguration(Reader $configuration)
95
    {
96 17
        $this->configuration = $configuration;
97 17
        $this->configEntites = $configuration->getConfigValues()['entities'];
98 17
    }
99
100
101
    /**
102
     * Evaluate, from the configuration if I have to update or Truncate the table
103
     *
104
     * @return int
105
     */
106 13
    protected function whatToDoWithEntity(): int
107
    {
108 13
        $this->checkEntityIsInConfig();
109
110 11
        $entityConfig = $this->configEntites[$this->entity];
111
112 11
        $actions = 0;
113 11
        if (array_key_exists('delete', $entityConfig) && $entityConfig['delete'] === true) {
114 4
            $actions |= self::TRUNCATE_TABLE;
115
        }
116
117 11
        if (array_key_exists('cols', $entityConfig)) {
118 11
            switch ($entityConfig['action']) {
119 11
                case 'update':
120 11
                    $actions |= self::UPDATE_TABLE;
121 11
                    break;
122
                case 'insert':
123
                    $actions |= self::INSERT_TABLE;
124
                    break;
125
            }
126
        }
127
128 11
        return $actions;
129
    }
130
131
132
    /**
133
     * Returns the 'delete_where' parameter for an entity in config (or empty)
134
     *
135
     * @return string
136
     */
137 4
    public function getWhereConditionInConfig(): string
138
    {
139 4
        $this->checkEntityIsInConfig();
140
141 4
        if (!array_key_exists('delete_where', $this->configEntites[$this->entity])) {
142 1
            return '';
143
        }
144
145 3
        return $this->configEntites[$this->entity]['delete_where'];
146
    }
147
148
149
    /**
150
     * Generate fake data for an entity and return it as an Array
151
     *
152
     * @return array
153
     */
154 9
    protected function generateFakeData(): array
155
    {
156 9
        $this->checkEntityIsInConfig();
157
158 9
        $faker = \Faker\Factory::create($this->configuration->getConfigValues()['language']);
159
160 9
        $colsInConfig = $this->configEntites[$this->entity]['cols'];
161 9
        $row = [];
162 9
        foreach ($colsInConfig as $colName => $colProps) {
163 9
            $this->checkColIsInEntity($colName);
164 8
            $data = call_user_func_array(
165 8
                [$faker, $colProps['method']],
166 8
                $colProps['params']
167
            );
168
169 8
            if (!is_scalar($data)) {
170 1
                $msg = "You must use faker methods that generate strings: '{$colProps['method']}' forbidden";
171 1
                throw new NeuralizerConfigurationException($msg);
172
            }
173
174 8
            $row[$colName] = $data;
175
176 8
            $colLength = $this->entityCols[$colName]['length'];
177
            // Cut the value if too long ...
178 8
            if (!empty($colLength) && strlen($data) > $colLength) {
179 8
                $row[$colName] = substr($data, 0, $this->entityCols[$colName]['length']);
180
            }
181
        }
182
183 7
        return $row;
184
    }
185
186
187
    /**
188
     * Make sure that entity is defined in the configuration
189
     *
190
     * @throws NeuralizerConfigurationException
191
     */
192 13
    private function checkEntityIsInConfig()
193
    {
194 13
        if (empty($this->configEntites)) {
195 1
            throw new NeuralizerConfigurationException(
196 1
                'No entities found. Have you loaded a configuration file ?'
197
            );
198
        }
199 12
        if (!array_key_exists($this->entity, $this->configEntites)) {
200 1
            throw new NeuralizerConfigurationException(
201 1
                "No configuration for that entity ({$this->entity})"
202
            );
203
        }
204 11
    }
205
206
    /**
207
     * Verify a column is defined in the real entityCols
208
     * @param  string $colName
209
     */
210 9
    private function checkColIsInEntity(string $colName)
211
    {
212 9
        if (!array_key_exists($colName, $this->entityCols)) {
213 1
            throw new NeuralizerConfigurationException("Col $colName does not exist");
214
        }
215 8
    }
216
}
217