diff --git a/.github/workflows/unit.yml b/.github/workflows/unit.yml index f60747b..2ca24c9 100644 --- a/.github/workflows/unit.yml +++ b/.github/workflows/unit.yml @@ -3,6 +3,7 @@ on: push: branches: - 'main' + - 'feature/6.6-compatibility' tags-ignore: - '*' pull_request: @@ -15,15 +16,14 @@ jobs: fail-fast: false matrix: shopware-version: - - 'v6.5.2.0' - - 'v6.5.3.2' - - 'trunk' + - 'v6.6.0.0-rc1' steps: - name: Setup Shopware uses: FriendsOfShopware/setup-shopware@main with: shopware-version: ${{ matrix.shopware-version }} - php-version: 8.1 + php-version: 8.2 + php-extensions: pcov - name: Checkout uses: actions/checkout@v3 diff --git a/README.md b/README.md index dbcce0d..90aec9c 100644 --- a/README.md +++ b/README.md @@ -14,8 +14,8 @@ This plugin allows to store the mails in theme instead of database. This gives u ## Requirements -- Shopware 6.4.1 or newer -- PHP 7.4 +- Shopware 6.6.0 or newer +- PHP 8.2 ## Installation diff --git a/composer.json b/composer.json index e8b5366..c6b422f 100644 --- a/composer.json +++ b/composer.json @@ -1,6 +1,6 @@ { "name": "frosh/frosh-platform-template-mail", - "version": "2.0.2", + "version": "3.0.0", "type": "shopware-platform-plugin", "description": "Load mail templates from theme", "keywords": [ @@ -45,6 +45,6 @@ } }, "require": { - "shopware/core": "~6.5.0" + "shopware/core": "~6.6.0" } } diff --git a/phpunit.xml b/phpunit.xml index 33bd40c..a919f32 100644 --- a/phpunit.xml +++ b/phpunit.xml @@ -1,13 +1,15 @@ - + xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/10.5/phpunit.xsd" + backupGlobals="false" + colors="true" + bootstrap="tests/TestBootstraper.php" + cacheResult="false"> + ./src/ - + diff --git a/src/DependencyInjection/CacheCompilerPass.php b/src/DependencyInjection/CacheCompilerPass.php deleted file mode 100644 index 086e8c6..0000000 --- a/src/DependencyInjection/CacheCompilerPass.php +++ /dev/null @@ -1,19 +0,0 @@ -getParameter('kernel.environment') === 'prod') { - return; - } - - $container->removeDefinition(CachedMailFinderService::class); - } -} diff --git a/src/Extension/Content/MailTemplate/MailTemplateExtension.php b/src/Extension/Content/MailTemplate/MailTemplateExtension.php index 3b42a49..71706db 100644 --- a/src/Extension/Content/MailTemplate/MailTemplateExtension.php +++ b/src/Extension/Content/MailTemplate/MailTemplateExtension.php @@ -7,7 +7,9 @@ use Shopware\Core\Framework\DataAbstractionLayer\Field\Flag\Runtime; use Shopware\Core\Framework\DataAbstractionLayer\Field\StringField; use Shopware\Core\Framework\DataAbstractionLayer\FieldCollection; +use Symfony\Component\DependencyInjection\Attribute\AutoconfigureTag; +#[AutoconfigureTag('shopware.entity_extension')] class MailTemplateExtension extends EntityExtension { public function extendFields(FieldCollection $collection): void diff --git a/src/FroshPlatformTemplateMail.php b/src/FroshPlatformTemplateMail.php index 64601ef..9ceba0b 100644 --- a/src/FroshPlatformTemplateMail.php +++ b/src/FroshPlatformTemplateMail.php @@ -2,16 +2,8 @@ namespace Frosh\TemplateMail; -use Frosh\TemplateMail\DependencyInjection\CacheCompilerPass; use Shopware\Core\Framework\Plugin; -use Symfony\Component\DependencyInjection\ContainerBuilder; class FroshPlatformTemplateMail extends Plugin { - public function build(ContainerBuilder $container): void - { - $container->addCompilerPass(new CacheCompilerPass()); - - parent::build($container); - } } diff --git a/src/Resources/config/loaders.xml b/src/Resources/config/loaders.xml deleted file mode 100644 index dedb1d9..0000000 --- a/src/Resources/config/loaders.xml +++ /dev/null @@ -1,17 +0,0 @@ - - - - - - - - - - - - - - - diff --git a/src/Resources/config/services.xml b/src/Resources/config/services.xml index 522fd1f..d5cd324 100644 --- a/src/Resources/config/services.xml +++ b/src/Resources/config/services.xml @@ -3,55 +3,11 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + diff --git a/src/Services/CachedMailFinderService.php b/src/Services/CachedMailFinderService.php index ac74e08..deab086 100644 --- a/src/Services/CachedMailFinderService.php +++ b/src/Services/CachedMailFinderService.php @@ -4,25 +4,29 @@ use Frosh\TemplateMail\Services\TemplateMailContext; use Symfony\Component\Cache\CacheItem; +use Symfony\Component\DependencyInjection\Attribute\AsDecorator; +use Symfony\Component\DependencyInjection\Attribute\When; use Symfony\Contracts\Cache\CacheInterface; -class CachedMailFinderService implements MailFinderServiceInterface +#[When('prod')] +#[AsDecorator(MailFinderService::class)] +readonly class CachedMailFinderService implements MailFinderServiceInterface { public function __construct( - private readonly MailFinderServiceInterface $mailFinderService, - private readonly CacheInterface $cache + private MailFinderServiceInterface $mailFinderService, + private CacheInterface $cache ) { } public function findTemplateByTechnicalName( - string $type, - string $technicalName, + string $type, + string $technicalName, TemplateMailContext $businessEvent, - bool $returnFolder = false + bool $returnFolder = false ): ?string { $salesChannelId = $businessEvent->getSalesChannelId(); - $cacheKey = md5( + $cacheKey = hash('xxh128', $type . $technicalName . $salesChannelId diff --git a/src/Services/MailFinderService.php b/src/Services/MailFinderService.php index 8dd4c2d..40c1d50 100644 --- a/src/Services/MailFinderService.php +++ b/src/Services/MailFinderService.php @@ -5,13 +5,18 @@ use Doctrine\DBAL\Connection; use Frosh\TemplateMail\Services\TemplateMailContext; use Frosh\TemplateMail\Services\MailLoader\LoaderInterface; +use Shopware\Core\Framework\Adapter\Translation\AbstractTranslator; use Shopware\Core\Framework\Adapter\Translation\Translator; use Shopware\Core\Framework\DataAbstractionLayer\EntityRepository; use Shopware\Core\Framework\DataAbstractionLayer\Search\Criteria; use Shopware\Core\Framework\Uuid\Uuid; use Shopware\Core\System\Language\LanguageEntity; +use Symfony\Component\DependencyInjection\Attribute\AsAlias; +use Symfony\Component\DependencyInjection\Attribute\Autowire; +use Symfony\Component\DependencyInjection\Attribute\TaggedIterator; use Twig\Loader\FilesystemLoader; +#[AsAlias] class MailFinderService implements MailFinderServiceInterface { final public const TYPE_HTML = 'html.'; @@ -22,20 +27,23 @@ class MailFinderService implements MailFinderServiceInterface * @param LoaderInterface[] $availableLoaders */ public function __construct( + #[Autowire(service: 'twig.loader.native_filesystem')] private readonly FilesystemLoader $filesystemLoader, + #[TaggedIterator('frosh_template_mail.loader')] private readonly iterable $availableLoaders, private readonly EntityRepository $languageRepository, - private readonly Translator $translator, + #[Autowire(service: Translator::class)] + private readonly AbstractTranslator $translator, private readonly SearchPathProvider $searchPathProvider, private readonly Connection $connection ) { } public function findTemplateByTechnicalName( - string $type, - string $technicalName, + string $type, + string $technicalName, TemplateMailContext $businessEvent, - bool $returnFolder = false + bool $returnFolder = false ): ?string { $paths = $this->filesystemLoader->getPaths(); diff --git a/src/Services/MailFinderServiceInterface.php b/src/Services/MailFinderServiceInterface.php index 3868e0e..d37ce91 100644 --- a/src/Services/MailFinderServiceInterface.php +++ b/src/Services/MailFinderServiceInterface.php @@ -2,14 +2,12 @@ namespace Frosh\TemplateMail\Services; -use Frosh\TemplateMail\Services\TemplateMailContext; - interface MailFinderServiceInterface { public function findTemplateByTechnicalName( - string $type, - string $technicalName, + string $type, + string $technicalName, TemplateMailContext $businessEvent, - bool $returnFolder = false + bool $returnFolder = false ): ?string; } diff --git a/src/Services/MailLoader/MjmlLoader.php b/src/Services/MailLoader/MjmlLoader.php index 3da414c..ac9fbf6 100644 --- a/src/Services/MailLoader/MjmlLoader.php +++ b/src/Services/MailLoader/MjmlLoader.php @@ -14,8 +14,7 @@ class MjmlLoader implements LoaderInterface public function __construct( private readonly LoggerInterface $logger, - private readonly Client $client = new Client( - ) + private readonly Client $client = new Client() ) { } diff --git a/src/Services/MailLoader/TwigLoader.php b/src/Services/MailLoader/TwigLoader.php index f98efa1..1e448c3 100644 --- a/src/Services/MailLoader/TwigLoader.php +++ b/src/Services/MailLoader/TwigLoader.php @@ -2,6 +2,9 @@ namespace Frosh\TemplateMail\Services\MailLoader; +use Symfony\Component\DependencyInjection\Attribute\AsAlias; + +#[AsAlias] class TwigLoader implements LoaderInterface { public function load(string $path): ?string diff --git a/src/Services/StringTemplateRenderer.php b/src/Services/StringTemplateRenderer.php index 72f5a01..d90cd9e 100644 --- a/src/Services/StringTemplateRenderer.php +++ b/src/Services/StringTemplateRenderer.php @@ -5,12 +5,14 @@ use PHPUnit\Framework\Attributes\CodeCoverageIgnore; use Shopware\Core\Framework\Adapter\Twig\Exception\StringTemplateRenderingException; use Shopware\Core\Framework\Context; +use Symfony\Component\DependencyInjection\Attribute\AsDecorator; use Twig\Environment; use Twig\Error\Error; use Twig\Extension\CoreExtension; use Twig\Loader\ArrayLoader; use Twig\Loader\ChainLoader; +#[AsDecorator(\Shopware\Core\Framework\Adapter\Twig\StringTemplateRenderer::class)] class StringTemplateRenderer extends \Shopware\Core\Framework\Adapter\Twig\StringTemplateRenderer { private Environment $twig; diff --git a/src/Services/TemplateMailContext.php b/src/Services/TemplateMailContext.php index 4778cda..978f4a9 100644 --- a/src/Services/TemplateMailContext.php +++ b/src/Services/TemplateMailContext.php @@ -10,11 +10,11 @@ /** * @codeCoverageIgnore */ -class TemplateMailContext +readonly class TemplateMailContext { public function __construct( - private readonly string $salesChannelId, - private readonly Context $context + private string $salesChannelId, + private Context $context ) { } diff --git a/src/Subscriber/FlowSubscriber.php b/src/Subscriber/FlowSubscriber.php index 020c4fd..0593552 100644 --- a/src/Subscriber/FlowSubscriber.php +++ b/src/Subscriber/FlowSubscriber.php @@ -15,11 +15,11 @@ use Symfony\Component\EventDispatcher\EventSubscriberInterface; use Symfony\Component\HttpFoundation\ParameterBag; -class FlowSubscriber implements EventSubscriberInterface +readonly class FlowSubscriber implements EventSubscriberInterface { public function __construct( - private readonly EntityRepository $mailTemplateTypeRepository, - private readonly MailFinderServiceInterface $mailFinderService + private EntityRepository $mailTemplateTypeRepository, + private MailFinderServiceInterface $mailFinderService ) { } diff --git a/src/Subscriber/MailTemplateSubscriber.php b/src/Subscriber/MailTemplateSubscriber.php index 0f0b64b..0ceabb9 100644 --- a/src/Subscriber/MailTemplateSubscriber.php +++ b/src/Subscriber/MailTemplateSubscriber.php @@ -18,11 +18,11 @@ use Shopware\Core\Framework\Struct\ArrayStruct; use Symfony\Component\EventDispatcher\EventSubscriberInterface; -class MailTemplateSubscriber implements EventSubscriberInterface +readonly class MailTemplateSubscriber implements EventSubscriberInterface { public function __construct( - private readonly EntityRepository $mailTemplateTypeRepository, - private readonly MailFinderServiceInterface $mailFinderService + private EntityRepository $mailTemplateTypeRepository, + private MailFinderServiceInterface $mailFinderService ) { } diff --git a/tests/DependencyInjection/CacheCompilerPassTest.php b/tests/DependencyInjection/CacheCompilerPassTest.php deleted file mode 100644 index da99edd..0000000 --- a/tests/DependencyInjection/CacheCompilerPassTest.php +++ /dev/null @@ -1,42 +0,0 @@ -buildContainer(); - $c->setParameter('kernel.environment', 'dev'); - $c->compile(); - - static::assertFalse($c->hasDefinition(CachedMailFinderService::class)); - } - - public function testCacheStaysInProd(): void - { - $c = $this->buildContainer(); - $c->compile(); - - static::assertTrue($c->hasDefinition(CachedMailFinderService::class)); - } - - private function buildContainer(): ContainerBuilder - { - $container = new ContainerBuilder(); - $container->addCompilerPass(new CacheCompilerPass()); - $d = new Definition(); - $d->setPublic(true); - $container->setDefinition(CachedMailFinderService::class, $d); - $container->setParameter('kernel.environment', 'prod'); - - return $container; - } -} diff --git a/tests/Extension/MailTemplateExtensionTest.php b/tests/Extension/MailTemplateExtensionTest.php index 9138364..011fae8 100644 --- a/tests/Extension/MailTemplateExtensionTest.php +++ b/tests/Extension/MailTemplateExtensionTest.php @@ -21,11 +21,7 @@ public function testExtendFieldsAddsStringField(): void $collection ->expects(static::once()) ->method('add') - ->withConsecutive( - [ - (new StringField('frosh_template_mail', 'froshTemplateMail'))->addFlags(new Runtime()), - ] - ); + ->with((new StringField('frosh_template_mail', 'froshTemplateMail'))->addFlags(new Runtime())); (new MailTemplateExtension())->extendFields($collection); } diff --git a/tests/Services/SearchPathProviderTest.php b/tests/Services/SearchPathProviderTest.php index 509cf31..6339fec 100644 --- a/tests/Services/SearchPathProviderTest.php +++ b/tests/Services/SearchPathProviderTest.php @@ -11,14 +11,10 @@ use Shopware\Core\Framework\Api\Context\SystemSource; use Shopware\Core\Framework\Context; use Shopware\Core\Framework\DataAbstractionLayer\EntityCollection; -use Shopware\Core\Framework\DataAbstractionLayer\EntityRepository; -use Shopware\Core\Framework\DataAbstractionLayer\Search\Criteria; -use Shopware\Core\Framework\DataAbstractionLayer\Search\EntitySearchResult; -use Shopware\Core\Framework\Event\BusinessEvent; use Shopware\Core\System\Language\LanguageEntity; use Shopware\Core\System\Locale\LocaleEntity; use Shopware\Core\Test\TestDefaults; -use Shopware\Tests\Unit\Common\Stubs\DataAbstractionLayer\StaticEntityRepository; +use Shopware\Core\Test\Stub\DataAbstractionLayer\StaticEntityRepository; class SearchPathProviderTest extends TestCase { @@ -38,12 +34,12 @@ public function testPaths(TemplateMailContext $event, array $expectedPaths): voi static::assertSame($expectedPaths, $provider->buildPaths($event)); } - public function eventProvider(): iterable + public static function eventProvider(): iterable { // Without sales channel source yield [ - $this->createEvent(), + self::createEvent(), [ '98432def39fc4624b33213a56b8c944d/en-GB', // Sales channel and language combo '98432def39fc4624b33213a56b8c944d', // Sales channel @@ -56,7 +52,7 @@ public function eventProvider(): iterable // With sales channel source yield [ - $this->createEvent(true), + self::createEvent(true), [ '98432def39fc4624b33213a56b8c944d/en-GB', // Sales channel and language combo '98432def39fc4624b33213a56b8c944d', // Sales channel @@ -67,7 +63,7 @@ public function eventProvider(): iterable ]; } - private function createEvent(bool $salesChannelSource = false): TemplateMailContext + private static function createEvent(bool $salesChannelSource = false): TemplateMailContext { $context = new Context( $salesChannelSource ? new SalesChannelApiSource(TestDefaults::SALES_CHANNEL) : new SystemSource() diff --git a/tests/TestBootstrap.php b/tests/TestBootstrap.php deleted file mode 100644 index 89c7d5b..0000000 --- a/tests/TestBootstrap.php +++ /dev/null @@ -1,11 +0,0 @@ -addCallingPlugin() - ->addActivePlugins('FroshPlatformTemplateMail') - ->bootstrap() - ->getClassLoader(); - -$loader->addPsr4('Frosh\\TemplateMail\\Tests\\', __DIR__); diff --git a/tests/TestBootstraper.php b/tests/TestBootstraper.php new file mode 100644 index 0000000..a60ca86 --- /dev/null +++ b/tests/TestBootstraper.php @@ -0,0 +1,46 @@ +setLoadEnvFile(true) + ->setForceInstallPlugins(true) + ->addActivePlugins('FroshPlatformTemplateMail') + ->bootstrap() + ->getClassLoader(); +} + +$paths = [ + '../../../../src/Core/TestBootstrapper.php', + '../vendor/shopware/core/TestBootstrapper.php', + '../../../../vendor/shopware/core/TestBootstrapper.php', +]; + +foreach ($paths as $path) { + $path = realpath(__DIR__ . '/' . $path); + + if (!\is_string($path)) { + continue; + } + + if (!\is_file($path)) { + continue; + } + + require $path; + + return (new TestBootstrapper()) + ->setPlatformEmbedded(false) + ->setLoadEnvFile(true) + ->setForceInstallPlugins(true) + ->addActivePlugins('FroshPlatformTemplateMail') + ->bootstrap() + ->getClassLoader(); +}