custom/plugins/SasBlogModule/src/SasBlogModule.php line 24

Open in your IDE?
  1. <?php declare(strict_types=1);
  2. namespace Sas\BlogModule;
  3. use Doctrine\DBAL\Connection;
  4. use Sas\BlogModule\Content\Blog\BlogEntriesDefinition;
  5. use Sas\BlogModule\Util\Lifecycle;
  6. use Sas\BlogModule\Util\Update;
  7. use Shopware\Core\Content\MailTemplate\Aggregate\MailTemplateType\MailTemplateTypeEntity;
  8. use Shopware\Core\Content\MailTemplate\MailTemplateEntity;
  9. use Shopware\Core\Framework\Context;
  10. use Shopware\Core\Framework\DataAbstractionLayer\EntityRepositoryInterface;
  11. use Shopware\Core\Framework\DataAbstractionLayer\Search\Criteria;
  12. use Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\EqualsAnyFilter;
  13. use Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\EqualsFilter;
  14. use Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\MultiFilter;
  15. use Shopware\Core\Framework\Plugin;
  16. use Shopware\Core\Framework\Plugin\Context\InstallContext;
  17. use Shopware\Core\Framework\Plugin\Context\UninstallContext;
  18. use Shopware\Core\Framework\Plugin\Context\UpdateContext;
  19. use Shopware\Core\Framework\Uuid\Uuid;
  20. use Shopware\Core\System\SystemConfig\SystemConfigService;
  21. class SasBlogModule extends Plugin
  22. {
  23.     public const ANONYMOUS_AUTHOR_ID '64f4c60194634128b9b85d9299797c45';
  24.     public const TEMPLATE_TYPE_NAME 'NewsMailType';
  25.     public const TEMPLATE_TYPE_TECHNICAL_NAME 'news_mail';
  26.     public const MAIL_TEMPLATE_NAME 'NewsMailTemplate';
  27.     public function install(InstallContext $installContext): void
  28.     {
  29.         parent::install($installContext);
  30.         $this->createBlogMediaFolder($installContext->getContext());
  31.         $this->getLifeCycle()->install($installContext->getContext());
  32.         $this->createNewsTemplateType($installContext);
  33.     }
  34.     public function uninstall(UninstallContext $context): void
  35.     {
  36.         parent::uninstall($context);
  37.         if ($context->keepUserData()) {
  38.             return;
  39.         }
  40.         /*
  41.          * We need to uninstall our default media folder,
  42.          * the media folder and the thumbnail sizes.
  43.          * However, we have to clean this up within a next update :)
  44.          */
  45.         $this->deleteMediaFolder($context->getContext());
  46.         $this->deleteDefaultMediaFolder($context->getContext());
  47.         $this->deleteSeoUrlTemplate($context->getContext());
  48.         $this->checkForThumbnailSizes($context->getContext());
  49.         /**
  50.          * And of course we need to drop our tables
  51.          */
  52.         $connection $this->container->get(Connection::class);
  53.         $connection->executeStatement('SET FOREIGN_KEY_CHECKS=0;');
  54.         $connection->executeStatement('DROP TABLE IF EXISTS `sas_blog_entries`');
  55.         $connection->executeStatement('DROP TABLE IF EXISTS `sas_blog_entries_translation`');
  56.         $connection->executeStatement('DROP TABLE IF EXISTS `sas_blog_blog_category`');
  57.         $connection->executeStatement('DROP TABLE IF EXISTS `sas_blog_category_translation`');
  58.         $connection->executeStatement('DROP TABLE IF EXISTS `sas_blog_category`');
  59.         $connection->executeStatement('DROP TABLE IF EXISTS `sas_blog_author_translation`');
  60.         $connection->executeStatement('DROP TABLE IF EXISTS `sas_blog_author`');
  61.         $connection->executeStatement('DROP TABLE IF EXISTS `sas_blog_entries_read_state`');
  62.         $connection->executeStatement('DROP TABLE IF EXISTS `sas_blog_newsletter`');
  63.         /** @var EntityRepositoryInterface $cmsBlockRepo */
  64.         $cmsBlockRepo $this->container->get('cms_block.repository');
  65.         //$context = Context::createDefaultContext();
  66.         $criteria = new Criteria();
  67.         $criteria->addFilter(new EqualsAnyFilter('type', ['blog-detail''blog-listing']));
  68.         $cmsBlocks $cmsBlockRepo->searchIds($criteria$context->getContext());
  69.         $cmsBlockRepo->delete(array_values($cmsBlocks->getData()), $context->getContext());
  70.         $connection->executeQuery('SET FOREIGN_KEY_CHECKS=1;');
  71.         $this->deleteNewsTemplateType($context);
  72.     }
  73.     public function update(UpdateContext $updateContext): void
  74.     {
  75.         parent::update($updateContext);
  76.         (new Update())->update($this->container$updateContext);
  77.         if (version_compare($updateContext->getCurrentPluginVersion(), '1.1.0''<')) {
  78.             $this->createBlogMediaFolder($updateContext->getContext());
  79.         }
  80.     }
  81.     /**
  82.      * We need to create a folder for the blog media with it's,
  83.      * own configuration to generate thumbnails for the teaser image.
  84.      */
  85.     public function createBlogMediaFolder(Context $context): void
  86.     {
  87.         $this->deleteDefaultMediaFolder($context);
  88.         $this->checkForThumbnailSizes($context);
  89.         /** @var EntityRepositoryInterface $mediaFolderRepository */
  90.         $mediaFolderRepository $this->container->get('media_default_folder.repository');
  91.         $mediaFolderRepository->create([
  92.             [
  93.                 'entity' => BlogEntriesDefinition::ENTITY_NAME,
  94.                 'associationFields' => ['media'],
  95.                 'folder' => [
  96.                     'name' => 'Blog Images',
  97.                     'useParentConfiguration' => false,
  98.                     'configuration' => [
  99.                         'createThumbnails' => true,
  100.                         'mediaThumbnailSizes' => [
  101.                             [
  102.                                 'width' => 650,
  103.                                 'height' => 330,
  104.                             ],
  105.                         ],
  106.                     ],
  107.                 ],
  108.             ],
  109.         ], $context);
  110.     }
  111.     private function deleteDefaultMediaFolder(Context $context): void
  112.     {
  113.         $criteria = new Criteria();
  114.         $criteria->addFilter(
  115.             new EqualsAnyFilter('entity', [
  116.                 BlogEntriesDefinition::ENTITY_NAME,
  117.             ])
  118.         );
  119.         /** @var EntityRepositoryInterface $mediaFolderRepository */
  120.         $mediaFolderRepository $this->container->get('media_default_folder.repository');
  121.         $mediaFolderIds $mediaFolderRepository->searchIds($criteria$context)->getIds();
  122.         if (!empty($mediaFolderIds)) {
  123.             $ids array_map(static function ($id) {
  124.                 return ['id' => $id];
  125.             }, $mediaFolderIds);
  126.             $mediaFolderRepository->delete($ids$context);
  127.         }
  128.     }
  129.     private function deleteMediaFolder(Context $context): void
  130.     {
  131.         $criteria = new Criteria();
  132.         $criteria->addFilter(
  133.             new EqualsFilter('name''Blog Images')
  134.         );
  135.         /** @var EntityRepositoryInterface $mediaFolderRepository */
  136.         $mediaFolderRepository $this->container->get('media_folder.repository');
  137.         $mediaFolderRepository->search($criteria$context);
  138.         $mediaFolderIds $mediaFolderRepository->searchIds($criteria$context)->getIds();
  139.         if (!empty($mediaFolderIds)) {
  140.             $ids array_map(static function ($id) {
  141.                 return ['id' => $id];
  142.             }, $mediaFolderIds);
  143.             $mediaFolderRepository->delete($ids$context);
  144.         }
  145.     }
  146.     private function deleteSeoUrlTemplate(Context $context): void
  147.     {
  148.         $criteria = new Criteria();
  149.         $criteria->addFilter(
  150.             new EqualsFilter('entityName''sas_blog_entries')
  151.         );
  152.         /** @var EntityRepositoryInterface $seoUrlTemplateRepository */
  153.         $seoUrlTemplateRepository $this->container->get('seo_url_template.repository');
  154.         $seoUrlTemplateRepository->search($criteria$context);
  155.         $seoUrlTemplateIds $seoUrlTemplateRepository->searchIds($criteria$context)->getIds();
  156.         if (!empty($seoUrlTemplateIds)) {
  157.             $ids array_map(static function ($id) {
  158.                 return ['id' => $id];
  159.             }, $seoUrlTemplateIds);
  160.             $seoUrlTemplateRepository->delete($ids$context);
  161.         }
  162.     }
  163.     private function checkForThumbnailSizes(Context $context): void
  164.     {
  165.         $criteria = new Criteria();
  166.         $criteria->addFilter(
  167.             new MultiFilter(
  168.                 MultiFilter::CONNECTION_AND,
  169.                 [
  170.                     new EqualsFilter('width'650),
  171.                     new EqualsFilter('height'330),
  172.                 ]
  173.             )
  174.         );
  175.         /** @var EntityRepositoryInterface $thumbnailSizeRepository */
  176.         $thumbnailSizeRepository $this->container->get('media_thumbnail_size.repository');
  177.         $thumbnailIds $thumbnailSizeRepository->searchIds($criteria$context)->getIds();
  178.         if (!empty($thumbnailIds)) {
  179.             $ids array_map(static function ($id) {
  180.                 return ['id' => $id];
  181.             }, $thumbnailIds);
  182.             $thumbnailSizeRepository->delete($ids$context);
  183.         }
  184.     }
  185.     private function getLifeCycle(): Lifecycle
  186.     {
  187.         /** @var SystemConfigService $systemConfig */
  188.         $systemConfig $this->container->get(SystemConfigService::class);
  189.         /** @var EntityRepositoryInterface $cmsPageRepository */
  190.         $cmsPageRepository $this->container->get('cms_page.repository');
  191.         return new Lifecycle(
  192.             $systemConfig,
  193.             $cmsPageRepository
  194.         );
  195.     }
  196.     public function createNewsTemplateType(InstallContext $installContext): void
  197.     {
  198.         /** @var EntityRepositoryInterface $mailTemplateTypeRepository */
  199.         $mailTemplateTypeRepository $this->container->get('mail_template_type.repository');
  200.         /** @var EntityRepositoryInterface $mailTemplateRepository */
  201.         $mailTemplateRepository $this->container->get('mail_template.repository');
  202.         /** @var MailTemplateTypeEntity $myCustomMailTemplateType */
  203.         $myCustomMailTemplateType $mailTemplateTypeRepository->search(
  204.             (new Criteria())->addFilter(new EqualsFilter('technicalName'self::TEMPLATE_TYPE_TECHNICAL_NAME)),
  205.             $installContext->getContext()
  206.         )->first();
  207.         if (is_null($myCustomMailTemplateType)) {
  208.             $mailTemplateTypeId Uuid::randomHex();
  209.             $mailTemplateType = [
  210.                 [
  211.                     'id' => $mailTemplateTypeId,
  212.                     'name' => self::TEMPLATE_TYPE_NAME,
  213.                     'technicalName' => self::TEMPLATE_TYPE_TECHNICAL_NAME,
  214.                     'availableEntities' => [
  215.                         'product' => 'product',
  216.                         'salesChannel' => 'sales_channel'
  217.                     ]
  218.                 ]
  219.             ];
  220.             try {
  221.                 $mailTemplateTypeRepository->create($mailTemplateType$installContext->getContext());
  222.             } catch (UniqueConstraintViolationException $exception) {
  223.                 // No, we've already installed the fields, it's fine.
  224.             }
  225.         } else {
  226.             $mailTemplateTypeId $myCustomMailTemplateType->getId();
  227.         }
  228.         /** @var MailTemplateEntity $myCustomMailTemplate */
  229.         $myCustomMailTemplate $mailTemplateRepository->search(
  230.             (new Criteria())->addFilter(new EqualsFilter('mailTemplateTypeId'$mailTemplateTypeId)),
  231.             $installContext->getContext()
  232.         )->first();
  233.         if (is_null($myCustomMailTemplate)) {
  234.             //You can add translations with the matching ISO-Codes. You always have to provide a value vor the default system language
  235.             //Later you can change and add translations also in the administration
  236.             $mailTemplate = [
  237.                 [
  238.                     'id' => Uuid::randomHex(),
  239.                     'mailTemplateTypeId' => $mailTemplateTypeId,
  240.                     'sender_name' => [
  241.                         'en-GB' => 'info@connect-io.de',
  242.                         'de-DE' => 'info@connect-io.de'
  243.                     ],
  244.                     'description' => [
  245.                         'en-GB' => 'Mail content for news',
  246.                         'de-DE' => 'Email für News'
  247.                     ],
  248.                     'subject' => [
  249.                         'en-GB' => 'Breaking news',
  250.                         'de-DE' => 'Aktuelle News'
  251.                     ],
  252.                     'contentPlain' => [
  253.                         'en-GB' => $this->getTextContent('en'),
  254.                         'de-DE' => $this->getTextContent(),
  255.                     ],
  256.                     'contentHtml' => [
  257.                         'en-GB' => $this->getHtmlContent('en'),
  258.                         'de-DE' => $this->getHtmlContent(),
  259.                     ],
  260.                 ]
  261.             ];
  262.             try {
  263.                 $mailTemplateRepository->create($mailTemplate$installContext->getContext());
  264.             } catch (UniqueConstraintViolationException $exception) {
  265.                 // No, we've already installed the fields, it's fine.
  266.             }
  267.         }
  268.     }
  269.     protected function deleteNewsTemplateType(UninstallContext $uninstallContext): void
  270.     {
  271.         //Keep UserData? Then do nothing here
  272.         if ($uninstallContext->keepUserData()) {
  273.             return;
  274.         }
  275.         //get the Templates and Associations added by this Plugin from the DB
  276.         /** @var EntityRepositoryInterface $mailTemplateTypeRepository */
  277.         $mailTemplateTypeRepository $this->container->get('mail_template_type.repository');
  278.         /** @var EntityRepositoryInterface $mailTemplateRepository */
  279.         $mailTemplateRepository $this->container->get('mail_template.repository');
  280.         /** @var MailTemplateTypeEntity $myCustomMailTemplateType */
  281.         $myCustomMailTemplateType $mailTemplateTypeRepository->search(
  282.             (new Criteria())->addFilter(new EqualsFilter('technicalName'self::TEMPLATE_TYPE_TECHNICAL_NAME)),
  283.             $uninstallContext->getContext()
  284.         )->first();
  285.         if (is_null($myCustomMailTemplateType)) {
  286.             return;
  287.         }
  288.         $mailTemplateIds $mailTemplateRepository->searchIds(
  289.             (new Criteria())->addFilter(new EqualsFilter('mailTemplateTypeId'$myCustomMailTemplateType->getId())),
  290.             $uninstallContext->getContext()
  291.         )->getIds();
  292.         //Get the Ids from the fetched Entities
  293.         $ids array_map(static function ($id) {
  294.             return ['id' => $id];
  295.         }, $mailTemplateIds);
  296.         //Delete the Templates which were added by this Plugin
  297.         $mailTemplateRepository->delete($ids$uninstallContext->getContext());
  298.         //Delete the TemplateType which were added by this Plugin
  299.         $mailTemplateTypeRepository->delete([
  300.             ['id' => $myCustomMailTemplateType->getId()]
  301.         ], $uninstallContext->getContext());
  302.     }
  303.     protected function getTextContent($lang 'de')
  304.     {
  305.         $plain = [];
  306.         if ($lang == 'en') {
  307.             $plain[] = '{{anrede}} {{name}},';
  308.             $plain[] = '';
  309.             $plain[] = 'Thank you for your interest in our news.';
  310.             $plain[] = 'Your News:';
  311.             $plain[] = '';
  312.             $plain[] = '{{NEWS}}';
  313.             $plain[] = '';
  314.             $plain[] = '';
  315.             $plain[] = '--';
  316.             $plain[] = 'Kind regards,';
  317.             $plain[] = 'your EWE Team';
  318.         } else {
  319.             $plain[] = '{{anrede}} {{name}},';
  320.             $plain[] = '';
  321.             $plain[] = 'vielen Dank, dass Sie sich für unsere News interessieren.';
  322.             $plain[] = 'Ihre News:';
  323.             $plain[] = '';
  324.             $plain[] = '{{NEWS}}';
  325.             $plain[] = '';
  326.             $plain[] = '';
  327.             $plain[] = '--';
  328.             $plain[] = 'Mit freundlichen Grüßen,';
  329.             $plain[] = 'Ihr EWE Team';
  330.         }
  331.         return implode("\n"$plain);
  332.     }
  333.     protected function getHtmlContent($lang 'de')
  334.     {
  335.         $email = [];
  336.         if ($lang == 'en') {
  337.             $email[] = '<!doctype html>';
  338.             $email[] = '<html lang="en">';
  339.             $email[] = '<head>';
  340.             $email[] = '    <meta charset="UTF-8">';
  341.             $email[] = '    <meta name="viewport"';
  342.             $email[] = '          content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">';
  343.             $email[] = '    <meta http-equiv="X-UA-Compatible" content="ie=edge">';
  344.             $email[] = '    <title>News</title>';
  345.             $email[] = '</head>';
  346.             $email[] = '<body>';
  347.             $email[] = '<p>{{anrede}} {{name}},</p>';
  348.             $email[] = '';
  349.             $email[] = '<p>Thank you for your interest in our news.</p>';
  350.             $email[] = '<h4>Your News:</h4>';
  351.             $email[] = '';
  352.             $email[] = '<table>';
  353.             $email[] = '    <thead>';
  354.             $email[] = '        <tr>';
  355.             $email[] = '            <th>Title</th>';
  356.             $email[] = '            <th>Teaser</th>';
  357.             $email[] = '            <th>Date</th>';
  358.             $email[] = '        </tr>';
  359.             $email[] = '    </thead>';
  360.             $email[] = '    <tbody>';
  361.             $email[] = '{{NEWS | raw}}';
  362.             $email[] = '    </tbody>';
  363.             $email[] = '</table>';
  364.             $email[] = '';
  365.             $email[] = '';
  366.             $email[] = '<p>--</p>';
  367.             $email[] = '<p>Kind regards,</p>';
  368.             $email[] = '<p>your EWE Team</p>';
  369.             $email[] = '</body>';
  370.             $email[] = '</html>';
  371.         } else {
  372.             $email[] = '<!doctype html>';
  373.             $email[] = '<html lang="de">';
  374.             $email[] = '<head>';
  375.             $email[] = '    <meta charset="UTF-8">';
  376.             $email[] = '    <meta name="viewport"';
  377.             $email[] = '          content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">';
  378.             $email[] = '    <meta http-equiv="X-UA-Compatible" content="ie=edge">';
  379.             $email[] = '    <title>News</title>';
  380.             $email[] = '</head>';
  381.             $email[] = '<body>';
  382.             $email[] = '<p>{{anrede}} {{name}},</p>';
  383.             $email[] = '';
  384.             $email[] = '<p>vielen Dank, dass Sie sich für unsere News interessieren.</p>';
  385.             $email[] = '<h4>Ihre News:</h4>';
  386.             $email[] = '';
  387.             $email[] = '<table>';
  388.             $email[] = '    <thead>';
  389.             $email[] = '        <tr>';
  390.             $email[] = '            <th>Titel</th>';
  391.             $email[] = '            <th>Teaser</th>';
  392.             $email[] = '            <th>Datum</th>';
  393.             $email[] = '        </tr>';
  394.             $email[] = '    </thead>';
  395.             $email[] = '    <tbody>';
  396.             $email[] = '{{NEWS | raw}}';
  397.             $email[] = '    </tbody>';
  398.             $email[] = '</table>';
  399.             $email[] = '';
  400.             $email[] = '';
  401.             $email[] = '<p>--</p>';
  402.             $email[] = '<p>Mit freundlichen Grüßen,</p>';
  403.             $email[] = '<p>Ihr EWE Team</p>';
  404.             $email[] = '</body>';
  405.             $email[] = '</html>';
  406.         }
  407.         return implode("\n"$email);
  408.     }
  409. }