Passed
Push — master ( bf62c3...8c031b )
by Emmanuel
01:56
created

AbstractAnonymizer::generateFakeData()   B

Complexity

Conditions 6
Paths 7

Size

Total Lines 28
Code Lines 17

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 13
CRAP Score 6

Importance

Changes 0
Metric Value
dl 0
loc 28
ccs 13
cts 13
cp 1
rs 8.439
c 0
b 0
f 0
cc 6
eloc 17
nc 7
nop 0
crap 6
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
     * Constant to define the type of action for that table
33
     */
34
    const TRUNCATE_TABLE = 1;
35
36
    /**
37
     * Constant to define the type of action for that table
38
     */
39
    const UPDATE_TABLE = 2;
40
41
    /**
42
     * Contain the configuration object
43
     *
44
     * @var Reader
45
     */
46
    protected $configuration;
47
48
    /**
49
     * Configuration of entities
50
     *
51
     * @var array
52
     */
53
    protected $configEntites = [];
54
55
    /**
56
     * Current table (entity) to process
57
     * @var string
58
     */
59
    protected $entity;
60
61
    /**
62
     * Current table (entity) Columns
63
     * @var array
64
     */
65
    protected $entityCols;
66
67
68
    /**
69
     * Process the entity according to the anonymizer type
70
     *
71
     * @param string        $entity         Entity's name
72
     * @param callable|null $callback       Callback function with current row num as parameter
73
     * @param bool          $pretend        Simulate update
74
     * @param bool          $returnRes      Return queries
75
     */
76
    abstract public function processEntity(
77
        string $entity,
78
        callable $callback = null,
79
        bool $pretend = true,
80
        bool $returnRes = false
81
    ): array;
82
83
84
    /**
85
     * Set the configuration
86
     *
87
     * @param Reader $configuration
88
     */
89
    public function setConfiguration(Reader $configuration)
90
    {
91
        $this->configuration = $configuration;
92
        $this->configEntites = $configuration->getConfigValues()['entities'];
93
    }
94 17
95
96 17
    /**
97 17
     * Evaluate, from the configuration if I have to update or Truncate the table
98 17
     *
99
     * @return int
100
     */
101
    protected function whatToDoWithEntity(): int
102
    {
103
        $this->checkEntityIsInConfig();
104
105
        $entityConfig = $this->configEntites[$this->entity];
106 13
107
        $actions = 0;
108 13
        if (array_key_exists('delete', $entityConfig) && $entityConfig['delete'] === true) {
109
            $actions |= self::TRUNCATE_TABLE;
110 11
        }
111
112 11
        if (array_key_exists('cols', $entityConfig)) {
113 11
            $actions |= self::UPDATE_TABLE;
114 4
        }
115
116
        return $actions;
117 11
    }
118 11
119 11
120 11
    /**
121 11
     * Returns the 'delete_where' parameter for an entity in config (or empty)
122
     *
123
     * @return string
124
     */
125
    public function getWhereConditionInConfig(): string
126
    {
127
        $this->checkEntityIsInConfig();
128 11
129
        if (!array_key_exists('delete_where', $this->configEntites[$this->entity])) {
130
            return '';
131
        }
132
133
        return $this->configEntites[$this->entity]['delete_where'];
134
    }
135
136
137 4
    /**
138
     * Generate fake data for an entity and return it as an Array
139 4
     *
140
     * @return array
141 4
     */
142 1
    protected function generateFakeData(): array
143
    {
144
        $this->checkEntityIsInConfig();
145 3
146
        $faker = \Faker\Factory::create($this->configuration->getConfigValues()['language']);
147
148
        $colsInConfig = $this->configEntites[$this->entity]['cols'];
149
        $row = [];
150
        foreach ($colsInConfig as $colName => $colProps) {
151
            $this->checkColIsInEntity($colName);
152
            $args = empty($colProps['params']) ? [] : $colProps['params'];
153
            $data = call_user_func_array([$faker, $colProps['method']], $args);
154 9
            if (!is_scalar($data)) {
155
                $msg = "You must use faker methods that generate strings: '{$colProps['method']}' forbidden";
156 9
                throw new NeuralizerConfigurationException($msg);
157
            }
158 9
159
            $row[$colName] = $data;
160 9
161 9
            $colLength = $this->entityCols[$colName]['length'];
162 9
            // Cut the value if too long ...
163 9
            if (!empty($colLength) && strlen($data) > $colLength) {
164 8
                $row[$colName] = substr($data, 0, $this->entityCols[$colName]['length']);
165 8
            }
166 8
        }
167
168
        return $row;
169 8
    }
170 1
171 1
172
    /**
173
     * Make sure that entity is defined in the configuration
174 8
     *
175
     * @throws NeuralizerConfigurationException
176 8
     */
177
    private function checkEntityIsInConfig()
178 8
    {
179 8
        if (empty($this->configEntites)) {
180
            throw new NeuralizerConfigurationException(
181
                'No entities found. Have you loaded a configuration file ?'
182
            );
183 7
        }
184
        if (!array_key_exists($this->entity, $this->configEntites)) {
185
            throw new NeuralizerConfigurationException(
186
                "No configuration for that entity ({$this->entity})"
187
            );
188
        }
189
    }
190
191
    /**
192 13
     * Verify a column is defined in the real entityCols
193
     * @param  string $colName
194 13
     */
195 1
    private function checkColIsInEntity(string $colName)
196 1
    {
197
        if (!array_key_exists($colName, $this->entityCols)) {
198
            throw new NeuralizerConfigurationException("Col $colName does not exist");
199 12
        }
200 1
    }
201
}
202