X hide

Magento GDPR v1.x Developers Guide and API Reference

From Plumrocket Documentation


Contents

Downloading, Deleting and Anonymizing Customer Data

Plumrocket GDPR Magento 1 extension allows you to manage any third-party data stored in your Magento database. Use this manual to make your third-party extension GDPR compliant. Contact vendors of the third-party extensions you are using, and ask them if their extensions record any personal customer data in your Magento database. If they collect any personal data, they may become GDPR compliant by integrating their plugins with Plumrocket GDPR Extension using the provided API.


Export, delete or anonymize third-party data in 2 simple steps:

  1. Create a new observer in your module:
    1. Register observer in config.xml
    2. Create observer method
  2. Create GDPR model in the third-party plugin to manage your customer data.



Step 1. Create a New Observer in Your Module

a) Register observer in config.xml file.
Open the file:

app/code/community/VendorName/ModuleName/etc/config.xml

and add the code as shown below (or download the template here.):

<global>
 <events>
 <prgdpr_processors_collect_after>
 <observers>
 <Яfcff58Юobserver_name-!!>
 <type>singleton</type>
 <class>Яfcff58ЮgroupedClassName/observerModelName-!!</class>
 <method>Яfcff58ЮprgdprProcessorsCollectAfter-!!</method>
 </Яfcff58Юobserver_name-!!>
 </observers>
 </prgdpr_processors_collect_after>
 </events>
</global>



b) Create observer method
Your observer method must receive one argument - $observer with instance of Plumrocket_GDPR_Model_AbstractGdprTool in it.

Method Plumrocket_GDPR_Model_AbstractGdprTool::addProcessorWithSort can have 3 arguments:

  • “$processor” - “GDPR” model that should process all data (export / anonymize / delete)
  • “[$sort]” - describes the sort position of each GDPR model defined in $sortValue. Allowed values: "before", "after". Default value is "before".
  • “[$sortValue]” - Key name of your GDPR model which is used in sorting. Allowed values: Key name of GDPR model (example: “order”) or use dash (-) to position your GDPR model before/after all other models in the list. Default value is "customer".

Please note: The last two arguments are not required. They are useful when you need to specify the order in which your GDPR model must be executed. Example: let’s say you have 3 GDPR models with key names - “myCustomGDPRmodel”, “order” and “customer”. You can set the execution position of these models and specify that “myCustomGDPRmodel” should be executed after the “customer” model.


Example:

Я49ff70Ю$tool->addProcessorWithSort($myCustomGDPRmodel, ‘after’, ‘customer’);-!!


Now let’s create our observer method.

Open or create file:

 app/code/community/VendorName/ModuleName/Model/ObserverModelName.php

Add method prgdprProcessorsCollectAfter()
and add the code as shown below (or download the template here.):

 
/**
 * @param Varien_Event_Observer $observer
 * @return void
 */
public function prgdprProcessorsCollectAfter(Я92e1ffЮ$observer-!!)
{
 /** @var Яfcff58ЮVendorName-!!_Яfcff58ЮModuleName-!!_Model_Яfcff58ЮProcessorModelName-!! $processor */
 $processor = Mage::getModel('Яfcff58ЮgroupedClassName/processorModelName-!!');
 
 /** @var Plumrocket_GDPR_Model_AbstractGdprTool $tool */
 $tool = $observer->getTool();
 
 $tool->addProcessorWithSort($processor, ‘before’, ‘customer’);
}


Step 2. Create GDPR Model

Create your class “VendorName_ModuleName_Model_Gdpr_Processor” that extends Plumrocket_GDPR_Model_AbstractProcessor.


Class Plumrocket_GDPR_Model_AbstractProcessor has the following methods:

  • _anonymize(Mage_Core_Model_Abstract $model)
  • _erase(Mage_Core_Model_Abstract $model)
  • _export(Varien_Object $model)
  • _massExport($models)
  • _massAnonymize(array $models, callable $callback = null)
  • _massErase(array $models, callable $callback = null)


