Skip to content

Commit

Permalink
opengento#13 add action on admin ui
Browse files Browse the repository at this point in the history
  • Loading branch information
thomas-kl1 committed Jun 12, 2019
1 parent ac21544 commit 81e65d3
Show file tree
Hide file tree
Showing 12 changed files with 217 additions and 15 deletions.
16 changes: 16 additions & 0 deletions Api/Data/EraseCustomerInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ interface EraseCustomerInterface extends ExtensibleDataInterface
public const SCHEDULED_AT = 'scheduled_at';
public const STATE = 'state';
public const STATUS = 'status';
public const MESSAGE = 'message';
public const ERASED_AT = 'erased_at';
/**#@-*/

Expand Down Expand Up @@ -118,6 +119,21 @@ public function getStatus(): string;
*/
public function setStatus(string $status): EraseCustomerInterface;

/**
* Retrieve the error message
*
* @return string|null
*/
public function getMessage(): ?string;

/**
* Set the error message
*
* @param string|null $message
* @return \Opengento\Gdpr\Api\Data\EraseCustomerInterface
*/
public function setMessage(?string $message): EraseCustomerInterface;

/**
* Retrieve the erased at if it exists
*
Expand Down
78 changes: 78 additions & 0 deletions Controller/Adminhtml/Privacy/MassErase.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
<?php
/**
* Copyright © OpenGento, All rights reserved.
* See LICENSE bundled with this library for license details.
*/
declare(strict_types=1);

namespace Opengento\Gdpr\Controller\Adminhtml\Privacy;

use Magento\Backend\App\Action\Context;
use Magento\Customer\Controller\Adminhtml\Index\AbstractMassAction;
use Magento\Customer\Model\ResourceModel\Customer\CollectionFactory;
use Magento\Eav\Model\Entity\Collection\AbstractCollection;
use Magento\Framework\Controller\ResultFactory;
use Magento\Framework\Exception\LocalizedException;
use Magento\Framework\Phrase;
use Magento\Ui\Component\MassAction\Filter;
use Opengento\Gdpr\Api\EraseCustomerManagementInterface;

/**
* Class MassErase
*/
class MassErase extends AbstractMassAction
{
/**
* @var \Opengento\Gdpr\Api\EraseCustomerManagementInterface
*/
private $eraseCustomerManagement;

/**
* @param \Magento\Backend\App\Action\Context $context
* @param \Magento\Ui\Component\MassAction\Filter $filter
* @param \Magento\Customer\Model\ResourceModel\Customer\CollectionFactory $collectionFactory
* @param \Opengento\Gdpr\Api\EraseCustomerManagementInterface $eraseCustomerManagement
*/
public function __construct(
Context $context,
Filter $filter,
CollectionFactory $collectionFactory,
EraseCustomerManagementInterface $eraseCustomerManagement
) {
$this->eraseCustomerManagement = $eraseCustomerManagement;
parent::__construct($context, $filter, $collectionFactory);
}

/**
* @inheritdoc
*/
protected function massAction(AbstractCollection $collection)
{
$customerErased = 0;

foreach ($collection->getAllIds() as $customerId) {
try {
$this->eraseCustomerManagement->process($this->eraseCustomerManagement->create((int) $customerId));
$customerErased++;
} catch (LocalizedException $e) {
$this->messageManager->addErrorMessage(
new Phrase('Customer with id "%1": %2', [$customerId, $e->getMessage()])
);
} catch (\Exception $e) {
$this->messageManager->addExceptionMessage($e, new Phrase('An error occurred on the server.'));
}
}

if ($customerErased) {
$this->messageManager->addSuccessMessage(
new Phrase('A total of %1 record(s) were erased.', [$customerErased])
);
}

/** @var \Magento\Backend\Model\View\Result\Redirect $resultRedirect */
$resultRedirect = $this->resultFactory->create(ResultFactory::TYPE_REDIRECT);
$resultRedirect->setPath('customer/index/index');

return $resultRedirect;
}
}
16 changes: 16 additions & 0 deletions Model/EraseCustomer.php
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,22 @@ public function setStatus(string $status): EraseCustomerInterface
return $this->setData(self::STATUS, $status);
}

/**
* @inheritdoc
*/
public function getMessage(): ?string
{
return $this->_getData(self::MESSAGE) === null ? null : (string) $this->_getData(self::MESSAGE);
}

