diff --git a/src/Block/Breadcrumb/BaseBreadcrumbMenuBlockService.php b/src/Block/Breadcrumb/BaseBreadcrumbMenuBlockService.php index 04bc3fad..8e690eb1 100644 --- a/src/Block/Breadcrumb/BaseBreadcrumbMenuBlockService.php +++ b/src/Block/Breadcrumb/BaseBreadcrumbMenuBlockService.php @@ -17,6 +17,7 @@ use Knp\Menu\ItemInterface; use Sonata\BlockBundle\Block\BlockContextInterface; use Sonata\BlockBundle\Block\Service\AbstractBlockService; +use Symfony\Component\HttpFoundation\Response; use Symfony\Component\OptionsResolver\OptionsResolver; use Twig\Environment; @@ -41,17 +42,49 @@ public function handleContext(string $context): bool return $this->getContext() === $context; } - public function configureSettings(OptionsResolver $resolver): void + final public function execute(BlockContextInterface $blockContext, ?Response $response = null): Response { - parent::configureSettings($resolver); + $responseSettings = [ + 'menu' => $this->getMenu($blockContext), + 'menu_options' => $this->getMenuOptions($blockContext->getSettings()), + 'block' => $blockContext->getBlock(), + 'context' => $blockContext, + ]; + + $template = $blockContext->getTemplate(); + + \assert(\is_string($template)); + + if ('private' === $blockContext->getSetting('cache_policy')) { + return $this->renderPrivateResponse($template, $responseSettings, $response); + } + + return $this->renderResponse($template, $responseSettings, $response); + } + public function configureSettings(OptionsResolver $resolver): void + { $resolver->setDefaults([ + 'cache_policy' => 'public', + 'template' => '@SonataBlock/Block/block_core_menu.html.twig', + 'safe_labels' => false, + 'current_class' => 'active', + 'first_class' => false, + 'last_class' => false, + 'current_uri' => null, + 'menu_class' => 'list-group', + 'children_class' => 'list-group-item', 'menu_template' => '@SonataSeo/Block/breadcrumb.html.twig', 'include_homepage_link' => true, - 'context' => false, + 'context' => null, ]); } + protected function getMenu(BlockContextInterface $blockContext): ItemInterface + { + return $this->getRootMenu($blockContext); + } + final protected function getFactory(): FactoryInterface { return $this->factory; @@ -59,10 +92,7 @@ final protected function getFactory(): FactoryInterface abstract protected function getContext(): string; - /** - * Initialize breadcrumb menu. - */ - protected function getRootMenu(BlockContextInterface $blockContext): ItemInterface + final protected function getRootMenu(BlockContextInterface $blockContext): ItemInterface { $settings = $blockContext->getSettings(); /* @@ -70,13 +100,7 @@ protected function getRootMenu(BlockContextInterface $blockContext): ItemInterfa */ $menu = $this->factory->createItem('breadcrumb'); - $menu->setChildrenAttribute('class', 'breadcrumb'); - - if (method_exists($menu, 'setCurrentUri')) { - $menu->setCurrentUri($settings['current_uri']); - } - $menu->setCurrent(true); $menu->setUri($settings['current_uri']); @@ -86,4 +110,32 @@ protected function getRootMenu(BlockContextInterface $blockContext): ItemInterfa return $menu; } + + /** + * Replaces setting keys with knp menu item options keys. + * + * @param array $settings + * + * @return array + */ + private function getMenuOptions(array $settings): array + { + $mapping = [ + 'current_class' => 'currentClass', + 'first_class' => 'firstClass', + 'last_class' => 'lastClass', + 'safe_labels' => 'allow_safe_labels', + 'menu_template' => 'template', + ]; + + $options = []; + + foreach ($settings as $key => $value) { + if (null !== $value && \array_key_exists($key, $mapping)) { + $options[$mapping[$key]] = $value; + } + } + + return $options; + } } diff --git a/src/Block/Breadcrumb/HomepageBreadcrumbBlockService.php b/src/Block/Breadcrumb/HomepageBreadcrumbBlockService.php index c2ad10a7..2e886101 100644 --- a/src/Block/Breadcrumb/HomepageBreadcrumbBlockService.php +++ b/src/Block/Breadcrumb/HomepageBreadcrumbBlockService.php @@ -28,7 +28,7 @@ protected function getContext(): string return 'homepage'; } - private function getMenu(BlockContextInterface $blockContext): ItemInterface + protected function getMenu(BlockContextInterface $blockContext): ItemInterface { $menu = $this->getRootMenu($blockContext); diff --git a/src/Resources/config/blocks.php b/src/Resources/config/blocks.php index c47a371c..4c55efcc 100644 --- a/src/Resources/config/blocks.php +++ b/src/Resources/config/blocks.php @@ -27,6 +27,8 @@ ->tag('sonata.breadcrumb') ->args([ new ReferenceConfigurator('twig'), + new ReferenceConfigurator('knp_menu.menu_provider'), + new ReferenceConfigurator('sonata.block.menu.registry'), new ReferenceConfigurator('knp_menu.factory'), ]); }; diff --git a/tests/Block/Breadcrumb/BreadcrumbTest.php b/tests/Block/Breadcrumb/BreadcrumbTest.php index 2c18261e..191b7528 100644 --- a/tests/Block/Breadcrumb/BreadcrumbTest.php +++ b/tests/Block/Breadcrumb/BreadcrumbTest.php @@ -15,9 +15,12 @@ use Knp\Menu\FactoryInterface; use Knp\Menu\ItemInterface; +use Sonata\BlockBundle\Block\BlockContext; use Sonata\BlockBundle\Block\BlockContextInterface; +use Sonata\BlockBundle\Model\Block; use Sonata\BlockBundle\Test\BlockServiceTestCase; use Sonata\SeoBundle\Block\Breadcrumb\BaseBreadcrumbMenuBlockService; +use Symfony\Component\HttpFoundation\Response; use Twig\Environment; final class BreadcrumbMenuBlockService_Test extends BaseBreadcrumbMenuBlockService @@ -41,10 +44,57 @@ final class BreadcrumbTest extends BlockServiceTestCase public function testBlockService(): void { $blockService = new BreadcrumbMenuBlockService_Test( - $this->createMock(Environment::class), - $this->createMock(FactoryInterface::class) + $this->createStub(Environment::class), + $this->createStub(FactoryInterface::class) ); static::assertTrue($blockService->handleContext('test')); } + + public function testBlockExectute(): void + { + $menuFactory = $this->createMock(FactoryInterface::class); + + $blockService = new BreadcrumbMenuBlockService_Test( + $this->createStub(Environment::class), + $menuFactory + ); + + $menu = $this->createStub(ItemInterface::class); + $menuFactory->expects(static::once())->method('createItem')->with('breadcrumb') + ->willReturn($menu); + + $blockContext = new BlockContext(new Block(), [ + 'current_uri' => null, + 'include_homepage_link' => false, + 'cache_policy' => 'public', + 'template' => '@SonataBlock/Block/block_core_menu.html.twig', + ]); + $blockService->execute($blockContext, new Response()); + } + + public function testDefaultSettings(): void + { + $blockService = new BreadcrumbMenuBlockService_Test( + $this->createStub(Environment::class), + $this->createStub(FactoryInterface::class) + ); + + $blockContext = $this->getBlockContext($blockService); + + $this->assertSettings([ + 'cache_policy' => 'public', + 'template' => '@SonataBlock/Block/block_core_menu.html.twig', + 'safe_labels' => false, + 'current_class' => 'active', + 'first_class' => false, + 'last_class' => false, + 'current_uri' => null, + 'menu_class' => 'list-group', + 'children_class' => 'list-group-item', + 'menu_template' => '@SonataSeo/Block/breadcrumb.html.twig', + 'include_homepage_link' => true, + 'context' => null, + ], $blockContext); + } }