├── Console
└── Command
│ └── FakeMyData.php
├── Faker
└── Provider
│ └── Got
│ └── Person.php
├── Model
└── FakeMyData.php
├── README.md
├── composer.json
├── etc
├── adminhtml
│ └── system.xml
├── config.xml
├── di.xml
└── module.xml
└── registration.php
/Console/Command/FakeMyData.php:
--------------------------------------------------------------------------------
1 | fakeMyDataModel = $fakeMyDataModel;
20 | parent::__construct('fakemydata');
21 | }
22 |
23 | /**
24 | * {@inheritdoc}
25 | */
26 | protected function execute(
27 | InputInterface $input,
28 | OutputInterface $output
29 | ) {
30 | $this->fakeMyDataModel->fakeAll();
31 | }
32 |
33 | /**
34 | * {@inheritdoc}
35 | */
36 | protected function configure()
37 | {
38 | $this->setName("experius_fakemydata:fakeall");
39 | $this->setDescription("Replace Customer Data with Fake Names");
40 | parent::configure();
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/Faker/Provider/Got/Person.php:
--------------------------------------------------------------------------------
1 | faker = $faker;
68 | $this->resourceConnection = $resourceConnection;
69 | $this->connection = $this->resourceConnection->getConnection();
70 | $this->encryptor = $encryptor;
71 | $this->scopeConfig = $scopeConfig;
72 | $this->state = $state;
73 | $this->storeRepository = $storeRepository;
74 | }
75 |
76 | public function initStores(){
77 | $stores = $this->storeRepository->getList();
78 | foreach($stores as $store){
79 | $this->stores[$store->getId()] = $this->scopeConfig->getValue('general/locale/code',\Magento\Store\Model\ScopeInterface::SCOPE_STORE,$store->getId());
80 | }
81 | }
82 |
83 | public function getLocaleByStoreId($storeId){
84 | if(isset($this->stores[$storeId])){
85 | return $this->stores[$storeId];
86 | }
87 | return 'en_US';
88 | }
89 |
90 | public function getExcludedEmailDomains(){
91 | if(!$this->excludedEmailDomains){
92 | $this->excludedEmailDomains = $this->scopeConfig->getValue('fakemydata/general/excluded_email_domains');
93 | }
94 | return $this->excludedEmailDomains;
95 | }
96 |
97 | public function getFakeEmailDomain(){
98 | if(!$this->fakeEmailDomain){
99 | $this->fakeEmailDomain = $this->scopeConfig->getValue('fakemydata/general/fake_email_domain');
100 | }
101 | return $this->fakeEmailDomain;
102 | }
103 |
104 | public function getFakeEmailPrefix(){
105 | if(!$this->fakeEmailPrefix){
106 | $this->fakeEmailPrefix = $this->scopeConfig->getValue('fakemydata/general/fake_email_prefix');
107 | }
108 | return $this->fakeEmailPrefix;
109 | }
110 |
111 | public function getPassword(){
112 | if(!$this->password){
113 | $this->password = $this->scopeConfig->getValue('fakemydata/general/password');
114 | }
115 | return $this->password;
116 | }
117 |
118 | public function getCustomProvider(){
119 | if(!$this->customProvider){
120 | $this->customProvider = $this->scopeConfig->getValue('fakemydata/general/customprovider');
121 | }
122 | return $this->customProvider;
123 | }
124 |
125 | public function getSelect($tableName,$excludeEmailField='email',$join){
126 | $select = $this->connection->select();
127 | $select->from($tableName,'*');
128 |
129 | if($join) {
130 | $select->joinLeft(['customers' => 'customer_entity'], 'customers.entity_id' . ' = ' . $tableName . '.parent_id', ['email']);
131 | }
132 |
133 | foreach(explode(',',$this->getExcludedEmailDomains()) as $excludedEmailDomain){
134 | $select->where($excludeEmailField . " NOT LIKE '%" . $excludedEmailDomain ."'");
135 | }
136 |
137 | return $select;
138 | }
139 |
140 | public function fakeAll(){
141 |
142 | if(\Magento\Framework\App\State::MODE_DEVELOPER != $this->state->getMode()){
143 | echo "Wow you're not in develop mode. Don't run this on production environments";
144 | exit;
145 | }
146 |
147 | $this->initStores();
148 |
149 | foreach($this->fakedDataTypes as $type) {
150 | $this->fakeData($type);
151 | }
152 | }
153 |
154 | public function stringToUniqueInt($value){
155 | return base_convert(md5($value), 10, 10);
156 | }
157 |
158 | public function getSeed($value){
159 | if(!is_numeric($value)){
160 | return $this->stringToUniqueInt($value);
161 | }
162 | return $value;
163 | }
164 |
165 | /* TODO make unique address work */
166 |
167 | public function getFakeCustomerData($results,$identifier='entity_id',$uniqueAddress=false){
168 | foreach($results as $result) {
169 |
170 | $seed = $this->getSeed($result[$identifier]);
171 |
172 | $locale = 'en_US';
173 | if(isset($result['store_id'])){
174 | $locale = $this->getLocaleByStoreId($result['store_id']);
175 | }
176 |
177 | $faker = $this->faker->create($locale);
178 | $faker->seed($seed);
179 |
180 | if($this->getCustomProvider()) {
181 | $customProvider = $this->getCustomProvider();
182 | $class = "\\Experius\\FakeMyData\\Faker\\Provider\\" . $customProvider . "\\Person";
183 | $faker->addProvider(new $class($faker));
184 | }
185 |
186 | $firstname = $faker->firstName;
187 | $lastname = $faker->lastName;
188 | $dateOfBirthYear = $faker->dateTimeThisCentury->format('Y');
189 |
190 | $fakeData = [
191 | 'firstname'=>$firstname,
192 | 'lastname'=>$lastname,
193 | 'name' => $firstname . ' ' . $lastname,
194 | 'email'=> $this->getFakeEmail([$firstname,$lastname,$dateOfBirthYear]),
195 | 'street' => $this->getFakeStreet([$faker->streetName, $faker->buildingNumber]),
196 | 'postcode' => $faker->postcode,
197 | 'telephone' => $faker->phoneNumber,
198 | 'city'=> $faker->city,
199 | 'company' => $faker->company,
200 | 'password_hash' => $this->getPasswordHash()
201 | ];
202 |
203 | $fakeData['address'] = $fakeData['street'] . "\n" . $fakeData['postcode'] . "\n". $fakeData['city'];
204 |
205 | $this->fakedData[$seed] = $fakeData;
206 |
207 | }
208 | }
209 |
210 | public function fakeData($type){
211 |
212 | switch($type){
213 | case 'customer':
214 |
215 | $select = $this->getSelect('customer_entity','email',false);
216 | $results = $this->connection->fetchAll($select);
217 | $this->getFakeCustomerData($results,'entity_id');
218 | $this->updateData('entity_id',['firstname'=>'firstname','lastname'=>'lastname','email'=>'email','password_hash'=>'password_hash'],'customer_entity',$results,'entity_id');
219 |
220 | break;
221 | case 'customer_address':
222 |
223 | $select = $this->getSelect('customer_address_entity','email','customer_id');
224 | $results = $this->connection->fetchAll($select);
225 |
226 | /* TODO fake each address different */
227 |
228 | $this->getFakeCustomerData($results,'parent_id');
229 | $this->updateData('parent_id',['firstname'=>'firstname','lastname'=>'lastname','postcode'=>'postcode','telephone'=>'telephone','city'=>'city','street'=>'street'],'customer_address_entity',$results,'entity_id');
230 |
231 | break;
232 |
233 | case 'order':
234 |
235 | $select = $this->getSelect('sales_order','customer_email',false);
236 | $select->where('customer_id IS NOT NULL');
237 | $results = $this->connection->fetchAll($select);
238 | $this->getFakeCustomerData($results,'customer_id');
239 | $this->updateData('customer_id',['customer_firstname'=>'firstname','customer_lastname'=>'lastname','customer_email'=>'email'],'sales_order',$results,'entity_id');
240 |
241 | $select = $this->getSelect('sales_order','customer_email',false);
242 | $select->where('customer_id IS NULL');
243 | $results = $this->connection->fetchAll($select);
244 | $this->getFakeCustomerData($results,'entity_id');
245 | $this->updateData('entity_id',['customer_firstname'=>'firstname','customer_lastname'=>'lastname','customer_email'=>'email'],'sales_order',$results,'entity_id');
246 |
247 | break;
248 | case 'order_grid':
249 |
250 | $select = $this->getSelect('sales_order_grid','customer_email',false);
251 | $select->where('customer_id IS NOT NULL');
252 | $results = $this->connection->fetchAll($select);
253 | $this->getFakeCustomerData($results,'customer_id');
254 | $this->updateData('customer_id',['shipping_name'=>'name','billing_name'=>'name','customer_name'=>'name','customer_email'=>'email'],'sales_order_grid',$results,'entity_id');
255 |
256 | $select = $this->getSelect('sales_order_grid','customer_email',false);
257 | $select->where('customer_id IS NULL');
258 | $results = $this->connection->fetchAll($select);
259 | $this->getFakeCustomerData($results,'entity_id');
260 | $this->updateData('entity_id',['shipping_name'=>'name','billing_name'=>'name','customer_name'=>'name','customer_email'=>'email'],'sales_order_grid',$results,'entity_id');
261 |
262 | break;
263 |
264 | case 'sales_invoice_grid':
265 | case 'sales_shipment_grid':
266 | case 'sales_creditmemo_grid':
267 | $select = $this->getSelect($type,$type.'.customer_email',false);
268 | $select->joinLeft(['sales_order_grid' => 'sales_order_grid'], 'sales_order_grid.entity_id' . ' = '.$type.'.order_id', ['customer_id'=>'customer_id']);
269 | $select->where('sales_order_grid.customer_id IS NOT NULL');
270 | $results = $this->connection->fetchAll($select);
271 | $this->getFakeCustomerData($results,'customer_id');
272 | $this->updateData('customer_id',['billing_name'=>'name','customer_name'=>'name','customer_email'=>'email','billing_address'=>'address','shipping_address'=>'address'],$type,$results,'entity_id');
273 |
274 | $select = $this->getSelect($type,$type.'.customer_email',false);
275 | $select->joinLeft(['sales_order_grid' => 'sales_order_grid'], 'sales_order_grid.entity_id' . ' = '.$type.'.order_id', ['customer_id'=>'customer_id']);
276 | $select->where('sales_order_grid.customer_id IS NULL');
277 | $results = $this->connection->fetchAll($select);
278 | $this->getFakeCustomerData($results,'order_id');
279 | $this->updateData('order_id',['billing_name'=>'name','customer_name'=>'name','customer_email'=>'email','billing_address'=>'address','shipping_address'=>'address'],$type,$results,'entity_id');
280 | break;
281 | case 'quote':
282 |
283 | $select = $this->getSelect('quote','customer_email',false);
284 | $select->where('customer_id IS NOT NULL');
285 | $results = $this->connection->fetchAll($select);
286 | $this->getFakeCustomerData($results,'customer_id');
287 | $this->updateData('customer_id',['customer_firstname'=>'firstname','customer_lastname'=>'lastname','customer_email'=>'email'],'quote',$results,'entity_id');
288 |
289 | /* Todo Join with order Table */
290 | $select = $this->getSelect('quote','customer_email',false);
291 | $select->where('customer_id IS NULL');
292 | $select->where('customer_firstname IS NOT NULL OR customer_lastname IS NOT NULL OR customer_email IS NOT NULL');
293 | $results = $this->connection->fetchAll($select);
294 | $this->getFakeCustomerData($results,'entity_id');
295 | $this->updateData('entity_id',['customer_firstname'=>'firstname','customer_lastname'=>'lastname','customer_email'=>'email'],'quote',$results,'entity_id');
296 |
297 | break;
298 | case 'quote_address':
299 | break;
300 | case 'review':
301 | break;
302 | case 'newsletter':
303 |
304 | $select = $this->getSelect('newsletter_subscriber','subscriber_email',false);
305 | $select->where('customer_id IS NOT NULL');
306 | $results = $this->connection->fetchAll($select);
307 | $this->getFakeCustomerData($results,'customer_id');
308 | $this->updateData('customer_id',['subscriber_email'=>'email'],'newsletter_subscriber',$results,'subscriber_id');
309 |
310 | $select = $this->getSelect('newsletter_subscriber','subscriber_email',false);
311 | $select->where('subscriber_id IS NOT NULL');
312 | $results = $this->connection->fetchAll($select);
313 | $this->getFakeCustomerData($results,'customer_id');
314 | $this->updateData('subscriber_id',['subscriber_email'=>'email'],'newsletter_subscriber',$results,'subscriber_id');
315 |
316 | break;
317 | }
318 |
319 | }
320 |
321 | public function updateData($identifier,$fields,$tableName,$results,$updateIdentifier){
322 | $tableName = $this->resourceConnection->getTableName($tableName);
323 | $this->updateFlat($identifier,$results,$fields,$tableName,$updateIdentifier);
324 | }
325 |
326 | public function getFakeEmail($values){
327 | return $this->getFakeEmailPrefix() . str_replace([" ","'",],'.',implode('.',$values)) . '@' . $this->getFakeEmailDomain();
328 | }
329 |
330 | public function getPasswordHash(){
331 | if(!$this->passwordHash) {
332 | $this->passwordHash = $this->encryptor->getHash($this->getPassword(), true);
333 | }
334 | return $this->passwordHash;
335 | }
336 |
337 | public function getAddressLines(){
338 | if(!$this->addressLines){
339 | $this->addressLines = $this->scopeConfig->getValue('customer/address/street_lines');
340 | }
341 | return $this->addressLines;
342 | }
343 |
344 | public function getFakeStreet($values){
345 | $addressLines = $this->addressLines;
346 |
347 | if($addressLines==1){
348 | return implode(" ",$values);
349 | }
350 |
351 | if($addressLines==2){
352 | return $values[0] . "\n" . $values[1] . (isset($values[3])) ? " " . $values[3] : '';
353 | }
354 |
355 | return implode("\n",$values);
356 | }
357 |
358 | /* TODO Optional update only if field has value */
359 | public function updateFlat($identifier,$results,$fields,$tableName,$updateIdentifier){
360 |
361 | foreach($results as $result){
362 |
363 | $seed = $this->getSeed($result[$identifier]);
364 |
365 | $updateData = [];
366 |
367 | $fakeData = $this->fakedData[$seed];
368 |
369 | foreach($fields as $field=>$fakeDataArrayKey){
370 | $updateData[$field] = $fakeData[$fakeDataArrayKey];
371 | }
372 |
373 | $this->connection->update($tableName,$updateData,[$updateIdentifier." = ? " => $result[$updateIdentifier]]);
374 |
375 | }
376 | }
377 | }
378 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | **Data Faker For Magento 2**
2 |
3 | Based on fzaninotto/Faker https://github.com/fzaninotto/Faker
4 |
5 | Replaces existing customer data for fake data. Used for develop and staging environments.
6 |
7 | Effects Following Tables
8 |
9 | - customer_entity
10 | - customer_address_entity
11 | - sales_order
12 | - sales_order_grid
13 | - sales_invoice_grid
14 | - sales_creditmemo_grid
15 | - sales_shipment_grid
16 | - qoute
17 | - newsletter
18 |
19 | php bin/magento experius_fakemydata:fakeall
20 |
21 |
22 |
--------------------------------------------------------------------------------
/composer.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "experius/module-fakemydata",
3 | "description": "Magento 2 Customer Data Faker. Replaces existing customer data for fake data. Used for develop and staging environments.",
4 | "license": "proprietary",
5 | "authors": [
6 | {
7 | "name": "Mage2Gen",
8 | "email": "info@mage2gen.com"
9 | },
10 | {
11 | "name": "Derrick Heesbeen",
12 | "email": "derrick@experius.nl"
13 | }
14 | ],
15 | "minimum-stability": "dev",
16 | "require": {
17 | "fzaninotto/faker": "1.6.*"
18 | },
19 | "autoload": {
20 | "psr-4": {
21 | "Experius\\FakeMyData\\": ""
22 | },
23 | "files": [
24 | "registration.php"
25 | ]
26 | }
27 | }
--------------------------------------------------------------------------------
/etc/adminhtml/system.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | advanced
7 | Experius_FakeMyData::config_experius_fakemydata
8 |
9 |
10 |
11 |
12 | (comma separated) Data with e-mail addresses with these domains will not be changed
13 |
14 |
15 |
16 | (comma separated) Is used for the fake email addresses (In case its the same as Excluded domain. Data will only be changed once)
17 |
18 |
19 |
20 | for example john+
21 |
22 |
23 |
24 | Will be used for all changed customer accounts
25 |
26 |
27 |
28 |
29 |
--------------------------------------------------------------------------------
/etc/config.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | experius.nl
7 | experius.nl
8 |
9 | F@k3MyD@t@
10 | 0
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/etc/di.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | - Experius\FakeMyData\Console\Command\FakeMyData
7 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/etc/module.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/registration.php:
--------------------------------------------------------------------------------
1 |