<?php declare(strict_types=1);
namespace Sas\BlogModule;
use Doctrine\DBAL\Connection;
use Sas\BlogModule\Content\Blog\BlogEntriesDefinition;
use Sas\BlogModule\Util\Lifecycle;
use Sas\BlogModule\Util\Update;
use Shopware\Core\Content\MailTemplate\Aggregate\MailTemplateType\MailTemplateTypeEntity;
use Shopware\Core\Content\MailTemplate\MailTemplateEntity;
use Shopware\Core\Framework\Context;
use Shopware\Core\Framework\DataAbstractionLayer\EntityRepositoryInterface;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Criteria;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\EqualsAnyFilter;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\EqualsFilter;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\MultiFilter;
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\SystemConfig\SystemConfigService;
class SasBlogModule extends Plugin
{
public const ANONYMOUS_AUTHOR_ID = '64f4c60194634128b9b85d9299797c45';
public const TEMPLATE_TYPE_NAME = 'NewsMailType';
public const TEMPLATE_TYPE_TECHNICAL_NAME = 'news_mail';
public const MAIL_TEMPLATE_NAME = 'NewsMailTemplate';
public function install(InstallContext $installContext): void
{
parent::install($installContext);
$this->createBlogMediaFolder($installContext->getContext());
$this->getLifeCycle()->install($installContext->getContext());
$this->createNewsTemplateType($installContext);
}
public function uninstall(UninstallContext $context): void
{
parent::uninstall($context);
if ($context->keepUserData()) {
return;
}
/*
* We need to uninstall our default media folder,
* the media folder and the thumbnail sizes.
* However, we have to clean this up within a next update :)
*/
$this->deleteMediaFolder($context->getContext());
$this->deleteDefaultMediaFolder($context->getContext());
$this->deleteSeoUrlTemplate($context->getContext());
$this->checkForThumbnailSizes($context->getContext());
/**
* And of course we need to drop our tables
*/
$connection = $this->container->get(Connection::class);
$connection->executeStatement('SET FOREIGN_KEY_CHECKS=0;');
$connection->executeStatement('DROP TABLE IF EXISTS `sas_blog_entries`');
$connection->executeStatement('DROP TABLE IF EXISTS `sas_blog_entries_translation`');
$connection->executeStatement('DROP TABLE IF EXISTS `sas_blog_blog_category`');
$connection->executeStatement('DROP TABLE IF EXISTS `sas_blog_category_translation`');
$connection->executeStatement('DROP TABLE IF EXISTS `sas_blog_category`');
$connection->executeStatement('DROP TABLE IF EXISTS `sas_blog_author_translation`');
$connection->executeStatement('DROP TABLE IF EXISTS `sas_blog_author`');
$connection->executeStatement('DROP TABLE IF EXISTS `sas_blog_entries_read_state`');
$connection->executeStatement('DROP TABLE IF EXISTS `sas_blog_newsletter`');
/** @var EntityRepositoryInterface $cmsBlockRepo */
$cmsBlockRepo = $this->container->get('cms_block.repository');
//$context = Context::createDefaultContext();
$criteria = new Criteria();
$criteria->addFilter(new EqualsAnyFilter('type', ['blog-detail', 'blog-listing']));
$cmsBlocks = $cmsBlockRepo->searchIds($criteria, $context->getContext());
$cmsBlockRepo->delete(array_values($cmsBlocks->getData()), $context->getContext());
$connection->executeQuery('SET FOREIGN_KEY_CHECKS=1;');
$this->deleteNewsTemplateType($context);
}
public function update(UpdateContext $updateContext): void
{
parent::update($updateContext);
(new Update())->update($this->container, $updateContext);
if (version_compare($updateContext->getCurrentPluginVersion(), '1.1.0', '<')) {
$this->createBlogMediaFolder($updateContext->getContext());
}
}
/**
* We need to create a folder for the blog media with it's,
* own configuration to generate thumbnails for the teaser image.
*/
public function createBlogMediaFolder(Context $context): void
{
$this->deleteDefaultMediaFolder($context);
$this->checkForThumbnailSizes($context);
/** @var EntityRepositoryInterface $mediaFolderRepository */
$mediaFolderRepository = $this->container->get('media_default_folder.repository');
$mediaFolderRepository->create([
[
'entity' => BlogEntriesDefinition::ENTITY_NAME,
'associationFields' => ['media'],
'folder' => [
'name' => 'Blog Images',
'useParentConfiguration' => false,
'configuration' => [
'createThumbnails' => true,
'mediaThumbnailSizes' => [
[
'width' => 650,
'height' => 330,
],
],
],
],
],
], $context);
}
private function deleteDefaultMediaFolder(Context $context): void
{
$criteria = new Criteria();
$criteria->addFilter(
new EqualsAnyFilter('entity', [
BlogEntriesDefinition::ENTITY_NAME,
])
);
/** @var EntityRepositoryInterface $mediaFolderRepository */
$mediaFolderRepository = $this->container->get('media_default_folder.repository');
$mediaFolderIds = $mediaFolderRepository->searchIds($criteria, $context)->getIds();
if (!empty($mediaFolderIds)) {
$ids = array_map(static function ($id) {
return ['id' => $id];
}, $mediaFolderIds);
$mediaFolderRepository->delete($ids, $context);
}
}
private function deleteMediaFolder(Context $context): void
{
$criteria = new Criteria();
$criteria->addFilter(
new EqualsFilter('name', 'Blog Images')
);
/** @var EntityRepositoryInterface $mediaFolderRepository */
$mediaFolderRepository = $this->container->get('media_folder.repository');
$mediaFolderRepository->search($criteria, $context);
$mediaFolderIds = $mediaFolderRepository->searchIds($criteria, $context)->getIds();
if (!empty($mediaFolderIds)) {
$ids = array_map(static function ($id) {
return ['id' => $id];
}, $mediaFolderIds);
$mediaFolderRepository->delete($ids, $context);
}
}
private function deleteSeoUrlTemplate(Context $context): void
{
$criteria = new Criteria();
$criteria->addFilter(
new EqualsFilter('entityName', 'sas_blog_entries')
);
/** @var EntityRepositoryInterface $seoUrlTemplateRepository */
$seoUrlTemplateRepository = $this->container->get('seo_url_template.repository');
$seoUrlTemplateRepository->search($criteria, $context);
$seoUrlTemplateIds = $seoUrlTemplateRepository->searchIds($criteria, $context)->getIds();
if (!empty($seoUrlTemplateIds)) {
$ids = array_map(static function ($id) {
return ['id' => $id];
}, $seoUrlTemplateIds);
$seoUrlTemplateRepository->delete($ids, $context);
}
}
private function checkForThumbnailSizes(Context $context): void
{
$criteria = new Criteria();
$criteria->addFilter(
new MultiFilter(
MultiFilter::CONNECTION_AND,
[
new EqualsFilter('width', 650),
new EqualsFilter('height', 330),
]
)
);
/** @var EntityRepositoryInterface $thumbnailSizeRepository */
$thumbnailSizeRepository = $this->container->get('media_thumbnail_size.repository');
$thumbnailIds = $thumbnailSizeRepository->searchIds($criteria, $context)->getIds();
if (!empty($thumbnailIds)) {
$ids = array_map(static function ($id) {
return ['id' => $id];
}, $thumbnailIds);
$thumbnailSizeRepository->delete($ids, $context);
}
}
private function getLifeCycle(): Lifecycle
{
/** @var SystemConfigService $systemConfig */
$systemConfig = $this->container->get(SystemConfigService::class);
/** @var EntityRepositoryInterface $cmsPageRepository */
$cmsPageRepository = $this->container->get('cms_page.repository');
return new Lifecycle(
$systemConfig,
$cmsPageRepository
);
}
public function createNewsTemplateType(InstallContext $installContext): void
{
/** @var EntityRepositoryInterface $mailTemplateTypeRepository */
$mailTemplateTypeRepository = $this->container->get('mail_template_type.repository');
/** @var EntityRepositoryInterface $mailTemplateRepository */
$mailTemplateRepository = $this->container->get('mail_template.repository');
/** @var MailTemplateTypeEntity $myCustomMailTemplateType */
$myCustomMailTemplateType = $mailTemplateTypeRepository->search(
(new Criteria())->addFilter(new EqualsFilter('technicalName', self::TEMPLATE_TYPE_TECHNICAL_NAME)),
$installContext->getContext()
)->first();
if (is_null($myCustomMailTemplateType)) {
$mailTemplateTypeId = Uuid::randomHex();
$mailTemplateType = [
[
'id' => $mailTemplateTypeId,
'name' => self::TEMPLATE_TYPE_NAME,
'technicalName' => self::TEMPLATE_TYPE_TECHNICAL_NAME,
'availableEntities' => [
'product' => 'product',
'salesChannel' => 'sales_channel'
]
]
];
try {
$mailTemplateTypeRepository->create($mailTemplateType, $installContext->getContext());
} catch (UniqueConstraintViolationException $exception) {
// No, we've already installed the fields, it's fine.
}
} else {
$mailTemplateTypeId = $myCustomMailTemplateType->getId();
}
/** @var MailTemplateEntity $myCustomMailTemplate */
$myCustomMailTemplate = $mailTemplateRepository->search(
(new Criteria())->addFilter(new EqualsFilter('mailTemplateTypeId', $mailTemplateTypeId)),
$installContext->getContext()
)->first();
if (is_null($myCustomMailTemplate)) {
//You can add translations with the matching ISO-Codes. You always have to provide a value vor the default system language
//Later you can change and add translations also in the administration
$mailTemplate = [
[
'id' => Uuid::randomHex(),
'mailTemplateTypeId' => $mailTemplateTypeId,
'sender_name' => [
'en-GB' => 'info@connect-io.de',
'de-DE' => 'info@connect-io.de'
],
'description' => [
'en-GB' => 'Mail content for news',
'de-DE' => 'Email für News'
],
'subject' => [
'en-GB' => 'Breaking news',
'de-DE' => 'Aktuelle News'
],
'contentPlain' => [
'en-GB' => $this->getTextContent('en'),
'de-DE' => $this->getTextContent(),
],
'contentHtml' => [
'en-GB' => $this->getHtmlContent('en'),
'de-DE' => $this->getHtmlContent(),
],
]
];
try {
$mailTemplateRepository->create($mailTemplate, $installContext->getContext());
} catch (UniqueConstraintViolationException $exception) {
// No, we've already installed the fields, it's fine.
}
}
}
protected function deleteNewsTemplateType(UninstallContext $uninstallContext): void
{
//Keep UserData? Then do nothing here
if ($uninstallContext->keepUserData()) {
return;
}
//get the Templates and Associations added by this Plugin from the DB
/** @var EntityRepositoryInterface $mailTemplateTypeRepository */
$mailTemplateTypeRepository = $this->container->get('mail_template_type.repository');
/** @var EntityRepositoryInterface $mailTemplateRepository */
$mailTemplateRepository = $this->container->get('mail_template.repository');
/** @var MailTemplateTypeEntity $myCustomMailTemplateType */
$myCustomMailTemplateType = $mailTemplateTypeRepository->search(
(new Criteria())->addFilter(new EqualsFilter('technicalName', self::TEMPLATE_TYPE_TECHNICAL_NAME)),
$uninstallContext->getContext()
)->first();
if (is_null($myCustomMailTemplateType)) {
return;
}
$mailTemplateIds = $mailTemplateRepository->searchIds(
(new Criteria())->addFilter(new EqualsFilter('mailTemplateTypeId', $myCustomMailTemplateType->getId())),
$uninstallContext->getContext()
)->getIds();
//Get the Ids from the fetched Entities
$ids = array_map(static function ($id) {
return ['id' => $id];
}, $mailTemplateIds);
//Delete the Templates which were added by this Plugin
$mailTemplateRepository->delete($ids, $uninstallContext->getContext());
//Delete the TemplateType which were added by this Plugin
$mailTemplateTypeRepository->delete([
['id' => $myCustomMailTemplateType->getId()]
], $uninstallContext->getContext());
}
protected function getTextContent($lang = 'de')
{
$plain = [];
if ($lang == 'en') {
$plain[] = '{{anrede}} {{name}},';
$plain[] = '';
$plain[] = 'Thank you for your interest in our news.';
$plain[] = 'Your News:';
$plain[] = '';
$plain[] = '{{NEWS}}';
$plain[] = '';
$plain[] = '';
$plain[] = '--';
$plain[] = 'Kind regards,';
$plain[] = 'your EWE Team';
} else {
$plain[] = '{{anrede}} {{name}},';
$plain[] = '';
$plain[] = 'vielen Dank, dass Sie sich für unsere News interessieren.';
$plain[] = 'Ihre News:';
$plain[] = '';
$plain[] = '{{NEWS}}';
$plain[] = '';
$plain[] = '';
$plain[] = '--';
$plain[] = 'Mit freundlichen Grüßen,';
$plain[] = 'Ihr EWE Team';
}
return implode("\n", $plain);
}
protected function getHtmlContent($lang = 'de')
{
$email = [];
if ($lang == 'en') {
$email[] = '<!doctype html>';
$email[] = '<html lang="en">';
$email[] = '<head>';
$email[] = ' <meta charset="UTF-8">';
$email[] = ' <meta name="viewport"';
$email[] = ' content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">';
$email[] = ' <meta http-equiv="X-UA-Compatible" content="ie=edge">';
$email[] = ' <title>News</title>';
$email[] = '</head>';
$email[] = '<body>';
$email[] = '<p>{{anrede}} {{name}},</p>';
$email[] = '';
$email[] = '<p>Thank you for your interest in our news.</p>';
$email[] = '<h4>Your News:</h4>';
$email[] = '';
$email[] = '<table>';
$email[] = ' <thead>';
$email[] = ' <tr>';
$email[] = ' <th>Title</th>';
$email[] = ' <th>Teaser</th>';
$email[] = ' <th>Date</th>';
$email[] = ' </tr>';
$email[] = ' </thead>';
$email[] = ' <tbody>';
$email[] = '{{NEWS | raw}}';
$email[] = ' </tbody>';
$email[] = '</table>';
$email[] = '';
$email[] = '';
$email[] = '<p>--</p>';
$email[] = '<p>Kind regards,</p>';
$email[] = '<p>your EWE Team</p>';
$email[] = '</body>';
$email[] = '</html>';
} else {
$email[] = '<!doctype html>';
$email[] = '<html lang="de">';
$email[] = '<head>';
$email[] = ' <meta charset="UTF-8">';
$email[] = ' <meta name="viewport"';
$email[] = ' content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">';
$email[] = ' <meta http-equiv="X-UA-Compatible" content="ie=edge">';
$email[] = ' <title>News</title>';
$email[] = '</head>';
$email[] = '<body>';
$email[] = '<p>{{anrede}} {{name}},</p>';
$email[] = '';
$email[] = '<p>vielen Dank, dass Sie sich für unsere News interessieren.</p>';
$email[] = '<h4>Ihre News:</h4>';
$email[] = '';
$email[] = '<table>';
$email[] = ' <thead>';
$email[] = ' <tr>';
$email[] = ' <th>Titel</th>';
$email[] = ' <th>Teaser</th>';
$email[] = ' <th>Datum</th>';
$email[] = ' </tr>';
$email[] = ' </thead>';
$email[] = ' <tbody>';
$email[] = '{{NEWS | raw}}';
$email[] = ' </tbody>';
$email[] = '</table>';
$email[] = '';
$email[] = '';
$email[] = '<p>--</p>';
$email[] = '<p>Mit freundlichen Grüßen,</p>';
$email[] = '<p>Ihr EWE Team</p>';
$email[] = '</body>';
$email[] = '</html>';
}
return implode("\n", $email);
}
}