Please note:
$callback - is a function executed for each model before mass erasure or anonymization.


function getMapping() defines which data will be anonymized or exported.


Where:

db_field_name1” is the name of the database field or attribute code that should be anonymized or exported:


Data anonymization options:

  • Array Key (bool) "anonymize" defines whether field should be anonymized or not. Default value is “true”.
  • Array Key (string) "default" - replaces field value with your string value. if nothing is defined, [Anonymization Key] + “-” + [Customer Id] will be set instead.
    Please note: the “Anonymization Key” can be set in Magento System Configuration -> GDPR -> Account Removal Settings -> Anonymization Key.



Data export options:

  • Array Key (bool) "export" defines whether field should be exported or not. Default value is “true”.
  • Array Key (string) "title" allows you to rename “db_field_name1” column in the CSV file.
    Default value is a result of the function uc_words(“db_field_name1”).
  • Array Key (callable) "decorator" - anonymous function allows you to define custom format of the field “db_field_name1” before it's exported to the CSV file. This function can receive two arguments - value of the “db_field_name1” and the current model. Example of the code below allows you to format Order Grand Total using our anonymous function:
 'decorator' => function ($value, $order) {
 return $order>getOrderCurrency()->formatPrecision($value, 2, array(), false);
 },


Lastly, if you provide empty array of options, (see 'db_field_name2' in example below), the default values will be set.


Now, let’s create GDPR Model file:

app/code/pool/VendorName/ModuleName/Model/Gdpr/Processor.php

and add the code as shown below (or download the template here.):

class Яfcff58ЮVendorName_ModuleName_Model_Gdpr_Processor-!! extends Plumrocket_GDPR_Model_AbstractProcessor implements
 Plumrocket_GDPR_Model_ProcessorInterface
{
 public function getKey()
 {
 return Яfcff58Ю'unique_key'-!!; // unique key of your GDPR model
 }
 
 public function getModuleName()
 {
 return Яfcff58Ю'VendorName_ModuleName'-!!;
 }
 
 public function getPublicFilename()
 {
 return Яfcff58Ю'your_filename'-!!; // your CSV file name
 }
 
 /**
 * @return array
 */
 public function getMapping()
 {
 return array(
 Яfcff58Ю'db_field_name1'-!! => array(
 Я49ff70Ю// data anonymization options-!!
 ‘anonymize’ => bool,
 'default' => string,
 Я49ff70Ю// data export options-!!
 'export' => bool,
 ‘title’ => string,
 ‘decorator’ => callable,
 ),
 Яfcff58Ю'db_field_name2'-!! => array(),
 Яfcff58Ю 'db_field_name3'-!! => array(
 'export' => bool,
 ‘title’ => string,
 ‘decorator’ => callable,
 ),
 );
 }
 
/**
 * @param Mage_Customer_Model_Customer $customer
 * @return bool
 */
public function anonymize($customer)
{
 $collection = $this->_getCollectionByCustomer($customer);
 
 return $this->_massAnonymize($collection);
}
 
/**
 * @param Mage_Customer_Model_Customer $customer
 * @return bool
 */
public function erase($customer)
{
 $collection = $this->_getCollectionByCustomer($customer);
 
 return $this->_massErase($collection);
}
 
/**
 * @param Mage_Customer_Model_Customer $customer
 * @return bool
 */
public function export($customer)
{
 $collection = $this->_getCollectionByCustomer($customer);
 
 return $this->_massExport($collection);
}
 
/**
 * @param Mage_Customer_Model_Customer $customer
 * @return Mage_Core_Model_Abstract[]
 */
protected function _getCollectionByCustomer($customer)
{
 /** @var Mage_Core_Model_Resource_Db_Collection_Abstract $collection */
 $collection = Mage::getModel(Яfcff58Ю'groupedClassName/entity_name'-!!)->getCollection();
 $collection->addFieldToFilter('customer_id', $customer->getId());
 
 return $collection->getItems();
}
}
Example

