├── .travis.yml
├── .travis
└── bundle.sh
├── README.md
├── composer.json
├── modman
├── phpunit.xml.dist
├── src
├── app
│ ├── code
│ │ └── community
│ │ │ └── IntegerNet
│ │ │ └── Anonymizer
│ │ │ ├── Model
│ │ │ ├── Anonymizer.php
│ │ │ └── Bridge
│ │ │ │ ├── Entity
│ │ │ │ ├── Abstract.php
│ │ │ │ ├── Address
│ │ │ │ │ ├── Abstract.php
│ │ │ │ │ ├── CustomerAddress.php
│ │ │ │ │ ├── OrderAddress.php
│ │ │ │ │ └── QuoteAddress.php
│ │ │ │ ├── Customer.php
│ │ │ │ ├── Enterprise
│ │ │ │ │ ├── Giftregistry.php
│ │ │ │ │ └── GiftregistryPerson.php
│ │ │ │ ├── NewsletterSubscriber.php
│ │ │ │ └── Order.php
│ │ │ │ └── Iterator.php
│ │ │ ├── Test
│ │ │ ├── Model
│ │ │ │ ├── Anonymizer.php
│ │ │ │ └── Bridge
│ │ │ │ │ └── Entity
│ │ │ │ │ ├── Abstract.php
│ │ │ │ │ ├── Customer.php
│ │ │ │ │ ├── CustomerAddress.php
│ │ │ │ │ ├── Giftregistry.php
│ │ │ │ │ ├── GiftregistryPerson.php
│ │ │ │ │ ├── NewsletterSubscriber.php
│ │ │ │ │ ├── Order.php
│ │ │ │ │ ├── OrderAddress.php
│ │ │ │ │ ├── QuoteAddress.php
│ │ │ │ │ ├── expectations
│ │ │ │ │ └── bridge.yaml
│ │ │ │ │ └── providers
│ │ │ │ │ ├── testCustomerAddressBridge.yaml
│ │ │ │ │ ├── testCustomerBridge.yaml
│ │ │ │ │ ├── testGiftregistryBridge.yaml
│ │ │ │ │ ├── testGiftregistryPersonBridge.yaml
│ │ │ │ │ ├── testNewsletterSubscriberBridge.yaml
│ │ │ │ │ ├── testOrderAddressBridge.yaml
│ │ │ │ │ ├── testOrderBridge.yaml
│ │ │ │ │ └── testQuoteAddressBridge.yaml
│ │ │ └── fixtures
│ │ │ │ ├── customers.yaml
│ │ │ │ └── enterprise.yaml
│ │ │ └── etc
│ │ │ └── config.xml
│ └── etc
│ │ └── modules
│ │ └── IntegerNet_Anonymizer.xml
├── lib
│ ├── IntegerNet
│ │ └── Anonymizer
│ │ │ ├── AnonymizableValue.php
│ │ │ ├── Anonymizer.php
│ │ │ ├── Implementor
│ │ │ ├── AnonymizableEntity.php
│ │ │ └── CollectionIterator.php
│ │ │ ├── Provider.php
│ │ │ └── Updater.php
│ └── n98-magerun
│ │ └── modules
│ │ └── IntegerNet_Anonymizer
│ │ ├── n98-magerun.yaml
│ │ └── src
│ │ └── IntegerNet
│ │ └── Anonymizer
│ │ └── AnonymizeCommand.php
└── shell
│ └── anonymize.php
└── test
├── IntegerNet
└── Anonymizer
│ ├── AnonymizerTest.php
│ ├── Mock
│ ├── AnonymizableMock.php
│ └── CollectionMock.php
│ ├── ProviderTest.php
│ └── UpdaterTest.php
└── bootstrap.php
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: php
2 | php:
3 | - 5.6
4 | - 7.0
5 | - 7.1
6 | env:
7 | - MAGENTO_VERSION=magento-mirror-1.9.3.10
8 | - MAGENTO_VERSION=magento-mirror-1.9.2.2
9 | - MAGENTO_VERSION=magento-mirror-1.9.1.0
10 | script:
11 | - composer install --dev --no-interaction
12 | - phpunit
13 | - curl -sSL https://raw.githubusercontent.com/schmengler/MageTestStand/master/setup.sh | bash
14 | before_deploy: .travis/bundle.sh
15 | deploy:
16 | provider: releases
17 | api_key:
18 | secure: YBCy2em9MOCaxS5cG+MqUO0kcW7ELPXHSs6mpM/fG+CcKaSOlrEuXmxgaCC9OJsj3aybZJ7WeiuxphLpv7CcgN5/pv+RC1RyEU/5Mt13/fG4P4YNKCEmDPsSnPQVtLKQJIWby9jf0ZhznjJJ/SvwGYmfGF0mn3/yINg2eNF/f3Y=
19 | file:
20 | - "integernet-anonymizer.zip"
21 | - "integernet-anonymizer.tar.gz"
22 | skip_cleanup: true
23 | on:
24 | tags: true
--------------------------------------------------------------------------------
/.travis/bundle.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 | ################################################################################
3 | # #
4 | # This script is used by Travis CI to create a downloadable build for each #
5 | # release with all dependencies, for manual installation. #
6 | # #
7 | ################################################################################
8 |
9 | set -e
10 | set -x
11 | if [ "$TRAVIS_TAG" == "" ]; then
12 | exit 0
13 | fi
14 | cd $TRAVIS_BUILD_DIR
15 | RELEASE_DIR=integernet-anonymizer-${TRAVIS_TAG}
16 | mkdir -p ${RELEASE_DIR}
17 | cp -rf src/* ${RELEASE_DIR}/
18 | cp -rf .modman/psr0autoloader/app ${RELEASE_DIR}/
19 | cp -rf .modman/psr0autoloader/shell ${RELEASE_DIR}/
20 | cp -rf vendor/fzaninotto/faker/src/Faker ${RELEASE_DIR}/lib/
21 | zip -r integernet-anonymizer.zip ${RELEASE_DIR}
22 | tar -czf integernet-anonymizer.tar.gz ${RELEASE_DIR}
23 | printf "\x1b[32mBundled release ${TRAVIS_TAG}\x1b[0m"
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | IntegerNet_Anonymizer
2 | =====================
3 | This module allows anonymizing customer data in a sensible way. It uses dummy data provided by Faker and maintains associations like customer address <=> order address.
4 |
5 | Facts
6 | -----
7 |
8 | | Branch | Build Status | Code Quality |
9 | | ------ | ------------ | ------------ |
10 | | master | [](https://travis-ci.org/integer-net/Anonymizer) | [](https://scrutinizer-ci.com/g/integer-net/Anonymizer/?branch=master) |
11 | | development | [](https://travis-ci.org/integer-net/Anonymizer) | [](https://scrutinizer-ci.com/g/integer-net/Anonymizer/?branch=development) |
12 |
13 | - version: 2.0.0
14 | - extension key: integer-net/anonymizer
15 | - [extension on GitHub](https://github.com/integer-net/Anonymizer)
16 | - [direct download link](https://github.com/integer-net/Anonymizer/archive/master.zip)
17 |
18 | Usage
19 | -----------
20 | Run the anonymizer via command line:
21 |
22 | cd shell
23 | php anonymizer.php
24 |
25 | To display progress in real time:
26 |
27 | php anonymizer.php --progress
28 |
29 | To only update the progress display every 100 entities:
30 |
31 | php anonymizer.php --progress 100
32 |
33 | If you have n98-magerun installed, you can also use this command:
34 |
35 | n98-magerun db:anonymize
36 |
37 | **Be aware that the process will run very long if you have more than a few thousand orders. Consider deleting old sales data first.**
38 |
39 | [](https://asciinema.org/a/9j4kylm874s4legd8ddbj494m)
40 |
41 |
42 | Requirements
43 | ------------
44 | - PHP >= 5.4
45 | - [Faker](https://github.com/fzaninotto/faker)
46 | - [Magento-PSR-0-Autoloader](https://github.com/magento-hackathon/Magento-PSR-0-Autoloader)
47 |
48 | Compatibility
49 | -------------
50 | - Magento CE 1.7, 1.8, 1.9
51 | - Magento EE 1.12, 1.13, 1.14
52 |
53 | Installation Instructions
54 | -------------------------
55 | 1. Install via composer: `composer require integer-net/anonymizer`
56 | 2. Configure Magento-PSR-0-Autoloader to use the composer autoloader. Add this to the `global` node of your `app/etc/local.xml`:
57 |
58 |
59 |
60 | Alternatively download the archive from the [Github release page](https://github.com/integer-net/Anonymizer/releases) and extract it into your installation. It contains the Faker library and no additional configuration is required.
61 |
62 | Support
63 | -------
64 | If you have any issues with this extension, open an issue on [GitHub](https://github.com/integer-net/Anonymizer/issues).
65 |
66 | Contribution
67 | ------------
68 | Any contribution is highly appreciated. The best way to contribute code is to open a [pull request on GitHub](https://help.github.com/articles/using-pull-requests).
69 |
70 | Developer
71 | ---------
72 | Fabian Schmengler, [integer_net GmbH](http://www.integer-net.de)
73 |
74 | Twitter: [@fschmengler](https://twitter.com/fschmengler) [@integer_net](https://twitter.com/integer_net)
75 |
76 | Licence
77 | -------
78 | [OSL - Open Software Licence 3.0](http://opensource.org/licenses/osl-3.0.php)
79 |
80 | Copyright
81 | ---------
82 | © 2015 integer_net GmbH
83 |
--------------------------------------------------------------------------------
/composer.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "integer-net/anonymizer",
3 | "license": "OSL-3.0",
4 | "type": "magento-module",
5 | "description": "Anonymizes all Customer Data",
6 | "require": {
7 | "fzaninotto/faker": ">=1.0",
8 | "firegento/psr0autoloader": ">=0.1.0"
9 | },
10 | "autoload": {
11 | "psr-4": {
12 | "IntegerNet\\Anonymizer\\": "src/lib/IntegerNet/Anonymizer"
13 | }
14 | },
15 | "autoload-dev": {
16 | "psr-4": {
17 | "IntegerNet\\Anonymizer\\": "test/IntegerNet/Anonymizer"
18 | }
19 | },
20 | "require-dev": {
21 | "ecomdev/ecomdev_phpunit": "dev-dev@dev",
22 | "aoepeople/composer-installers": "*"
23 | },
24 | "repositories": [
25 | {
26 | "type": "composer",
27 | "url": "https://packages.firegento.com"
28 | }
29 | ],
30 | "authors":[
31 | {
32 | "name":"Fabian Schmengler",
33 | "email":"fs@integer-net.de"
34 | }
35 | ]
36 | }
--------------------------------------------------------------------------------
/modman:
--------------------------------------------------------------------------------
1 | src/app/code/community/IntegerNet/Anonymizer app/code/community/IntegerNet/Anonymizer
2 | src/app/etc/modules/* app/etc/modules/
3 | src/lib/IntegerNet/* lib/IntegerNet/
4 | src/lib/n98-magerun/modules/IntegerNet_Anonymizer lib/n98-magerun/modules/IntegerNet_Anonymizer
5 |
6 | @shell cp -fu $MODULE/src/shell/* $PROJECT/shell/
--------------------------------------------------------------------------------
/phpunit.xml.dist:
--------------------------------------------------------------------------------
1 |
2 |
13 |
14 |
15 | ./test/
16 |
17 |
18 |
19 |
20 |
21 | ./src/
22 |
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/src/app/code/community/IntegerNet/Anonymizer/Model/Anonymizer.php:
--------------------------------------------------------------------------------
1 |
9 | */
10 |
11 | class IntegerNet_Anonymizer_Model_Anonymizer
12 | {
13 | /**
14 | * @var \IntegerNet\Anonymizer\Updater
15 | */
16 | protected $_updater;
17 |
18 | public function __construct()
19 | {
20 | $anonymizer = new \IntegerNet\Anonymizer\Anonymizer();
21 | $this->_updater = new \IntegerNet\Anonymizer\Updater($anonymizer);
22 | }
23 | protected function _getEntityModels()
24 | {
25 | $entityModelsConfigXml = Mage::getConfig()->getNode('global/integernet_anonymizer/entity_models');
26 |
27 | $entityModelsConfigArray = $entityModelsConfigXml->asArray();
28 | $entityModelsConfigArray = $this->_sortEntityModelsConfig($entityModelsConfigArray);
29 |
30 | $entityModels = [];
31 |
32 | foreach ($entityModelsConfigArray as $entityModelsConfig) {
33 | $entityModel = Mage::getModel($entityModelsConfig['class']);
34 | if ($entityModel instanceof IntegerNet_Anonymizer_Model_Bridge_Entity_Abstract
35 | && $entityModel->entityExists()) {
36 | $entityModels[] = $entityModelsConfig['class'];
37 | }
38 | }
39 |
40 | return $entityModels;
41 | }
42 | protected function _sortEntityModelsConfig($entityModelsConfig)
43 | {
44 | usort(
45 | $entityModelsConfig,
46 | function ($entityModel1, $entityModel2) {
47 | return strcmp($entityModel1['sort'], $entityModel2['sort']);
48 | }
49 | );
50 | return $entityModelsConfig;
51 | }
52 | /**
53 | * @param resource $stream stream resource used for output (for example opened file pointer or STDOUT)
54 | */
55 | public function setOutputStream($stream)
56 | {
57 | $this->_updater->setOutputStream($stream);
58 | }
59 | /**
60 | * @param boolean $showProgress True if progress should be output (default is true)
61 | */
62 | public function setShowProgress($showProgress)
63 | {
64 | $this->_updater->setShowProgress($showProgress);
65 | }
66 | /**
67 | * @param $steps How often progress output should be refreshed (default is 1 = after every entity update; example: 10 = every 10 entity updates)
68 | */
69 | public function setProgressSteps($steps)
70 | {
71 | $this->_updater->setProgressSteps($steps);
72 | }
73 |
74 | public function anonymizeAll()
75 | {
76 | /** @var Varien_Db_Adapter_Interface $connection */
77 | $connection = Mage::getSingleton('core/resource')->getConnection('core_write');
78 | $connection->beginTransaction();
79 | try {
80 | foreach ($this->_getEntityModels() as $entityModelAlias) {
81 | /** @var IntegerNet_Anonymizer_Model_Bridge_Entity_Abstract $entityModel */
82 | $entityModel = Mage::getModel($entityModelAlias);
83 | while ($collectionIterator = $entityModel->getCollectionIterator()) {
84 | $this->_updater->update($collectionIterator, $entityModel);
85 | }
86 | }
87 | $connection->commit();
88 | } catch (\Exception $e) {
89 | $connection->rollBack();
90 | throw $e;
91 | }
92 | }
93 | public function anonymizeStore()
94 | {
95 | //TODO different locales per store
96 | }
97 | protected function _clearPaymentData()
98 | {
99 | //TODO UPDATE sales_flat_order_payment SET additional_data=NULL, additional_information=NULL
100 | }
101 | }
--------------------------------------------------------------------------------
/src/app/code/community/IntegerNet/Anonymizer/Model/Bridge/Entity/Abstract.php:
--------------------------------------------------------------------------------
1 |
11 | */
12 | abstract class IntegerNet_Anonymizer_Model_Bridge_Entity_Abstract
13 | implements IntegerNet\Anonymizer\Implementor\AnonymizableEntity
14 | {
15 | const ROWS_PER_QUERY = 50000;
16 | /**
17 | * @var string
18 | */
19 | protected $_identifier;
20 | /**
21 | * @var Mage_Core_Model_Abstract
22 | */
23 | protected $_entity;
24 | /**
25 | * @var string|null is overridden with entity type code if the model is a EAV entity
26 | */
27 | protected $_entityType = null;
28 | /**
29 | * @var string[]
30 | */
31 | protected $_formattersByAttribute = array();
32 | /**
33 | * @var string[] Specifies attributes that will be loaded
34 | */
35 | protected $_attributesUsedForIdentifier = array();
36 | /**
37 | * @var string[]
38 | */
39 | protected $_uniqueAttributes = array();
40 | /**
41 | * @var AnonymizableValue[]
42 | */
43 | protected $_values;
44 | /**
45 | * @var int Current page of collection for chunking
46 | */
47 | protected $currentPage = 0;
48 |
49 | /**
50 | * Returns identifier, for example the customer email address. Entities with the same identifier will get the same
51 | * anonymized values.
52 | *
53 | * Important: The return value must not be affected by anonymization!
54 | *
55 | * @return string
56 | */
57 | public function getIdentifier()
58 | {
59 | return $this->_identifier;
60 | }
61 |
62 | /**
63 | * Sets identifier based on current entity
64 | *
65 | * @return void
66 | */
67 | abstract protected function _setIdentifier();
68 |
69 | /**
70 | * @return AnonymizableValue[]
71 | */
72 | public function getValues()
73 | {
74 | if ($this->_values === null) {
75 | $this->_values = array();
76 | foreach ($this->_formattersByAttribute as $attribute => $formatter) {
77 | $this->_values[$attribute] = new AnonymizableValue(
78 | $formatter, $this->_entity->getDataUsingMethod($attribute),
79 | in_array($attribute, $this->_uniqueAttributes));
80 | }
81 | }
82 | return $this->_values;
83 | }
84 |
85 | /**
86 | * Sets raw data from database
87 | *
88 | * @param string[] $data
89 | * @return void
90 | */
91 | public function setRawData($data)
92 | {
93 | $this->_entity->addData($data);
94 | // reset derived attributes:
95 | $this->_setIdentifier();
96 | $this->_values = null;
97 | }
98 |
99 | /**
100 | * Update values in database
101 | *
102 | * @return void
103 | */
104 | public function updateValues()
105 | {
106 | $resource = $this->_entity->getResource();
107 | $staticAttributes = array();
108 | foreach ($this->getValues() as $attributeCode => $value) {
109 | if (!$resource instanceof Mage_Eav_Model_Entity_Abstract) {
110 | $staticAttributes[$attributeCode] = $value->getValue();
111 | continue;
112 | }
113 | $attribute = Mage::getSingleton('eav/config')->getAttribute($this->_entityType, $attributeCode);
114 | if ($attribute->isStatic()) {
115 | $staticAttributes[$attributeCode] = $value->getValue();
116 | continue;
117 | }
118 | $this->_entity->setData($attributeCode, $value->getValue());
119 | $resource->saveAttribute($this->_entity, $attributeCode);
120 | }
121 | if (!empty($staticAttributes)) {
122 | $this->_entity->addData($staticAttributes);
123 | if ($resource instanceof Mage_Eav_Model_Entity_Abstract) {
124 | $resource->isPartialSave(true);
125 | }
126 | try {
127 | $resource->save($this->_entity);
128 | } catch (Mage_Customer_Exception $e) {
129 | // 'This customer email already exists'
130 | //TODO instead exclude all customers with @example.* email addresses from the customer collection
131 | // AND from associated collections as well
132 | }
133 | }
134 | }
135 |
136 | /**
137 | * Reset to empty instance
138 | *
139 | * @return void
140 | */
141 | public function clearInstance()
142 | {
143 | $this->_entity->setData(array());
144 | $this->_entity->clearInstance();
145 | // reset derived attributes
146 | $this->setRawData(array());
147 | }
148 |
149 | /**
150 | * @return IntegerNet_Anonymizer_Model_Bridge_Iterator|null
151 | */
152 | public function getCollectionIterator()
153 | {
154 | /** @var Varien_Data_Collection_Db $collection */
155 | $collection = $this->_entity->getCollection();
156 | $fields = array_unique(array_merge(
157 | array_keys($this->_formattersByAttribute),
158 | $this->_attributesUsedForIdentifier
159 | ));
160 | if ($collection instanceof Mage_Eav_Model_Entity_Collection_Abstract) {
161 | $collection->addAttributeToSelect($fields, 'left');
162 | } elseif ($collection instanceof Mage_Core_Model_Resource_Db_Collection_Abstract) {
163 | $collection->addFieldToSelect($fields);
164 | }
165 | $iterationOffset = $this->currentPage * self::ROWS_PER_QUERY;
166 | if ($collection->getSize() <= $iterationOffset) {
167 | return null;
168 | }
169 | $this->currentPage++;
170 | $collection->getSelect()->limitPage($this->currentPage, self::ROWS_PER_QUERY);
171 | /** @var IntegerNet_Anonymizer_Model_Bridge_Iterator $iterator */
172 | $iterator = Mage::getModel('integernet_anonymizer/bridge_iterator', $collection);
173 | $iterator->setIterationOffset($iterationOffset);
174 | return $iterator;
175 | }
176 |
177 | /**
178 | * Check if the entity exists
179 | * @return bool
180 | */
181 | public function entityExists()
182 | {
183 | return (bool)$this->_entity;
184 | }
185 | }
--------------------------------------------------------------------------------
/src/app/code/community/IntegerNet/Anonymizer/Model/Bridge/Entity/Address/Abstract.php:
--------------------------------------------------------------------------------
1 |
9 | */
10 | abstract class IntegerNet_Anonymizer_Model_Bridge_Entity_Address_Abstract
11 | extends IntegerNet_Anonymizer_Model_Bridge_Entity_Abstract
12 | {
13 | protected $_formattersByAttribute = array(
14 | 'firstname' => 'firstName',
15 | 'lastname' => 'lastName',
16 | 'middlename' => 'firstName',
17 | 'prefix' => 'title',
18 | 'suffix' => 'suffix',
19 | 'company' => 'company',
20 | 'city' => 'city',
21 | 'street' => 'streetAddress',
22 | 'telephone' => 'phoneNumber',
23 | 'fax' => 'phoneNumber',
24 | 'vat_id' => 'randomNumber' // 'vat' provider is not implemented for most counries
25 | );
26 |
27 | /**
28 | * Sets identifier based on current entity
29 | *
30 | * @return void
31 | */
32 | protected function _setIdentifier()
33 | {
34 | $customerId = $this->_entity->getCustomerId();
35 | if ($customerId) {
36 | $this->_identifier = $customerId;
37 | return;
38 | }
39 | $entityId = $this->_entity->getId();
40 | if ($entityId) {
41 | $this->_identifier = $this->getEntityName() . $entityId;
42 | return;
43 | }
44 | $this->_identifier = null;
45 | }
46 |
47 | }
--------------------------------------------------------------------------------
/src/app/code/community/IntegerNet/Anonymizer/Model/Bridge/Entity/Address/CustomerAddress.php:
--------------------------------------------------------------------------------
1 |
9 | */
10 | class IntegerNet_Anonymizer_Model_Bridge_Entity_Address_CustomerAddress
11 | extends IntegerNet_Anonymizer_Model_Bridge_Entity_Address_Abstract
12 | {
13 | protected $_attributesUsedForIdentifier = array(
14 | 'parent_id'
15 | );
16 |
17 | protected $_entityType = 'customer_address';
18 |
19 | function __construct()
20 | {
21 | $this->_entity = Mage::getModel('customer/address');
22 | }
23 |
24 | /**
25 | * Returns name of entity as translatable string
26 | *
27 | * @return string
28 | */
29 | function getEntityName()
30 | {
31 | return 'Customer Address';
32 | }
33 |
34 |
35 | }
--------------------------------------------------------------------------------
/src/app/code/community/IntegerNet/Anonymizer/Model/Bridge/Entity/Address/OrderAddress.php:
--------------------------------------------------------------------------------
1 |
9 | */
10 | class IntegerNet_Anonymizer_Model_Bridge_Entity_Address_OrderAddress
11 | extends IntegerNet_Anonymizer_Model_Bridge_Entity_Address_Abstract
12 | {
13 | protected $_attributesUsedForIdentifier = array(
14 | 'customer_id'
15 | );
16 |
17 | function __construct()
18 | {
19 | $this->_entity = Mage::getModel('sales/order_address');
20 | }
21 |
22 | /**
23 | * Returns name of entity as translatable string
24 | *
25 | * @return string
26 | */
27 | function getEntityName()
28 | {
29 | return 'Order Address';
30 | }
31 |
32 | }
--------------------------------------------------------------------------------
/src/app/code/community/IntegerNet/Anonymizer/Model/Bridge/Entity/Address/QuoteAddress.php:
--------------------------------------------------------------------------------
1 |
9 | */
10 | class IntegerNet_Anonymizer_Model_Bridge_Entity_Address_QuoteAddress
11 | extends IntegerNet_Anonymizer_Model_Bridge_Entity_Address_Abstract
12 | {
13 | protected $_attributesUsedForIdentifier = array(
14 | 'customer_id'
15 | );
16 |
17 | function __construct()
18 | {
19 | $this->_entity = Mage::getModel('sales/quote_address');
20 | }
21 |
22 | /**
23 | * Returns name of entity as translatable string
24 | *
25 | * @return string
26 | */
27 | function getEntityName()
28 | {
29 | return 'Quote Address';
30 | }
31 |
32 |
33 | }
--------------------------------------------------------------------------------
/src/app/code/community/IntegerNet/Anonymizer/Model/Bridge/Entity/Customer.php:
--------------------------------------------------------------------------------
1 |
9 | */
10 | class IntegerNet_Anonymizer_Model_Bridge_Entity_Customer extends IntegerNet_Anonymizer_Model_Bridge_Entity_Abstract
11 | {
12 | protected $_entityType = 'customer';
13 |
14 | protected $_formattersByAttribute = array(
15 | 'email' => 'safeEmail',
16 | 'firstname' => 'firstName',
17 | 'lastname' => 'lastName',
18 | 'middlename' => 'firstName',
19 | 'prefix' => 'title',
20 | 'suffix' => 'suffix',
21 | 'taxvat' => 'randomNumber' // 'vat' provider is not implemented for most counries
22 | );
23 | protected $_uniqueAttributes = array(
24 | 'email'
25 | );
26 |
27 | function __construct()
28 | {
29 | $this->_entity = Mage::getModel('customer/customer');
30 | }
31 |
32 | protected function _setIdentifier()
33 | {
34 | $this->_identifier = $this->_entity->getId();
35 | }
36 |
37 | /**
38 | * Returns name of entity as translatable string
39 | *
40 | * @return string
41 | */
42 | function getEntityName()
43 | {
44 | return 'Customer';
45 | }
46 |
47 |
48 | }
--------------------------------------------------------------------------------
/src/app/code/community/IntegerNet/Anonymizer/Model/Bridge/Entity/Enterprise/Giftregistry.php:
--------------------------------------------------------------------------------
1 |
9 | */
10 | class IntegerNet_Anonymizer_Model_Bridge_Entity_Enterprise_Giftregistry
11 | extends IntegerNet_Anonymizer_Model_Bridge_Entity_Abstract
12 | {
13 |
14 | protected $_formattersByAttribute = array(
15 | 'title' => 'sentence',
16 | 'message' => 'paragraph',
17 | 'shipping_address' => 'address',
18 | 'custom_values' => 'null',
19 | );
20 |
21 |
22 | function __construct()
23 | {
24 | $this->_entity = Mage::getModel('enterprise_giftregistry/entity');
25 | }
26 |
27 | /**
28 | * Sets identifier based on current entity
29 | *
30 | * @return void
31 | */
32 | protected function _setIdentifier()
33 | {
34 | $entityId = $this->_entity->getId();
35 | if ($entityId) {
36 | $this->_identifier = '_gift_registry_' . $entityId;
37 | } else {
38 | $this->_identifier = '';
39 | }
40 | }
41 |
42 | /**
43 | * Returns name of entity as translatable string
44 | *
45 | * @return string
46 | */
47 | function getEntityName()
48 | {
49 | return 'Gift Registry';
50 | }
51 |
52 |
53 | }
--------------------------------------------------------------------------------
/src/app/code/community/IntegerNet/Anonymizer/Model/Bridge/Entity/Enterprise/GiftregistryPerson.php:
--------------------------------------------------------------------------------
1 |
9 | */
10 | class IntegerNet_Anonymizer_Model_Bridge_Entity_Enterprise_GiftregistryPerson
11 | extends IntegerNet_Anonymizer_Model_Bridge_Entity_Abstract
12 | {
13 |
14 | protected $_formattersByAttribute = array(
15 | 'email' => 'safeEmail',
16 | 'firstname' => 'firstName',
17 | 'lastname' => 'lastName',
18 | 'custom_values' => 'null',
19 | );
20 |
21 |
22 | function __construct()
23 | {
24 | $this->_entity = Mage::getModel('enterprise_giftregistry/person');
25 | }
26 |
27 | /**
28 | * Sets identifier based on current entity
29 | *
30 | * @return void
31 | */
32 | protected function _setIdentifier()
33 | {
34 | $this->_identifier = $this->_entity->getEmail();
35 | }
36 |
37 | /**
38 | * Returns name of entity as translatable string
39 | *
40 | * @return string
41 | */
42 | function getEntityName()
43 | {
44 | return 'Gift Registry Person';
45 | }
46 |
47 |
48 | }
--------------------------------------------------------------------------------
/src/app/code/community/IntegerNet/Anonymizer/Model/Bridge/Entity/NewsletterSubscriber.php:
--------------------------------------------------------------------------------
1 |
9 | */
10 | class IntegerNet_Anonymizer_Model_Bridge_Entity_NewsletterSubscriber
11 | extends IntegerNet_Anonymizer_Model_Bridge_Entity_Abstract
12 | {
13 |
14 | protected $_attributesUsedForIdentifier = array(
15 | 'customer_id'
16 | );
17 | protected $_formattersByAttribute = array(
18 | 'subscriber_email' => 'safeEmail',
19 | );
20 |
21 | function __construct()
22 | {
23 | $this->_entity = Mage::getModel('newsletter/subscriber');
24 | }
25 |
26 | /**
27 | * Sets identifier based on current entity
28 | *
29 | * @return void
30 | */
31 | protected function _setIdentifier()
32 | {
33 | $this->_identifier = $this->_entity->getCustomerId() ?: $this->_entity->getEmail();
34 | }
35 |
36 | /**
37 | * Returns name of entity as translatable string
38 | *
39 | * @return string
40 | */
41 | function getEntityName()
42 | {
43 | return 'Newsletter Subscriber';
44 | }
45 |
46 |
47 | }
--------------------------------------------------------------------------------
/src/app/code/community/IntegerNet/Anonymizer/Model/Bridge/Entity/Order.php:
--------------------------------------------------------------------------------
1 |
9 | */
10 | class IntegerNet_Anonymizer_Model_Bridge_Entity_Order extends IntegerNet_Anonymizer_Model_Bridge_Entity_Abstract
11 | {
12 | protected $_entityType = 'order';
13 |
14 | protected $_attributesUsedForIdentifier = array(
15 | 'customer_id', 'increment_id'
16 | );
17 |
18 | protected $_formattersByAttribute = array(
19 | 'customer_email' => 'safeEmail',
20 | 'customer_firstname' => 'firstName',
21 | 'customer_lastname' => 'lastName',
22 | 'customer_middlename' => 'firstName',
23 | 'customer_prefix' => 'title',
24 | 'customer_suffix' => 'suffix',
25 | 'customer_taxvat' => 'randomNumber' // 'vat' provider is not implemented for most counries
26 | );
27 | protected $_uniqueAttributes = array(
28 | 'customer_email'
29 | );
30 |
31 | function __construct()
32 | {
33 | $this->_entity = Mage::getModel('sales/order');
34 | }
35 |
36 | protected function _setIdentifier()
37 | {
38 | $this->_identifier = $this->_entity->getCustomerId();
39 | }
40 |
41 | /**
42 | * Returns name of entity as translatable string
43 | *
44 | * @return string
45 | */
46 | function getEntityName()
47 | {
48 | return 'Order';
49 | }
50 |
51 | }
--------------------------------------------------------------------------------
/src/app/code/community/IntegerNet/Anonymizer/Model/Bridge/Iterator.php:
--------------------------------------------------------------------------------
1 |
9 | */
10 | class IntegerNet_Anonymizer_Model_Bridge_Iterator implements \IntegerNet\Anonymizer\Implementor\CollectionIterator
11 | {
12 | /**
13 | * @var Mage_Eav_Model_Entity_Collection_Abstract|Mage_Core_Model_Resource_Db_Collection_Abstract
14 | */
15 | protected $_collection;
16 | /**
17 | * @var Mage_Core_Model_Resource_Iterator
18 | */
19 | protected $_iterator;
20 | /**
21 | * @var string[]
22 | */
23 | protected $_data;
24 | /**
25 | * @var int Iteration counter
26 | */
27 | protected $_iteration;
28 | /**
29 | * @var int Iteration counter offset for chunking
30 | */
31 | protected $_iterationOffset = 0;
32 |
33 | public function __construct(Varien_Data_Collection_Db $collection)
34 | {
35 | $this->_collection = $collection;
36 | $this->_iterator = Mage::getResourceModel('core/iterator');
37 | }
38 |
39 | /**
40 | * @return Mage_Core_Model_Resource_Db_Collection_Abstract|Mage_Eav_Model_Entity_Collection_Abstract
41 | */
42 | public function getCollection()
43 | {
44 | return $this->_collection;
45 | }
46 |
47 | /**
48 | * @param callable $callable
49 | * @return mixed
50 | */
51 | function walk(/*callable*/ $callable) // PHP 5.3
52 | {
53 | $self = $this; // PHP 5.3
54 | $this->_iterator->walk($this->_collection->getSelect(), array(
55 | function($args) use ($callable, $self) {
56 | $self->_setIteration($args['idx']);
57 | $self->_setRawData($args['row']);
58 | $callable($self);
59 | }
60 | ));
61 | $this->_afterWalk();
62 | }
63 |
64 | public function _setRawData($data)
65 | {
66 | $this->_data = $data;
67 | }
68 | public function _setIteration($iteration)
69 | {
70 | $this->_iteration = $iteration;
71 | }
72 | public function setIterationOffset($offset)
73 | {
74 | $this->_iterationOffset = $offset;
75 | }
76 |
77 | /**
78 | * Returns raw data from database
79 | *
80 | * @return mixed
81 | */
82 | function getRawData()
83 | {
84 | return $this->_data;
85 | }
86 |
87 | /**
88 | * Returns number of iteration
89 | *
90 | * @return int
91 | */
92 | function getIteration()
93 | {
94 | return $this->_iterationOffset + $this->_iteration;
95 | }
96 |
97 | /**
98 | * Returns total size of collection
99 | *
100 | * @return mixed
101 | */
102 | function getSize()
103 | {
104 | return $this->_collection->getSize();
105 | }
106 |
107 | /**
108 | * Additional processing at the end:
109 | * - update grid tables
110 | *
111 | * @return void
112 | */
113 | protected function _afterWalk()
114 | {
115 | $entityResource = $this->_collection->getResource();
116 | if ($entityResource instanceof Mage_Sales_Model_Resource_Order_Abstract) {
117 | $entityResource->updateGridRecords($this->_collection->getAllIds());
118 | }
119 | }
120 |
121 | }
--------------------------------------------------------------------------------
/src/app/code/community/IntegerNet/Anonymizer/Test/Model/Anonymizer.php:
--------------------------------------------------------------------------------
1 |
9 | */
10 |
11 | class IntegerNet_Anonymizer_Test_Model_Anonymizer extends EcomDev_PHPUnit_Test_Case
12 | {
13 | /**
14 | * @test
15 | * @loadFixture customers.yaml
16 | */
17 | public function testAnonymizeAllCommunity()
18 | {
19 | $this->_testAnonymizeAll();
20 | }
21 |
22 | /**
23 | * @test
24 | */
25 | public function isEnterprise()
26 | {
27 | if (Mage::getEdition() !== Mage::EDITION_ENTERPRISE) {
28 | $this->markTestSkipped('Skipping test for Magento Enterprise');
29 | }
30 | }
31 | /**
32 | * @test
33 | * @depends isEnterprise
34 | * @loadFixture customers.yaml
35 | * @loadFixture enterprise.yaml
36 | */
37 | public function testAnonymizeAllEnterprise()
38 | {
39 | $this->_testAnonymizeAll();
40 | //TODO EE assertions
41 | $this->markTestIncomplete();
42 | }
43 |
44 | /**
45 | *
46 | */
47 | protected function _testAnonymizeAll()
48 | {
49 | // TEST PRE CONDITIONS
50 |
51 | /** @var Mage_Sales_Model_Resource_Order_Grid_Collection $orderGridCollection */
52 | $orderGridCollection = Mage::getResourceModel('sales/order_grid_collection');
53 | $orderGridData = $orderGridCollection->addFieldToFilter('entity_id', 1)->getFirstItem();
54 | $this->assertEquals('Testname Testname', $orderGridData->getShippingName());
55 | $this->assertEquals('Testname Testname', $orderGridData->getBillingName());
56 | $this->assertEquals('1000000001', $orderGridData->getIncrementId(), 'Precondition: Increment ID in grid');
57 |
58 | // RUN ANONYMIZER
59 |
60 | /** @var IntegerNet_Anonymizer_Model_Anonymizer $anonymizer */
61 | $anonymizer = Mage::getModel('integernet_anonymizer/anonymizer');
62 | $anonymizer->anonymizeAll();
63 |
64 | // TEST POST CONDITIONS
65 |
66 | $customer = Mage::getModel('customer/customer')->load(2);
67 | $this->assertNotEquals('test2@test.de', $customer->getData('email'));
68 | $this->assertNotEquals('Testname', $customer->getData('firstname'));
69 | $this->assertNotEquals('Testname', $customer->getData('lastname'));
70 |
71 | $customerAddress = $customer->getDefaultBillingAddress();
72 | $this->assertNotEquals('Testname', $customerAddress->getData('firstname'));
73 | $this->assertNotEquals('Testname', $customerAddress->getData('lastname'));
74 | $this->assertNotEquals('ACME GmbH', $customerAddress->getData('company'));
75 | $this->assertNotEquals('Buxtehude', $customerAddress->getData('city'));
76 | $this->assertNotEquals('Am Arm 1', $customerAddress->getData('street'));
77 | $this->assertNotEquals('555-12345', $customerAddress->getData('telephone'));
78 | $this->assertNotEquals('555-12345', $customerAddress->getData('fax'));
79 | $this->assertNotEquals('DE 987654321', $customerAddress->getData('vat_id'));
80 | $this->assertEquals('67890', $customerAddress->getData('postcode'));
81 | $this->assertEquals('DE', $customerAddress->getCountryId());
82 |
83 | $quote = Mage::getModel('sales/quote')->load(1);
84 | $quoteAddress = $quote->getBillingAddress();
85 | $this->assertEquals($customerAddress->getCustomerId(), $quoteAddress->getCustomerId(),
86 | 'Quote address and customer address refer to the same customer');
87 | $this->assertNotEquals($customerAddress->getData('lastname'), $quoteAddress->getData('lastname'),
88 | 'Different values stay different');
89 | $this->assertNotEquals($customerAddress->getData('lastname'), $quoteAddress->getData('lastname'),
90 | 'Different values stay different');
91 | $this->assertEquals($customerAddress->getData('company'), $quoteAddress->getData('company'),
92 | 'Same values stay the same');
93 |
94 | $this->assertNotEquals('Somebody', $quoteAddress->getData('firstname'));
95 | $this->assertNotEquals('Else', $quoteAddress->getData('lastname'));
96 | $this->assertNotEquals('ACME GmbH', $quoteAddress->getData('company'));
97 | $this->assertNotEquals('Buxtehude', $quoteAddress->getData('city'));
98 | $this->assertNotEquals('Am Arm 1', $quoteAddress->getData('street'));
99 | $this->assertNotEquals('555-12345', $quoteAddress->getData('telephone'));
100 | $this->assertNotEquals('555-12345', $quoteAddress->getData('fax'));
101 | $this->assertNotEquals('DE 987654321', $quoteAddress->getData('vat_id'));
102 | $this->assertEquals('67890', $quoteAddress->getData('postcode'));
103 | $this->assertEquals('DE', $quoteAddress->getCountryId());
104 |
105 | /** @var Mage_Sales_Model_Order $order */
106 | $order = Mage::getModel('sales/order')->load(1);
107 | $this->assertEquals('1000000001', $order->getIncrementId(), 'Increment ID should be unchanged');
108 | $this->assertNotEquals('test2@test.de', $order->getCustomerEmail());
109 | $this->assertNotEquals('Testname', $order->getCustomerFirstname());
110 | $this->assertNotEquals('J', $order->getCustomerMiddlename());
111 | $this->assertNotEquals('Testname', $order->getCustomerLastname());
112 | $this->assertNotEquals('Kaiser', $order->getCustomerPrefix());
113 | $this->assertNotEquals('der Große', $order->getCustomerSuffix());
114 |
115 | $orderAddress = $order->getBillingAddress();
116 | $this->assertEquals($quoteAddress->getCustomerId(), $orderAddress->getCustomerId(),
117 | 'Quote address and customer address refer to the same customer');
118 | $this->assertNotEquals($quoteAddress->getData('lastname'), $orderAddress->getData('lastname'),
119 | 'Different values stay different');
120 | $this->assertNotEquals($quoteAddress->getData('lastname'), $orderAddress->getData('lastname'),
121 | 'Different values stay different');
122 | $this->assertEquals($quoteAddress->getData('company'), $orderAddress->getData('company'),
123 | 'Same values stay the same');
124 |
125 | $this->assertNotEquals('Testname', $orderAddress->getData('firstname'));
126 | $this->assertNotEquals('Testname', $orderAddress->getData('lastname'));
127 | $this->assertNotEquals('ACME GmbH', $orderAddress->getData('company'));
128 | $this->assertNotEquals('Buxtehude', $orderAddress->getData('city'));
129 | $this->assertNotEquals('Am Arm 1', $orderAddress->getData('street'));
130 | $this->assertNotEquals('555-12345', $orderAddress->getData('telephone'));
131 | $this->assertNotEquals('555-12345', $orderAddress->getData('fax'));
132 | $this->assertNotEquals('DE 987654321', $orderAddress->getData('vat_id'));
133 | $this->assertEquals('67890', $orderAddress->getData('postcode'));
134 | $this->assertEquals('DE', $orderAddress->getCountryId());
135 |
136 | /** @var Mage_Sales_Model_Resource_Order_Grid_Collection $orderGridCollection */
137 | $orderGridCollection = Mage::getResourceModel('sales/order_grid_collection');
138 | $orderGridData = $orderGridCollection->addFieldToFilter('entity_id', 1)->getFirstItem();
139 | $this->assertNotEquals('Testname Testname', $orderGridData->getShippingName());
140 | $this->assertNotEquals('Testname Testname', $orderGridData->getBillingName());
141 | $this->assertEquals($orderAddress->getName(), $orderGridData->getBillingName());
142 | $this->assertEquals('1000000001', $orderGridData->getIncrementId(), 'Increment ID in grid should be unchanged');
143 |
144 | $subscriber = Mage::getModel('newsletter/subscriber')->load(1);
145 | $this->assertNotEquals('guest1@example.com', $subscriber->getSubscriberEmail());
146 |
147 |
148 | $guestQuote = Mage::getModel('sales/quote')->load(2);
149 | $guestQuoteAddress = $guestQuote->getBillingAddress();
150 | $otherGuestQuote = Mage::getModel('sales/quote')->load(3);
151 | $otherGuestQuoteAddress = $otherGuestQuote->getBillingAddress();
152 |
153 | $this->assertNotEquals($guestQuoteAddress->getData('firstname'), $otherGuestQuoteAddress->getData('firstname'));
154 | $this->assertNotEquals($guestQuoteAddress->getData('lastname'), $otherGuestQuoteAddress->getData('lastname'));
155 | $this->assertNotEquals($guestQuoteAddress->getData('company'), $otherGuestQuoteAddress->getData('company'));
156 | $this->assertNotEquals($guestQuoteAddress->getData('city'), $otherGuestQuoteAddress->getData('city'));
157 | $this->assertNotEquals($guestQuoteAddress->getData('street'), $otherGuestQuoteAddress->getData('street'));
158 | $this->assertNotEquals($guestQuoteAddress->getData('telephone'), $otherGuestQuoteAddress->getData('telephone'));
159 | $this->assertNotEquals($guestQuoteAddress->getData('fax'), $otherGuestQuoteAddress->getData('fax'));
160 | $this->assertNotEquals($guestQuoteAddress->getData('vat_id'), $otherGuestQuoteAddress->getData('vat_id'));
161 |
162 | }
163 | }
--------------------------------------------------------------------------------
/src/app/code/community/IntegerNet/Anonymizer/Test/Model/Bridge/Entity/Abstract.php:
--------------------------------------------------------------------------------
1 |
9 | */
10 | abstract class IntegerNet_Anonymizer_Test_Model_Bridge_Entity_Abstract extends EcomDev_PHPUnit_Test_Case
11 | {
12 | /**
13 | * @param $bridge
14 | * @param $expected
15 | */
16 | protected function _testGetValues(IntegerNet_Anonymizer_Model_Bridge_Entity_Abstract $bridge,
17 | Mage_Core_Model_Abstract $model, Varien_Object $expected)
18 | {
19 | $bridge->setRawData($model->getData());
20 | $this->assertEquals($expected['identifier'], $bridge->getIdentifier(), 'Identifier');
21 | $actualValues = $bridge->getValues();
22 | reset($actualValues);
23 | foreach ($expected['values'] as $expectedValue) {
24 | $this->assertInstanceOf(IntegerNet\Anonymizer\AnonymizableValue::__CLASS,
25 | current($actualValues), 'Value instance');
26 | $this->assertEquals($expectedValue['formatter'],
27 | current($actualValues)->getFakerFormatter(), 'Value formatter');
28 | $this->assertEquals($expectedValue['value'],
29 | current($actualValues)->getValue(), 'Value');
30 | if (!empty($expectedValue['unique'])) {
31 | $this->assertTrue(current($actualValues)->isUnique(), 'Unique');
32 | }
33 | next($actualValues);
34 | }
35 | }
36 |
37 | /**
38 | * @param $bridge
39 | */
40 | protected function _updateValues($bridge)
41 | {
42 | $bridge->updateValues();
43 |
44 | $this->assertNotEquals('', $bridge->getIdentifier());
45 | $bridge->clearInstance();
46 | $this->assertEquals('', $bridge->getIdentifier());
47 | foreach ($bridge->getValues() as $value) {
48 | $this->logicalOr(
49 | $this->isEmpty($value->getValue()),
50 | $this->equalTo(array(''))
51 | );
52 | }
53 | }
54 |
55 | /**
56 | * @param $id
57 | * @param $bridge
58 | * @return mixed
59 | */
60 | protected function _loadEntityByCollection($idField, $id, $bridge)
61 | {
62 | $entity = $bridge->getCollectionIterator()->getCollection()
63 | ->addFieldToFilter($idField, $id)
64 | ->getFirstItem();
65 | return $entity;
66 | }
67 | }
--------------------------------------------------------------------------------
/src/app/code/community/IntegerNet/Anonymizer/Test/Model/Bridge/Entity/Customer.php:
--------------------------------------------------------------------------------
1 |
9 | */
10 |
11 | /**
12 | * @group IntegerNet_Anonymizer
13 | */
14 | class IntegerNet_Anonymizer_Test_Model_Bridge_Entity_Customer
15 | extends IntegerNet_Anonymizer_Test_Model_Bridge_Entity_Abstract
16 | {
17 | /**
18 | * @param $customerId
19 | * @test
20 | * @dataProvider dataProvider
21 | * @dataProviderFile testCustomerBridge.yaml
22 | * @loadExpectation bridge.yaml
23 | * @loadFixture customers.yaml
24 | */
25 | public function testGetValues($customerId)
26 | {
27 | /** @var IntegerNet_Anonymizer_Model_Bridge_Entity_Customer $bridge */
28 | $bridge = Mage::getModel('integernet_anonymizer/bridge_entity_customer');
29 | /** @var Mage_Customer_Model_Customer $customer */
30 | $customer = $this->_loadEntityByCollection('entity_id', $customerId, $bridge);
31 | $expected = $this->expected('customer_%d', $customerId);
32 |
33 | $this->_testGetValues($bridge, $customer, $expected);
34 | }
35 |
36 | /**
37 | * @param $customerId
38 | * @test
39 | * @dataProvider dataProvider
40 | * @dataProviderFile testCustomerBridge.yaml
41 | * @loadFixture customers.yaml
42 | */
43 | public function testUpdateValues($customerId)
44 | {
45 | static $changedEmail = 'changed@example.com',
46 | $changedMiddlename = 'trouble';
47 |
48 | /** @var IntegerNet_Anonymizer_Model_Bridge_Entity_Customer $bridge */
49 | $bridge = Mage::getModel('integernet_anonymizer/bridge_entity_customer');
50 |
51 | $bridge->setRawData(array(
52 | 'entity_id' => $customerId,
53 | 'email' => $changedEmail,
54 | 'middlename' => $changedMiddlename
55 | ));
56 |
57 | $this->_updateValues($bridge);
58 |
59 | $customer = Mage::getModel('customer/customer')->load($customerId);
60 | $this->assertEquals($changedMiddlename, $customer->getMiddlename());
61 | $this->assertEquals($changedEmail, $customer->getEmail());
62 | }
63 |
64 | }
--------------------------------------------------------------------------------
/src/app/code/community/IntegerNet/Anonymizer/Test/Model/Bridge/Entity/CustomerAddress.php:
--------------------------------------------------------------------------------
1 |
9 | */
10 |
11 | /**
12 | * @group IntegerNet_Anonymizer
13 | */
14 | class IntegerNet_Anonymizer_Test_Model_Bridge_Entity_CustomerAddress
15 | extends IntegerNet_Anonymizer_Test_Model_Bridge_Entity_Abstract
16 | {
17 | /**
18 | * @param $customerAddressId
19 | * @test
20 | * @dataProvider dataProvider
21 | * @dataProviderFile testCustomerAddressBridge.yaml
22 | * @loadExpectation bridge.yaml
23 | * @loadFixture customers.yaml
24 | */
25 | public function testGetValues($customerAddressId)
26 | {
27 | /** @var IntegerNet_Anonymizer_Model_Bridge_Entity_CustomerAddress $bridge */
28 | $bridge = Mage::getModel('integernet_anonymizer/bridge_entity_address_customerAddress');
29 | /** @var Mage_Customer_Model_Address $customerAddress */
30 | $customerAddress = $this->_loadEntityByCollection('entity_id', $customerAddressId, $bridge);
31 | $expected = $this->expected('customer_address_%d', $customerAddressId);
32 |
33 | $this->_testGetValues($bridge, $customerAddress, $expected);
34 | }
35 |
36 | /**
37 | * @param $customerAddressId
38 | * @test
39 | * @dataProvider dataProvider
40 | * @dataProviderFile testCustomerAddressBridge.yaml
41 | * @loadFixture customers.yaml
42 | */
43 | public function testUpdateValues($customerAddressId)
44 | {
45 | static $changedMiddlename = 'trouble',
46 | $changedStreet = "New Street\nSecond Line";
47 |
48 | /** @var IntegerNet_Anonymizer_Model_Bridge_Entity_Address_CustomerAddress $bridge */
49 | $bridge = Mage::getModel('integernet_anonymizer/bridge_entity_address_customerAddress');
50 |
51 | /** @var Mage_Customer_Model_Address $customerAddress */
52 | $dataProvider = Mage::getModel('customer/address')->load($customerAddressId);
53 | $bridge->setRawData($dataProvider->load($customerAddressId)->getData());
54 | $bridge->getValues()['middlename']->setValue($changedMiddlename);
55 | $bridge->getValues()['street']->setValue($changedStreet);
56 |
57 | $this->_updateValues($bridge);
58 |
59 | $customerAddress = Mage::getModel('customer/address')->load($customerAddressId);
60 | $this->assertEquals($changedMiddlename, $customerAddress->getMiddlename());
61 | $this->assertEquals($changedStreet, $customerAddress->getStreetFull());
62 | }
63 |
64 |
65 | }
--------------------------------------------------------------------------------
/src/app/code/community/IntegerNet/Anonymizer/Test/Model/Bridge/Entity/Giftregistry.php:
--------------------------------------------------------------------------------
1 |
9 | */
10 |
11 | /**
12 | * @group IntegerNet_Anonymizer
13 | */
14 | class IntegerNet_Anonymizer_Test_Model_Bridge_Entity_Giftregistry
15 | extends IntegerNet_Anonymizer_Test_Model_Bridge_Entity_Abstract
16 | {
17 | /**
18 | * @test
19 | */
20 | public function isEnterprise()
21 | {
22 | if (Mage::getEdition() !== Mage::EDITION_ENTERPRISE) {
23 | $this->markTestSkipped('Skipping test for Magento Enterprise');
24 | }
25 | }
26 |
27 | /**
28 | * @param $registryId
29 | * @test
30 | * @depends isEnterprise
31 | * @dataProvider dataProvider
32 | * @dataProviderFile testGiftregistryBridge.yaml
33 | * @loadExpectation bridge.yaml
34 | * @loadFixture customers.yaml
35 | * @loadFixture enterprise.yaml
36 | */
37 | public function testGetValues($registryId)
38 | {
39 | /** @var IntegerNet_Anonymizer_Model_Bridge_Entity_Enterprise_Giftregistry $bridge */
40 | $bridge = Mage::getModel('integernet_anonymizer/bridge_entity_enterprise_giftregistry');
41 | /** @var Enterprise_GiftRegistry_Model_Entity $registry */
42 | $registry = $this->_loadEntityByCollection('entity_id', $registryId, $bridge);
43 | $expected = $this->expected('giftregistry_%d', $registryId);
44 |
45 | $this->_testGetValues($bridge, $registry, $expected);
46 | }
47 |
48 | /**
49 | * @param $registryId
50 | * @test
51 | * @depends isEnterprise
52 | * @dataProvider dataProvider
53 | * @dataProviderFile testGiftregistryBridge.yaml
54 | * @loadFixture customers.yaml
55 | * @loadFixture enterprise.yaml
56 | */
57 | public function testUpdateValues($registryId)
58 | {
59 | static $changedTitle = 'Changed Gift Registry Title';
60 |
61 | /** @var IntegerNet_Anonymizer_Model_Bridge_Entity_Enterprise_Giftregistry $bridge */
62 | $bridge = Mage::getModel('integernet_anonymizer/bridge_entity_enterprise_giftregistry');
63 |
64 | $dataProvider = Mage::getModel('enterprise_giftregistry/entity');
65 | $bridge->setRawData($dataProvider->load($registryId)->setId($registryId)->getData());
66 | $bridge->getValues()['title']->setValue($changedTitle);
67 |
68 | $this->_updateValues($bridge);
69 |
70 | $registry = Mage::getModel('enterprise_giftregistry/entity')->load($registryId);
71 | $this->assertEquals($changedTitle, $registry->getTitle());
72 | }
73 | }
--------------------------------------------------------------------------------
/src/app/code/community/IntegerNet/Anonymizer/Test/Model/Bridge/Entity/GiftregistryPerson.php:
--------------------------------------------------------------------------------
1 |
9 | */
10 |
11 | /**
12 | * @group IntegerNet_Anonymizer
13 | */
14 | class IntegerNet_Anonymizer_Test_Model_Bridge_Entity_GiftregistryPerson
15 | extends IntegerNet_Anonymizer_Test_Model_Bridge_Entity_Abstract
16 | {
17 | /**
18 | * @test
19 | */
20 | public function isEnterprise()
21 | {
22 | if (Mage::getEdition() !== Mage::EDITION_ENTERPRISE) {
23 | $this->markTestSkipped('Skipping test for Magento Enterprise');
24 | }
25 | }
26 |
27 | /**
28 | * @param $personId
29 | * @test
30 | * @depends isEnterprise
31 | * @dataProvider dataProvider
32 | * @dataProviderFile testGiftregistryPersonBridge.yaml
33 | * @loadExpectation bridge.yaml
34 | * @loadFixture customers.yaml
35 | * @loadFixture enterprise.yaml
36 | */
37 | public function testGetValues($personId)
38 | {
39 | /** @var IntegerNet_Anonymizer_Model_Bridge_Entity_Enterprise_GiftregistryPerson $bridge */
40 | $bridge = Mage::getModel('integernet_anonymizer/bridge_entity_enterprise_giftregistryPerson');
41 | /** @var Enterprise_GiftRegistry_Model_Person $person */
42 | $person = $this->_loadEntityByCollection('person_id', $personId, $bridge);
43 | $expected = $this->expected('giftregistry_person_%d', $personId);
44 |
45 | $this->_testGetValues($bridge, $person, $expected);
46 | }
47 |
48 | /**
49 | * @param $registryId
50 | * @test
51 | * @depends isEnterprise
52 | * @dataProvider dataProvider
53 | * @dataProviderFile testGiftregistryPersonBridge.yaml
54 | * @loadFixture customers.yaml
55 | * @loadFixture enterprise.yaml
56 | */
57 | public function testUpdateValues($registryId)
58 | {
59 | static $changedEmail = 'changed@email.com';
60 |
61 | /** @var IntegerNet_Anonymizer_Model_Bridge_Entity_Enterprise_GiftregistryPerson $bridge */
62 | $bridge = Mage::getModel('integernet_anonymizer/bridge_entity_enterprise_giftregistryPerson');
63 |
64 | $dataProvider = Mage::getModel('enterprise_giftregistry/person');;
65 | $bridge->setRawData($dataProvider->load($registryId)->setId($registryId)->getData());
66 | $bridge->getValues()['email']->setValue($changedEmail);
67 |
68 | $this->_updateValues($bridge);
69 |
70 | $person = Mage::getModel('enterprise_giftregistry/person')->load($registryId);
71 | $this->assertEquals($changedEmail, $person->getEmail());
72 | }
73 | }
--------------------------------------------------------------------------------
/src/app/code/community/IntegerNet/Anonymizer/Test/Model/Bridge/Entity/NewsletterSubscriber.php:
--------------------------------------------------------------------------------
1 |
9 | */
10 |
11 | /**
12 | * @group IntegerNet_Anonymizer
13 | */
14 | class IntegerNet_Anonymizer_Test_Model_Bridge_Entity_NewsletterSubscriber
15 | extends IntegerNet_Anonymizer_Test_Model_Bridge_Entity_Abstract
16 | {
17 | /**
18 | * @param $subscriberId
19 | * @test
20 | * @dataProvider dataProvider
21 | * @dataProviderFile testNewsletterSubscriberBridge.yaml
22 | * @loadExpectation bridge.yaml
23 | * @loadFixture customers.yaml
24 | */
25 | public function testGetValues($subscriberId)
26 | {
27 | /** @var IntegerNet_Anonymizer_Model_Bridge_Entity_NewsletterSubscriber $bridge */
28 | $bridge = Mage::getModel('integernet_anonymizer/bridge_entity_newsletterSubscriber');
29 | /** @var Mage_Newsletter_Model_Subscriber $subscriber */
30 | $subscriber = $this->_loadEntityByCollection('subscriber_id', $subscriberId, $bridge);
31 | $expected = $this->expected('newsletter_subscriber_%d', $subscriberId);
32 |
33 | $this->_testGetValues($bridge, $subscriber, $expected);
34 | }
35 |
36 | /**
37 | * @param $subscriberId
38 | * @test
39 | * @dataProvider dataProvider
40 | * @dataProviderFile testNewsletterSubscriberBridge.yaml
41 | * @loadFixture customers.yaml
42 | */
43 | public function testUpdateValues($subscriberId)
44 | {
45 | static $changedEmail = 'changed@example.com';
46 |
47 | /** @var IntegerNet_Anonymizer_Model_Bridge_Entity_NewsletterSubscriber $bridge */
48 | $bridge = Mage::getModel('integernet_anonymizer/bridge_entity_newsletterSubscriber');
49 |
50 | $dataProvider = Mage::getModel('newsletter/subscriber');
51 | $bridge->setRawData($dataProvider->load($subscriberId)->getData());
52 | $bridge->getValues()['subscriber_email']->setValue($changedEmail);
53 |
54 | $this->_updateValues($bridge);
55 |
56 | $subscriber = Mage::getModel('newsletter/subscriber')->load($subscriberId);
57 | $this->assertEquals($changedEmail, $subscriber->getSubscriberEmail());
58 | }
59 | }
--------------------------------------------------------------------------------
/src/app/code/community/IntegerNet/Anonymizer/Test/Model/Bridge/Entity/Order.php:
--------------------------------------------------------------------------------
1 |
9 | */
10 |
11 | /**
12 | * @group IntegerNet_Anonymizer
13 | */
14 | class IntegerNet_Anonymizer_Test_Model_Bridge_Entity_Order
15 | extends IntegerNet_Anonymizer_Test_Model_Bridge_Entity_Abstract
16 | {
17 | /**
18 | * @param $orderId
19 | * @test
20 | * @dataProvider dataProvider
21 | * @dataProviderFile testOrderBridge.yaml
22 | * @loadExpectation bridge.yaml
23 | * @loadFixture customers.yaml
24 | */
25 | public function testGetValues($orderId)
26 | {
27 | /** @var IntegerNet_Anonymizer_Test_Model_Bridge_Entity_Order $bridge */
28 | $bridge = Mage::getModel('integernet_anonymizer/bridge_entity_order');
29 | /** @var Mage_Sales_Model_Order $order */
30 | $order = $this->_loadEntityByCollection('entity_id', $orderId, $bridge);
31 | $expected = $this->expected('order_%d', $orderId);
32 |
33 | $this->_testGetValues($bridge, $order, $expected);
34 | }
35 |
36 | /**
37 | * @param $orderId
38 | * @param $customerId
39 | * @test
40 | * @dataProvider dataProvider
41 | * @dataProviderFile testOrderBridge.yaml
42 | * @loadFixture customers.yaml
43 | */
44 | public function testUpdateValues($orderId, $customerId)
45 | {
46 | static $changedEmail = 'changed@example.com',
47 | $changedMiddlename = 'trouble';
48 |
49 | /** @var IntegerNet_Anonymizer_Model_Bridge_Entity_Order $bridge */
50 | $bridge = Mage::getModel('integernet_anonymizer/bridge_entity_order');
51 |
52 | $bridge->setRawData(array(
53 | 'entity_id' => $orderId,
54 | 'increment_id' => '1000000001',
55 | 'customer_id' => $customerId,
56 | 'customer_email' => $changedEmail,
57 | 'customer_middlename' => $changedMiddlename
58 | ));
59 |
60 | $this->_updateValues($bridge);
61 |
62 | $order = Mage::getModel('sales/order')->load($orderId);
63 | $this->assertEquals($changedMiddlename, $order->getCustomerMiddlename());
64 | $this->assertEquals($changedEmail, $order->getCustomerEmail());
65 | $this->assertNotEmpty($order->getIncrementId(), 'Increment ID should not be empty');
66 | }
67 |
68 | }
--------------------------------------------------------------------------------
/src/app/code/community/IntegerNet/Anonymizer/Test/Model/Bridge/Entity/OrderAddress.php:
--------------------------------------------------------------------------------
1 |
9 | */
10 |
11 | /**
12 | * @group IntegerNet_Anonymizer
13 | */
14 | class IntegerNet_Anonymizer_Test_Model_Bridge_Entity_OrderAddress
15 | extends IntegerNet_Anonymizer_Test_Model_Bridge_Entity_Abstract
16 | {
17 | /**
18 | * @param $orderAddressId
19 | * @test
20 | * @dataProvider dataProvider
21 | * @dataProviderFile testOrderAddressBridge.yaml
22 | * @loadExpectation bridge.yaml
23 | * @loadFixture customers.yaml
24 | */
25 | public function testGetValues($orderAddressId)
26 | {
27 | /** @var IntegerNet_Anonymizer_Model_Bridge_Entity_Address_QuoteAddress $bridge */
28 | $bridge = Mage::getModel('integernet_anonymizer/bridge_entity_address_orderAddress');
29 | /** @var Mage_Sales_Model_Quote_Address $orderAddress */
30 | $orderAddress = $this->_loadEntityByCollection('entity_id', $orderAddressId, $bridge);
31 | $expected = $this->expected('order_address_%d', $orderAddressId);
32 |
33 | $this->_testGetValues($bridge, $orderAddress, $expected);
34 | }
35 |
36 | /**
37 | * @param $orderAddressId
38 | * @test
39 | * @dataProvider dataProvider
40 | * @dataProviderFile testOrderAddressBridge.yaml
41 | * @loadFixture customers.yaml
42 | */
43 | public function testUpdateValues($orderAddressId)
44 | {
45 | static $changedMiddlename = 'trouble',
46 | $changedStreet = "New Street\nSecond Line";
47 |
48 | /** @var IntegerNet_Anonymizer_Model_Bridge_Entity_Address_OrderAddress $bridge */
49 | $bridge = Mage::getModel('integernet_anonymizer/bridge_entity_address_orderAddress');
50 |
51 | $dataProvider = Mage::getModel('sales/order_address');
52 | $bridge->setRawData($dataProvider->load($orderAddressId)->getData());
53 | $bridge->getValues()['middlename']->setValue($changedMiddlename);
54 | $bridge->getValues()['street']->setValue($changedStreet);
55 |
56 | $this->_updateValues($bridge);
57 |
58 | $orderAddress = Mage::getModel('sales/order_address')->load($orderAddressId);
59 | $this->assertEquals($changedMiddlename, $orderAddress->getMiddlename());
60 | $this->assertEquals($changedStreet, $orderAddress->getStreetFull());
61 | }
62 | }
--------------------------------------------------------------------------------
/src/app/code/community/IntegerNet/Anonymizer/Test/Model/Bridge/Entity/QuoteAddress.php:
--------------------------------------------------------------------------------
1 |
9 | */
10 |
11 | /**
12 | * @group IntegerNet_Anonymizer
13 | */
14 | class IntegerNet_Anonymizer_Test_Model_Bridge_Entity_QuoteAddress
15 | extends IntegerNet_Anonymizer_Test_Model_Bridge_Entity_Abstract
16 | {
17 | /**
18 | * @param $quoteAddressId
19 | * @test
20 | * @dataProvider dataProvider
21 | * @dataProviderFile testQuoteAddressBridge.yaml
22 | * @loadExpectation bridge.yaml
23 | * @loadFixture customers.yaml
24 | */
25 | public function testGetValues($quoteAddressId)
26 | {
27 | /** @var IntegerNet_Anonymizer_Model_Bridge_Entity_Address_QuoteAddress $bridge */
28 | $bridge = Mage::getModel('integernet_anonymizer/bridge_entity_address_quoteAddress');
29 | /** @var Mage_Sales_Model_Quote_Address $quoteAddress */
30 | $quoteAddress = $this->_loadEntityByCollection('address_id', $quoteAddressId, $bridge);
31 | $expected = $this->expected('quote_address_%d', $quoteAddressId);
32 |
33 | $this->_testGetValues($bridge, $quoteAddress, $expected);
34 | }
35 |
36 | /**
37 | * @param $quoteAddressId
38 | * @test
39 | * @dataProvider dataProvider
40 | * @dataProviderFile testQuoteAddressBridge.yaml
41 | * @loadFixture customers.yaml
42 | */
43 | public function testUpdateValues($quoteAddressId)
44 | {
45 | static $changedMiddlename = 'trouble',
46 | $changedStreet = "New Street\nSecond Line";
47 |
48 | /** @var IntegerNet_Anonymizer_Model_Bridge_Entity_Address_QuoteAddress $bridge */
49 | $bridge = Mage::getModel('integernet_anonymizer/bridge_entity_address_quoteAddress');
50 |
51 | $dataProvider = Mage::getModel('sales/quote_address');
52 | $bridge->setRawData($dataProvider->load($quoteAddressId)->getData());
53 | $bridge->getValues()['middlename']->setValue($changedMiddlename);
54 | $bridge->getValues()['street']->setValue($changedStreet);
55 |
56 | $this->_updateValues($bridge);
57 |
58 | $quoteAddresss = Mage::getModel('sales/quote_address')->load($quoteAddressId);
59 | $this->assertEquals($changedMiddlename, $quoteAddresss->getMiddlename());
60 | $this->assertEquals($changedStreet, $quoteAddresss->getStreetFull());
61 | }
62 |
63 | }
--------------------------------------------------------------------------------
/src/app/code/community/IntegerNet/Anonymizer/Test/Model/Bridge/Entity/expectations/bridge.yaml:
--------------------------------------------------------------------------------
1 | customer_1:
2 | identifier: '1'
3 | values:
4 | - formatter: safeEmail
5 | value: test@test.de
6 | unique: true
7 | - formatter: firstName
8 | value: Testname
9 | - formatter: lastName
10 | value: Testname
11 | - formatter: firstName
12 | value: J
13 | - formatter: title
14 | value: Kaiser
15 | - formatter: suffix
16 | value: "der Große"
17 | - formatter: randomNumber
18 | value: DE 123456789
19 | customer_address_1:
20 | identifier: '1'
21 | values:
22 | - formatter: firstName
23 | value: Testname
24 | - formatter: lastName
25 | value: Testname
26 | - formatter: firstName
27 | value: J
28 | - formatter: title
29 | value: Kaiser
30 | - formatter: suffix
31 | value: III.
32 | - formatter: company
33 | value: Testfirma
34 | - formatter: city
35 | value: Testingen
36 | - formatter: streetAddress
37 | value: [ Teststraße 42 ]
38 | - formatter: phoneNumber
39 | value: 555-123-1
40 | - formatter: phoneNumber
41 | value: 555-123-2
42 | - formatter: randomNumber
43 | value: DE 123456789
44 | quote_address_1:
45 | identifier: '2'
46 | values:
47 | - formatter: firstName
48 | value: Somebody
49 | - formatter: lastName
50 | value: Else
51 | - formatter: firstName
52 | value:
53 | - formatter: title
54 | value:
55 | - formatter: suffix
56 | value:
57 | - formatter: company
58 | value: ACME GmbH
59 | - formatter: city
60 | value: Buxtehude
61 | - formatter: streetAddress
62 | value: [ Am Arm 1 ]
63 | - formatter: phoneNumber
64 | value: 555-12345
65 | - formatter: phoneNumber
66 | value: 555-12345
67 | - formatter: randomNumber
68 | value: DE 987654321
69 | order_address_1:
70 | identifier: '2'
71 | values:
72 | - formatter: firstName
73 | value: Testname
74 | - formatter: lastName
75 | value: Testname
76 | - formatter: firstName
77 | value: K
78 | - formatter: title
79 | value: Dr. phil.
80 | - formatter: suffix
81 | value:
82 | - formatter: company
83 | value: ACME GmbH
84 | - formatter: city
85 | value: Buxtehude
86 | - formatter: streetAddress
87 | value: [ Am Arm 1 ]
88 | - formatter: phoneNumber
89 | value: 555-12345
90 | - formatter: phoneNumber
91 | value: 555-12345
92 | - formatter: randomNumber
93 | value: DE 987654321
94 | order_1:
95 | identifier: '2'
96 | values:
97 | - formatter: safeEmail
98 | value: test2@test.de
99 | - formatter: firstName
100 | value: Testname
101 | - formatter: lastName
102 | value: Testname
103 | - formatter: firstName
104 | value: J
105 | - formatter: title
106 | value: Kaiser
107 | - formatter: suffix
108 | value: III
109 | - formatter: randomNumber
110 | value: DE 987654321
111 | newsletter_subscriber_1:
112 | identifier: 'guest1@example.com'
113 | values:
114 | - formatter: safeEmail
115 | value: guest1@example.com
116 | newsletter_subscriber_2:
117 | identifier: 'guest2@example.com'
118 | values:
119 | - formatter: safeEmail
120 | value: guest2@example.com
121 | newsletter_subscriber_3:
122 | identifier: '1'
123 | values:
124 | - formatter: safeEmail
125 | value: test@test.de
126 | giftregistry_1:
127 | identifier: '_gift_registry_1'
128 | values:
129 | - formatter: sentence
130 | value: My Gift Registry
131 | - formatter: paragraph
132 | value: My Private Message
133 | - formatter: address
134 | value: Something something somewhere
135 | - formatter: 'null'
136 | value:
137 | foo: 'bar'
138 | giftregistry_person_1:
139 | identifier: 'b.schenkter@example.com'
140 | values:
141 | - formatter: safeEmail
142 | value: b.schenkter@example.com
143 | - formatter: firstName
144 | value: Bernd
145 | - formatter: lastName
146 | value: Schenkter
147 | - formatter: 'null'
148 | value: 'a:1:{s:3:"foo";s:3:"bar";}'
149 |
--------------------------------------------------------------------------------
/src/app/code/community/IntegerNet/Anonymizer/Test/Model/Bridge/Entity/providers/testCustomerAddressBridge.yaml:
--------------------------------------------------------------------------------
1 | customer_address_1:
2 | id: 1
--------------------------------------------------------------------------------
/src/app/code/community/IntegerNet/Anonymizer/Test/Model/Bridge/Entity/providers/testCustomerBridge.yaml:
--------------------------------------------------------------------------------
1 | customer_1:
2 | id: 1
--------------------------------------------------------------------------------
/src/app/code/community/IntegerNet/Anonymizer/Test/Model/Bridge/Entity/providers/testGiftregistryBridge.yaml:
--------------------------------------------------------------------------------
1 | giftregistry_1:
2 | id: 1
--------------------------------------------------------------------------------
/src/app/code/community/IntegerNet/Anonymizer/Test/Model/Bridge/Entity/providers/testGiftregistryPersonBridge.yaml:
--------------------------------------------------------------------------------
1 | giftregistry_person_1:
2 | id: 1
--------------------------------------------------------------------------------
/src/app/code/community/IntegerNet/Anonymizer/Test/Model/Bridge/Entity/providers/testNewsletterSubscriberBridge.yaml:
--------------------------------------------------------------------------------
1 | newsletter_subscriber_1:
2 | id: 1
3 | newsletter_subscriber_2:
4 | id: 2
5 | newsletter_subscriber_3:
6 | id: 3
7 |
--------------------------------------------------------------------------------
/src/app/code/community/IntegerNet/Anonymizer/Test/Model/Bridge/Entity/providers/testOrderAddressBridge.yaml:
--------------------------------------------------------------------------------
1 | order_address_1:
2 | id: 1
--------------------------------------------------------------------------------
/src/app/code/community/IntegerNet/Anonymizer/Test/Model/Bridge/Entity/providers/testOrderBridge.yaml:
--------------------------------------------------------------------------------
1 | order_1:
2 | id: 1
3 | customer_id: 1
--------------------------------------------------------------------------------
/src/app/code/community/IntegerNet/Anonymizer/Test/Model/Bridge/Entity/providers/testQuoteAddressBridge.yaml:
--------------------------------------------------------------------------------
1 | quote_address_1:
2 | id: 1
--------------------------------------------------------------------------------
/src/app/code/community/IntegerNet/Anonymizer/Test/fixtures/customers.yaml:
--------------------------------------------------------------------------------
1 | eav:
2 | customer:
3 | - entity_id: 1
4 | website_id: 1
5 | increment_id: 1000000001
6 | email: test@test.de
7 | firstname: Testname
8 | lastname: Testname
9 | middlename: J
10 | prefix: Kaiser
11 | suffix: "der Große"
12 | taxvat: DE 123456789
13 | group_id: 1
14 | store_id: 1
15 | is_active: 1
16 | attribute_set_id: 0
17 | default_billing: 1
18 | default_shipping: 2
19 | - entity_id: 2
20 | website_id: 1
21 | increment_id: 1000000002
22 | email: test2@test.de
23 | firstname: Testname
24 | lastname: Testname
25 | middlename: K
26 | prefix: Dr. phil.
27 | suffix:
28 | group_id: 1
29 | store_id: 1
30 | is_active: 1
31 | attribute_set_id: 0
32 | default_billing: 4
33 | default_shipping: 4
34 | - entity_id: 3
35 | website_id: 1
36 | increment_id: 1000000003
37 | email: test3@test.de
38 | firstname: Test
39 | lastname: Test
40 | group_id: 1
41 | store_id: 1
42 | is_active: 1
43 | attribute_set_id: 0
44 | customer_address:
45 | - entity_id: 1
46 | parent_id: 1
47 | attribute_set_id: 0
48 | is_default_billing: 1
49 | firstname: Testname
50 | lastname: Testname
51 | middlename: J
52 | prefix: Kaiser
53 | suffix: III.
54 | company: Testfirma
55 | postcode: 12345
56 | city: Testingen
57 | street: Teststraße 42
58 | telephone: 555-123-1
59 | fax: 555-123-2
60 | vat_id: DE 123456789
61 | country_id: DE
62 | region_id: 88
63 | - entity_id: 2
64 | parent_id: 1
65 | attribute_set_id: 0
66 | is_default_shipping: 1
67 | firstname: Testname
68 | lastname: Testname
69 | middlename: J
70 | prefix: Kaiser
71 | suffix: III.
72 | company: Testfirma
73 | postcode: 12345
74 | city: Anderswo
75 | street: Testweg 3
76 | telephone: (0)555-123-11
77 | fax: (0)555-123-12
78 | vat_id: DE 123456789
79 | country_id: DE
80 | region_id: 88
81 | - entity_id: 3
82 | parent_id: 1
83 | attribute_set_id: 0
84 | - entity_id: 4
85 | parent_id: 2
86 | attribute_set_id: 0
87 | is_default_billing: 1
88 | is_default_shipping: 1
89 | firstname: Testname
90 | lastname: Testname
91 | middlename: K
92 | prefix: Dr. phil.
93 | suffix:
94 | company: ACME GmbH
95 | postcode: 67890
96 | city: Buxtehude
97 | street: Am Arm 1
98 | telephone: 555-12345
99 | fax: 555-12345
100 | vat_id: DE 987654321
101 | country_id: DE
102 | region_id: 88
103 |
104 | tables:
105 | sales/quote:
106 | - entity_id: 1
107 | customer_id: 2
108 | - entity_id: 2
109 | customer_id: null
110 | - entity_id: 3
111 | customer_id: null
112 | sales/order:
113 | - entity_id: 1
114 | increment_id: 1000000001
115 | quote_id: 1
116 | billing_address_id: 1
117 | customer_id: 2
118 | customer_email: test2@test.de
119 | customer_firstname: Testname
120 | customer_lastname: Testname
121 | customer_middlename: J
122 | customer_prefix: Kaiser
123 | customer_suffix: III
124 | customer_taxvat: DE 987654321
125 | - entity_id: 2
126 | increment_id: 1000000002
127 | quote_id: 2
128 | billing_address_id: 2
129 | customer_email: guest@guest.de
130 | customer_firstname: Gast
131 | customer_lastname: Gast
132 | sales/order_grid:
133 | - entity_id: 1
134 | increment_id: 1000000001
135 | customer_id: 2
136 | shipping_name: Testname Testname
137 | billing_name: Testname Testname
138 | #TODO invoice, creditmemo
139 | sales/quote_address:
140 | - address_id: 1
141 | address_type: billing
142 | quote_id: 1
143 | customer_id: 2
144 | customer_address_id: 4
145 | firstname: Somebody
146 | lastname: Else
147 | middlename:
148 | prefix:
149 | suffix:
150 | company: ACME GmbH
151 | postcode: 67890
152 | city: Buxtehude
153 | street: Am Arm 1
154 | telephone: 555-12345
155 | fax: 555-12345
156 | vat_id: DE 987654321
157 | country_id: DE
158 | region_id: 88
159 | - address_id: 2
160 | address_type: billing
161 | quote_id: 2
162 | customer_id: null
163 | customer_address_id: null
164 | firstname: Gast
165 | lastname: Gast
166 | middlename:
167 | prefix:
168 | suffix:
169 | company: Gastro
170 | postcode: 111222
171 | city: Gastdorf
172 | street: Gaststraße 1
173 | telephone:
174 | fax:
175 | vat_id:
176 | country_id: DE
177 | region_id: 88
178 | - address_id: 3
179 | address_type: billing
180 | quote_id: 3
181 | customer_id: null
182 | customer_address_id: null
183 | firstname: Anderer
184 | lastname: Gast
185 | middlename:
186 | prefix:
187 | suffix:
188 | company:
189 | postcode: 333444
190 | city: Gastburg
191 | street: Gastweg 2
192 | telephone:
193 | fax:
194 | vat_id:
195 | country_id: DE
196 | region_id: 89
197 | sales/order_address:
198 | - entity_id: 1
199 | address_type: billing
200 | parent_id: 1
201 | customer_id: 2
202 | customer_address_id: 4
203 | firstname: Testname
204 | lastname: Testname
205 | middlename: K
206 | prefix: Dr. phil.
207 | suffix:
208 | company: ACME GmbH
209 | postcode: 67890
210 | city: Buxtehude
211 | street: Am Arm 1
212 | telephone: 555-12345
213 | fax: 555-12345
214 | vat_id: DE 987654321
215 | country_id: DE
216 | region_id: 88
217 | - entity_id: 2
218 | address_type: billing
219 | parent_id: 2
220 | customer_id: null
221 | customer_address_id: null
222 | firstname: Gast
223 | lastname: Gast
224 | middlename:
225 | prefix:
226 | suffix:
227 | company: Gastro
228 | postcode: 111222
229 | city: Gastdorf
230 | street: Gaststraße 1
231 | telephone:
232 | fax:
233 | vat_id:
234 | country_id: DE
235 | region_id: 88
236 | sales/quote_item: []
237 | sales/order_item: []
238 | newsletter/subscriber:
239 | - subscriber_id: 1
240 | customer_id: 0
241 | subscriber_email: guest1@example.com
242 | - subscriber_id: 2
243 | customer_id: 0
244 | subscriber_email: guest2@example.com
245 | - subscriber_id: 3
246 | customer_id: 1
247 | subscriber_email: test@test.de
248 |
--------------------------------------------------------------------------------
/src/app/code/community/IntegerNet/Anonymizer/Test/fixtures/enterprise.yaml:
--------------------------------------------------------------------------------
1 | tables:
2 | enterprise_giftregistry/entity:
3 | - entity_id: 1
4 | type_id: 1
5 | customer_id: 2
6 | title: My Gift Registry
7 | message: My Private Message
8 | shipping_address: Something something somewhere
9 | custom_values: 'a:1:{s:3:"foo";s:3:"bar";}'
10 | enterprise_giftregistry/person:
11 | - person_id: 1
12 | entity_id: 1
13 | firstname: Bernd
14 | lastname: Schenkter
15 | email: b.schenkter@example.com
16 | custom_values: 'a:1:{s:3:"foo";s:3:"bar";}'
--------------------------------------------------------------------------------
/src/app/code/community/IntegerNet/Anonymizer/etc/config.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | 1.0.0
6 |
7 |
8 |
9 |
10 |
11 | IntegerNet_Anonymizer_Model
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 | integernet_anonymizer/bridge_entity_customer
22 | 100
23 |
24 |
25 | integernet_anonymizer/bridge_entity_address_customerAddress
26 | 200
27 |
28 |
29 | integernet_anonymizer/bridge_entity_address_quoteAddress
30 | 300
31 |
32 |
33 | integernet_anonymizer/bridge_entity_address_orderAddress
34 | 400
35 |
36 |
37 | integernet_anonymizer/bridge_entity_newsletterSubscriber
38 | 500
39 |
40 |
41 | integernet_anonymizer/bridge_entity_enterprise_giftregistry
42 | 600
43 |
44 |
45 | integernet_anonymizer/bridge_entity_enterprise_giftregistryPerson
46 | 700
47 |
48 |
49 |
50 | integernet_anonymizer/bridge_entity_order
51 | 800
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
--------------------------------------------------------------------------------
/src/app/etc/modules/IntegerNet_Anonymizer.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | true
6 | community
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/src/lib/IntegerNet/Anonymizer/AnonymizableValue.php:
--------------------------------------------------------------------------------
1 |
9 | */
10 |
11 | namespace IntegerNet\Anonymizer;
12 |
13 |
14 | class AnonymizableValue
15 | {
16 | const __CLASS = __CLASS__;
17 | /**
18 | * @var string
19 | */
20 | private $formatter;
21 | /**
22 | * @var string
23 | */
24 | private $value;
25 | /**
26 | * @var bool
27 | */
28 | private $unique;
29 |
30 | public function __construct($formatter, $value, $unique = false)
31 | {
32 | $this->formatter = $formatter;
33 | $this->value = $value;
34 | $this->unique = (bool) $unique;
35 | }
36 | /**
37 | * @return string
38 | */
39 | public function getFakerFormatter()
40 | {
41 | return $this->formatter;
42 | }
43 |
44 | /**
45 | * If the value is optional, returns probability of presence.
46 | * 1.0 = not optional
47 | * 0.0 = always empty
48 | *
49 | * @return float
50 | */
51 | public function getOptionalWeight()
52 | {
53 | //TODO use this
54 | //TODO or add a FakerFormatterOptions property for more customizability
55 | return 1.0;
56 | }
57 |
58 | public function isUnique()
59 | {
60 | return $this->unique;
61 | }
62 |
63 | /**
64 | * @return mixed
65 | */
66 | public function getValue()
67 | {
68 | return $this->value;
69 | }
70 |
71 | /**
72 | * @param mixed $value
73 | * @return void
74 | */
75 | public function setValue($value)
76 | {
77 | $this->value = $value;
78 | }
79 | }
--------------------------------------------------------------------------------
/src/lib/IntegerNet/Anonymizer/Anonymizer.php:
--------------------------------------------------------------------------------
1 | provider = $provider;
32 | $this->provider->initialize($locale);
33 | }
34 |
35 | /**
36 | * @param AnonymizableEntity[] $inputData
37 | */
38 | public function anonymize(array $inputData)
39 | {
40 | foreach ($inputData as $entity) {
41 | foreach ($entity->getValues() as $value) {
42 | $value->setValue($this->provider->getFakerData(
43 | $value->getFakerFormatter(), $this->_getFieldIdentifier($entity, $value), $value->isUnique()));
44 | }
45 | }
46 | }
47 |
48 | /**
49 | * Returns identifier for a field, based on entity and current value. This is used to map real data to fake
50 | * data in the same way for each unique entity identifier (i.e. customer id)
51 | *
52 | * @param AnonymizableEntity $entity
53 | * @param AnonymizableValue $value
54 | * @return string
55 | */
56 | private function _getFieldIdentifier(AnonymizableEntity $entity, AnonymizableValue $value)
57 | {
58 | return sprintf('%s|%s', $entity->getIdentifier(), join('', (array)$value->getValue()));
59 | }
60 |
61 | public function resetUniqueGenerator()
62 | {
63 | $this->provider->resetUniqueGenerator();
64 | }
65 | }
--------------------------------------------------------------------------------
/src/lib/IntegerNet/Anonymizer/Implementor/AnonymizableEntity.php:
--------------------------------------------------------------------------------
1 |
9 | */
10 |
11 | namespace IntegerNet\Anonymizer\Implementor;
12 |
13 |
14 | use IntegerNet\Anonymizer\AnonymizableValue;
15 |
16 | interface AnonymizableEntity
17 | {
18 | /**
19 | * Returns name of entity as translatable string
20 | *
21 | * @return string
22 | */
23 | function getEntityName();
24 | /**
25 | * Returns identifier, for example the customer email address. Entities with the same identifier will get the same
26 | * anonymized values.
27 | *
28 | * Important: The return value must not be affected by anonymization!
29 | *
30 | * @return string
31 | */
32 | function getIdentifier();
33 |
34 | /**
35 | * Returns anonymizable value objects as array with attribute codes as keys
36 | *
37 | * @return AnonymizableValue[]
38 | */
39 | function getValues();
40 |
41 | /**
42 | * Sets raw data from database
43 | *
44 | * @param string[] $data
45 | * @return void
46 | */
47 | function setRawData($data);
48 |
49 | /**
50 | * Update values in database
51 | *
52 | * @return void
53 | */
54 | function updateValues();
55 |
56 | /**
57 | * Reset to empty instance
58 | *
59 | * @return void
60 | */
61 | function clearInstance();
62 |
63 | }
--------------------------------------------------------------------------------
/src/lib/IntegerNet/Anonymizer/Implementor/CollectionIterator.php:
--------------------------------------------------------------------------------
1 |
9 | */
10 |
11 | namespace IntegerNet\Anonymizer\Implementor;
12 |
13 |
14 | interface CollectionIterator
15 | {
16 |
17 | /**
18 | * @param callable $callable
19 | * @return mixed
20 | */
21 | function walk(/*callable*/ $callable);
22 |
23 | /**
24 | * Returns raw data from database
25 | *
26 | * @return mixed
27 | */
28 | function getRawData();
29 |
30 | /**
31 | * Returns number of iteration
32 | *
33 | * @return int
34 | */
35 | function getIteration();
36 |
37 | /**
38 | * Returns total size of collection
39 | *
40 | * @return mixed
41 | */
42 | function getSize();
43 | }
--------------------------------------------------------------------------------
/src/lib/IntegerNet/Anonymizer/Provider.php:
--------------------------------------------------------------------------------
1 |
9 | */
10 |
11 | namespace IntegerNet\Anonymizer;
12 |
13 |
14 | use Faker\Factory;
15 |
16 | class Provider
17 | {
18 | const __CLASS = __CLASS__;
19 |
20 | /**
21 | * @var \Faker\Generator
22 | */
23 | private $faker;
24 |
25 | private $salt;
26 |
27 | /**
28 | * Initializes Faker, generates new salt for RNG seeds
29 | *
30 | * @param string|null $locale
31 | * @return void
32 | */
33 | public function initialize($locale = null)
34 | {
35 | if ($locale === null) {
36 | $locale = Factory::DEFAULT_LOCALE;
37 | }
38 | $this->faker = Factory::create($locale);
39 | $this->salt = sha1(uniqid('', true));
40 | }
41 |
42 | /**
43 | * Resets the UniqueGenerator of Faker, this should be used after anonymizing a database table with
44 | * unique values to free memory and allow the same values in other tables
45 | *
46 | * @return void
47 | */
48 | public function resetUniqueGenerator()
49 | {
50 | $this->faker->unique(true);
51 | }
52 |
53 | /**
54 | * Return fake data from given Faker provider, always return the same data for each ($formatter, $identifier)
55 | * combination after initialized.
56 | *
57 | * @param $formatter
58 | * @param $identifier
59 | * @return mixed
60 | */
61 | public function getFakerData($formatter, $identifier, $unique = false)
62 | {
63 | $faker = $this->faker;
64 | if ($formatter === 'null') {
65 | return $faker->optional(0)->randomDigit;
66 | }
67 | if ($unique) {
68 | $faker = $faker->unique();
69 | }
70 | $this->seedRng($formatter.$identifier);
71 | $result = $faker->format($formatter);
72 | $this->resetRng();
73 | return $result;
74 | }
75 |
76 | /**
77 | * @param $identifier
78 | */
79 | private function seedRng($identifier)
80 | {
81 | $this->faker->seed(hexdec(hash("crc32b", $identifier . $this->salt)));
82 | }
83 |
84 | private function resetRng()
85 | {
86 | //$this->faker->seed();
87 | //TODO use above as soon as pr 543 has been merged
88 | mt_srand();
89 | }
90 | }
--------------------------------------------------------------------------------
/src/lib/IntegerNet/Anonymizer/Updater.php:
--------------------------------------------------------------------------------
1 |
9 | */
10 | namespace IntegerNet\Anonymizer;
11 |
12 | use IntegerNet\Anonymizer\Implementor\AnonymizableEntity;
13 | use IntegerNet\Anonymizer\Implementor\CollectionIterator;
14 |
15 | class Updater
16 | {
17 | const __CLASS = __CLASS__;
18 |
19 | /**
20 | * @var Anonymizer
21 | */
22 | private $anonymizer;
23 | /**
24 | * @var null|resource
25 | */
26 | private $outputStream = null;
27 | /**
28 | * @var bool
29 | */
30 | private $showProgress = true;
31 | /**
32 | * @var int
33 | */
34 | private $progressSteps = 1;
35 |
36 | /**
37 | * @var AnonymizableEntity
38 | */
39 | private $entityModel;
40 |
41 | public function __construct(Anonymizer $anonymizer)
42 | {
43 | $this->anonymizer = $anonymizer;
44 | }
45 | /**
46 | * @param null|resource $stream writable stream resource or null if no output required
47 | */
48 | public function setOutputStream($stream)
49 | {
50 | $this->outputStream = $stream;
51 | }
52 |
53 | /**
54 | * @param boolean $showProgress
55 | */
56 | public function setShowProgress($showProgress)
57 | {
58 | $this->showProgress = $showProgress;
59 | }
60 |
61 | /**
62 | * @param int $progressSteps
63 | */
64 | public function setProgressSteps($progressSteps)
65 | {
66 | $this->progressSteps = $progressSteps;
67 | }
68 |
69 | public function update(CollectionIterator $iterator, AnonymizableEntity $entityModel)
70 | {
71 | $this->entityModel = $entityModel;
72 | $this->outputStart();
73 | $iterator->walk(array($this, 'updateCurrentRow'));
74 | $this->anonymizer->resetUniqueGenerator();
75 | $this->outputDone();
76 | $this->entityModel = null;
77 | }
78 |
79 | /**
80 | * @param CollectionIterator $iterator
81 | */
82 | public function updateCurrentRow(CollectionIterator $iterator)
83 | {
84 | $this->entityModel->setRawData($iterator->getRawData());
85 | $this->anonymizer->anonymize(array($this->entityModel));
86 | $this->entityModel->updateValues();
87 | $this->entityModel->clearInstance();
88 | $this->outputIteratorStatus($iterator);
89 | }
90 |
91 | private function outputStart()
92 | {
93 | if (is_resource($this->outputStream) && get_resource_type($this->outputStream) === 'stream') {
94 | fwrite($this->outputStream, sprintf("Updater started at %s.\n", date('H:i:s')));
95 | }
96 | }
97 |
98 | /**
99 | * @param CollectionIterator $iterator
100 | */
101 | private function outputIteratorStatus(CollectionIterator $iterator)
102 | {
103 | if ($this->showProgress && (($iterator->getIteration() + 1) % $this->progressSteps === 0)
104 | && is_resource($this->outputStream) && get_resource_type($this->outputStream) === 'stream'
105 | ) {
106 | fwrite($this->outputStream, sprintf("\rUpdating %s: %s/%s - Memory usage %s Bytes",
107 | $this->entityModel->getEntityName(),
108 | str_pad($iterator->getIteration() + 1, strlen($iterator->getSize()), ' '), $iterator->getSize(),
109 | number_format(memory_get_usage())));
110 | }
111 | }
112 |
113 | private function outputDone()
114 | {
115 | if (is_resource($this->outputStream) && get_resource_type($this->outputStream) === 'stream') {
116 | fwrite($this->outputStream, sprintf("\nUpdater finished at %s.\n\n", date('H:i:s')));
117 | }
118 | }
119 | }
--------------------------------------------------------------------------------
/src/lib/n98-magerun/modules/IntegerNet_Anonymizer/n98-magerun.yaml:
--------------------------------------------------------------------------------
1 | autoloaders:
2 | IntegerNet\Anonymizer\AnonymizeCommand: %module%/src
3 |
4 | commands:
5 | customCommands:
6 | - IntegerNet\Anonymizer\AnonymizeCommand
--------------------------------------------------------------------------------
/src/lib/n98-magerun/modules/IntegerNet_Anonymizer/src/IntegerNet/Anonymizer/AnonymizeCommand.php:
--------------------------------------------------------------------------------
1 |
9 | */
10 |
11 | namespace IntegerNet\Anonymizer;
12 |
13 | use N98\Magento\Command\AbstractMagentoCommand;
14 | use Symfony\Component\Console\Input\InputInterface;
15 | use Symfony\Component\Console\Output\OutputInterface;
16 | use Symfony\Component\Console\Output\StreamOutput;
17 |
18 | class AnonymizeCommand extends AbstractMagentoCommand
19 | {
20 | protected function configure()
21 | {
22 | $this
23 | ->setName('db:anonymize')
24 | ->setDescription('Anonymize customer data');
25 | }
26 |
27 | /**
28 | * @param \Symfony\Component\Console\Input\InputInterface $input
29 | * @param \Symfony\Component\Console\Output\OutputInterface $output
30 | * @return int|void
31 | */
32 | protected function execute(InputInterface $input, OutputInterface $output)
33 | {
34 | $this->detectMagento($output, true);
35 | if ($this->initMagento()) {
36 | $this->registerPsr0Autoloader();
37 | /** @var \IntegerNet_Anonymizer_Model_Anonymizer $anonymizer */
38 | $anonymizer = \Mage::getModel('integernet_anonymizer/anonymizer');
39 | if ($output instanceof StreamOutput) {
40 | $anonymizer->setOutputStream($output->getStream());
41 | } else {
42 | //TODO allow OutputInterface in Anonymizer?
43 | //TODO pass ansi/no-ansi configuration to Anonymizer and use colors
44 | ob_start();
45 | $anonymizer->setOutputStream(STDOUT);
46 | $output->write(ob_get_clean());
47 | }
48 | $anonymizer->anonymizeAll();
49 | }
50 | }
51 | private function registerPsr0Autoloader()
52 | {
53 | \Mage::getConfig()->init()->loadEventObservers('global');
54 | \Mage::app()->addEventArea('global');
55 | \Mage::dispatchEvent('add_spl_autoloader');
56 | }
57 | }
--------------------------------------------------------------------------------
/src/shell/anonymize.php:
--------------------------------------------------------------------------------
1 |
9 | */
10 |
11 | require_once 'abstract.php';
12 | require_once 'autoloader_initializer.php';
13 |
14 | class IntegerNet_Anonymizer_Shell extends AutoloaderInitializer
15 | {
16 | /**
17 | * Run script
18 | */
19 | public function run()
20 | {
21 | ini_set('memory_limit', '1024M');
22 | /** @var IntegerNet_Anonymizer_Model_Anonymizer $anonymizer */
23 | $anonymizer = Mage::getModel('integernet_anonymizer/anonymizer');
24 | $anonymizer->setOutputStream(STDOUT);
25 | $anonymizer->setShowProgress((bool) $this->getArg('progress'));
26 | $anonymizer->setProgressSteps((int) $this->getArg('progress'));
27 | $anonymizer->anonymizeAll();
28 | }
29 |
30 | public function usageHelp()
31 | {
32 | return <<run();
--------------------------------------------------------------------------------
/test/IntegerNet/Anonymizer/AnonymizerTest.php:
--------------------------------------------------------------------------------
1 | getMock(Provider::__CLASS);
23 | $provider->expects($this->once())->method('initialize');
24 | $provider->expects($this->exactly(count($expectedValues)))->method('getFakerData')
25 | ->willReturnCallback(function($formatter, $identifier) {
26 | return sprintf('%s_%s', $formatter, explode('|', $identifier, 2)[0]);
27 | });
28 |
29 | $anonymizer = new Anonymizer($provider, 'de_DE');
30 | $anonymizer->anonymize($inputData);
31 |
32 | reset($expectedValues);
33 | /** @var AnonymizableMock $anonymizedEntity */
34 | foreach ($inputData as $anonymizedEntity) {
35 | foreach ($anonymizedEntity->getValues() as $anonymizedValue) {
36 | $this->assertEquals(current($expectedValues), $anonymizedValue->getValue());
37 | next($expectedValues);
38 | }
39 | }
40 | }
41 |
42 | /**
43 | * Provider::getFakerData() should be called with
44 | * - identifier as combination of entity identifier and current value
45 | * - unique key parameter for values marked as unique
46 | *
47 | * @test
48 | */
49 | public function testGetFakerDataParameters()
50 | {
51 | $provider = $this->getMock(Provider::__CLASS);
52 | $provider->expects($this->once())->method('initialize');
53 | $provider->expects($this->exactly(2))->method('getFakerData')
54 | ->withConsecutive(
55 | array('email', 'email@example.com|email@example.com', true),
56 | array('name', 'email@example.com|Mr. Email', false));
57 |
58 | $anonymizer = new Anonymizer($provider, 'de_DE');
59 | $anonymizer->anonymize([new AnonymizableMock(['email' => 'email@example.com', 'name' => 'Mr. Email'], 'email')]);
60 |
61 | }
62 |
63 | public static function getAnonymizableData()
64 | {
65 | return array(
66 | array(
67 | 'inputData' => array(
68 | new AnonymizableMock(['email' => 'max.mustermann@example.com', 'firstName' => 'Max', 'lastName' => 'Mustermann']),
69 | new AnonymizableMock(['email' => 'max.mustermann2@example.com', 'firstName' => 'Max', 'lastName' => 'Mustermann']),
70 | new AnonymizableMock(['email' => 'maxi.musterfrau@example.com', 'firstName' => 'Maxi', 'lastName' => 'Musterfrau']),
71 | new AnonymizableMock(['email' => 'max.mustermann@example.com', 'firstName' => 'Max', 'lastName' => 'Mustermann', 'streetAddress' => 'Musterstraße 42']),
72 | ),
73 | 'expectedValues' => array(
74 | 'email_max.mustermann@example.com', 'firstName_max.mustermann@example.com', 'lastName_max.mustermann@example.com',
75 | 'email_max.mustermann2@example.com', 'firstName_max.mustermann2@example.com', 'lastName_max.mustermann2@example.com',
76 | 'email_maxi.musterfrau@example.com', 'firstName_maxi.musterfrau@example.com', 'lastName_maxi.musterfrau@example.com',
77 | 'email_max.mustermann@example.com', 'firstName_max.mustermann@example.com', 'lastName_max.mustermann@example.com', 'streetAddress_max.mustermann@example.com'
78 | )
79 | )
80 | );
81 | }
82 | }
83 |
--------------------------------------------------------------------------------
/test/IntegerNet/Anonymizer/Mock/AnonymizableMock.php:
--------------------------------------------------------------------------------
1 |
9 | */
10 |
11 | namespace IntegerNet\Anonymizer\Mock;
12 |
13 |
14 | use IntegerNet\Anonymizer\Implementor\AnonymizableEntity;
15 | use IntegerNet\Anonymizer\AnonymizableValue;
16 |
17 | /**
18 | * Dumb implementation of AnonymizableEntity that generates AnonymizableValue instances from test data
19 | *
20 | * @package IntegerNet\Anonymizer\Mock
21 | */
22 | class AnonymizableMock implements AnonymizableEntity
23 | {
24 | const __CLASS = __CLASS__;
25 |
26 | private $data = array();
27 | private $identifier = '';
28 | private $uniqueKey = null;
29 |
30 | /**
31 | * @param mixed[] $data data in the form [formatter => value], the first entry will be used as identifier
32 | * @param string|null $uniqueKey
33 | */
34 | function __construct($data = array(), $uniqueKey = null)
35 | {
36 | $this->uniqueKey = $uniqueKey;
37 | $this->setRawData($data);
38 | }
39 |
40 | /**
41 | * @return string
42 | */
43 | function getIdentifier()
44 | {
45 | return $this->identifier;
46 | }
47 |
48 | /**
49 | * @return AnonymizableValue[]
50 | */
51 | function getValues()
52 | {
53 | return $this->data;
54 | }
55 |
56 | /**
57 | * Sets raw data from database
58 | *
59 | * @param string[] $data
60 | * @return void
61 | */
62 | function setRawData($data)
63 | {
64 | foreach ($data as $key => $value) {
65 | $this->data[] = new AnonymizableValue($key, $value, $this->uniqueKey === $key);
66 | }
67 | if (!empty($this->data)) {
68 | $this->identifier = reset($this->data)->getValue();
69 | }
70 | }
71 |
72 | /**
73 | * Update values in database
74 | *
75 | * @return mixed
76 | */
77 | function updateValues()
78 | {
79 | // method stub. Should be mocked with PHPUnit to set expectations
80 | }
81 |
82 | /**
83 | * Reset to empty instance
84 | *
85 | * @return mixed
86 | */
87 | function clearInstance()
88 | {
89 | $this->data = array();
90 | $this->identifier = '';
91 | }
92 |
93 | /**
94 | * Returns name of entity as translatable string
95 | *
96 | * @return string
97 | */
98 | function getEntityName()
99 | {
100 | return 'Mock';
101 | }
102 |
103 | }
104 |
--------------------------------------------------------------------------------
/test/IntegerNet/Anonymizer/Mock/CollectionMock.php:
--------------------------------------------------------------------------------
1 |
9 | */
10 |
11 | namespace IntegerNet\Anonymizer\Mock;
12 |
13 |
14 | use IntegerNet\Anonymizer\Implementor\CollectionIterator;
15 |
16 | /**
17 | * Dumb implementation of CollectionIterator that iterates over an array of data
18 | *
19 | * @package IntegerNet\Anonymizer\Mock
20 | */
21 | class CollectionMock extends \ArrayIterator implements CollectionIterator
22 | {
23 | const __CLASS = __CLASS__;
24 |
25 | /**
26 | * @param callable $callable
27 | * @return mixed
28 | */
29 | function walk(/*callable*/ $callable)
30 | {
31 | foreach ($this as $row) {
32 | $callable($this);
33 | }
34 | }
35 |
36 | /**
37 | * Returns raw data from database
38 | *
39 | * @return mixed
40 | */
41 | function getRawData()
42 | {
43 | return $this->current();
44 | }
45 |
46 | /**
47 | * Returns number of iteration
48 | *
49 | * @return int
50 | */
51 | function getIteration()
52 | {
53 | return $this->key();
54 | }
55 |
56 | /**
57 | * Returns total size of collection
58 | *
59 | * @return mixed
60 | */
61 | function getSize()
62 | {
63 | return $this->count();
64 | }
65 |
66 | }
--------------------------------------------------------------------------------
/test/IntegerNet/Anonymizer/ProviderTest.php:
--------------------------------------------------------------------------------
1 |
9 | */
10 |
11 | namespace IntegerNet\Anonymizer;
12 |
13 |
14 | class ProviderTest extends \PHPUnit_Framework_TestCase
15 | {
16 | public function testDeterministicValues()
17 | {
18 | $provider = new Provider();
19 | $provider->initialize('de_DE');
20 | $aName = $provider->getFakerData('name', 'a@example.com');
21 | $aRandomNumber = mt_rand();
22 | $aDifferentName = $provider->getFakerData('name', 'b@example.com');
23 | $aSameName = $provider->getFakerData('name', 'a@example.com');
24 | $this->assertNotEquals($aName, $aDifferentName, 'Name should be different for different identifier (email address)');
25 | $this->assertEquals($aName, $aSameName, 'Name should be equal for same identifier (email address)');
26 | $this->assertNotEquals($aRandomNumber, mt_rand(), 'The provider should not have side effects on mt_rand.');
27 |
28 | $provider->initialize('de_DE');
29 | $aNameAfterReinitialize = $provider->getFakerData('name', 'a@example.com');
30 | $this->assertNotEquals($aName, $aNameAfterReinitialize, 'Names should be different each anonymization process.');
31 | }
32 | public function testNullFormatter()
33 | {
34 | $provider = new Provider();
35 | $provider->initialize('de_DE');
36 | $nulledData = $provider->getFakerData('null', 'a@example.com');
37 | $this->assertEquals(null, $nulledData);
38 | }
39 | public function testUniqueData()
40 | {
41 | $provider = new Provider();
42 | $provider->initialize('de_DE');
43 | $randomDigits = array();
44 | for ($d = 0; $d < 10; ++$d) {
45 | $randomDigits[] = $provider->getFakerData('randomDigit', 'a@example.com', true);
46 | }
47 | sort($randomDigits);
48 | $this->assertEquals(range(0,9), $randomDigits, '10 unique digits should be all from 0..9');
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/test/IntegerNet/Anonymizer/UpdaterTest.php:
--------------------------------------------------------------------------------
1 |
9 | */
10 |
11 | namespace IntegerNet\Anonymizer;
12 |
13 |
14 | use IntegerNet\Anonymizer\Mock\AnonymizableMock;
15 | use IntegerNet\Anonymizer\Mock\CollectionMock;
16 |
17 | class UpdaterTest extends \PHPUnit_Framework_TestCase
18 | {
19 | /**
20 | * @var Anonymizer|\PHPUnit_Framework_MockObject_MockObject
21 | */
22 | private $anonymizerMock;
23 | /**
24 | * @var Updater
25 | */
26 | private $updater;
27 |
28 | protected function setUp()
29 | {
30 | $this->anonymizerMock = $this->getMock(Anonymizer::__CLASS, array('anonymize', 'resetUniqueGenerator'), array(), '', false);
31 | $this->updater = new Updater($this->anonymizerMock);
32 | }
33 |
34 | /**
35 | * @test
36 | * @dataProvider getCollectionData
37 | */
38 | public function testUpdater($collectionData)
39 | {
40 | $entityCount = count($collectionData);
41 |
42 | $this->anonymizerMock->expects($this->exactly(1))->method('resetUniqueGenerator');
43 | $this->anonymizerMock->expects($this->exactly($entityCount))->method('anonymize');
44 |
45 | $entityModel = $this->getEntityMock();
46 | foreach ($collectionData as $i => $entityData) {
47 | $entityModel->expects($this->at($i * 3))->method('setRawData')
48 | ->with($entityData);
49 | $entityModel->expects($this->at($i * 3 + 1))->method('updateValues');
50 | $entityModel->expects($this->at($i * 3 + 2))->method('clearInstance');
51 | }
52 | $entityModel->expects($this->exactly($entityCount))->method('setRawData');
53 | $entityModel->expects($this->exactly($entityCount))->method('updateValues');
54 | $entityModel->expects($this->exactly($entityCount))->method('clearInstance');
55 |
56 | $collectionIterator = new CollectionMock($collectionData);
57 |
58 | $this->updater->update($collectionIterator, $entityModel);
59 | }
60 |
61 | private function getEntityMock()
62 | {
63 | return $this->getMock(AnonymizableMock::__CLASS, array('setRawData', 'updateValues', 'clearInstance'));
64 | }
65 |
66 | /**
67 | * @test
68 | * @dataProvider getCollectionData
69 | */
70 | public function testOutputControl($collectionData)
71 | {
72 | $stream = fopen('php://temp', 'r+');
73 | $this->updater->setOutputStream($stream);
74 | $this->updater->update(new CollectionMock($collectionData), $this->getEntityMock());
75 | $actualOutput = stream_get_contents($stream, -1, 0);
76 | $this->assertContains('Updater started at', $actualOutput);
77 | $this->assertContains('Updating Mock: 1/5 ', $actualOutput);
78 | $this->assertContains('Updating Mock: 2/5 ', $actualOutput);
79 | $this->assertContains('Updating Mock: 3/5 ', $actualOutput);
80 | $this->assertContains('Updating Mock: 4/5 ', $actualOutput);
81 | $this->assertContains('Updating Mock: 5/5 ', $actualOutput);
82 | $this->assertContains('Updater finished at', $actualOutput);
83 | fclose($stream);
84 |
85 | $stream = fopen('php://temp', 'r+');
86 | $this->updater->setOutputStream($stream);
87 | $this->updater->setProgressSteps(2);
88 | $this->updater->update(new CollectionMock($collectionData), $this->getEntityMock());
89 | $actualOutput = stream_get_contents($stream, -1, 0);
90 | $this->assertContains('Updater started at', $actualOutput);
91 | $this->assertNotContains('Updating Mock: 1/5 ', $actualOutput);
92 | $this->assertContains('Updating Mock: 2/5 ', $actualOutput);
93 | $this->assertNotContains('Updating Mock: 3/5 ', $actualOutput);
94 | $this->assertContains('Updating Mock: 4/5 ', $actualOutput);
95 | $this->assertNotContains('Updating Mock: 5/5 ', $actualOutput);
96 | $this->assertContains('Updater finished at', $actualOutput);
97 | fclose($stream);
98 |
99 | $stream = fopen('php://temp', 'r+');
100 | $this->updater->setOutputStream($stream);
101 | $this->updater->setShowProgress(false);
102 | $this->updater->update(new CollectionMock($collectionData), $this->getEntityMock());
103 | $actualOutput = stream_get_contents($stream, -1, 0);
104 | $this->assertContains('Updater started at', $actualOutput);
105 | $this->assertNotContains('Updating ', $actualOutput);
106 | $this->assertContains('Updater finished at', $actualOutput);
107 | fclose($stream);
108 |
109 | }
110 |
111 | public static function getCollectionData()
112 | {
113 | return array(
114 | array(
115 | 'collectionData' => array(
116 | array('email' => 'death@example.com', 'name' => 'Death'),
117 | array('email' => 'pestilence@example.com', 'name' => 'Pestilence'),
118 | array('email' => 'famine@example.com', 'name' => 'Famine'),
119 | array('email' => 'war@example.com', 'name' => 'War'),
120 | array('email' => 'ronny@example.com', 'name' => 'Ronny')
121 | )
122 | )
123 | );
124 | }
125 |
126 | }
127 |
--------------------------------------------------------------------------------
/test/bootstrap.php:
--------------------------------------------------------------------------------
1 |