diff --git a/core/Command/UserCreateCommand.php b/core/Command/UserCreateCommand.php new file mode 100644 index 0000000..5715663 --- /dev/null +++ b/core/Command/UserCreateCommand.php @@ -0,0 +1,73 @@ +userFactory = $userFactory; + $this->entityManager = $entityManager; + + parent::__construct(); + } + + protected function configure() + { + $this + ->setDescription(self::$defaultDescription) + ->addArgument('email', InputArgument::OPTIONAL, 'E-mail') + ; + } + + protected function execute(InputInterface $input, OutputInterface $output): int + { + $io = new SymfonyStyle($input, $output); + $helper = $this->getHelper('question'); + + $emailQuestion = new Question('E-mail: '); + $emailQuestion->setValidator(function ($value) { + return !empty($value); + }); + + $passwordQuestion = new Question('Password (leave empty to generate a random password): '); + $passwordQuestion->setHidden(true); + $isAdminQuestion = new ConfirmationQuestion('Is admin? [y/n] ', false); + $isWriterQuestion = new ConfirmationQuestion('Is writer? [y/n] ', false); + + $email = $input->getArgument('email'); + + if (empty($email)) { + $email = $helper->ask($input, $output, $emailQuestion); + } + + $password = $helper->ask($input, $output, $passwordQuestion); + $isAdmin = $helper->ask($input, $output, $isAdminQuestion); + $isWriter = $helper->ask($input, $output, $isWriterQuestion); + + $user = $this->userFactory->create($email, $password); + $user->setIsAdmin($isAdmin); + $user->setIsWriter($isWriter); + + $this->entityManager->create($user); + + $io->success('User created!'); + + return Command::SUCCESS; + } +} diff --git a/core/Controller/Setting/SettingAdminController.php b/core/Controller/Setting/SettingAdminController.php new file mode 100644 index 0000000..e466193 --- /dev/null +++ b/core/Controller/Setting/SettingAdminController.php @@ -0,0 +1,98 @@ +dispatch(new SettingEvent(), SettingEvent::INIT_EVENT); + + $pager = $query + ->orderBy('.section, .label') + ->paginate($page) + ; + + return $this->render('@Core/setting/setting_admin/index.html.twig', [ + 'pager' => $pager, + ]); + } + + /** + * @Route("/edit/{entity}", name="admin_setting_edit") + */ + public function edit( + Entity $entity, + EntityManager $entityManager, + EventDispatcherInterface $eventDispatcher, + Request $request + ): Response + { + $builder = $this->createFormBuilder($entity); + + $eventDispatcher->dispatch(new SettingEvent([ + 'builder' => $builder, + 'entity' => $entity, + ]), SettingEvent::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_setting_index'); + } + + $this->addFlash('warning', 'The form is not valid.'); + } + + return $this->render('@Core/setting/setting_admin/edit.html.twig', [ + 'form' => $form->createView(), + 'entity' => $entity, + ]); + } + + /** + * @Route("/delete/{entity}", name="admin_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_setting_index'); + } + + public function getSection(): string + { + return 'setting'; + } +} diff --git a/core/Entity/Setting.php b/core/Entity/Setting.php new file mode 100644 index 0000000..92f9cd3 --- /dev/null +++ b/core/Entity/Setting.php @@ -0,0 +1,92 @@ +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; + } +} diff --git a/core/Event/EntityManager/EntityManagerEvent.php b/core/Event/EntityManager/EntityManagerEvent.php index ee69320..7c5c666 100644 --- a/core/Event/EntityManager/EntityManagerEvent.php +++ b/core/Event/EntityManager/EntityManagerEvent.php @@ -6,7 +6,7 @@ use App\Core\Entity\EntityInterface; use Symfony\Contracts\EventDispatcher\Event; /** - * class EntityEvent. + * class EntityManagerEvent. * * @author Simon Vieille */ diff --git a/core/Event/Setting/SettingEvent.php b/core/Event/Setting/SettingEvent.php new file mode 100644 index 0000000..065b426 --- /dev/null +++ b/core/Event/Setting/SettingEvent.php @@ -0,0 +1,28 @@ + + */ +class SettingEvent extends Event +{ + const INIT_EVENT = 'setting_event.init'; + const FORM_INIT_EVENT = '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/SettingEventSubscriber.php b/core/EventSuscriber/SettingEventSubscriber.php new file mode 100644 index 0000000..d65e783 --- /dev/null +++ b/core/EventSuscriber/SettingEventSubscriber.php @@ -0,0 +1,32 @@ + + */ +class SettingEventSubscriber implements EventSubscriberInterface +{ + protected static int $priority = 0; + + public static function getSubscribedEvents() + { + return [ + SettingEvent::INIT_EVENT => ['onInit', self::$priority], + SettingEvent::FORM_INIT_EVENT => ['onFormInit', self::$priority], + ]; + } + + public function onInit(SettingEvent $event) + { + } + + public function onFormInit(SettingEvent $event) + { + } +} diff --git a/core/Factory/SettingFactory.php b/core/Factory/SettingFactory.php new file mode 100644 index 0000000..ceeb0dd --- /dev/null +++ b/core/Factory/SettingFactory.php @@ -0,0 +1,22 @@ + + */ +class SettingFactory +{ + public function create(string $code): Setting + { + $entity = new Setting(); + + $entity->setCode($code); + + return $entity; + } +} diff --git a/core/Form/Site/Page/Filter/PageFilterType.php b/core/Form/Site/Page/Filter/PageFilterType.php new file mode 100644 index 0000000..fc3cc0f --- /dev/null +++ b/core/Form/Site/Page/Filter/PageFilterType.php @@ -0,0 +1,64 @@ +add( + 'name', + TextType::class, + [ + 'label' => 'Name', + 'required' => false, + 'attr' => [ + ], + 'constraints' => [ + ], + ] + ); + + $builder->add( + 'navigation', + EntityType::class, + [ + 'label' => 'Naviation', + 'class' => Navigation::class, + 'choice_label' => 'label', + 'choice_value' => 'id', + 'required' => false, + 'attr' => [ + ], + 'query_builder' => function (EntityRepository $repo) { + return $repo->createQueryBuilder('n') + ->orderBy('n.label, n.domain', 'ASC') + ; + }, + 'constraints' => [ + ], + ] + ); + } + + public function configureOptions(OptionsResolver $resolver) + { + $resolver->setDefaults([ + 'data_class' => null, + 'csrf_protection' => false, + ]); + } +} diff --git a/core/Repository/SettingRepository.php b/core/Repository/SettingRepository.php new file mode 100644 index 0000000..6976ae2 --- /dev/null +++ b/core/Repository/SettingRepository.php @@ -0,0 +1,21 @@ + + */ +class SettingRepositoryQuery extends RepositoryQuery +{ + public function __construct(SettingRepository $repository, PaginatorInterface $paginator) + { + parent::__construct($repository, 's', $paginator); + } +} diff --git a/core/Resources/translations/messages.fr.yaml b/core/Resources/translations/messages.fr.yaml index e2d552b..23f95f1 100644 --- a/core/Resources/translations/messages.fr.yaml +++ b/core/Resources/translations/messages.fr.yaml @@ -129,3 +129,6 @@ "Yes": "Oui" "No": "Non" "Locale": "Langue" +"Settings": "Paramètres" +"Setting": "Paramètre" +"Section": "Section" diff --git a/core/Resources/views/admin/module/menu.html.twig b/core/Resources/views/admin/module/menu.html.twig index a94cc19..e684a6b 100644 --- a/core/Resources/views/admin/module/menu.html.twig +++ b/core/Resources/views/admin/module/menu.html.twig @@ -67,5 +67,15 @@ + + {% endif %} diff --git a/core/Resources/views/setting/setting_admin/_form.html.twig b/core/Resources/views/setting/setting_admin/_form.html.twig new file mode 100644 index 0000000..f73d2c4 --- /dev/null +++ b/core/Resources/views/setting/setting_admin/_form.html.twig @@ -0,0 +1,5 @@ +
+
+ {{ form_widget(form) }} +
+
diff --git a/core/Resources/views/setting/setting_admin/edit.html.twig b/core/Resources/views/setting/setting_admin/edit.html.twig new file mode 100644 index 0000000..49c84e6 --- /dev/null +++ b/core/Resources/views/setting/setting_admin/edit.html.twig @@ -0,0 +1,20 @@ + + diff --git a/core/Resources/views/setting/setting_admin/filters.html.twig b/core/Resources/views/setting/setting_admin/filters.html.twig new file mode 100644 index 0000000..5cb33d8 --- /dev/null +++ b/core/Resources/views/setting/setting_admin/filters.html.twig @@ -0,0 +1,21 @@ + diff --git a/core/Resources/views/setting/setting_admin/index.html.twig b/core/Resources/views/setting/setting_admin/index.html.twig new file mode 100644 index 0000000..6e7ae07 --- /dev/null +++ b/core/Resources/views/setting/setting_admin/index.html.twig @@ -0,0 +1,67 @@ +{% extends '@Core/admin/layout.html.twig' %} + +{% block title %}{{ 'Settings'|trans }} - {{ parent() }}{% endblock %} + +{% block body %} +
+
+
+

{{ 'Settings'|trans }}

+
+
+ + {{ knp_pagination_render(pager) }} +
+ +
+ + + + + + + + + + {% for item in pager %} + {% set edit = path('admin_setting_edit', {entity: item.id}) %} + + + + + + + {% else %} + + + + {% endfor %} + +
{{ 'Label'|trans }}{{ 'Section'|trans }}{{ 'Actions'|trans }}
+ + {{ item.label }} + + + {{ item.section }} + + + + + + +
+ + +
+
+
+ +
+
+ {{ 'No result'|trans }} +
+
+
+{% endblock %} diff --git a/core/Resources/views/site/navigation_admin/index.html.twig b/core/Resources/views/site/navigation_admin/index.html.twig index d847c60..0ae0fbd 100644 --- a/core/Resources/views/site/navigation_admin/index.html.twig +++ b/core/Resources/views/site/navigation_admin/index.html.twig @@ -72,7 +72,7 @@ {% else %} - +
diff --git a/core/Resources/views/site/page_admin/filters.html.twig b/core/Resources/views/site/page_admin/filters.html.twig new file mode 100644 index 0000000..5cb33d8 --- /dev/null +++ b/core/Resources/views/site/page_admin/filters.html.twig @@ -0,0 +1,21 @@ + diff --git a/core/Resources/views/site/page_admin/index.html.twig b/core/Resources/views/site/page_admin/index.html.twig index c913359..34328ed 100644 --- a/core/Resources/views/site/page_admin/index.html.twig +++ b/core/Resources/views/site/page_admin/index.html.twig @@ -67,7 +67,7 @@ {% else %} - +
diff --git a/core/Resources/views/user/user_admin/index.html.twig b/core/Resources/views/user/user_admin/index.html.twig index 6c5b75d..99daf5f 100644 --- a/core/Resources/views/user/user_admin/index.html.twig +++ b/core/Resources/views/user/user_admin/index.html.twig @@ -59,7 +59,7 @@ {% else %} - +
diff --git a/core/Setting/SettingManager.php b/core/Setting/SettingManager.php new file mode 100644 index 0000000..f6018ec --- /dev/null +++ b/core/Setting/SettingManager.php @@ -0,0 +1,73 @@ + + */ +class SettingManager +{ + protected EntityManager $entityManager; + protected SettingRepositoryQuery $query; + protected SettingFactory $factory; + + public function __construct(EntityManager $entityManager, SettingRepositoryQuery $query, SettingFactory $factory) + { + $this->entityManager = $entityManager; + $this->query = $query; + $this->factory = $factory; + } + + public function init(string $code, string $section, string $label, $value = null) + { + $entity = $this->get($code); + $isNew = null === $entity; + + if ($isNew) { + $entity = $this->factory->create($code); + $entity->setValue($value); + } + + $entity + ->setCode($code) + ->setSection($section) + ->setLabel($label) + ; + + if ($isNew) { + $this->entityManager->create($entity); + } else { + $this->entityManager->update($entity); + } + } + + public function get(string $code): ?Setting + { + return $this->query->create() + ->where('.code = :code') + ->setParameter(':code', $code) + ->findOne() + ; + } + + public function set(string $code, $value): bool + { + $entity = $this->get($code); + + if (!$entity) { + return false; + } + + $entity->setValue($value); + $this->entityManager->update($entity); + + return true; + } +} diff --git a/core/Twig/Extension/SettingExtension.php b/core/Twig/Extension/SettingExtension.php new file mode 100644 index 0000000..defbc79 --- /dev/null +++ b/core/Twig/Extension/SettingExtension.php @@ -0,0 +1,34 @@ +manager = $manager; + } + + /** + * {@inheritdoc} + */ + public function getFunctions(): array + { + return [ + new TwigFunction('setting', [$this, 'getSetting']), + ]; + } + + public function getSetting(string $code) + { + $entity = $this->manager->get($code); + + return $entity ? $entity->getValue() : null; + } +}