This example is based on Free Plumrocket Twitter & Facebook Login Extension for Magento 1. You can download it from our store for your reference.


Step 1.a “config.xml” file of Plumrocket Twitter & Facebook Login Extension

1.a) Observer in config.xml file
Open the file:

app/code/community/Plumrocket/SocialLogin/etc/config.xml
<global>
 <events>
 <prgdpr_processors_collect_after>
 <observers>
 <pslogin_observer>
 <type>singleton</type>
 <class>Яfcff58Юpslogin/observer-!!</class>
 <method>Яfcff58ЮprgdprProcessorsCollectAfter-!!</method>
 </pslogin_observer>
 </observers>
 </prgdpr_processors_collect_after>
 </events>
</global>



Step 1.b “Observer.php” file of Plumrocket Twitter & Facebook Login Extension

1.b) Observer method
Open the file:

app/code/community/Plumrocket/SocialLogin/Model/Observer.php
/**
 * @param Varien_Event_Observer $observer
 * @return void
 */
public function Яfcff58ЮprgdprProcessorsCollectAfter($observer)-!!
{
 /** @var Plumrocket_SocialLogin_Model_Gdpr_Processor $processor */
 $processor = Mage::getModel('pslogin/gdpr_processor');
 
 /** @var Plumrocket_GDPR_Model_AbstractGdprTool $tool */
 $tool = $observer->getTool();
 
 $tool->addProcessorWithSort($processor);
}



Step 2. GDPR Model of Plumrocket Twitter & Facebook Login Extension

File path:

app/code/community/Plumrocket/SocialLogin/Model/Gdpr/Processor.php
class Plumrocket_SocialLogin_Model_Gdpr_Processor extends Plumrocket_GDPR_Model_AbstractProcessor
{
 const KEY = 'pslogin';
 
 /**
 * @return string
 */
 public function getKey()
 {
 return self::KEY;
 }
 
 /**
 * @return string
 */
 public function getPublicFilename()
 {
 return 'social_accounts';
 }
 
 /**
 * @return string
 */
 public function getModuleName()
 {
 return 'Plumrocket_SocialLogin';
 }
 
 /**
 * @return array
 */
 public function getMapping()
 {
 return array(
 'type' => array(
 'title' => 'Social network',
 'anonymize' => false,
 ),
 'user_id' => array(
 'title' => 'Id in social network',
 ),
 'Я92e1ffЮphoto-!!' => array(
 'title' => 'Photo',
 'decorator' => $this->getPhotoDecorator()
 ),
 Я92e1ffЮ// In this case, photo is not a db field, its created by our "decorator" - anonymous function using helper and model-!!
 );
 }
 
 /**
 * @param Mage_Customer_Model_Customer $customer
 * @return bool
 */
 Я49ff70Юpublic function anonymize($customer)-!!
 {
 return $this->_massAnonymize($this->getSocialAccounts($customer), Я92e1ffЮ$this->getRemovePhotoCallback()-!!);
 }
 
 /**
 * @param Mage_Customer_Model_Customer $customer
 * @return bool
 */
 Я49ff70Юpublic function erase($customer)-!!
 {
 return $this->_massErase($this->getSocialAccounts($customer), Я92e1ffЮ$this->getRemovePhotoCallback()-!!);
 }
Я92e1ffЮ// $this->getRemovePhotoCallback() - is used to remove profile photo. Returns function that will be called before anonymization/erasure procedure and will delete the picture file.-!!
 
 /**
 * @param Mage_Customer_Model_Customer $customer
 * @return array|null
 */
 Я49ff70Юpublic function export($customer)-!!
 {
 return $this->_massExport($this->getSocialAccounts($customer));
 }
 