/**
* @inheritdoc
*/
public function setMessage(?string $message): EraseCustomerInterface
{
return $this->setData(self::MESSAGE, $message);
}

/**
* @inheritdoc
*/
Expand Down
2 changes: 1 addition & 1 deletion Model/EraseCustomerChecker.php
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,6 @@ public function canProcess(int $customerId): bool
&& $entity->getStatus() === EraseCustomerInterface::STATUS_READY)
|| ($entity->getState() === EraseCustomerInterface::STATE_PROCESSING
&& $entity->getStatus() === EraseCustomerInterface::STATUS_FAILED))
&& $this->customerChecker->hasPendingOrders($entity->getCustomerId());
&& !$this->customerChecker->hasPendingOrders($entity->getCustomerId());
}
}
46 changes: 40 additions & 6 deletions Model/EraseCustomerManagement.php
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,7 @@ public function cancel(int $customerId): bool

/**
* @inheritdoc
* @throws \Exception
*/
public function process(EraseCustomerInterface $entity): EraseCustomerInterface
{
Expand All @@ -128,14 +129,47 @@ public function process(EraseCustomerInterface $entity): EraseCustomerInterface
$entity = $this->eraseCustomerRepository->save($entity);

try {
$this->eraseManagement->erase($entity->getCustomerId());
$entity->setState(EraseCustomerInterface::STATE_COMPLETE);
$entity->setStatus(EraseCustomerInterface::STATUS_SUCCEED);
$entity->setErasedAt($this->localeDate->gmtDate());
if ($this->eraseManagement->erase($entity->getCustomerId())) {
return $this->success($entity);
}

return $this->fail($entity);
} catch (\Exception $e) {
$entity->setState(EraseCustomerInterface::STATE_PROCESSING);
$entity->setStatus(EraseCustomerInterface::STATUS_FAILED);
$this->fail($entity, $e->getMessage());
throw $e;
}
}

/**
* Erasure has succeeded
*
* @param \Opengento\Gdpr\Api\Data\EraseCustomerInterface $entity
* @return \Opengento\Gdpr\Api\Data\EraseCustomerInterface
* @throws \Magento\Framework\Exception\CouldNotSaveException
*/
private function success(EraseCustomerInterface $entity): EraseCustomerInterface
{
$entity->setState(EraseCustomerInterface::STATE_COMPLETE);
$entity->setStatus(EraseCustomerInterface::STATUS_SUCCEED);
$entity->setErasedAt($this->localeDate->gmtDate());
$entity->setMessage(null);

return $this->eraseCustomerRepository->save($entity);
}

/**
* Erasure has failed
*
* @param \Opengento\Gdpr\Api\Data\EraseCustomerInterface $entity
* @param string|null $message
* @return \Opengento\Gdpr\Api\Data\EraseCustomerInterface
* @throws \Magento\Framework\Exception\CouldNotSaveException
*/
private function fail(EraseCustomerInterface $entity, ?string $message = null): EraseCustomerInterface
{
$entity->setState(EraseCustomerInterface::STATE_PROCESSING);
$entity->setStatus(EraseCustomerInterface::STATUS_FAILED);
$entity->setMessage($message);

return $this->eraseCustomerRepository->save($entity);
}
Expand Down
13 changes: 13 additions & 0 deletions Model/Newsletter/Subscriber.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,13 @@

namespace Opengento\Gdpr\Model\Newsletter;

use \Magento\Newsletter\Model\Subscriber as SubscriberModel;
use Magento\Newsletter\Model\SubscriberFactory;

