Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix breadcrumb rendering #619

Merged
merged 2 commits into from
Nov 1, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
78 changes: 65 additions & 13 deletions src/Block/Breadcrumb/BaseBreadcrumbMenuBlockService.php
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand All @@ -41,42 +42,65 @@ 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;
}

abstract protected function getContext(): string;

/**
* Initialize breadcrumb menu.
*/
protected function getRootMenu(BlockContextInterface $blockContext): ItemInterface
final protected function getRootMenu(BlockContextInterface $blockContext): ItemInterface
{
$settings = $blockContext->getSettings();
/*
* @todo : Use the router to get the homepage URI
*/

$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']);

Expand All @@ -86,4 +110,32 @@ protected function getRootMenu(BlockContextInterface $blockContext): ItemInterfa

return $menu;
}

/**
* Replaces setting keys with knp menu item options keys.
*
* @param array<string, mixed> $settings
*
* @return array<string, mixed>
*/
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;
}
}
2 changes: 1 addition & 1 deletion src/Block/Breadcrumb/HomepageBreadcrumbBlockService.php
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand Down
2 changes: 2 additions & 0 deletions src/Resources/config/blocks.php
Original file line number Diff line number Diff line change
Expand Up @@ -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'),
]);
};
54 changes: 52 additions & 2 deletions tests/Block/Breadcrumb/BreadcrumbTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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);
}
}