<?php declare(strict_types=1);
namespace Cogi\Affiliate;
use Cogi\Affiliate\ScheduledTask\TransactionTask;
use Doctrine\DBAL\Connection;
use Doctrine\DBAL\Exception\UniqueConstraintViolationException;
use Shopware\Core\Content\ImportExport\Exception\FileNotFoundException;
use Shopware\Core\Content\MailTemplate\Aggregate\MailTemplateType\MailTemplateTypeEntity;
use Shopware\Core\Defaults;
use Shopware\Core\Framework\Context;
use Shopware\Core\Framework\DataAbstractionLayer\EntityRepository;
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\MessageQueue\ScheduledTask\ScheduledTaskDefinition;
use Shopware\Core\Framework\Plugin;
use Shopware\Core\Framework\Plugin\Context\InstallContext;
use Shopware\Core\Framework\Plugin\Context\UninstallContext;
use Shopware\Core\Framework\Plugin\Context\UpdateContext;
use Shopware\Core\Framework\Uuid\Uuid;
use Shopware\Core\System\CustomField\CustomFieldTypes;
use Shopware\Core\System\Language\LanguageEntity;
use Shopware\Core\System\NumberRange\Aggregate\NumberRangeType\NumberRangeTypeEntity;
use Shopware\Core\System\NumberRange\NumberRangeEntity;
class CogiAffiliate extends Plugin
{
// Settings
public const MIN_PAYOUT = 100; // Minimum balance for payout
public const DAYS_TO_WAIT = 15; // At least 14 days correspond to the withdrawal period
// Mails
public const ADMIN_NEW_APPLICATION_TEMPLATE_TYPE_TECHNICAL_NAME = 'ca_admin_new_application';
public const AFFILIATE_APPLICATION_ACCEPT_TEMPLATE_TYPE_TECHNICAL_NAME = 'ca_affiliate_application_accept';
public const ADMIN_PAYOUT_REQUEST_TEMPLATE_TYPE_TECHNICAL_NAME = 'ca_admin_payout_request';
public const ADMIN_NEW_TRANSACTION_TEMPLATE_TYPE_TECHNICAL_NAME = 'ca_admin_new_transaction';
public const AFFILIATE_NEW_TRANSACTION_TEMPLATE_TYPE_TECHNICAL_NAME = 'ca_affiliate_new_transaction';
public const AFFILIATE_PAYOUT_DOCUMENT_TEMPLATE_TYPE_TECHNICAL_NAME = 'ca_affiliate_payout_document';
public const AFFILIATE_SEPA_XML_TEMPLATE_TYPE_TECHNICAL_NAME = 'ca_affiliate_sepa_xml';
// Number range
public const AFFILIATE_PAYOUT_NUMBER_RANGE = 'cogi_affiliate_payout';
/**
* Installs the plugin (Email templates, custom field set)
* @param InstallContext $installContext
* @return void
*/
public function install(InstallContext $installContext): void
{
// Install custom field set
$this->installCustomFieldSet($installContext->getContext());
// Install email templates
$this->installEmailTemplates($installContext->getContext());
}
/**
* postUpdate installs scheduled task, email templates and custom field set, if not existent
* @param UpdateContext $updateContext
* @return void
*/
public function postUpdate(UpdateContext $updateContext): void
{
parent::postUpdate($updateContext);
// Install scheduled task, if not existent (already exists for newer versions)
try {
$scheduledTaskRepository = $this->container->get('scheduled_task.repository');
$task = new TransactionTask();
$scheduledTaskRepository->create([
[
'name' => $task::getTaskName(),
'scheduledTaskClass' => get_class($task),
'runInterval' => $task::getDefaultInterval(),
'status' => ScheduledTaskDefinition::STATUS_SCHEDULED,
],
], Context::createDefaultContext());
} catch (\Exception $e) {}
// Update custom field set
$this->removeCustomFieldSet($updateContext->getContext());
$this->installCustomFieldSet($updateContext->getContext());
// Update email templates
$this->installEmailTemplates($updateContext->getContext());
}
/**
* Uninstalls the extension
* @param UninstallContext $uninstallContext
* @return void
*/
public function uninstall(UninstallContext $uninstallContext): void
{
parent::uninstall($uninstallContext);
if ($uninstallContext->keepUserData()) {
return;
}
$connection = $this->container->get(Connection::class);
$connection->executeStatement('
DROP TABLE IF EXISTS `ca_product_group_product`;
DROP TABLE IF EXISTS `ca_product_group_affiliate`;
DROP TABLE IF EXISTS `ca_product_group`;
DROP TABLE IF EXISTS `ca_partner_group`;
DROP TABLE IF EXISTS `ca_transaction`;
DROP TABLE IF EXISTS `ca_promotion_customer`;
');
try {
$connection->executeStatement('
ALTER TABLE `product`
DROP COLUMN `productGroups`;
');
} catch (\Exception $e) {
}
try {
$connection->executeStatement('
ALTER TABLE `promotion`
DROP COLUMN `affiliatePartner`;
');
} catch (\Exception $e) {
}
try {
$connection->executeStatement('
ALTER TABLE `customer`
DROP COLUMN `affiliatePromotion`;
');
} catch (\Exception $e) {
}
try {
$connection->executeStatement('
ALTER TABLE `product`
DROP COLUMN `ca_product_group_id`;
');
} catch (\Exception $e) {
}
// Uninstall custom field set
$this->removeCustomFieldSet($uninstallContext->getContext());
// Uninstall email templates
$this->removeEmailTemplate(self::ADMIN_NEW_APPLICATION_TEMPLATE_TYPE_TECHNICAL_NAME, $uninstallContext->getContext());
$this->removeEmailTemplate(self::AFFILIATE_APPLICATION_ACCEPT_TEMPLATE_TYPE_TECHNICAL_NAME, $uninstallContext->getContext());
$this->removeEmailTemplate(self::ADMIN_PAYOUT_REQUEST_TEMPLATE_TYPE_TECHNICAL_NAME, $uninstallContext->getContext());
$this->removeEmailTemplate(self::ADMIN_NEW_TRANSACTION_TEMPLATE_TYPE_TECHNICAL_NAME, $uninstallContext->getContext());
$this->removeEmailTemplate(self::AFFILIATE_NEW_TRANSACTION_TEMPLATE_TYPE_TECHNICAL_NAME, $uninstallContext->getContext());
$this->removeEmailTemplate(self::AFFILIATE_PAYOUT_DOCUMENT_TEMPLATE_TYPE_TECHNICAL_NAME, $uninstallContext->getContext());
$this->removeEmailTemplate(self::AFFILIATE_SEPA_XML_TEMPLATE_TYPE_TECHNICAL_NAME, $uninstallContext->getContext());
// Uninstall number range
$this->removeNumberRange($connection, $uninstallContext->getContext());
}
/**
* Installs the custom field set
* @param Context $context
* @return void
*/
public function installCustomFieldSet(Context $context) {
$customFieldSetRepository = $this->container->get('custom_field_set.repository');
$fieldSetId = $this->getFieldSetId($customFieldSetRepository, $context);
if (!$fieldSetId) {
$customFieldSetRepository->create([[
'name' => 'cogi_affiliate_set',
'customFields' => [
[
'name' => 'ca_active',
'type' => CustomFieldTypes::BOOL,
'config' => [
'type' => CustomFieldTypes::SWITCH,
'label' => [
'en-GB' => 'Active',
'de-DE' => 'Aktiv'
],
'helpText' => [
'en-GB' => 'Indicates whether an affiliate is active. Can be changed in the affiliate overview.',
'de-DE' => 'Gibt an, ob ein Affiliate aktiv ist. Kann in der Affiliate-Übersicht geändert werden.'
],
'componentName' => 'sw-field',
'customFieldType' => CustomFieldTypes::SWITCH,
'customFieldPosition' => 1,
'translated' => false,
'disabled' => true
],
], [
'name' => 'ca_lifetime_affiliate_id',
'type' => CustomFieldTypes::ENTITY,
'config' => [
'entity' => 'customer',
'label' => [
'en-GB' => 'Assign lifetime affiliate',
'de-DE' => 'Dauerhaften Affiliate zuweisen'
],
'placeholder' => [
'en-GB' => 'Lifetime affiliate',
'de-DE' => 'Dauerhafter Affiliate'
],
'helpText' => [
'en-GB' => 'Provisions every valid order in favor of the affiliate, if activated in the plugin configuration',
'de-DE' => 'Provisioniert jede gültige Bestellung zugunsten des Affiliates, sofern in der Plugin-Konfiguration aktiviert'
],
'componentName' => 'sw-entity-single-select',
'customFieldType' => CustomFieldTypes::ENTITY,
'customFieldPosition' => 2,
'labelProperty' => ["firstName", "lastName"],
'translated' => false
],
], [
'name' => 'ca_code',
'type' => CustomFieldTypes::TEXT,
'config' => [
'label' => [
'en-GB' => 'Affiliate code',
'de-DE' => 'Affiliate-Code'
],
'placeholder' => [
'en-GB' => 'Affiliate code',
'de-DE' => 'Affiliate-Code'
],
'helpText' => [
'en-GB' => 'Can be changed in the affiliate overview.',
'de-DE' => 'Kann in der Affiliate-Übersicht geändert werden.'
],
'customFieldType' => CustomFieldTypes::TEXT,
'customFieldPosition' => 3,
'translated' => false,
'disabled' => true
],
], [
'name' => 'ca_multiplier',
'type' => 'number',
'config' => [
'label' => [
'en-GB' => 'Individual provision multiplier',
'de-DE' => 'Individueller Provisionsmultiplikator'
],
'placeholder' => [
'en-GB' => 'Individual provision multiplier',
'de-DE' => 'Individueller Provisionsmultiplikator'
],
'helpText' => [
'en-GB' => 'Can be changed in the affiliate overview.',
'de-DE' => 'Kann in der Affiliate-Übersicht geändert werden.'
],
'numberType' => CustomFieldTypes::FLOAT,
'componentName' => 'sw-field',
'customFieldType' => 'number',
'max' => 10,
'min' => 0,
'step' => 0.01,
'customFieldPosition' => 4,
'translated' => false,
'disabled' => true
],
], [
'name' => 'ca_iban',
'type' => CustomFieldTypes::TEXT,
'config' => [
'label' => [
'en-GB' => 'IBAN',
'de-DE' => 'IBAN'
],
'placeholder' => [
'en-GB' => 'IBAN',
'de-DE' => 'IBAN'
],
'helpText' => [
'en-GB' => 'Can be changed in the affiliate overview.',
'de-DE' => 'Kann in der Affiliate-Übersicht geändert werden.'
],
'customFieldType' => CustomFieldTypes::TEXT,
'customFieldPosition' => 5,
'translated' => false,
'disabled' => true
],
], [
'name' => 'ca_bic',
'type' => CustomFieldTypes::TEXT,
'config' => [
'label' => [
'en-GB' => 'BIC',
'de-DE' => 'BIC'
],
'placeholder' => [
'en-GB' => 'BIC',
'de-DE' => 'BIC'
],
'helpText' => [
'en-GB' => 'Can be changed in the affiliate overview.',
'de-DE' => 'Kann in der Affiliate-Übersicht geändert werden.'
],
'customFieldType' => CustomFieldTypes::TEXT,
'customFieldPosition' => 6,
'translated' => false,
'disabled' => true
],
], [
'name' => 'ca_company',
'type' => CustomFieldTypes::TEXT,
'config' => [
'label' => [
'en-GB' => 'Company',
'de-DE' => 'Firma'
],
'placeholder' => [
'en-GB' => 'Company',
'de-DE' => 'Firma'
],
'helpText' => [
'en-GB' => 'Used only if the configuration of the extended master data is activated',
'de-DE' => 'Wird nur verwendet, wenn die Konfiguration der erweiterten Stammdaten aktiviert ist'
],
'customFieldType' => CustomFieldTypes::TEXT,
'customFieldPosition' => 7,
'translated' => false
],
], [
'name' => 'ca_name',
'type' => CustomFieldTypes::TEXT,
'config' => [
'label' => [
'en-GB' => 'Name',
'de-DE' => 'Name'
],
'placeholder' => [
'en-GB' => 'Name',
'de-DE' => 'Name'
],
'helpText' => [
'en-GB' => 'Used only if the configuration of the extended master data is activated',
'de-DE' => 'Wird nur verwendet, wenn die Konfiguration der erweiterten Stammdaten aktiviert ist'
],
'customFieldType' => CustomFieldTypes::TEXT,
'customFieldPosition' => 8,
'translated' => false
],
], [
'name' => 'ca_street',
'type' => CustomFieldTypes::TEXT,
'config' => [
'label' => [
'en-GB' => 'Street address',
'de-DE' => 'Straße und Hausnummer'
],
'placeholder' => [
'en-GB' => 'Street address',
'de-DE' => 'Straße und Hausnummer'
],
'helpText' => [
'en-GB' => 'Used only if the configuration of the extended master data is activated',
'de-DE' => 'Wird nur verwendet, wenn die Konfiguration der erweiterten Stammdaten aktiviert ist'
],
'customFieldType' => CustomFieldTypes::TEXT,
'customFieldPosition' => 9,
'translated' => false
],
], [
'name' => 'ca_zipcode',
'type' => CustomFieldTypes::TEXT,
'config' => [
'label' => [
'en-GB' => 'Postal code',
'de-DE' => 'PLZ'
],
'placeholder' => [
'en-GB' => 'Postal code',
'de-DE' => 'PLZ'
],
'helpText' => [
'en-GB' => 'Used only if the configuration of the extended master data is activated',
'de-DE' => 'Wird nur verwendet, wenn die Konfiguration der erweiterten Stammdaten aktiviert ist'
],
'customFieldType' => CustomFieldTypes::TEXT,
'customFieldPosition' => 10,
'translated' => false
],
], [
'name' => 'ca_city',
'type' => CustomFieldTypes::TEXT,
'config' => [
'label' => [
'en-GB' => 'City',
'de-DE' => 'Ort'
],
'placeholder' => [
'en-GB' => 'City',
'de-DE' => 'Ort'
],
'helpText' => [
'en-GB' => 'Used only if the configuration of the extended master data is activated',
'de-DE' => 'Wird nur verwendet, wenn die Konfiguration der erweiterten Stammdaten aktiviert ist'
],
'customFieldType' => CustomFieldTypes::TEXT,
'customFieldPosition' => 11,
'translated' => false
],
], [
'name' => 'ca_vatid',
'type' => CustomFieldTypes::TEXT,
'config' => [
'label' => [
'en-GB' => 'VAT Reg.No.',
'de-DE' => 'Umsatzsteuer-ID'
],
'placeholder' => [
'en-GB' => 'VAT Reg.No.',
'de-DE' => 'Umsatzsteuer-ID'
],
'helpText' => [
'en-GB' => 'Used only if the configuration of the extended master data is activated',
'de-DE' => 'Wird nur verwendet, wenn die Konfiguration der erweiterten Stammdaten aktiviert ist'
],
'customFieldType' => CustomFieldTypes::TEXT,
'customFieldPosition' => 12,
'translated' => false
],
], [
'name' => 'ca_vatexempt',
'type' => CustomFieldTypes::BOOL,
'config' => [
'type' => CustomFieldTypes::SWITCH,
'label' => [
'en-GB' => 'VAT exempt',
'de-DE' => 'Umsatzsteuer befreit'
],
'helpText' => [
'en-GB' => 'Used only if the configuration of the extended master data is activated',
'de-DE' => 'Wird nur verwendet, wenn die Konfiguration der erweiterten Stammdaten aktiviert ist'
],
'componentName' => 'sw-field',
'customFieldType' => CustomFieldTypes::SWITCH,
'customFieldPosition' => 13,
'translated' => false
],
], [
'name' => 'ca_taxnumber',
'type' => CustomFieldTypes::TEXT,
'config' => [
'label' => [
'en-GB' => 'Tax no',
'de-DE' => 'Steuernummer'
],
'placeholder' => [
'en-GB' => 'Tax no',
'de-DE' => 'Steuernummer'
],
'helpText' => [
'en-GB' => 'Used only if the configuration of the extended master data is activated',
'de-DE' => 'Wird nur verwendet, wenn die Konfiguration der erweiterten Stammdaten aktiviert ist'
],
'customFieldType' => CustomFieldTypes::TEXT,
'customFieldPosition' => 14,
'translated' => false
],
]
],
'relations' => [
[
'entityName' => 'customer'
]
],
'config' => [
'label' => [
'en-GB' => 'Affiliate Marketing',
'de-DE' => 'Affiliate-Marketing'
],
'translated' => true
],
]], $context);
}
}
/**
* Removes the custom field set
* @param Context $context
* @return void
*/
public function removeCustomFieldSet(Context $context) {
$customFieldSetRepository = $this->container->get('custom_field_set.repository');
$fieldSetId = $this->getFieldSetId($customFieldSetRepository, $context);
if ($fieldSetId) {
$customFieldSetRepository->delete([["id" => $fieldSetId]], $context);
}
}
/**
* Gets the custom field set id
* @param $customFieldSetRepository
* @param Context $context
* @return string|null
*/
public function getFieldSetId($customFieldSetRepository, Context $context): ?string
{
$criteria = new Criteria();
$criteria->addFilter(new EqualsFilter('custom_field_set.name', 'cogi_affiliate_set'));
$customFieldSet = $customFieldSetRepository->search($criteria, $context)->first();
return (!$customFieldSet ? null : $customFieldSet->getId());
}
/**
* Installs all email templates
* @param Context $context
* @return void
*/
public function installEmailTemplates(Context $context) {
// To store owner: Application mail
$this->addEmailTemplate(
[
'en-GB' => 'Affiliate Marketing (Admin): Affiliate application',
'de-DE' => 'Affiliate-Marketing (Admin): Affiliate-Bewerbung'
],
self::ADMIN_NEW_APPLICATION_TEMPLATE_TYPE_TECHNICAL_NAME,
[
'en-GB' => 'A new affiliate has registered!',
'de-DE' => 'Ein neuer Affiliate hat sich beworben!'
],
[
'en-GB' => 'This template is sent to the store owner as soon as a new affiliate applies.',
'de-DE' => 'Dieses Template wird an den Shopbetreiber verschickt, sobald sich ein neuer Affiliate bewirbt.'
],
[
'customer' => 'customer',
'salesChannel' => 'sales_channel'
], $context);
// To affiliate: Application accepted
$this->addEmailTemplate(
[
'en-GB' => 'Affiliate Marketing (Affiliate): Application accepted',
'de-DE' => 'Affiliate-Marketing (Affiliate): Bewerbung akzeptiert'
],
self::AFFILIATE_APPLICATION_ACCEPT_TEMPLATE_TYPE_TECHNICAL_NAME,
[
'en-GB' => 'Your affiliate-application has been accepted!',
'de-DE' => 'Ihre Affiliate-Bewerbung wurde akzeptiert!'
],
[
'en-GB' => 'This template is sent to the affiliate as soon as his application is accepted.',
'de-DE' => 'Dieses Template wird an den Affiliate verschickt, sobald seine Bewerbung akzeptiert wurde.'
],
[
'customer' => 'customer',
'salesChannel' => 'sales_channel'
], $context);
// To store owner: Payout request mail
$this->addEmailTemplate(
[
'en-GB' => 'Affiliate Marketing (Admin): Affiliate payout request',
'de-DE' => 'Affiliate-Marketing (Admin): Auszahlungsanfrage von Affiliate'
],
self::ADMIN_PAYOUT_REQUEST_TEMPLATE_TYPE_TECHNICAL_NAME,
[
'en-GB' => 'New payout request from an affiliate',
'de-DE' => 'Neue Auszahlungsanfrage eines Affiliates'
],
[
'en-GB' => 'This template is sent to the store owner for each payout request by an affiliate.',
'de-DE' => 'Dieses Template wird an den Shopbetreiber für jede Auszahlungsanfrage eines Affiliates verschickt.'
],
[
'customer' => 'customer',
'salesChannel' => 'sales_channel'
], $context);
// To store owner: New transaction
$this->addEmailTemplate(
[
'en-GB' => 'Affiliate Marketing (Admin): New transaction',
'de-DE' => 'Affiliate-Marketing (Admin): Neue Transaktion'
],
self::ADMIN_NEW_TRANSACTION_TEMPLATE_TYPE_TECHNICAL_NAME,
[
'en-GB' => 'A new affiliate provision has been recorded',
'de-DE' => 'Eine neue Affiliate-Provision wurde erfasst'
],
[
'en-GB' => 'This template is sent to the store owner for each new provision by an affiliate.',
'de-DE' => 'Dieses Template wird an den Shopbetreiber für jede neue Provisionserfassung eines Affiliates verschickt.'
],
[
'customer' => 'customer',
'salesChannel' => 'sales_channel'
], $context);
// To affiliate: New transaction
$this->addEmailTemplate(
[
'en-GB' => 'Affiliate Marketing (Affiliate): New transaction',
'de-DE' => 'Affiliate-Marketing (Affiliate): Neue Transaktion'
],
self::AFFILIATE_NEW_TRANSACTION_TEMPLATE_TYPE_TECHNICAL_NAME,
[
'en-GB' => 'A new affiliate provision has been tracked',
'de-DE' => 'Eine neue Affiliate-Provision wurde erfasst'
],
[
'en-GB' => 'This template is sent to the affiliate for each new provision.',
'de-DE' => 'Dieses Template wird an den Affiliate für jede neue Provisionserfassung verschickt.'
],
[
'customer' => 'customer',
'salesChannel' => 'sales_channel'
], $context);
// To affiliate: Payout document
$this->addEmailTemplate(
[
'en-GB' => 'Affiliate Marketing (Affiliate): Payout receipt',
'de-DE' => 'Affiliate-Marketing (Affiliate): Auszahlungsbeleg'
],
self::AFFILIATE_PAYOUT_DOCUMENT_TEMPLATE_TYPE_TECHNICAL_NAME,
[
'en-GB' => 'Affiliate-Marketing Payout receipt',
'de-DE' => 'Affiliate Marketing Auszahlungsbeleg'
],
[
'en-GB' => 'This template is sent to the affiliate if payout receipts are enabled.',
'de-DE' => 'Dieses Template wird an den Affiliate gesendet, wenn Auszahlungsbelege aktiviert sind.'
],
[
'customer' => 'customer'
], $context);
// To custom receiver: SEPA XML
$this->addEmailTemplate(
[
'en-GB' => 'Affiliate Marketing (Affiliate): SEPA XML',
'de-DE' => 'Affiliate-Marketing (Affiliate): SEPA XML'
],
self::AFFILIATE_SEPA_XML_TEMPLATE_TYPE_TECHNICAL_NAME,
[
'en-GB' => 'SEPA payout document for affiliate provisions',
'de-DE' => 'SEPA Auszahlungsbeleg für Affiliate-Provisionen'
],
[
'en-GB' => 'This template is sent if SEPA XML documents are enabled.',
'de-DE' => 'Dieses Template wird gesendet, wenn SEPA XML-Dokumente aktiviert sind.'
],
[], $context);
}
/**
* Adds a single email template, if it does not already exist
* @param $templateTypeName
* @param $templateTypeTechnicalName
* @param $mailSubject
* @param $mailDescription
* @param $availableEntities
* @param Context $context
* @return void
*/
public function addEmailTemplate($templateTypeName, $templateTypeTechnicalName, $mailSubject, $mailDescription, $availableEntities, Context $context)
{
/** @var EntityRepositoryInterface $mailTemplateTypeRepository */
$mailTemplateTypeRepository = $this->container->get('mail_template_type.repository');
/** @var EntityRepositoryInterface $mailTemplateRepository */
$mailTemplateRepository = $this->container->get('mail_template.repository');
$mailTemplateTypeId = Uuid::randomHex();
$mailTemplateType = [
[
'id' => $mailTemplateTypeId,
'name' => $templateTypeName,
'technicalName' => $templateTypeTechnicalName,
'availableEntities' => $availableEntities
]
];
// Add fallback
$defaultLocaleCode = $this->getDefaultLocaleCode($context);
if (!in_array($defaultLocaleCode, ['de-DE', 'en-GB'])) {
$mailTemplateType[0]['name'][$defaultLocaleCode] = $templateTypeName['en-GB'];
}
$mailTemplate = [
[
'id' => Uuid::randomHex(),
'mailTemplateTypeId' => $mailTemplateTypeId,
'senderName' => [
'en-GB' => '{{ salesChannel.translated.name }}',
'de-DE' => '{{ salesChannel.translated.name }}'
],
'subject' => $mailSubject,
'description' => $mailDescription,
'contentPlain' => [
'en-GB' => $this->getMailContent('en-GB', $templateTypeTechnicalName, 'plain'),
'de-DE' => $this->getMailContent('de-DE', $templateTypeTechnicalName, 'plain')
],
'contentHtml' => [
'en-GB' => $this->getMailContent('en-GB', $templateTypeTechnicalName, 'html'),
'de-DE' => $this->getMailContent('de-DE', $templateTypeTechnicalName, 'html')
]
]
];
// Add fallback
if (!in_array($defaultLocaleCode, ['de-DE', 'en-GB'])) {
$mailTemplate[0]['senderName'][$defaultLocaleCode] = '{{ salesChannel.translated.name }}';
$mailTemplate[0]['subject'][$defaultLocaleCode] = $mailSubject['en-GB'];
$mailTemplate[0]['description'][$defaultLocaleCode] = $mailDescription['en-GB'];
$mailTemplate[0]['contentPlain'][$defaultLocaleCode] = $this->getMailContent('en-GB', $templateTypeTechnicalName, 'plain');
$mailTemplate[0]['contentHtml'][$defaultLocaleCode] = $this->getMailContent('en-GB', $templateTypeTechnicalName, 'html');
}
try {
$mailTemplateTypeRepository->create($mailTemplateType, $context);
$mailTemplateRepository->create($mailTemplate, $context);
} catch (UniqueConstraintViolationException $exception) {}
}
/**
* Gets the default locale code
* @param $context
* @return string
*/
private function getDefaultLocaleCode($context): string {
/** @var EntityRepository $languageRepository */
$languageRepository = $this->container->get('language.repository');
$criteria = new Criteria();
$criteria->addAssociation('locale');
$criteria->addFilter(new EqualsFilter('id', Defaults::LANGUAGE_SYSTEM));
/** @var LanguageEntity $languageEntity */
$languageEntity = $languageRepository->search($criteria, $context)->get(Defaults::LANGUAGE_SYSTEM);
return $languageEntity->getLocale()->getCode();
}
/**
* Gets the content of a mail while considering the locale
* @param string $locale
* @param string $prefix
* @param string $type
* @return string
*/
private function getMailContent(string $locale, string $prefix, string $type): string {
$path = $this->getPath() . '/Resources/email/' . $locale . '/';
switch ($type) {
case 'html':
$ext = 'html';
break;
case 'plain':
$ext = 'txt';
break;
default:
$ext = 'txt';
}
$file = $path . $prefix . '.' . $ext;
if (!is_file($file)) {
throw new FileNotFoundException($file);
}
return file_get_contents($file);
}
/**
* Removes a specific email template by templateTypeTechnicalName
* @param $templateTypeTechnicalName
* @param Context $context
* @return void
*/
public function removeEmailTemplate($templateTypeTechnicalName, Context $context)
{
/** @var EntityRepositoryInterface $mailTemplateTypeRepository */
$mailTemplateTypeRepository = $this->container->get('mail_template_type.repository');
/** @var EntityRepositoryInterface $mailTemplateRepository */
$mailTemplateRepository = $this->container->get('mail_template.repository');
/** @var MailTemplateTypeEntity $customMailTemplateType */
$customMailTemplateType = $mailTemplateTypeRepository->search(
(new Criteria())
->addFilter(new EqualsFilter('technicalName', $templateTypeTechnicalName)),
$context
)->first();
if ($customMailTemplateType) {
$mailTemplateIds = $mailTemplateRepository->searchIds(
(new Criteria())
->addFilter(new EqualsFilter('mailTemplateTypeId', $customMailTemplateType->getId())),
$context
)->getIds();
$ids = array_map(static function ($id) {
return ['id' => $id];
}, $mailTemplateIds);
$mailTemplateRepository->delete($ids, $context);
// Delete the TemplateType which were added by this Plugin
$mailTemplateTypeRepository->delete([
['id' => $customMailTemplateType->getId()]
], $context);
}
}
public function removeNumberRange($connection, Context $context)
{
/** @var EntityRepositoryInterface $numberRangeTypeRepository */
$numberRangeTypeRepository = $this->container->get('number_range_type.repository');
/** @var EntityRepositoryInterface $numberRangeTypeRepository */
$numberRangeRepository = $this->container->get('number_range.repository');
/** @var NumberRangeTypeEntity $numberRangeType */
$numberRangeType = $numberRangeTypeRepository->search(
(new Criteria())
->addFilter(new EqualsFilter('technicalName', self::AFFILIATE_PAYOUT_NUMBER_RANGE)),
$context
)->getEntities()->first();
if ($numberRangeType) {
$numberRangeTypeId = $numberRangeType->getId();
$connection->executeStatement('
DELETE FROM `number_range`
WHERE `type_id` = UNHEX(\'' . $numberRangeTypeId . '\')
');
/** @var NumberRangeEntity $numberRange */
$numberRange = $numberRangeRepository->search(
(new Criteria())
->addFilter(new EqualsFilter('typeId', $numberRangeTypeId)),
$context
)->getEntities()->first();
if ($numberRange) {
$numberRangeId = $numberRange->getId();
$connection->executeStatement('
DELETE FROM `number_range_state`
WHERE `number_range_id` = UNHEX(\'' . $numberRangeId . '\')
');
}
$connection->executeStatement('
DELETE FROM `number_range_type`
WHERE `technical_name` LIKE \'%' . self::AFFILIATE_PAYOUT_NUMBER_RANGE . '%\'
');
}
}
}