diff --git a/src/Form/Type/UiElement/BlockType.php b/src/Form/Type/UiElement/BlockType.php index 4da4b01..c953107 100644 --- a/src/Form/Type/UiElement/BlockType.php +++ b/src/Form/Type/UiElement/BlockType.php @@ -17,6 +17,7 @@ use MonsieurBiz\SyliusCmsBlockPlugin\Repository\BlockRepositoryInterface; use Sylius\Bundle\ResourceBundle\Form\DataTransformer\ResourceToIdentifierTransformer; use Sylius\Component\Locale\Context\LocaleContextInterface; +use Sylius\Resource\Translation\Provider\TranslationLocaleProviderInterface; use Symfony\Bridge\Doctrine\Form\Type\EntityType; use Symfony\Component\Form\AbstractType; use Symfony\Component\Form\FormBuilderInterface; @@ -28,6 +29,7 @@ final class BlockType extends AbstractType public function __construct( private BlockRepositoryInterface $blockRepository, private LocaleContextInterface $localeContext, + private TranslationLocaleProviderInterface $translationLocaleProvider, ) { } @@ -49,7 +51,7 @@ public function buildForm(FormBuilderInterface $builder, array $options): void 'multiple' => false, 'choice_label' => fn (BlockInterface $block): string => \sprintf('[%s] %s', $block->getCode(), $block->getName()), 'query_builder' => function (BlockRepository $blockRepository) { - return $blockRepository->createListQueryBuilder($this->localeContext->getLocaleCode()) + return $blockRepository->createListQueryBuilder($this->localeContext->getLocaleCode(), $this->translationLocaleProvider->getDefaultLocaleCode()) ->addOrderBy('o.code', 'ASC') ; }, @@ -59,7 +61,7 @@ public function buildForm(FormBuilderInterface $builder, array $options): void ]) ; - $reversedTransformer = new ReversedTransformer(new ResourceToIdentifierTransformer($this->blockRepository)); + $reversedTransformer = new ReversedTransformer(new ResourceToIdentifierTransformer($this->blockRepository, 'code')); $builder->get('block')->addModelTransformer($reversedTransformer); } } diff --git a/src/Repository/BlockRepository.php b/src/Repository/BlockRepository.php index c1a7797..2a6a785 100644 --- a/src/Repository/BlockRepository.php +++ b/src/Repository/BlockRepository.php @@ -18,27 +18,57 @@ class BlockRepository extends EntityRepository implements BlockRepositoryInterface { - public function createListQueryBuilder(string $localeCode): QueryBuilder + public function createListQueryBuilder(string $localeCode, ?string $fallbackLocaleCode = null): QueryBuilder { - return $this->createQueryBuilder('o') + $queryBuilder = $this->createQueryBuilder('o') ->addSelect('translation') ->leftJoin('o.translations', 'translation', 'WITH', 'translation.locale = :localeCode') ->setParameter('localeCode', $localeCode) ; + if (null !== $fallbackLocaleCode && $fallbackLocaleCode !== $localeCode) { + $queryBuilder + ->addSelect('fallbackTranslation') + ->leftJoin('o.translations', 'fallbackTranslation', 'WITH', 'fallbackTranslation.locale = :fallbackLocaleCode') + ->setParameter('fallbackLocaleCode', $fallbackLocaleCode) + ; + } + + return $queryBuilder; } /** * @throws NonUniqueResultException */ - public function findOneEnabledByCode(string $code): ?BlockInterface + public function findOneEnabledByCode(string $code, ?string $locale = null, ?string $fallbackLocaleCode = null): ?BlockInterface { - /** @phpstan-ignore-next-line */ - return $this->createQueryBuilder('b') - ->andWhere('b.code = :code') - ->andWhere('b.enabled = true') + $queryBuilder = $locale ? $this->createListQueryBuilder($locale, $fallbackLocaleCode) : $this->createQueryBuilder('o'); + + /** @var ?BlockInterface */ + return $queryBuilder + ->andWhere('o.code = :code') + ->andWhere('o.enabled = true') ->setParameter('code', $code) ->getQuery() ->getOneOrNullResult() ; } + + public function findOneEnabledByIdentifier(string $identifier, ?string $locale = null, ?string $fallbackLocaleCode = null): ?BlockInterface + { + $block = $this->findOneEnabledByCode($identifier, $locale, $fallbackLocaleCode); + if (null !== $block) { + return $block; + } + + $queryBuilder = $locale ? $this->createListQueryBuilder($locale, $fallbackLocaleCode) : $this->createQueryBuilder('o'); + + /** @var ?BlockInterface */ + return $queryBuilder + ->andWhere('o.id = :id') + ->andWhere('o.enabled = true') + ->setParameter('id', $identifier) + ->getQuery() + ->getOneOrNullResult() + ; + } } diff --git a/src/Repository/BlockRepositoryInterface.php b/src/Repository/BlockRepositoryInterface.php index a9a9b0a..f3bef56 100644 --- a/src/Repository/BlockRepositoryInterface.php +++ b/src/Repository/BlockRepositoryInterface.php @@ -11,13 +11,22 @@ namespace MonsieurBiz\SyliusCmsBlockPlugin\Repository; +use Doctrine\ORM\NonUniqueResultException; use Doctrine\ORM\QueryBuilder; use MonsieurBiz\SyliusCmsBlockPlugin\Entity\BlockInterface; use Sylius\Component\Resource\Repository\RepositoryInterface; interface BlockRepositoryInterface extends RepositoryInterface { - public function createListQueryBuilder(string $localeCode): QueryBuilder; + public function createListQueryBuilder(string $localeCode, ?string $fallbackLocaleCode = null): QueryBuilder; - public function findOneEnabledByCode(string $code): ?BlockInterface; + /** + * @throws NonUniqueResultException + */ + public function findOneEnabledByCode(string $code, ?string $locale = null, ?string $fallbackLocaleCode = null): ?BlockInterface; + + /** + * @throws NonUniqueResultException + */ + public function findOneEnabledByIdentifier(string $identifier, ?string $locale = null, ?string $fallbackLocaleCode = null): ?BlockInterface; } diff --git a/src/Resources/translations/messages.en.yaml b/src/Resources/translations/messages.en.yaml index b647f1a..6b1c4ed 100644 --- a/src/Resources/translations/messages.en.yaml +++ b/src/Resources/translations/messages.en.yaml @@ -7,6 +7,7 @@ monsieurbiz_cms_block: cms_content: "CMS content" blocks_subheader: "CMS block management" back_to_admin: "Back to admin" + block_not_found: 'Block "%name%" not found.' form: block_info: 'Block information' block_content: 'Block content' diff --git a/src/Resources/translations/messages.fr.yaml b/src/Resources/translations/messages.fr.yaml index 69c0900..3dbd9c5 100644 --- a/src/Resources/translations/messages.fr.yaml +++ b/src/Resources/translations/messages.fr.yaml @@ -7,6 +7,7 @@ monsieurbiz_cms_block: cms_content: "Contenu CMS" blocks_subheader: "Gestion des blocs CMS" back_to_admin: "Retour à l'administration" + block_not_found: 'Le bloc "%name%" n''a pas été trouvé.' form: block_info: 'Informations sur le bloc' block_content: 'Contenu du bloc' diff --git a/src/Resources/views/Admin/UiElement/block.html.twig b/src/Resources/views/Admin/UiElement/block.html.twig index 101e4db..09d1002 100644 --- a/src/Resources/views/Admin/UiElement/block.html.twig +++ b/src/Resources/views/Admin/UiElement/block.html.twig @@ -10,4 +10,8 @@ element methods: {% set blockEntity = ui_element.getBlock(element.block) %} {% if blockEntity and blockEntity.enabled %} {{ blockEntity.content|monsieurbiz_richeditor_render_field }} +{% else %} +
{% endif %} diff --git a/src/UiElement/BlockUiElement.php b/src/UiElement/BlockUiElement.php index 34e6553..125655b 100644 --- a/src/UiElement/BlockUiElement.php +++ b/src/UiElement/BlockUiElement.php @@ -11,10 +11,13 @@ namespace MonsieurBiz\SyliusCmsBlockPlugin\UiElement; +use Doctrine\ORM\NonUniqueResultException; use MonsieurBiz\SyliusCmsBlockPlugin\Entity\BlockInterface; use MonsieurBiz\SyliusCmsBlockPlugin\Repository\BlockRepositoryInterface; use MonsieurBiz\SyliusRichEditorPlugin\UiElement\UiElementInterface; use MonsieurBiz\SyliusRichEditorPlugin\UiElement\UiElementTrait; +use Sylius\Component\Locale\Context\LocaleContextInterface; +use Sylius\Resource\Translation\Provider\TranslationLocaleProviderInterface; final class BlockUiElement implements UiElementInterface { @@ -22,12 +25,21 @@ final class BlockUiElement implements UiElementInterface public function __construct( private BlockRepositoryInterface $blockRepository, + private LocaleContextInterface $localeContext, + private TranslationLocaleProviderInterface $translationLocaleProvider, ) { } - public function getBlock(string $id): ?BlockInterface + public function getBlock(string $identifier): ?BlockInterface { - /** @phpstan-ignore-next-line */ - return $this->blockRepository->find($id); + try { + return $this->blockRepository->findOneEnabledByIdentifier( + $identifier, + $this->localeContext->getLocaleCode(), + $this->translationLocaleProvider->getDefaultLocaleCode() + ); + } catch (NonUniqueResultException) { + return null; + } } }