From 92887b029eb7e3b1e064ed670a9d9d445e6baf2d Mon Sep 17 00:00:00 2001 From: Simon Vieille Date: Fri, 28 May 2021 10:43:52 +0200 Subject: [PATCH] add navigation setting --- .../NavigationSettingAdminController.php | 78 ++++++++++++ .../Site/NavigationAdminController.php | 23 +++- core/Entity/NavigationSetting.php | 111 ++++++++++++++++++ core/Entity/Site/Navigation.php | 37 ++++++ core/Event/Setting/NavigationSettingEvent.php | 28 +++++ .../NavigationSettingEventSubscriber.php | 32 +++++ core/Factory/NavigationSettingFactory.php | 25 ++++ .../NavigationSettingRepository.php | 21 ++++ .../NavigationSettingRepositoryQuery.php | 18 +++ .../navigation_setting_admin/_form.html.twig | 5 + .../navigation_setting_admin/edit.html.twig | 20 ++++ .../site/navigation_admin/_show.html.twig | 107 +++++++++++++---- core/Setting/NavigationSettingManager.php | 100 ++++++++++++++++ core/Setting/SettingManager.php | 1 - core/Twig/Extension/SettingExtension.php | 19 ++- 15 files changed, 592 insertions(+), 33 deletions(-) create mode 100644 core/Controller/Setting/NavigationSettingAdminController.php create mode 100644 core/Entity/NavigationSetting.php create mode 100644 core/Event/Setting/NavigationSettingEvent.php create mode 100644 core/EventSuscriber/NavigationSettingEventSubscriber.php create mode 100644 core/Factory/NavigationSettingFactory.php create mode 100644 core/Repository/NavigationSettingRepository.php create mode 100644 core/Repository/NavigationSettingRepositoryQuery.php create mode 100644 core/Resources/views/setting/navigation_setting_admin/_form.html.twig create mode 100644 core/Resources/views/setting/navigation_setting_admin/edit.html.twig create mode 100644 core/Setting/NavigationSettingManager.php diff --git a/core/Controller/Setting/NavigationSettingAdminController.php b/core/Controller/Setting/NavigationSettingAdminController.php new file mode 100644 index 0000000..9ef22e3 --- /dev/null +++ b/core/Controller/Setting/NavigationSettingAdminController.php @@ -0,0 +1,78 @@ +createFormBuilder($entity); + + $eventDispatcher->dispatch(new NavigationSettingEvent([ + 'builder' => $builder, + 'entity' => $entity, + ]), NavigationSettingEvent::FORM_INIT_EVENT); + + $form = $builder->getForm(); + + if ($request->isMethod('POST')) { + $form->handleRequest($request); + + if ($form->isValid()) { + $entityManager->update($entity); + $this->addFlash('success', 'The data has been saved.'); + + return $this->redirectToRoute('admin_site_navigation_show', [ + 'entity' => $entity->getNavigation()->getId(), + ]); + } + + $this->addFlash('warning', 'The form is not valid.'); + } + + return $this->render('@Core/setting/navigation_setting_admin/edit.html.twig', [ + 'form' => $form->createView(), + 'entity' => $entity, + ]); + } + + /** + * @Route("/delete/{entity}", name="admin_navigation_setting_delete", methods={"DELETE"}) + */ + public function delete(Entity $entity, EntityManager $entityManager, Request $request): Response + { + if ($this->isCsrfTokenValid('delete'.$entity->getId(), $request->request->get('_token'))) { + $entityManager->delete($entity); + + $this->addFlash('success', 'The data has been removed.'); + } + + return $this->redirectToRoute('admin_site_navigation_show', [ + 'entity' => $entity->getNavigation()->getId(), + ]); + } + + public function getSection(): string + { + return ''; + } +} diff --git a/core/Controller/Site/NavigationAdminController.php b/core/Controller/Site/NavigationAdminController.php index 63c5994..ce1bf54 100644 --- a/core/Controller/Site/NavigationAdminController.php +++ b/core/Controller/Site/NavigationAdminController.php @@ -6,10 +6,13 @@ use App\Core\Controller\Admin\Crud\CrudController; use App\Core\Crud\CrudConfiguration; use App\Core\Crud\Field; use App\Core\Entity\Site\Navigation as Entity; +use App\Core\Event\Setting\NavigationSettingEvent; use App\Core\Factory\Site\NavigationFactory as Factory; use App\Core\Form\Site\NavigationType as Type; use App\Core\Manager\EntityManager; +use App\Core\Repository\NavigationSettingRepositoryQuery; use App\Core\Repository\Site\NavigationRepositoryQuery as RepositoryQuery; +use Symfony\Component\EventDispatcher\EventDispatcherInterface; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpFoundation\Session\Session; @@ -36,8 +39,24 @@ class NavigationAdminController extends CrudController /** * @Route("/admin/site/navigation/show/{entity}", name="admin_site_navigation_show", methods={"GET"}) */ - public function show(Entity $entity): Response - { + public function show( + Entity $entity, + EventDispatcherInterface $eventDispatcher, + NavigationSettingRepositoryQuery $settingQuery + ): Response { + $eventDispatcher->dispatch(new NavigationSettingEvent([ + 'navigation' => $entity, + ]), NavigationSettingEvent::INIT_EVENT); + + $settings = $settingQuery + ->where('.navigation = :navigation') + ->orderBy('.section, .label') + ->setParameter(':navigation', $entity->getId()) + ->paginate(1, 1000) + ; + + $this->getConfiguration()->addViewData('show', 'settings', $settings); + return $this->doShow($entity); } diff --git a/core/Entity/NavigationSetting.php b/core/Entity/NavigationSetting.php new file mode 100644 index 0000000..cee3540 --- /dev/null +++ b/core/Entity/NavigationSetting.php @@ -0,0 +1,111 @@ +id; + } + + public function getSection(): ?string + { + return $this->section; + } + + public function setSection(string $section): self + { + $this->section = $section; + + return $this; + } + + public function getLabel(): ?string + { + return $this->label; + } + + public function setLabel(string $label): self + { + $this->label = $label; + + return $this; + } + + public function getCode(): ?string + { + return $this->code; + } + + public function setCode(string $code): self + { + $this->code = $code; + + return $this; + } + + public function getValue() + { + return json_decode($this->value, true); + } + + public function setValue($value): self + { + $this->value = json_encode($value); + + return $this; + } + + public function getNavigation(): ?Navigation + { + return $this->navigation; + } + + public function setNavigation(?Navigation $navigation): self + { + $this->navigation = $navigation; + + return $this; + } +} diff --git a/core/Entity/Site/Navigation.php b/core/Entity/Site/Navigation.php index 86800fc..22f5a88 100644 --- a/core/Entity/Site/Navigation.php +++ b/core/Entity/Site/Navigation.php @@ -4,6 +4,7 @@ namespace App\Core\Entity\Site; use App\Core\Doctrine\Timestampable; use App\Core\Entity\EntityInterface; +use App\Core\Entity\NavigationSetting; use App\Core\Repository\Site\NavigationRepository; use Doctrine\Common\Collections\ArrayCollection; use Doctrine\Common\Collections\Collection; @@ -64,9 +65,15 @@ class Navigation implements EntityInterface */ private $sortOrder; + /** + * @ORM\OneToMany(targetEntity=NavigationSetting::class, mappedBy="navigation", orphanRemoval=true) + */ + private $navigationSettings; + public function __construct() { $this->menus = new ArrayCollection(); + $this->navigationSettings = new ArrayCollection(); } public function getId(): ?int @@ -203,4 +210,34 @@ class Navigation implements EntityInterface return $this; } + + /** + * @return Collection|NavigationSetting[] + */ + public function getNavigationSettings(): Collection + { + return $this->navigationSettings; + } + + public function addNavigationSetting(NavigationSetting $navigationSetting): self + { + if (!$this->navigationSettings->contains($navigationSetting)) { + $this->navigationSettings[] = $navigationSetting; + $navigationSetting->setNavigation($this); + } + + return $this; + } + + public function removeNavigationSetting(NavigationSetting $navigationSetting): self + { + if ($this->navigationSettings->removeElement($navigationSetting)) { + // set the owning side to null (unless already changed) + if ($navigationSetting->getNavigation() === $this) { + $navigationSetting->setNavigation(null); + } + } + + return $this; + } } diff --git a/core/Event/Setting/NavigationSettingEvent.php b/core/Event/Setting/NavigationSettingEvent.php new file mode 100644 index 0000000..1611fcc --- /dev/null +++ b/core/Event/Setting/NavigationSettingEvent.php @@ -0,0 +1,28 @@ + + */ +class NavigationSettingEvent extends Event +{ + const INIT_EVENT = 'navigation_setting_event.init'; + const FORM_INIT_EVENT = 'navigation_setting_event.form_init'; + + protected $data; + + public function __construct($data = null) + { + $this->data = $data; + } + + public function getData() + { + return $this->data; + } +} diff --git a/core/EventSuscriber/NavigationSettingEventSubscriber.php b/core/EventSuscriber/NavigationSettingEventSubscriber.php new file mode 100644 index 0000000..d9ce5a6 --- /dev/null +++ b/core/EventSuscriber/NavigationSettingEventSubscriber.php @@ -0,0 +1,32 @@ + + */ +abstract class NavigationSettingEventSubscriber implements EventSubscriberInterface +{ + protected static int $priority = 0; + + public static function getSubscribedEvents() + { + return [ + NavigationSettingEvent::INIT_EVENT => ['onInit', self::$priority], + NavigationSettingEvent::FORM_INIT_EVENT => ['onFormInit', self::$priority], + ]; + } + + public function onInit(NavigationSettingEvent $event) + { + } + + public function onFormInit(NavigationSettingEvent $event) + { + } +} diff --git a/core/Factory/NavigationSettingFactory.php b/core/Factory/NavigationSettingFactory.php new file mode 100644 index 0000000..9b4f883 --- /dev/null +++ b/core/Factory/NavigationSettingFactory.php @@ -0,0 +1,25 @@ + + */ +class NavigationSettingFactory implements FactoryInterface +{ + public function create(Navigation $navigation, string $code): NavigationSetting + { + $entity = new NavigationSetting(); + + $entity + ->setNavigation($navigation) + ->setCode($code); + + return $entity; + } +} diff --git a/core/Repository/NavigationSettingRepository.php b/core/Repository/NavigationSettingRepository.php new file mode 100644 index 0000000..32a8382 --- /dev/null +++ b/core/Repository/NavigationSettingRepository.php @@ -0,0 +1,21 @@ + + */ +class NavigationSettingRepositoryQuery extends RepositoryQuery +{ + public function __construct(NavigationSettingRepository $repository, PaginatorInterface $paginator) + { + parent::__construct($repository, 'ns', $paginator); + } +} diff --git a/core/Resources/views/setting/navigation_setting_admin/_form.html.twig b/core/Resources/views/setting/navigation_setting_admin/_form.html.twig new file mode 100644 index 0000000..f73d2c4 --- /dev/null +++ b/core/Resources/views/setting/navigation_setting_admin/_form.html.twig @@ -0,0 +1,5 @@ +
+
+ {{ form_widget(form) }} +
+
diff --git a/core/Resources/views/setting/navigation_setting_admin/edit.html.twig b/core/Resources/views/setting/navigation_setting_admin/edit.html.twig new file mode 100644 index 0000000..03ac5d8 --- /dev/null +++ b/core/Resources/views/setting/navigation_setting_admin/edit.html.twig @@ -0,0 +1,20 @@ + + diff --git a/core/Resources/views/site/navigation_admin/_show.html.twig b/core/Resources/views/site/navigation_admin/_show.html.twig index 2610b43..d55624b 100644 --- a/core/Resources/views/site/navigation_admin/_show.html.twig +++ b/core/Resources/views/site/navigation_admin/_show.html.twig @@ -1,32 +1,33 @@ +{% set datas = configuration.viewDatas(context) %} +
  • - {{ 'Label'|trans }} - - {{ entity.label }} -
  • -
  • - {{ 'Locale'|trans }} - - {{ entity.locale }} -
  • -
  • - {{ 'Code'|trans }} - - {{ entity.code }} +
    +
    + {{ 'Label'|trans }} + {{ entity.label }} +
    +
    + {{ 'Locale'|trans }} + {{ entity.locale }} +
    +
    + {{ 'Code'|trans }} + {{ entity.code }} +
    +
  • - {{ 'Domain'|trans }} +
    + {{ 'Domain'|trans }} + {{ entity.domain }} +
    +
    + {% set additionalDomains = entity.additionalDomains %} - {{ entity.domain }} -
  • - - {% set additionalDomains = entity.additionalDomains %} - - {% if additionalDomains|length %} -
  • {{ 'Additional domains'|trans }} {% for item in additionalDomains %} @@ -37,11 +38,65 @@ ({{ 'Domain'|trans|lower }}) {% else %} ({{ 'Regular expression'|trans|lower }}) - {% endif %} -
- {% endfor %} - - {% endif %} + {% endif %} +
+ {% else %} + - + {% endfor %} + + + +
+ + + + + + + + + + {% for item in datas.settings %} + {% set edit = path('admin_navigation_setting_edit', {entity: item.id}) %} + + + + + + + {% else %} + + + + {% endfor %} + +
{{ 'Label'|trans }}{{ 'Section'|trans }}{{ 'Actions'|trans }}
+ + {{ item.label|trans }} + + + {{ item.section|trans }} + + + + + + +
+ + +
+
+
+ +
+
+ {{ 'No result'|trans }} +
+
+
diff --git a/core/Setting/NavigationSettingManager.php b/core/Setting/NavigationSettingManager.php new file mode 100644 index 0000000..cf40b27 --- /dev/null +++ b/core/Setting/NavigationSettingManager.php @@ -0,0 +1,100 @@ + + */ +class NavigationSettingManager +{ + protected EntityManager $entityManager; + protected NavigationSettingRepositoryQuery $query; + protected NavigationRepositoryQuery $navigationQuery; + protected NavigationSettingFactory $factory; + + public function __construct( + EntityManager $entityManager, + NavigationSettingRepositoryQuery $query, + NavigationRepositoryQuery $navigationQuery, + NavigationSettingFactory $factory + ) { + $this->entityManager = $entityManager; + $this->query = $query; + $this->navigationQuery = $navigationQuery; + $this->factory = $factory; + } + + public function init($navigation, string $code, string $section, string $label, $value = null) + { + $entity = $this->get($this->getNavigation($navigation), $code); + $isNew = null === $entity; + + if ($isNew) { + $entity = $this->factory->create($navigation, $code); + $entity->setValue($value); + } + + $entity + ->setSection($section) + ->setLabel($label) + ; + + if ($isNew) { + $this->entityManager->create($entity); + } else { + $this->entityManager->update($entity); + } + } + + public function get($navigation, string $code): ?NavigationSetting + { + return $this->query->create() + ->andWhere('.navigation = :navigation') + ->andWhere('.code = :code') + ->setParameter(':navigation', $this->getNavigation($navigation)->getId()) + ->setParameter(':code', $code) + ->findOne() + ; + } + + public function set($navigation, string $code, $value): bool + { + $entity = $this->get($this->getNavigation($navigation), $code); + + if (!$entity) { + return false; + } + + $entity->setValue($value); + $this->entityManager->update($entity); + + return true; + } + + protected function getNavigation($navigation): Navigation + { + if ($navigation instanceof Navigation) { + return $navigation; + } + + $entity = $this->navigationQuery->create() + ->where('.code', $navigation) + ->findOne() + ; + + if (!$entity) { + throw new \RuntimeException(sprintf('The navigation "%s" does not exist.', $navigation)); + } + + return $entity; + } +} diff --git a/core/Setting/SettingManager.php b/core/Setting/SettingManager.php index 01d2937..597a209 100644 --- a/core/Setting/SettingManager.php +++ b/core/Setting/SettingManager.php @@ -36,7 +36,6 @@ class SettingManager } $entity - ->setCode($code) ->setSection($section) ->setLabel($label) ; diff --git a/core/Twig/Extension/SettingExtension.php b/core/Twig/Extension/SettingExtension.php index defbc79..06a5cf4 100644 --- a/core/Twig/Extension/SettingExtension.php +++ b/core/Twig/Extension/SettingExtension.php @@ -3,16 +3,19 @@ namespace App\Core\Twig\Extension; use App\Core\Setting\SettingManager; +use App\Core\Setting\NavigationSettingManager; use Twig\Extension\AbstractExtension; use Twig\TwigFunction; class SettingExtension extends AbstractExtension { - private SettingManager $manager; + private SettingManager $settingManager; + private NavigationSettingManager $navigationSettingManager; - public function __construct(SettingManager $manager) + public function __construct(SettingManager $settingManager, NavigationSettingManager $navigationSettingManager) { - $this->manager = $manager; + $this->settingManager = $settingManager; + $this->navigationSettingManager = $navigationSettingManager; } /** @@ -22,12 +25,20 @@ class SettingExtension extends AbstractExtension { return [ new TwigFunction('setting', [$this, 'getSetting']), + new TwigFunction('navigation_setting', [$this, 'getNavigationSetting']), ]; } public function getSetting(string $code) { - $entity = $this->manager->get($code); + $entity = $this->settingManager->get($code); + + return $entity ? $entity->getValue() : null; + } + + public function getNavigationSetting($navigation, string $code) + { + $entity = $this->navigationSettingManager->get($navigation, $code); return $entity ? $entity->getValue() : null; }