From 80ddc84b5629848dff70cf9ca2f20f40674ea9d7 Mon Sep 17 00:00:00 2001 From: jkindly Date: Thu, 25 Jul 2024 13:41:22 +0200 Subject: [PATCH 1/3] OP-442: Locales functionality --- spec/Resolver/BlockResourceResolverSpec.php | 50 +++++++++++++++++-- src/Entity/Page.php | 3 -- src/Entity/PageInterface.php | 3 +- src/Form/Type/PageType.php | 1 - src/Migrations/Version20240725064430.php | 30 +++++++++++ src/Resolver/BlockResourceResolver.php | 19 +++++++ .../admin/js/bitbag/bitbag-page-slug.js | 30 ++++++----- src/Resources/config/doctrine/Page.orm.xml | 11 ---- src/Resources/config/services/resolver.xml | 2 + .../config/validation/PageTranslation.xml | 6 --- src/Resources/views/Page/Crud/_form.html.twig | 1 - .../bundles/SyliusShopBundle/layout.html.twig | 1 - 12 files changed, 113 insertions(+), 44 deletions(-) create mode 100644 src/Migrations/Version20240725064430.php diff --git a/spec/Resolver/BlockResourceResolverSpec.php b/spec/Resolver/BlockResourceResolverSpec.php index 1f9af7155..55931e0a6 100755 --- a/spec/Resolver/BlockResourceResolverSpec.php +++ b/spec/Resolver/BlockResourceResolverSpec.php @@ -14,19 +14,25 @@ use BitBag\SyliusCmsPlugin\Repository\BlockRepositoryInterface; use BitBag\SyliusCmsPlugin\Resolver\BlockResourceResolver; use BitBag\SyliusCmsPlugin\Resolver\BlockResourceResolverInterface; +use Doctrine\Common\Collections\ArrayCollection; use PhpSpec\ObjectBehavior; use Psr\Log\LoggerInterface; use Sylius\Component\Channel\Context\ChannelContextInterface; use Sylius\Component\Core\Model\ChannelInterface; +use Sylius\Component\Locale\Context\LocaleContextInterface; +use Sylius\Component\Locale\Model\LocaleInterface; +use Sylius\Component\Resource\Repository\RepositoryInterface; final class BlockResourceResolverSpec extends ObjectBehavior { public function let( BlockRepositoryInterface $blockRepository, LoggerInterface $logger, - ChannelContextInterface $channelContext + ChannelContextInterface $channelContext, + LocaleContextInterface $localeContext, + RepositoryInterface $localeRepository, ) { - $this->beConstructedWith($blockRepository, $logger, $channelContext); + $this->beConstructedWith($blockRepository, $logger, $channelContext, $localeContext, $localeRepository); } public function it_is_initializable(): void @@ -60,15 +66,53 @@ public function it_logs_warning_if_block_was_not_found( $this->findOrLog('homepage_banner'); } + public function it_logs_warning_if_block_was_found_but_it_does_not_have_locale( + BlockRepositoryInterface $blockRepository, + LoggerInterface $logger, + ChannelContextInterface $channelContext, + ChannelInterface $channel, + LocaleContextInterface $localeContext, + LocaleInterface $locale, + RepositoryInterface $localeRepository, + BlockInterface $block + ) { + $channel->getCode()->willReturn('WEB'); + $channelContext->getChannel()->willReturn($channel); + $blockRepository->findEnabledByCode('homepage_banner', 'WEB')->willReturn($block); + $localeContext->getLocaleCode()->willReturn('en_US'); + $locale->getCode()->willReturn('en_US'); + $localeRepository->findOneBy(['code' => 'en_US'])->willReturn($locale); + $block->hasLocale($locale)->willReturn(false); + $block->getLocales()->willReturn(new ArrayCollection(['pl_PL'])); + + $logger + ->warning(sprintf( + 'Block with "%s" code was found in the database, but it does not have "%s" locale.', + 'homepage_banner', + 'en_US' + )) + ->shouldBeCalled() + ; + + $this->findOrLog('homepage_banner'); + } + public function it_returns_block_if_found_in_database( BlockRepositoryInterface $blockRepository, BlockInterface $block, ChannelContextInterface $channelContext, - ChannelInterface $channel + ChannelInterface $channel, + LocaleContextInterface $localeContext, + LocaleInterface $locale, + RepositoryInterface $localeRepository, ) { $channel->getCode()->willReturn('WEB'); $channelContext->getChannel()->willReturn($channel); $blockRepository->findEnabledByCode('homepage_banner', 'WEB')->willReturn($block); + $localeContext->getLocaleCode()->willReturn('en_US'); + $locale->getCode()->willReturn('en_US'); + $localeRepository->findOneBy(['code' => 'en_US'])->willReturn($locale); + $block->hasLocale($locale)->willReturn(true); $this->findOrLog('homepage_banner')->shouldReturn($block); } diff --git a/src/Entity/Page.php b/src/Entity/Page.php index fbe380bfb..d6d418c6b 100755 --- a/src/Entity/Page.php +++ b/src/Entity/Page.php @@ -13,7 +13,6 @@ use BitBag\SyliusCmsPlugin\Entity\Trait\ChannelsAwareTrait; use BitBag\SyliusCmsPlugin\Entity\Trait\CollectibleTrait; use BitBag\SyliusCmsPlugin\Entity\Trait\ContentConfigurationAwareTrait; -use BitBag\SyliusCmsPlugin\Entity\Trait\LocaleAwareTrait; use Sylius\Component\Resource\Model\TimestampableTrait; use Sylius\Component\Resource\Model\ToggleableTrait; use Sylius\Component\Resource\Model\TranslatableTrait; @@ -26,7 +25,6 @@ class Page implements PageInterface use TimestampableTrait; use ChannelsAwareTrait; use ContentConfigurationAwareTrait; - use LocaleAwareTrait; use TranslatableTrait { __construct as protected initializeTranslationsCollection; } @@ -45,7 +43,6 @@ public function __construct() $this->initializeChannelsCollection(); $this->initializeTranslationsCollection(); $this->initializeContentElementsCollection(); - $this->initializeLocalesCollection(); $this->createdAt = new \DateTime(); } diff --git a/src/Entity/PageInterface.php b/src/Entity/PageInterface.php index 9e3944f0b..cc5bcb7e3 100755 --- a/src/Entity/PageInterface.php +++ b/src/Entity/PageInterface.php @@ -25,8 +25,7 @@ interface PageInterface extends TimestampableInterface, ChannelsAwareInterface, SlugAwareInterface, - ContentConfigurationAwareInterface, - LocaleAwareInterface + ContentConfigurationAwareInterface { public function getCode(): ?string; diff --git a/src/Form/Type/PageType.php b/src/Form/Type/PageType.php index a676f9b33..b97b0457d 100755 --- a/src/Form/Type/PageType.php +++ b/src/Form/Type/PageType.php @@ -56,7 +56,6 @@ public function buildForm(FormBuilderInterface $builder, array $options): void 'time_widget' => 'single_text', 'required' => false, ]) - ->add('locales') ->add('contentElements', CollectionType::class, [ 'label' => false, 'entry_type' => ContentConfigurationType::class, diff --git a/src/Migrations/Version20240725064430.php b/src/Migrations/Version20240725064430.php new file mode 100644 index 000000000..d9880d509 --- /dev/null +++ b/src/Migrations/Version20240725064430.php @@ -0,0 +1,30 @@ +addSql('ALTER TABLE bitbag_cms_page_locales DROP FOREIGN KEY FK_EF20FD23C4663E4'); + $this->addSql('ALTER TABLE bitbag_cms_page_locales DROP FOREIGN KEY FK_EF20FD23E559DFD1'); + $this->addSql('DROP TABLE bitbag_cms_page_locales'); + } + + public function down(Schema $schema): void + { + $this->addSql('CREATE TABLE bitbag_cms_page_locales (page_id INT NOT NULL, locale_id INT NOT NULL, INDEX IDX_EF20FD23E559DFD1 (locale_id), INDEX IDX_EF20FD23C4663E4 (page_id), PRIMARY KEY(page_id, locale_id)) DEFAULT CHARACTER SET utf8mb4 COLLATE `utf8mb4_unicode_ci` ENGINE = InnoDB COMMENT = \'\' '); + $this->addSql('ALTER TABLE bitbag_cms_page_locales ADD CONSTRAINT FK_EF20FD23C4663E4 FOREIGN KEY (page_id) REFERENCES bitbag_cms_page (id) ON DELETE CASCADE'); + $this->addSql('ALTER TABLE bitbag_cms_page_locales ADD CONSTRAINT FK_EF20FD23E559DFD1 FOREIGN KEY (locale_id) REFERENCES sylius_locale (id) ON DELETE CASCADE'); + } +} diff --git a/src/Resolver/BlockResourceResolver.php b/src/Resolver/BlockResourceResolver.php index baf6ab6a8..0eae3a8d2 100755 --- a/src/Resolver/BlockResourceResolver.php +++ b/src/Resolver/BlockResourceResolver.php @@ -14,6 +14,9 @@ use BitBag\SyliusCmsPlugin\Repository\BlockRepositoryInterface; use Psr\Log\LoggerInterface; use Sylius\Component\Channel\Context\ChannelContextInterface; +use Sylius\Component\Locale\Context\LocaleContextInterface; +use Sylius\Component\Locale\Model\LocaleInterface; +use Sylius\Component\Resource\Repository\RepositoryInterface; use Webmozart\Assert\Assert; final class BlockResourceResolver implements BlockResourceResolverInterface @@ -22,6 +25,8 @@ public function __construct( private BlockRepositoryInterface $blockRepository, private LoggerInterface $logger, private ChannelContextInterface $channelContext, + private LocaleContextInterface $localeContext, + private RepositoryInterface $localeRepository, ) { } @@ -40,6 +45,20 @@ public function findOrLog(string $code): ?BlockInterface return null; } + /** @var LocaleInterface $locale */ + $locale = $this->localeRepository->findOneBy(['code' => $this->localeContext->getLocaleCode()]); + Assert::notNull($locale); + + if (false === $block->hasLocale($locale) && 0 !== $block->getLocales()->count()) { + $this->logger->warning(sprintf( + 'Block with "%s" code was found in the database, but it does not have "%s" locale.', + $code, + $this->localeContext->getLocaleCode(), + )); + + return null; + } + return $block; } } diff --git a/src/Resources/assets/admin/js/bitbag/bitbag-page-slug.js b/src/Resources/assets/admin/js/bitbag/bitbag-page-slug.js index 6fa5f51bd..bd146b03a 100644 --- a/src/Resources/assets/admin/js/bitbag/bitbag-page-slug.js +++ b/src/Resources/assets/admin/js/bitbag/bitbag-page-slug.js @@ -12,12 +12,14 @@ export class HandleSlugUpdate { wrappersIndicator: 'data-bb-cms-wrapper', lockFieldIndicator: 'data-bb-cms-toggle-slug', bbTarget: 'bitbag_sylius_cms_plugin_page', + nameField: 'bitbag_sylius_cms_plugin_page_name', } ) { this.wrappers = document.querySelectorAll(`[${config.wrappersIndicator}]`); this.lockFieldIndicator = `[${config.lockFieldIndicator}]`; this.bbTarget = config.bbTarget; this.config = config; + this.nameField = document.getElementById(`${config.nameField}`); } init() { @@ -29,6 +31,10 @@ export class HandleSlugUpdate { throw new Error('Bitbag CMS Plugin - HandleSlugUpdate class config key values are not valid strings'); } + if (!this.nameField ) { + throw new Error('Bitbag CMS Plugin - HandleSlugUpdate name field not found'); + } + this._handleFields(); } @@ -36,37 +42,29 @@ export class HandleSlugUpdate { this.wrappers.forEach((item) => { const locale = item.dataset.locale; - let textField = item.querySelector(`#${this.bbTarget}_translations_${locale}_name`); - if (!textField) { - textField = item.querySelector(`#${this.bbTarget}_name`); - } - let slugField = item.querySelector(`#${this.bbTarget}_translations_${locale}_slug`); if (!slugField) { slugField = item.querySelector(`#${this.bbTarget}_slug`); } - const lockField = item.querySelector(this.lockFieldIndicator); - - if (!textField || !slugField) { + if (!slugField) { return; } let timeout; - textField.addEventListener('input', (e) => { + this.nameField.addEventListener('input', (e) => { e.preventDefault(); - if (slugField.readOnly) { - return; + if (!slugField.readOnly) { + clearTimeout(timeout); + timeout = setTimeout(() => { + this._updateSlug(slugField, this.nameField.value); + }, 1000); } - - clearTimeout(timeout); - timeout = setTimeout(() => { - this._updateSlug(slugField, textField.value); - }, 1000); }); + const lockField = item.querySelector(this.lockFieldIndicator); if (!lockField) { return; } diff --git a/src/Resources/config/doctrine/Page.orm.xml b/src/Resources/config/doctrine/Page.orm.xml index 7551901bb..c0ba3758f 100644 --- a/src/Resources/config/doctrine/Page.orm.xml +++ b/src/Resources/config/doctrine/Page.orm.xml @@ -58,16 +58,5 @@ - - - - - - - - - - - diff --git a/src/Resources/config/services/resolver.xml b/src/Resources/config/services/resolver.xml index 9d51b70b1..f95ea26ad 100644 --- a/src/Resources/config/services/resolver.xml +++ b/src/Resources/config/services/resolver.xml @@ -32,6 +32,8 @@ + + diff --git a/src/Resources/config/validation/PageTranslation.xml b/src/Resources/config/validation/PageTranslation.xml index 56b7b5588..811520f93 100644 --- a/src/Resources/config/validation/PageTranslation.xml +++ b/src/Resources/config/validation/PageTranslation.xml @@ -17,12 +17,6 @@ - - - - diff --git a/src/Resources/views/Page/Crud/_form.html.twig b/src/Resources/views/Page/Crud/_form.html.twig index db40b48ae..4e5e87850 100755 --- a/src/Resources/views/Page/Crud/_form.html.twig +++ b/src/Resources/views/Page/Crud/_form.html.twig @@ -12,7 +12,6 @@ {{ form_row(form.code) }} {{ form_row(form.enabled) }} {{ form_row(form.channels) }} - {{ form_row(form.locales) }} {{ form_row(form.collections) }} {{ form_row(form.publishAt) }} diff --git a/tests/Application/templates/bundles/SyliusShopBundle/layout.html.twig b/tests/Application/templates/bundles/SyliusShopBundle/layout.html.twig index ea0782be5..f95cedc86 100755 --- a/tests/Application/templates/bundles/SyliusShopBundle/layout.html.twig +++ b/tests/Application/templates/bundles/SyliusShopBundle/layout.html.twig @@ -104,7 +104,6 @@