 /**
 * @param Mage_Customer_Model_Customer $customer
 * @return array
 */
 protected function getSocialAccounts($customer)
 {
 /** @var Plumrocket_SocialLogin_Model_Mysql4_Account_Collection $collection */
 $collection = Mage::getResourceModel('pslogin/account_collection');
 $collection->addFieldToFilter('customer_id', $customer->getId());
 
 return $collection->getItems();
 }
 
 /**
 * @return Closure
 */
 private function getRemovePhotoCallback()
 {
 $io = new Varien_Io_File();
 /** @var Plumrocket_SocialLogin_Helper_Data $psLoginHelper */
 $psLoginHelper = Mage::helper('pslogin');
 /** @var Plumrocket_GDPR_Helper_Data $gdprHelper */
 $gdprHelper = Mage::helper('prgdpr');
 
 /**
 * @param Plumrocket_SocialLogin_Model_Account $model
 */
 $removePhotoCallback = function ($model) use ($io, $psLoginHelper, $gdprHelper) {
 $photo = $psLoginHelper->getAbsolutePhotoPath($model->getCustomerId());
 if ($photo) {
 if (!$io->rm($photo)) {
 $gdprHelper->logError('Unlink file ' . $photo . ' failed');
 }
 }
 
 $photo = $psLoginHelper->getAbsolutePhotoPath($model->getCustomerId(), $model->getType());
 if ($photo) {
 if (!$io->rm($photo)) {
 $gdprHelper->logError('Unlink file ' . $photo . ' failed');
 }
 }
 };
 
 return $removePhotoCallback;
 }
 
 /**
 * @return Closure
 */
 private function getPhotoDecorator()
 {
 return function ($photo, $model) {
 /** @var Plumrocket_SocialLogin_Model_Account $model */
 $photo = Mage::helper('pslogin')->getPhotoPath(
 false,
 $model->getCustomerId(),
 $model->getType()
 );
 
 if (!$photo) {
 $photo = $model->getAccountImage();
 }
 
 return $photo;
 };
 }
}


GDPR Developer’s FAQ:

1.How do I change the default Magento 1 GDPR config?
Edit files in folder:

app/code/community/Plumrocket/GDPR/Model/Processor


2.Can I anonymize all data instead of deleting it?
Yes, you can. In order to enable or disable the erasure/anonymization, you must set the value returned by the method isEraseMode in file

app/code/community/Plumrocket/GDPR/Helper/Config.php 

to “false”.


However, please note, that you can only enable the anonymization for a part of data, see more details below:


Data that can be erased or anonymized:

  • customer_address
  • customer_information
  • customer_log
  • log_of_account_removal_requests
  • reviews


Data that is always erased:

  • price_and_stock_alerts
  • compare_products
  • email_in_queue
  • enterprise_customerbalance
  • enterprise_giftregistry
  • enterprise_giftregistry_person
  • enterprise_invitation
  • enterprise_reward
  • log_of_account_data_downloads
  • log_of_customer_consents
  • order_gift_messages
  • poll_vote
  • addresses_saves_in_cart
  • cart_information
  • cart_flat
  • products_in_cart
  • forgot_password
  • newsletter_subscriber
  • rating
  • wishlist


Data that is always anonymized:

  • archive_order
  • archive_creditmemo
  • archive_invoice
  • archive_shipment
  • enterprise_rma
  • order_addresses
  • order_information


3.I have implemented the GDPR support in my third-party extension, can I share it with you?
Yes, absolutely. We can add the built-in support of the third-party extension to our GDPR module after we review your code. Please contact our tech support and submit your request.


4.What data and Magento tables are affected by the GDPR extension?
During download, deletion or anonymization process, the following database tables are affected:

