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
{
/**
* @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
*/

View File

@ -30,4 +30,9 @@ interface FixtureSourceInterface
* @return string|null a fontawesome css class
*/
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
{
/**
* @var string
*/
protected $name = 'guest user';
/**
* {@inheritdoc}
*

View File

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

View File

@ -42,6 +42,8 @@ class Right extends AbstractMeta implements RightInterface
* @ORM\ManyToOne(targetEntity="Law", inversedBy="rights")
* @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
*/
protected $law;

View File

@ -14,9 +14,17 @@ use Infinito\DBAL\Types\RESTResponseType;
use Infinito\DBAL\Types\Meta\Right\LayerType;
use Infinito\Controller\API\Rest\LayerController;
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
*
* @todo Refactor this class!
*/
class UserMenuSubscriber extends AbstractEntityMenuSubscriber implements EventSubscriberInterface
{
@ -35,42 +43,83 @@ class UserMenuSubscriber extends AbstractEntityMenuSubscriber implements EventSu
*/
private $tokenStorage;
/**
* @var FixtureSourceInterface[]
*/
private $fixtureSources;
/**
* @param TokenStorageInterface $tokenStorage
* @param TranslatorInterface $translator
*/
public function __construct(TokenStorageInterface $tokenStorage, TranslatorInterface $translator)
{
$this->fixtureSources = FixtureSourceFactory::getAllFixtureSources();
$this->tokenStorage = $tokenStorage;
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
*/
public function onUserMenuConfigure(MenuEvent $event): void
{
$menu = $event->getItem();
$fixtureSources = FixtureSourceFactory::getAllFixtureSources();
foreach ($fixtureSources as $fixtureSource) {
$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,
],
]);
foreach ([HomepageFixtureSource::getSlug(), ImpressumFixtureSource::getSlug(), InformationFixtureSource::getSlug(), HelpFixtureSource::getSlug()] as $slug) {
$this->deleteAndAddToItem($menu, $slug);
}
if ($this->shouldShowFormatSelection($event)) {
$this->generateShowDropdown($menu, $event, self::LAYER_GET_ROUTE);
}
$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',
],
]);
$guestUser = $this->getAndDeleteFixtureSource(GuestUserFixtureSource::getSlug());
if ($this->getRoles()) {
$dropdown->addChild($this->trans('logout'), [
'route' => 'logout',
@ -139,8 +189,10 @@ class UserMenuSubscriber extends AbstractEntityMenuSubscriber implements EventSu
'route' => 'fos_user_registration_register',
'attributes' => [
'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.
*/

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\TokenInterface;
use Symfony\Component\Security\Core\Role\Role;
use Infinito\Domain\FixtureManagement\FixtureSource\GuestUserFixtureSource;
/**
* @author kevinfrantz
@ -79,7 +80,8 @@ class UserMenuSubscriberIntegrationTest extends KernelTestCase
$menuEvent = new MenuEvent($factory, $item, $requests);
$this->subscriber->onUserMenuConfigure($menuEvent);
$children = $menuEvent->getItem()->getChildren()['user']->getChildren();
$unauthentificatedItems = ['login', 'register'];
$guestUserName = (new GuestUserFixtureSource())->getName();
$unauthentificatedItems = ['login', 'register', $guestUserName];
foreach ($unauthentificatedItems as $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());
}
}