/**
* `\Opengento\Gdpr\Model\Newsletter\Subscriber` class is the final state of `\Magento\Newsletter\Model\Subscriber`.
*
* @method SubscriberModel loadByCustomerId(int $customerId)
*/
final class Subscriber
{
Expand All @@ -30,6 +33,16 @@ public function __construct(
$this->subscriber = $subscriberFactory->create(['data' => $data]);
}

/**
* Retrieve the real subscriber subject
*
* @return \Magento\Newsletter\Model\Subscriber
*/
public function getRealSubscriber(): SubscriberModel
{
return $this->subscriber;
}

/**
* @inheritdoc
*/
Expand Down
5 changes: 3 additions & 2 deletions Service/Anonymize/Processor/SubscriberDataProcessor.php
Original file line number Diff line number Diff line change
Expand Up @@ -53,10 +53,11 @@ public function __construct(
*/
public function execute(int $customerId): bool
{
/** @var \Magento\Newsletter\Model\Subscriber $subscriber */
/** @var \Opengento\Gdpr\Model\Newsletter\Subscriber $subscriber */
$subscriber = $this->subscriberFactory->create();
$subscriber->loadByCustomerId($customerId);
$this->subscriberResourceModel->save($this->anonymizer->anonymize($subscriber));
$this->anonymizer->anonymize($subscriber);
$this->subscriberResourceModel->save($subscriber->getRealSubscriber());

return true;
}
Expand Down
6 changes: 3 additions & 3 deletions Service/Delete/Processor/SubscriberDataProcessor.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
namespace Opengento\Gdpr\Service\Delete\Processor;

use Magento\Newsletter\Model\ResourceModel\Subscriber as ResourceSubscriber;
use Opengento\Gdpr\Model\Newsletter\SubscriberFactory;
use Magento\Newsletter\Model\SubscriberFactory;
use Opengento\Gdpr\Service\Delete\ProcessorInterface;

/**
Expand All @@ -17,7 +17,7 @@
final class SubscriberDataProcessor implements ProcessorInterface
{
/**
* @var \Opengento\Gdpr\Model\Newsletter\SubscriberFactory
* @var \Magento\Newsletter\Model\SubscriberFactory
*/
private $subscriberFactory;

Expand All @@ -27,7 +27,7 @@ final class SubscriberDataProcessor implements ProcessorInterface
private $subscriberResourceModel;

/**
* @param \Opengento\Gdpr\Model\Newsletter\SubscriberFactory $subscriberFactory
* @param \Magento\Newsletter\Model\SubscriberFactory $subscriberFactory
* @param \Magento\Newsletter\Model\ResourceModel\Subscriber $subscriberResourceModel
*/
public function __construct(
Expand Down
9 changes: 8 additions & 1 deletion Setup/InstallSchema.php
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,13 @@ private function createEraseCustomerTable(SchemaSetupInterface $setup): bool
['nullable' => false],
'Status'
)
->addColumn(
EraseCustomerInterface::MESSAGE,
Table::TYPE_TEXT,
255,
['nullable' => true],
'Message'
)
->addColumn(
EraseCustomerInterface::ERASED_AT,
Table::TYPE_TIMESTAMP,
Expand All @@ -105,7 +112,7 @@ private function createEraseCustomerTable(SchemaSetupInterface $setup): bool
EraseCustomerInterface::CUSTOMER_ID,
$setup->getTable('customer_entity'),
'entity_id',
Table::ACTION_NO_ACTION
Table::ACTION_CASCADE
)
->setComment('Customer Erase Scheduler');

Expand Down
3 changes: 1 addition & 2 deletions TODO.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,7 @@ Area:
- Multiple export in command line result in filename expanded at each iteration

## Anonymizer

- Check customer only closed/completed orders

- Payment Data
- Invitation Data

Expand Down
14 changes: 14 additions & 0 deletions etc/adminhtml/routes.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<?xml version="1.0"?>
<!--
/**
* Copyright © OpenGento, All rights reserved.
* See LICENSE bundled with this library for license details.
*/
-->
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:App/etc/routes.xsd">
<router id="admin">
<route id="customer">
<module name="Opengento_Gdpr" after="Magento_Customer"/>
</route>
</router>
</config>
24 changes: 24 additions & 0 deletions view/adminhtml/ui_component/customer_listing.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
/**
* Copyright © OpenGento, All rights reserved.
* See LICENSE bundled with this library for license details.
*/
-->
<listing xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Ui:etc/ui_configuration.xsd">
<listingToolbar name="listing_top">
<massaction name="listing_massaction">
<action name="erase">
<settings>
<confirm>
<message translate="true">Are you sure you want to erase the selected customers?</message>
<title translate="true">Erase items</title>
</confirm>
<url path="customer/privacy/massErase"/>
<type>erase</type>
<label translate="true">Erase (GDPR)</label>
</settings>
</action>
</massaction>
</listingToolbar>
</listing>

0 comments on commit 81e65d3

Please sign in to comment.