Magento 1.x Community Edition (CE) Magento 1.x Enterprise Edition (EE)
  • customer_entity
  • customer_entity
  • customer_entity_*
  • product_alert_price
  • product_alert_stock
  • core_email_queue_recipients
  • customer_flowpassword
  • customer_address_entity
  • customer_address_entity_*
  • review
  • review_detail
  • wishlist
  • wishlist_item
  • catalog_compare_item
  • newsletter_subscriber
  • poll_vote
  • poll_answer
  • rating_option_vote
  • log_quote
  • log_url
  • log_visitor
  • log_visitor_info
  • log_customer
  • sales_flat_order
  • sales_flat_order_address
  • sales_flat_order_grid
  • sales_flat_order_item
  • gift_message
  • sales_flat_quote
  • sales_flat_quote_address
  • plumrocket_gdpr_consent
  • plumrocket_gdpr_eraser_log
  • plumrocket_gdpr_exporter_log
  • customer_entity
  • customer_entity_*
  • product_alert_price
  • product_alert_stock
  • customer_address_entity
  • customer_address_entity_*
  • review
  • review_detail
  • wishlist
  • wishlist_item
  • catalog_compare_item
  • newsletter_subscriber
  • poll_vote
  • poll_answer
  • rating_option_vote
  • log_quote
  • log_url
  • log_visitor
  • log_visitor_info
  • log_customer
  • sales_flat_order
  • sales_flat_order_address
  • sales_flat_order_grid
  • sales_flat_order_item
  • gift_message
  • sales_flat_quote
  • sales_flat_quote_address
  • enterprise_rma
  • enterprise_rma_grid
  • enterprise_rma_item_entity
  • enterprise_rma_item_entity_*
  • enterprise_giftregistry_entity
  • enterprise_giftregistry_person
  • enterprise_sales_order_grid_archive
  • enterprise_sales_creditmemo_grid_archive
  • enterprise_sales_invoice_grid_archive
  • enterprise_sales_shipment_grid_archive
  • enterprise_customerbalance
  • enterprise_invitation
  • enterprise_reward
  • plumrocket_gdpr_consent
  • plumrocket_gdpr_eraser_log
  • plumrocket_gdpr_exporter_log

See Magento Magento DevDocs for more information about the Magento 1.x GDPR compliance and data storage.


Adding Consent Checkboxes Manually

Use the documentation below to manually place checkboxes in the needed location of the page. At the moment 3 checkbox locations are supported: registration, checkout or newsletter subscription forms.

Please note, you must first add the “Consent Checkboxes” in the Magento System Configuration -> GDPR -> Consent Checkboxes. See wiki configuration page for more details.

Example 1. Displaying Checkboxes Using Structural Blocks

If your page is built using structural blocks (core/text_list blocks), then you should use the code from the example below.

In this example we will add checkboxes on the Registration Page. Add structural block to the XML layout file:


Open the file:

app/design/frontend/base/default/layout/your_module_layout_file.xml

and add the code as shown below:

<reference name="form.additional.info">
 <block type="prgdpr/checkboxes" name="prgdpr.register.checkbox">
 <action method="setTemplate" ifconfig="prgdpr/general/enable"><template>Я49ff70Юprgdpr/form/checkbox.phtml-!!</template></action>
 <action method="setType"><Я49ff70Юtype-!!>Я92e1ffЮregister-!!</Я49ff70Юtype-!!></action>
 </block>
</reference>


Where:
"type" argument describes the type of the checkbox. E.G:

<action method="setType"><Я49ff70Юtype-!!>Я92e1ffЮPageType-!!</Я49ff70Юtype-!!></action>


PageType” can have the following values: “register”, “newsletter” or “checkout”.


Example 2. Displaying Checkboxes Using Layout Blocks

Create layout blocks (core/template) if you need to add checkboxes within HTML content. Use the code from the example below.

In this example we will add checkboxes into the Newsletter Subscription form.

Open the file:

app/design/frontend/base/default/template/newsletter/subscribe.phtml

and add the highlighted code as shown below:

<div class="block block-subscribe">
 <div class="block-title">
 <strong><span><?php echo $this->__('Newsletter') ?></span></strong>
 </div>
 <form action="<?php echo $this->getFormActionUrl() ?>" method="post" id="newsletter-validate-detail">
 <div class="block-content">
 <div class="form-subscribe-header">
 <label for="newsletter"><?php echo $this->__('Sign Up for Our Newsletter:') ?></label>
 </div>
 <div class="input-box">
 <input type="text" name="email" id="newsletter" title="<?php echo Mage::helper('core')->quoteEscape($this->__('Sign up for our newsletter')) ?>" class="input-text required-entry validate-email" />
 </div>
 <div class="actions">
 <button type="submit" title="<?php echo Mage::helper('core')->quoteEscape($this->__('Subscribe')) ?>" class="button"><span><span><?php echo $this->__('Subscribe') ?></span></span></button>
 </div>
 </div>
 Я92e1ffЮ<div class="prgdpr-newsletter-checkboxes-container"></div>
 <script>
 pjQuery_1_12_4(document).ready(function($) {
 $.get('<?php echo $this->getUrl('prgdpr/newsletter/html') ?>', function (data) {
 $('.prgdpr-newsletter-checkboxes-container').each(function (index, elem) {
 $(elem).html(data);
 });
 })
 });
 </script>-!!
 </form>
 <script type="text/javascript">
 //<![CDATA[
 var newsletterSubscriberFormDetail = new VarienForm('newsletter-validate-detail');
 //]]>
 </script>
</div>


Displaying Checkboxes On Checkout Page

Plumrocket GDPR extension uses native Magento functionality of "Terms and Conditions" (Agreements) to display GDPR consent checkboxes on checkout page. This allows you to stay compatible with majority of third party extensions. Consent validation and logging also replicates this functionality. In order to display GDPR checkboxes make sure that your third party checkout extension supports native Magento "Terms and Conditions".


Go to your “Magento Admin -> Sales -> Terms and Conditions” to view this functionality.


Blocking non-essential Cookies

Plumrocket GDPR extension uses the native Magento “Cookie Restriction Mode” functionality to display Cookie Restriction Notice Block. It allows you to block all non-essential cookies until visitor consent is given. Only after the visitor consent is given (eg: "Allow Cookies" button is pressed), the non-essential cookies will be created.

According to GDPR, non-essential cookies, such as those used for analytics, cookies from advertisers or third parties, including affiliates and those that identify a user when he returns to the website should not be used until the consent is provided.


If your JavaScript code creates cookies, you can block it from execution, until the customer consent is given. To do so, copy the code below and insert your JavaScript in the highlighted section:

Copy File:

app/design/frontend/base/default/template/prgdpr/cookie/alert.phtml

To the folder with your Magento theme:

app/design/frontend/rwd/default/template/prgdpr/cookie/alert.phtml

Where “rwd>/default” is the name of your theme name / package name


Then add/edit the following code:

<?php if ($this->isAllowGtm()) : ?>
<script type="text/javascript">
 var gtm_tag = document.createElement('script');
 gtm_tag.type = 'text/javascript';
 gtm_tag.text = '(function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({\'gtm.start\':new Date().getTime(),event:\'gtm.js\'});var f=d.getElementsByTagName(s)[0],j=d.createElement(s),dl=l!=\'dataLayer\'?\'&l=\'+l:\'\';j.async=true;j.src=\'https://www.googletagmanager.com/gtm.js?id=\'+i+dl;f.parentNode.insertBefore(j,f);})(window,document,\'script\',\'dataLayer\',\'<?php echo $this->getGtmContainerId(); ?>\');';
 document.body.appendChild(gtm_tag);
 
 Яfcff58Ю// Add your js code here-!!
</script>
<?php endif; ?>


Developer’s Guide for GeoIP Functionality

Plumrocket GDPR extension comes bundled with Plumrocket GeoIP Lookup extension. This add-on is used to identify customer’s location from IP and deliver targeted content. With this plugin enabled, GDPR can be configured to display cookie restriction notice and consent checkboxes only for visitors from EU countries or custom list of countries. Learn more about GeoIP Rest API and other methods of retrieving customer location here - Magento GeoIP Lookup Developers Guide and API Reference.

Navigation