Add subscriber eraser for GDPR

[MAILPOET-1359]
This commit is contained in:
Pavel Dohnal
2018-05-09 09:15:19 +01:00
parent a742dacf32
commit bd01b5855e
4 changed files with 164 additions and 0 deletions

View File

@ -131,6 +131,7 @@ class Initializer {
$this->setupShortcodes(); $this->setupShortcodes();
$this->setupImages(); $this->setupImages();
$this->setupPersonalDataExporters(); $this->setupPersonalDataExporters();
$this->setupPersonalDataErasers();
$this->setupChangelog(); $this->setupChangelog();
$this->setupCronTrigger(); $this->setupCronTrigger();
@ -272,6 +273,11 @@ class Initializer {
$exporters->init(); $exporters->init();
} }
function setupPersonalDataErasers() {
$erasers = new PersonalDataErasers();
$erasers->init();
}
function setupPHPVersionWarnings() { function setupPHPVersionWarnings() {
$php_version_warnings = new PHPVersionWarnings(); $php_version_warnings = new PHPVersionWarnings();
$warnings = $php_version_warnings->init(phpversion(), Menu::isOnMailPoetAdminPage()); $warnings = $php_version_warnings->init(phpversion(), Menu::isOnMailPoetAdminPage());

View File

@ -0,0 +1,22 @@
<?php
namespace MailPoet\Config;
use MailPoet\Subscribers\SubscriberPersonalDataEraser;
class PersonalDataErasers {
function init() {
add_filter('wp_privacy_personal_data_erasers', array($this, 'registerSubscriberEraser'));
}
function registerSubscriberEraser($erasers) {
$erasers['mailpet-subscriber'] = array(
'eraser_friendly_name' => __('Mailpoet Subscribers', 'mailpoet'),
'callback' => array(new SubscriberPersonalDataEraser(), 'erase'),
);
return $erasers;
}
}

View File

@ -0,0 +1,56 @@
<?php
namespace MailPoet\Subscribers;
use MailPoet\Models\Subscriber;
use MailPoet\Models\SubscriberCustomField;
class SubscriberPersonalDataEraser {
function erase($email) {
if(empty($email)) {
return array(
'items_removed' => false,
'items_retained' => false,
'messages' => array(),
'done' => true,
);
}
$subscriber = Subscriber::findOne(trim($email));
$item_removed = false;
$items_retained = true;
if($subscriber) {
$this->eraseCustomFields($subscriber->id());
$this->anonymizeSubscriberData($subscriber);
$item_removed = true;
$items_retained = false;
}
return array(
'items_removed' => $item_removed,
'items_retained' => $items_retained,
'messages' => array(),
'done' => true,
);
}
private function eraseCustomFields($subscriber_id) {
$custom_fields = SubscriberCustomField::where('subscriber_id', $subscriber_id)->findMany();
foreach($custom_fields as $custom_field) {
$custom_field->value = '';
$custom_field->save();
}
}
private function anonymizeSubscriberData($subscriber) {
$subscriber->email = sprintf('deleted-%s@site.invalid', uniqid('', true));
$subscriber->first_name = 'Anonymous';
$subscriber->last_name = 'Anonymous';
$subscriber->status = Subscriber::STATUS_UNSUBSCRIBED;
$subscriber->subscribed_ip = '0.0.0.0';
$subscriber->confirmed_ip = '0.0.0.0';
$subscriber->save();
}
}

View File

@ -0,0 +1,80 @@
<?php
namespace MailPoet\Subscribers;
use MailPoet\Models\CustomField;
use MailPoet\Models\Subscriber;
use MailPoet\Models\SubscriberCustomField;
class SubscriberPersonalDataEraserTest extends \MailPoetTest {
/** @var SubscriberPersonalDataEraser */
private $eraser;
function _before() {
$this->eraser = new SubscriberPersonalDataEraser();
}
function testExportWorksWhenSubscriberNotFound() {
$result = $this->eraser->erase('email.that@doesnt.exists');
expect($result)->internalType('array');
expect($result)->hasKey('items_removed');
expect($result['items_removed'])->equals(0);
expect($result)->hasKey('done');
expect($result['done'])->equals(true);
}
function testItDeletesCustomFields() {
$subscriber = Subscriber::createOrUpdate(array(
'email' => 'email.that@has.custom.fields',
));
$custom_field1 = CustomField::createOrUpdate(array(
'name' => 'Custom field1',
'type' => 'input'
));
$custom_field2 = CustomField::createOrUpdate(array(
'name' => 'Custom field2',
'type' => 'input'
));
$subscriber->setCustomField($custom_field1->id(), 'Value');
$subscriber->setCustomField($custom_field2->id(), 'Value');
$this->eraser->erase('email.that@has.custom.fields');
$subscriber_custom_fields = SubscriberCustomField::where('subscriber_id', $subscriber->id())->findMany();
expect($subscriber_custom_fields)->count(2);
expect($subscriber_custom_fields[0]->value)->equals('');
expect($subscriber_custom_fields[1]->value)->equals('');
}
function testItDeletesSubscriberData() {
$subscriber = Subscriber::createOrUpdate(array(
'email' => 'subscriber@for.anon.test',
'first_name' => 'John',
'last_name' => 'Doe',
'status' => 'subscribed',
'created_at' => '2018-05-03 10:30:08',
'subscribed_ip' => 'IP1',
'confirmed_ip' => 'IP2',
'unconfirmed_data' => 'xyz',
));
$this->eraser->erase('subscriber@for.anon.test');
$subscriber_after = Subscriber::findOne($subscriber->id());
expect($subscriber_after->first_name)->equals('Anonymous');
expect($subscriber_after->last_name)->equals('Anonymous');
expect($subscriber_after->status)->equals('unsubscribed');
expect($subscriber_after->subscribed_ip)->equals('0.0.0.0');
expect($subscriber_after->confirmed_ip)->equals('0.0.0.0');
expect($subscriber_after->unconfirmed_data)->equals('');
}
function testItDeletesSubscriberEmailAddress() {
$subscriber = Subscriber::createOrUpdate(array(
'email' => 'subscriber@for.anon.test',
));
$this->eraser->erase('subscriber@for.anon.test');
$subscriber_after = Subscriber::findOne($subscriber->id());
expect($subscriber_after->email)->notEquals('subscriber@for.anon.test');
}
}