<?php
declare(strict_types=1);
namespace CioDataRetention;
use Doctrine\DBAL\Exception\UniqueConstraintViolationException;
use Shopware\Core\Framework\DataAbstractionLayer\EntityRepositoryInterface;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Criteria;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\EqualsFilter;
use Shopware\Core\Framework\Plugin\Context\ActivateContext;
use Shopware\Core\Framework\Plugin\Context\InstallContext;
use Shopware\Core\Framework\Plugin\Context\UninstallContext;
use Shopware\Core\Framework\Plugin;
use Shopware\Core\Framework\Uuid\Uuid;
class CioDataRetention extends Plugin
{
// CIO-AI-Driven
public const CUSTOMER_DELETION_MAIL_TEMPLATE_TYPE_NAME = 'Customer account deletion (Double-Opt-Out)';
public const CUSTOMER_DELETION_MAIL_TEMPLATE_TYPE_TECHNICAL_NAME = 'cio_data_retention_customer_deletion';
public function install(InstallContext $installContext): void
{
parent::install($installContext);
$this->ensureCustomerDeletionMailTemplateExists($installContext->getContext());
}
public function activate(ActivateContext $activateContext): void
{
parent::activate($activateContext);
// CIO-AI-Driven: ensure template exists even if plugin was already installed before this feature was added.
$this->ensureCustomerDeletionMailTemplateExists($activateContext->getContext());
}
public function uninstall(UninstallContext $uninstallContext): void
{
parent::uninstall($uninstallContext);
if ($uninstallContext->keepUserData()) {
return;
}
/** @var EntityRepositoryInterface $mailTemplateTypeRepository */
$mailTemplateTypeRepository = $this->container->get('mail_template_type.repository');
/** @var EntityRepositoryInterface $mailTemplateRepository */
$mailTemplateRepository = $this->container->get('mail_template.repository');
$mailTemplateType = $mailTemplateTypeRepository->search(
(new Criteria())->addFilter(new EqualsFilter('technicalName', self::CUSTOMER_DELETION_MAIL_TEMPLATE_TYPE_TECHNICAL_NAME)),
$uninstallContext->getContext()
)->first();
if ($mailTemplateType === null) {
return;
}
$mailTemplateIds = $mailTemplateRepository->searchIds(
(new Criteria())->addFilter(new EqualsFilter('mailTemplateTypeId', $mailTemplateType->getId())),
$uninstallContext->getContext()
)->getIds();
if ($mailTemplateIds !== []) {
$mailTemplateRepository->delete(array_map(static fn (string $id): array => ['id' => $id], $mailTemplateIds), $uninstallContext->getContext());
}
$mailTemplateTypeRepository->delete([
['id' => $mailTemplateType->getId()],
], $uninstallContext->getContext());
}
private function ensureCustomerDeletionMailTemplateExists(\Shopware\Core\Framework\Context $context): void
{
/** @var EntityRepositoryInterface $mailTemplateTypeRepository */
$mailTemplateTypeRepository = $this->container->get('mail_template_type.repository');
/** @var EntityRepositoryInterface $mailTemplateRepository */
$mailTemplateRepository = $this->container->get('mail_template.repository');
$existingType = $mailTemplateTypeRepository->search(
(new Criteria())->addFilter(new EqualsFilter('technicalName', self::CUSTOMER_DELETION_MAIL_TEMPLATE_TYPE_TECHNICAL_NAME)),
$context
)->first();
$mailTemplateTypeId = $existingType ? $existingType->getId() : Uuid::randomHex();
if ($existingType === null) {
try {
$mailTemplateTypeRepository->create([
[
'id' => $mailTemplateTypeId,
'name' => self::CUSTOMER_DELETION_MAIL_TEMPLATE_TYPE_NAME,
'technicalName' => self::CUSTOMER_DELETION_MAIL_TEMPLATE_TYPE_TECHNICAL_NAME,
'availableEntities' => [
'salesChannel' => 'sales_channel',
],
],
], $context);
} catch (UniqueConstraintViolationException $exception) {
// created concurrently / already exists
}
}
$existingTemplateId = $mailTemplateRepository->searchIds(
(new Criteria())
->addFilter(new EqualsFilter('mailTemplateTypeId', $mailTemplateTypeId))
->setLimit(1),
$context
)->firstId();
if ($existingTemplateId !== null) {
return;
}
try {
$mailTemplateRepository->create([
[
'id' => Uuid::randomHex(),
'mailTemplateTypeId' => $mailTemplateTypeId,
'subject' => [
'de-DE' => 'Bestätige die Löschung deines Kundenkontos',
'en-GB' => 'Confirm deletion of your customer account',
],
'senderName' => [
'de-DE' => '{{ salesChannel.name }}',
'en-GB' => '{{ salesChannel.name }}',
],
'description' => [
'de-DE' => 'CioDataRetention - Bestätigung der Kundenkonto Löschung',
'en-GB' => 'CioDataRetention - Customer account deletion confirmation',
],
'contentPlain' => [
'de-DE' => "Hallo,\n\nbitte bestätige die Löschung deines Kundenkontos über folgenden Link:\n\n{{ confirmUrl }}\n\nWenn du diese Anfrage nicht gestellt hast, ignoriere bitte diese E-Mail.\n",
'en-GB' => "Hello,\n\nplease confirm deletion of your customer account via the following link:\n\n{{ confirmUrl }}\n\nIf you did not request this, please ignore this email.\n",
],
'contentHtml' => [
'de-DE' => '<p>Hallo,</p><p>bitte bestätige die Löschung deines Kundenkontos über folgenden Link:</p><p><a href="{{ confirmUrl }}">{{ confirmUrl }}</a></p><p>Wenn du diese Anfrage nicht gestellt hast, ignoriere bitte diese E-Mail.</p>',
'en-GB' => '<p>Hello,</p><p>please confirm deletion of your customer account via the following link:</p><p><a href="{{ confirmUrl }}">{{ confirmUrl }}</a></p><p>If you did not request this, please ignore this email.</p>',
],
],
], $context);
} catch (UniqueConstraintViolationException $exception) {
// already exists
}
}
}