Optimized menu

This commit is contained in:
Kevin Frantz 2019-03-31 17:59:43 +02:00
parent 108debf6bf
commit 1aa5d35169
9 changed files with 129 additions and 17 deletions

View File

@ -9,6 +9,21 @@ namespace Infinito\Domain\FixtureManagement\FixtureSource;
*/ */
abstract class AbstractFixtureSource implements FixtureSourceInterface abstract class AbstractFixtureSource implements FixtureSourceInterface
{ {
/**
* @var string a human readable name
*/
protected $name = null;
/**
* {@inheritdoc}
*
* @see \Infinito\Domain\FixtureManagement\FixtureSource\FixtureSourceInterface::getName()
*/
public function getName(): string
{
return $this->name ?? self::getSlug();
}
/** /**
* @return string * @return string
*/ */

View File

@ -30,4 +30,9 @@ interface FixtureSourceInterface
* @return string|null a fontawesome css class * @return string|null a fontawesome css class
*/ */
public static function getIcon(): string; public static function getIcon(): string;
/**
* @return string A human readable name, if defined, otherwise a slug
*/
public function getName(): string;
} }

View File

@ -13,6 +13,11 @@ use Infinito\Domain\FixtureManagement\EntityTemplateFactory;
*/ */
final class GuestUserFixtureSource extends AbstractFixtureSource final class GuestUserFixtureSource extends AbstractFixtureSource
{ {
/**
* @var string
*/
protected $name = 'guest user';
/** /**
* {@inheritdoc} * {@inheritdoc}
* *

View File

@ -50,7 +50,8 @@ final class FixtureSourceFactory implements FixtureSourceFactoryInterface
{ {
$objects = []; $objects = [];
foreach ($classes as $class) { foreach ($classes as $class) {
$objects[] = new $class(); $object = new $class();
$objects[$object->getSlug()] = $object;
} }
return $objects; return $objects;

View File

@ -42,6 +42,8 @@ class Right extends AbstractMeta implements RightInterface
* @ORM\ManyToOne(targetEntity="Law", inversedBy="rights") * @ORM\ManyToOne(targetEntity="Law", inversedBy="rights")
* @ORM\JoinColumn(name="law_id", referencedColumnName="id",nullable=false) * @ORM\JoinColumn(name="law_id", referencedColumnName="id",nullable=false)
* *
* @deprecated it doesn't make sense to reference to the law, because the routing is allready possible over the source
*
* @var LawInterface * @var LawInterface
*/ */
protected $law; protected $law;

View File

@ -14,9 +14,17 @@ use Infinito\DBAL\Types\RESTResponseType;
use Infinito\DBAL\Types\Meta\Right\LayerType; use Infinito\DBAL\Types\Meta\Right\LayerType;
use Infinito\Controller\API\Rest\LayerController; use Infinito\Controller\API\Rest\LayerController;
use Infinito\Domain\FixtureManagement\FixtureSourceFactory; use Infinito\Domain\FixtureManagement\FixtureSourceFactory;
use Infinito\Domain\FixtureManagement\FixtureSource\FixtureSourceInterface;
use Infinito\Domain\FixtureManagement\FixtureSource\GuestUserFixtureSource;
use Infinito\Domain\FixtureManagement\FixtureSource\HomepageFixtureSource;
use Infinito\Domain\FixtureManagement\FixtureSource\ImpressumFixtureSource;
use Infinito\Domain\FixtureManagement\FixtureSource\InformationFixtureSource;
use Infinito\Domain\FixtureManagement\FixtureSource\HelpFixtureSource;
/** /**
* @author kevinfrantz * @author kevinfrantz
*
* @todo Refactor this class!
*/ */
class UserMenuSubscriber extends AbstractEntityMenuSubscriber implements EventSubscriberInterface class UserMenuSubscriber extends AbstractEntityMenuSubscriber implements EventSubscriberInterface
{ {
@ -35,42 +43,83 @@ class UserMenuSubscriber extends AbstractEntityMenuSubscriber implements EventSu
*/ */
private $tokenStorage; private $tokenStorage;
/**
* @var FixtureSourceInterface[]
*/
private $fixtureSources;
/** /**
* @param TokenStorageInterface $tokenStorage * @param TokenStorageInterface $tokenStorage
* @param TranslatorInterface $translator * @param TranslatorInterface $translator
*/ */
public function __construct(TokenStorageInterface $tokenStorage, TranslatorInterface $translator) public function __construct(TokenStorageInterface $tokenStorage, TranslatorInterface $translator)
{ {
$this->fixtureSources = FixtureSourceFactory::getAllFixtureSources();
$this->tokenStorage = $tokenStorage; $this->tokenStorage = $tokenStorage;
parent::__construct($translator); parent::__construct($translator);
} }
/**
* @param ItemInterface $item
* @param string $slug
*/
private function deleteAndAddToItem(ItemInterface $item, string $slug): void
{
$fixtureSource = $this->getAndDeleteFixtureSource($slug);
$this->addFixtureSourceToItem($item, $fixtureSource);
}
/**
* @param string $slug
*
* @return FixtureSourceInterface
*/
private function getAndDeleteFixtureSource(string $slug): FixtureSourceInterface
{
$result = clone $this->fixtureSources[$slug];
unset($this->fixtureSources[$slug]);
return $result;
}
/** /**
* @param MenuEvent $event * @param MenuEvent $event
*/ */
public function onUserMenuConfigure(MenuEvent $event): void public function onUserMenuConfigure(MenuEvent $event): void
{ {
$menu = $event->getItem(); $menu = $event->getItem();
$fixtureSources = FixtureSourceFactory::getAllFixtureSources(); foreach ([HomepageFixtureSource::getSlug(), ImpressumFixtureSource::getSlug(), InformationFixtureSource::getSlug(), HelpFixtureSource::getSlug()] as $slug) {
foreach ($fixtureSources as $fixtureSource) { $this->deleteAndAddToItem($menu, $slug);
$slug = $fixtureSource::getSlug();
$icon = $fixtureSource::getIcon();
$menu->addChild($this->trans($slug), [
'route' => self::LAYER_GET_ROUTE,
'routeParameters' => [
LayerController::IDENTITY_PARAMETER_KEY => $slug,
LayerController::FORMAT_PARAMETER_KEY => RESTResponseType::HTML,
LayerController::LAYER_PARAMETER_KEY => LayerType::SOURCE,
],
'attributes' => [
'icon' => $icon,
],
]);
} }
if ($this->shouldShowFormatSelection($event)) { if ($this->shouldShowFormatSelection($event)) {
$this->generateShowDropdown($menu, $event, self::LAYER_GET_ROUTE); $this->generateShowDropdown($menu, $event, self::LAYER_GET_ROUTE);
} }
$this->generateUserDropdown($menu); $this->generateUserDropdown($menu);
foreach ($this->fixtureSources as $fixtureSource) {
$this->addFixtureSourceToItem($menu, $fixtureSource);
}
}
/**
* @param ItemInterface $item
* @param FixtureSourceInterface $fixtureSource
*/
private function addFixtureSourceToItem(ItemInterface $item, FixtureSourceInterface $fixtureSource): void
{
$slug = $fixtureSource::getSlug();
$name = $fixtureSource->getName();
$icon = $fixtureSource::getIcon();
$item->addChild($this->trans($name), [
'route' => self::LAYER_GET_ROUTE,
'routeParameters' => [
LayerController::IDENTITY_PARAMETER_KEY => $slug,
LayerController::FORMAT_PARAMETER_KEY => RESTResponseType::HTML,
LayerController::LAYER_PARAMETER_KEY => LayerType::SOURCE,
],
'attributes' => [
'icon' => $icon,
],
]);
} }
/** /**
@ -112,6 +161,7 @@ class UserMenuSubscriber extends AbstractEntityMenuSubscriber implements EventSu
'icon' => 'fas fa-user', 'icon' => 'fas fa-user',
], ],
]); ]);
$guestUser = $this->getAndDeleteFixtureSource(GuestUserFixtureSource::getSlug());
if ($this->getRoles()) { if ($this->getRoles()) {
$dropdown->addChild($this->trans('logout'), [ $dropdown->addChild($this->trans('logout'), [
'route' => 'logout', 'route' => 'logout',
@ -139,8 +189,10 @@ class UserMenuSubscriber extends AbstractEntityMenuSubscriber implements EventSu
'route' => 'fos_user_registration_register', 'route' => 'fos_user_registration_register',
'attributes' => [ 'attributes' => [
'icon' => 'fas fa-file-signature', 'icon' => 'fas fa-file-signature',
'divider_append' => true,
], ],
]); ]);
$this->addFixtureSourceToItem($dropdown, $guestUser);
} }
} }

View File

@ -51,6 +51,18 @@ class FixtureSourceFactoryIntegrationTest extends TestCase
} }
} }
public function testFixtureSourceNames(): void
{
$names = [];
foreach ($this->fixtureSources as $fixtureSource) {
$this->assertInstanceOf(FixtureSourceInterface::class, $fixtureSource);
$name = $fixtureSource->getName();
$this->assertIsString($name);
$this->assertFalse(in_array($name, $names), 'An name has to be unique');
$names[] = $name;
}
}
/** /**
* The following test is redundant. * The following test is redundant.
*/ */

View File

@ -13,6 +13,7 @@ use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase;
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface; use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface; use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\Security\Core\Role\Role; use Symfony\Component\Security\Core\Role\Role;
use Infinito\Domain\FixtureManagement\FixtureSource\GuestUserFixtureSource;
/** /**
* @author kevinfrantz * @author kevinfrantz
@ -79,7 +80,8 @@ class UserMenuSubscriberIntegrationTest extends KernelTestCase
$menuEvent = new MenuEvent($factory, $item, $requests); $menuEvent = new MenuEvent($factory, $item, $requests);
$this->subscriber->onUserMenuConfigure($menuEvent); $this->subscriber->onUserMenuConfigure($menuEvent);
$children = $menuEvent->getItem()->getChildren()['user']->getChildren(); $children = $menuEvent->getItem()->getChildren()['user']->getChildren();
$unauthentificatedItems = ['login', 'register']; $guestUserName = (new GuestUserFixtureSource())->getName();
$unauthentificatedItems = ['login', 'register', $guestUserName];
foreach ($unauthentificatedItems as $key) { foreach ($unauthentificatedItems as $key) {
$this->assertInstanceOf(MenuItem::class, $children[$key]); $this->assertInstanceOf(MenuItem::class, $children[$key]);
} }

View File

@ -0,0 +1,18 @@
<?php
namespace tests\Unit\Domain\FixtureManagement;
use PHPUnit\Framework\TestCase;
use Infinito\Domain\FixtureManagement\FixtureSource\GuestUserFixtureSource;
/**
* @author kevinfrantz
*/
class GuestUserFixtureSourceTest extends TestCase
{
public function testSlugName(): void
{
$fixtureSource = new GuestUserFixtureSource();
$this->assertNotEquals($fixtureSource->getName(), $fixtureSource::getSlug());
}
}