<?php declare(strict_types=1);
namespace Cogi\CogiAdvancedContactForm;
use Shopware\Core\Content\Cms\Aggregate\CmsSlotTranslation\CmsSlotTranslationEntity;
use Shopware\Core\Defaults;
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\ContainsFilter;
use Shopware\Core\Framework\Plugin;
use Shopware\Core\Framework\Plugin\Context\ActivateContext;
use Shopware\Core\Framework\Plugin\Context\DeactivateContext;
use Shopware\Core\Framework\Plugin\Context\InstallContext;
use Shopware\Core\Framework\Plugin\Context\UninstallContext;
use Shopware\Core\Framework\Plugin\Context\UpdateContext;
use Doctrine\DBAL\Exception\UniqueConstraintViolationException;
use Shopware\Core\Content\ImportExport\Exception\FileNotFoundException;
use Shopware\Core\Content\MailTemplate\Aggregate\MailTemplateType\MailTemplateTypeEntity;
use Shopware\Core\Framework\Context;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\EqualsFilter;
use Shopware\Core\Framework\Uuid\Uuid;
use Shopware\Core\System\Language\LanguageEntity;
class CogiAdvancedContactForm extends Plugin {
public const COGI_NEW_FORM_SUBMIT_TEMPLATE_TYPE_TECHNICAL_NAME = 'cogi_advanced_contact_form_submit';
public function install(InstallContext $context): void {
// Install email templates
$this->installEmailTemplates($context->getContext());
}
public function update(UpdateContext $context): void {
parent::update($context);
}
public function activate(ActivateContext $context): void {
// your code you need to execute while your plugin gets activated
}
public function deactivate(DeactivateContext $context): void {
// your code you need to run while your plugin gets deactivated
}
public function uninstall(UninstallContext $context): void {
if ($context->keepUserData()) {
parent::uninstall($context);
return;
}
// Uninstall email templates
$this->removeEmailTemplate(self::COGI_NEW_FORM_SUBMIT_TEMPLATE_TYPE_TECHNICAL_NAME, $context->getContext());
// region remove existing customFields data
/** @var EntityRepositoryInterface $cmsSlotTranslationRepository */
$cmsSlotTranslationRepository = $this->container->get('cms_slot_translation.repository');
$criteria = new Criteria();
$criteria->addFilter(new ContainsFilter("customFields", "cogiAdvancedContactForm"));
$result = $cmsSlotTranslationRepository->search($criteria, $context->getContext());
/** @var CmsSlotTranslationEntity $cmsItem */
foreach ($result->getElements() as $cmsItem) {
$newCustomFields = $cmsItem->getCustomFields();
unset($newCustomFields['cogiAdvancedContactForm']);
if(count($newCustomFields) === 0){
$newCustomFields = null;
}
$cmsSlotTranslationRepository->update([
[
'cmsSlotId' => $cmsItem->getCmsSlotId(),
'cmsSlotVersionId' => $cmsItem->getVersionId(),
'languageId' => $cmsItem->getLanguageId(),
'customFields' => $newCustomFields
]
], $context->getContext());
}
// endregion
}
/**
* Installs all email templates
* @param $context
* @return void
*/
public function installEmailTemplates($context) {
// To store owner: Application mail
$this->addEmailTemplate(
[
'en-GB' => 'Advanced contact form - Message received',
'de-DE' => 'Erweitertes Kontaktformular - Anfrage erhalten'
],
self::COGI_NEW_FORM_SUBMIT_TEMPLATE_TYPE_TECHNICAL_NAME,
[
'en-GB' => 'Contact form received - {{ salesChannel.name }}',
'de-DE' => 'Kontaktanfrage erhalten - {{ salesChannel.name }}'
],
[
'en-GB' => 'This template is sent to shop administrators as soon as a visitor submits a contact form.',
'de-DE' => 'Dieses Template wird an Shopbetreiber verschickt, sobald ein Besucher ein Kontakformular absendet.'
],
[
'salesChannel' => 'sales_channel'
], $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
$defaultLocalCode = $this->getDefaultLocaleCode($context);
if (!in_array($defaultLocalCode, ['de-DE', 'en-GB'])) {
$mailTemplateType[0]['name'][$defaultLocalCode] = $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($defaultLocalCode, ['de-DE', 'en-GB'])) {
$mailTemplate[0]['senderName'][$defaultLocalCode] = '{{ salesChannel.translated.name }}';
$mailTemplate[0]['subject'][$defaultLocalCode] = $mailSubject['en-GB'];
$mailTemplate[0]['description'][$defaultLocalCode] = $mailDescription['en-GB'];
$mailTemplate[0]['contentPlain'][$defaultLocalCode] = $this->getMailContent('en-GB', $templateTypeTechnicalName, 'plain');
$mailTemplate[0]['contentHtml'][$defaultLocalCode] = $this->getMailContent('en-GB', $templateTypeTechnicalName, 'html');
}
try {
$mailTemplateTypeRepository->create($mailTemplateType, $context);
$mailTemplateRepository->create($mailTemplate, $context);
} catch (UniqueConstraintViolationException $exception) {
}
}
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 contant 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);
}
}
}