Skip to content

Commit

Permalink
Merge pull request #80 from APY/bug/reset-breadcrumb
Browse files Browse the repository at this point in the history
  • Loading branch information
rvanlaak authored Nov 29, 2021
2 parents ef95116 + d70dc57 commit 48d56e2
Show file tree
Hide file tree
Showing 8 changed files with 85 additions and 5 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
# v1.8

- introduce ResetBreadcrumbtrail attribute for resetting trail, prefer over empty annotation

# v1.7

- support breadcrumbs via PHP Attributes
Expand Down
4 changes: 2 additions & 2 deletions src/Annotation/Breadcrumb.php
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ class Breadcrumb
private $attributes = [];

/**
* @param array|string $title title, or the legacy array that contains all annotation data
* @param array|string|null $title title, or the legacy array that contains all annotation data. Passing `null` to reset the breadcrumb trail is deprecated and will throw an exception in `2.0`.
* @param ?string $routeName
* @param ?array<string,mixed> $routeParameters
* @param bool $routeAbsolute
Expand All @@ -62,7 +62,7 @@ class Breadcrumb
* @param array $attributes
*/
public function __construct(
$title,
$title = null,
$routeName = null,
$routeParameters = null,
$routeAbsolute = null,
Expand Down
11 changes: 11 additions & 0 deletions src/Annotation/ResetBreadcrumbTrail.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<?php

namespace APY\BreadcrumbTrailBundle\Annotation;

/**
* Resets the breadcrumb trail. Can be applied on controller classes, callables, invokables and action methods.
*/
#[\Attribute(\Attribute::TARGET_CLASS | \Attribute::TARGET_METHOD)]
final class ResetBreadcrumbTrail
{
}
22 changes: 21 additions & 1 deletion src/EventListener/BreadcrumbListener.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
namespace APY\BreadcrumbTrailBundle\EventListener;

use APY\BreadcrumbTrailBundle\Annotation\Breadcrumb;
use APY\BreadcrumbTrailBundle\Annotation\ResetBreadcrumbTrail;
use APY\BreadcrumbTrailBundle\BreadcrumbTrail\Trail;
use APY\BreadcrumbTrailBundle\MixedAnnotationWithAttributeBreadcrumbsException;
use Doctrine\Common\Annotations\Reader;
Expand All @@ -30,6 +31,11 @@ class BreadcrumbListener
*/
protected $breadcrumbTrail;

private $supportedAttributes = [
Breadcrumb::class,
ResetBreadcrumbTrail::class,
];

/**
* Constructor.
*
Expand Down Expand Up @@ -109,10 +115,20 @@ private function addBreadcrumbsToTrail(array $annotations)
{
// requirements (@Breadcrumb)
foreach ($annotations as $annotation) {
if ($annotation instanceof ResetBreadcrumbTrail) {
$this->breadcrumbTrail->reset();

continue;
}

if ($annotation instanceof Breadcrumb) {
$template = $annotation->getTemplate();
$title = $annotation->getTitle();

if (null === $title) {
trigger_deprecation('apy/breadcrumb-bundle', '1.8', 'Resetting the breadcrumb trail by passing a Breadcrumb without parameters, and will throw an exception in v2.0. Use #[ResetBreadcrumbTrail] attribute instead.');
}

if (null != $template) {
$this->breadcrumbTrail->setTemplate($template);
if (null === $title) {
Expand Down Expand Up @@ -158,7 +174,11 @@ private function getAttributes($reflected): array
}

$attributes = [];
foreach ($reflected->getAttributes(Breadcrumb::class) as $reflectionAttribute) {
foreach ($reflected->getAttributes() as $reflectionAttribute) {
if (false === \in_array($reflectionAttribute->getName(), $this->supportedAttributes)) {
continue;
}

$attributes[] = $reflectionAttribute->newInstance();
}

Expand Down
5 changes: 3 additions & 2 deletions src/Resources/doc/annotation_configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -284,17 +284,18 @@ Will render the following breadcrumb trail :

### Reset the trail

Passing an breadcrumb without any parameter values will remove all existing
Adding a ResetBreadcrumbTrail attribute will remove all existing
breadcrumbs from the trail.

Resetting might come in handy in case the controller class unwantedly defines
breadcrumbs already.

```php
use APY\BreadcrumbTrailBundle\Annotation\Breadcrumb;
use APY\BreadcrumbTrailBundle\Annotation\ResetBreadcrumbTrail;

#[Breadcrumb("Level 1")]
#[Breadcrumb()]
#[ResetBreadcrumbTrail()]
#[Breadcrumb("Level 2")]
#[Breadcrumb("Level 3")]
```
Expand Down
11 changes: 11 additions & 0 deletions tests/Annotation/BreadcrumbTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -50,4 +50,15 @@ public function testUnnamedWillGetInterpretedAsValueForTitle()

self::assertEquals($expected, $breadcrumb->getTitle());
}

/**
* @deprecated passing empty constructor is deprecated since 1.8. ResetBreadcrumbTrail attribute should be used instead. Will throw exception in 2.0.
*/
public function testConstructorWithoutArgumentsIsAllowedForResettingTrail()
{
$expected = null;
$breadcrumb = new Breadcrumb();

self::assertEquals($expected, $breadcrumb->getTitle());
}
}
15 changes: 15 additions & 0 deletions tests/EventListener/BreadcrumbListenerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
use APY\BreadcrumbTrailBundle\Fixtures\ControllerWithAttributes;
use APY\BreadcrumbTrailBundle\Fixtures\ControllerWithAttributesAndAnnotations;
use APY\BreadcrumbTrailBundle\Fixtures\InvokableControllerWithAnnotations;
use APY\BreadcrumbTrailBundle\Fixtures\ResetTrailAttribute;
use APY\BreadcrumbTrailBundle\MixedAnnotationWithAttributeBreadcrumbsException;
use Nyholm\BundleTest\AppKernel;
use Nyholm\BundleTest\BaseBundleTestCase;
Expand Down Expand Up @@ -86,6 +87,20 @@ public function testInvokableController()
self::assertCount(3, $this->breadcrumbTrail);
}

/**
* @requires PHP >= 8.0
*/
public function testResetTrailAttribute()
{
$this->setUpTest();

$controller = new ResetTrailAttribute();
$kernelEvent = $this->createControllerEvent($controller);
$this->listener->onKernelController($kernelEvent);

self::assertCount(1, $this->breadcrumbTrail);
}

protected function getBundleClass()
{
return APYBreadcrumbTrailBundle::class;
Expand Down
18 changes: 18 additions & 0 deletions tests/Fixtures/ResetTrailAttribute.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<?php

namespace APY\BreadcrumbTrailBundle\Fixtures;

use APY\BreadcrumbTrailBundle\Annotation\Breadcrumb;
use APY\BreadcrumbTrailBundle\Annotation\ResetBreadcrumbTrail;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;

#[Breadcrumb(title: 'first-breadcrumb')]
class ResetTrailAttribute extends AbstractController
{
#[ResetBreadcrumbTrail]
#[Breadcrumb(title: 'first-breadcrumb-again')]
public function indexAction()
{
return [];
}
}

0 comments on commit 48d56e2

Please sign in to comment.