From e550817ded2d4fc38f3c04913f672be4626bf0b8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Wed, 24 May 2023 21:57:20 +0200 Subject: [PATCH] Render for generic doc --- .../ChillDocStoreBundle.php | 7 +- ...ericDocForAccompanyingPeriodController.php | 26 ++++- .../GenericDoc/GenericDocDTO.php | 6 +- ...orAccompanyingPeriodProviderInterface.php} | 2 +- .../GenericDoc/Manager.php | 5 +- ...nyingProviderCourseDocumentGenericDoc.php} | 8 +- ...anyingCourseDocumentGenericDocRenderer.php | 44 ++++++++ .../GenericDoc/Twig/GenericDocExtension.php | 28 +++++ .../Twig/GenericDocExtensionRuntime.php | 50 +++++++++ .../Twig/GenericDocRendererInterface.php | 24 ++++ .../accompanying_period_list.html.twig | 48 ++++++++ .../Tests/GenericDoc/ManagerTest.php | 8 +- ...AccompanyingCourseDocumentProviderTest.php | 4 +- .../ChillDocStoreBundle/config/services.yaml | 105 ++++++++++-------- 14 files changed, 299 insertions(+), 66 deletions(-) rename src/Bundle/ChillDocStoreBundle/GenericDoc/{ProviderForAccompanyingPeriodInterface.php => GenericDocForAccompanyingPeriodProviderInterface.php} (93%) rename src/Bundle/ChillDocStoreBundle/GenericDoc/Providers/{AccompanyingCourseDocumentProvider.php => AccompanyingProviderCourseDocumentGenericDoc.php} (90%) create mode 100644 src/Bundle/ChillDocStoreBundle/GenericDoc/Renderer/AccompanyingCourseDocumentGenericDocRenderer.php create mode 100644 src/Bundle/ChillDocStoreBundle/GenericDoc/Twig/GenericDocExtension.php create mode 100644 src/Bundle/ChillDocStoreBundle/GenericDoc/Twig/GenericDocExtensionRuntime.php create mode 100644 src/Bundle/ChillDocStoreBundle/GenericDoc/Twig/GenericDocRendererInterface.php create mode 100644 src/Bundle/ChillDocStoreBundle/Resources/views/GenericDoc/accompanying_period_list.html.twig diff --git a/src/Bundle/ChillDocStoreBundle/ChillDocStoreBundle.php b/src/Bundle/ChillDocStoreBundle/ChillDocStoreBundle.php index 44bc7d70d..bc659d146 100644 --- a/src/Bundle/ChillDocStoreBundle/ChillDocStoreBundle.php +++ b/src/Bundle/ChillDocStoreBundle/ChillDocStoreBundle.php @@ -11,7 +11,8 @@ declare(strict_types=1); namespace Chill\DocStoreBundle; -use Chill\DocStoreBundle\GenericDoc\ProviderForAccompanyingPeriodInterface; +use Chill\DocStoreBundle\GenericDoc\GenericDocForAccompanyingPeriodProviderInterface; +use Chill\DocStoreBundle\GenericDoc\Twig\GenericDocRendererInterface; use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\HttpKernel\Bundle\Bundle; @@ -19,7 +20,9 @@ class ChillDocStoreBundle extends Bundle { public function build(ContainerBuilder $container) { - $container->registerForAutoconfiguration(ProviderForAccompanyingPeriodInterface::class) + $container->registerForAutoconfiguration(GenericDocForAccompanyingPeriodProviderInterface::class) ->addTag('chill_doc_store.generic_doc_accompanying_period_provider'); + $container->registerForAutoconfiguration(GenericDocRendererInterface::class) + ->addTag('chill_doc_store.generic_doc_renderer'); } } diff --git a/src/Bundle/ChillDocStoreBundle/Controller/GenericDocForAccompanyingPeriodController.php b/src/Bundle/ChillDocStoreBundle/Controller/GenericDocForAccompanyingPeriodController.php index 0a9175087..7403e2ebc 100644 --- a/src/Bundle/ChillDocStoreBundle/Controller/GenericDocForAccompanyingPeriodController.php +++ b/src/Bundle/ChillDocStoreBundle/Controller/GenericDocForAccompanyingPeriodController.php @@ -13,17 +13,22 @@ namespace Chill\DocStoreBundle\Controller; use Chill\DocStoreBundle\GenericDoc\Manager; use Chill\DocStoreBundle\Security\Authorization\AccompanyingCourseDocumentVoter; +use Chill\MainBundle\Pagination\PaginatorFactory; use Chill\PersonBundle\Entity\AccompanyingPeriod; +use Symfony\Bundle\TwigBundle\TwigEngine; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException; use Symfony\Component\Routing\Annotation\Route; use Symfony\Component\Security\Core\Security; +use Symfony\Component\Templating\EngineInterface; final readonly class GenericDocForAccompanyingPeriodController { public function __construct( private Security $security, - private Manager $manager + private Manager $manager, + private PaginatorFactory $paginator, + private EngineInterface $twig, ) { } @@ -41,12 +46,21 @@ final readonly class GenericDocForAccompanyingPeriodController } $nb = $this->manager->countDocForAccompanyingPeriod($accompanyingPeriod); + $paginator = $this->paginator->create($nb); + $documents = $this->manager->findDocForAccompanyingPeriod( + $accompanyingPeriod, + $paginator->getCurrentPageFirstItemNumber(), + $paginator->getItemsPerPage() + ); - foreach ($this->manager->findDocForAccompanyingPeriod($accompanyingPeriod) as $dto) { - dump($dto); - } - - return new Response($nb); + return new Response($this->twig->render( + '@ChillDocStore/GenericDoc/accompanying_period_list.html.twig', + [ + 'accompanyingCourse' => $accompanyingPeriod, + 'pagination' => $paginator, + 'documents' => iterator_to_array($documents), + ] + )); } } diff --git a/src/Bundle/ChillDocStoreBundle/GenericDoc/GenericDocDTO.php b/src/Bundle/ChillDocStoreBundle/GenericDoc/GenericDocDTO.php index 6fb6139aa..e47814685 100644 --- a/src/Bundle/ChillDocStoreBundle/GenericDoc/GenericDocDTO.php +++ b/src/Bundle/ChillDocStoreBundle/GenericDoc/GenericDocDTO.php @@ -11,12 +11,16 @@ declare(strict_types=1); namespace Chill\DocStoreBundle\GenericDoc; +use Chill\PersonBundle\Entity\AccompanyingPeriod; +use Chill\PersonBundle\Entity\Person; + class GenericDocDTO { public function __construct( public readonly string $key, public readonly array $identifiers, - public readonly \DateTimeImmutable $docDate + public readonly \DateTimeImmutable $docDate, + public AccompanyingPeriod|Person $linked, ) { } } diff --git a/src/Bundle/ChillDocStoreBundle/GenericDoc/ProviderForAccompanyingPeriodInterface.php b/src/Bundle/ChillDocStoreBundle/GenericDoc/GenericDocForAccompanyingPeriodProviderInterface.php similarity index 93% rename from src/Bundle/ChillDocStoreBundle/GenericDoc/ProviderForAccompanyingPeriodInterface.php rename to src/Bundle/ChillDocStoreBundle/GenericDoc/GenericDocForAccompanyingPeriodProviderInterface.php index 935fe48a9..4702e74c7 100644 --- a/src/Bundle/ChillDocStoreBundle/GenericDoc/ProviderForAccompanyingPeriodInterface.php +++ b/src/Bundle/ChillDocStoreBundle/GenericDoc/GenericDocForAccompanyingPeriodProviderInterface.php @@ -13,7 +13,7 @@ namespace Chill\DocStoreBundle\GenericDoc; use Chill\PersonBundle\Entity\AccompanyingPeriod; -interface ProviderForAccompanyingPeriodInterface +interface GenericDocForAccompanyingPeriodProviderInterface { public function buildFetchQueryForAccompanyingPeriod( AccompanyingPeriod $accompanyingPeriod, diff --git a/src/Bundle/ChillDocStoreBundle/GenericDoc/Manager.php b/src/Bundle/ChillDocStoreBundle/GenericDoc/Manager.php index d67ff6d0d..21189f55e 100644 --- a/src/Bundle/ChillDocStoreBundle/GenericDoc/Manager.php +++ b/src/Bundle/ChillDocStoreBundle/GenericDoc/Manager.php @@ -23,7 +23,7 @@ class Manager public function __construct( /** - * @var iterable + * @var iterable */ private readonly iterable $providersForAccompanyingPeriod, private readonly Connection $connection, @@ -81,7 +81,8 @@ class Manager yield new GenericDocDTO( $row['key'], json_decode($row['identifiers'], true, JSON_THROW_ON_ERROR), - new \DateTimeImmutable($row['doc_date']) + new \DateTimeImmutable($row['doc_date']), + $accompanyingPeriod, ); } } diff --git a/src/Bundle/ChillDocStoreBundle/GenericDoc/Providers/AccompanyingCourseDocumentProvider.php b/src/Bundle/ChillDocStoreBundle/GenericDoc/Providers/AccompanyingProviderCourseDocumentGenericDoc.php similarity index 90% rename from src/Bundle/ChillDocStoreBundle/GenericDoc/Providers/AccompanyingCourseDocumentProvider.php rename to src/Bundle/ChillDocStoreBundle/GenericDoc/Providers/AccompanyingProviderCourseDocumentGenericDoc.php index 8f6a9fdad..fc0eb3b5f 100644 --- a/src/Bundle/ChillDocStoreBundle/GenericDoc/Providers/AccompanyingCourseDocumentProvider.php +++ b/src/Bundle/ChillDocStoreBundle/GenericDoc/Providers/AccompanyingProviderCourseDocumentGenericDoc.php @@ -14,15 +14,17 @@ namespace Chill\DocStoreBundle\GenericDoc\Providers; use Chill\DocStoreBundle\Entity\AccompanyingCourseDocument; use Chill\DocStoreBundle\GenericDoc\FetchQuery; use Chill\DocStoreBundle\GenericDoc\FetchQueryInterface; -use Chill\DocStoreBundle\GenericDoc\ProviderForAccompanyingPeriodInterface; +use Chill\DocStoreBundle\GenericDoc\GenericDocForAccompanyingPeriodProviderInterface; use Chill\DocStoreBundle\Security\Authorization\AccompanyingCourseDocumentVoter; use Chill\PersonBundle\Entity\AccompanyingPeriod; use Doctrine\DBAL\Types\Types; use Doctrine\ORM\EntityManagerInterface; use Symfony\Component\Security\Core\Security; -final readonly class AccompanyingCourseDocumentProvider implements ProviderForAccompanyingPeriodInterface +final readonly class AccompanyingProviderCourseDocumentGenericDoc implements GenericDocForAccompanyingPeriodProviderInterface { + public const KEY = 'accompanying_course_document'; + public function __construct( private Security $security, private EntityManagerInterface $entityManager, @@ -34,7 +36,7 @@ final readonly class AccompanyingCourseDocumentProvider implements ProviderForAc $classMetadata = $this->entityManager->getClassMetadata(AccompanyingCourseDocument::class); $query = new FetchQuery( - 'accompanying_course_document', + self::KEY, sprintf('jsonb_build_object(\'id\', %s)', $classMetadata->getIdentifierColumnNames()[0]), sprintf($classMetadata->getColumnName('date')), $classMetadata->getSchemaName() . '.' . $classMetadata->getTableName() diff --git a/src/Bundle/ChillDocStoreBundle/GenericDoc/Renderer/AccompanyingCourseDocumentGenericDocRenderer.php b/src/Bundle/ChillDocStoreBundle/GenericDoc/Renderer/AccompanyingCourseDocumentGenericDocRenderer.php new file mode 100644 index 000000000..4e27f6335 --- /dev/null +++ b/src/Bundle/ChillDocStoreBundle/GenericDoc/Renderer/AccompanyingCourseDocumentGenericDocRenderer.php @@ -0,0 +1,44 @@ +key === AccompanyingProviderCourseDocumentGenericDoc::KEY; + } + + public function getTemplate(GenericDocDTO $genericDocDTO, $options = []): string + { + return '@ChillDocStore/List/list_item.html.twig'; + } + + public function getTemplateData(GenericDocDTO $genericDocDTO, $options = []): array + { + return [ + 'document' => $this->accompanyingCourseDocumentRepository->find($genericDocDTO->identifiers['id']), + 'accompanyingCourse' => $genericDocDTO->linked, + 'options' => $options, + ]; + } +} diff --git a/src/Bundle/ChillDocStoreBundle/GenericDoc/Twig/GenericDocExtension.php b/src/Bundle/ChillDocStoreBundle/GenericDoc/Twig/GenericDocExtension.php new file mode 100644 index 000000000..308d85cd7 --- /dev/null +++ b/src/Bundle/ChillDocStoreBundle/GenericDoc/Twig/GenericDocExtension.php @@ -0,0 +1,28 @@ + true, + 'is_safe' => ['html'], + ]) + ]; + } +} diff --git a/src/Bundle/ChillDocStoreBundle/GenericDoc/Twig/GenericDocExtensionRuntime.php b/src/Bundle/ChillDocStoreBundle/GenericDoc/Twig/GenericDocExtensionRuntime.php new file mode 100644 index 000000000..2dee0ed0b --- /dev/null +++ b/src/Bundle/ChillDocStoreBundle/GenericDoc/Twig/GenericDocExtensionRuntime.php @@ -0,0 +1,50 @@ + + */ + private iterable $renderers, + ) { + } + + /** + * @throws RuntimeError + * @throws SyntaxError + * @throws LoaderError + */ + public function renderGenericDoc(Environment $twig, GenericDocDTO $genericDocDTO, array $options = []): string + { + foreach ($this->renderers as $renderer) { + if ($renderer->supports($genericDocDTO)) { + return $twig->render( + $renderer->getTemplate($genericDocDTO, $options), + $renderer->getTemplateData($genericDocDTO, $options), + ); + } + } + + throw new \LogicException("no renderer found"); + } + +} diff --git a/src/Bundle/ChillDocStoreBundle/GenericDoc/Twig/GenericDocRendererInterface.php b/src/Bundle/ChillDocStoreBundle/GenericDoc/Twig/GenericDocRendererInterface.php new file mode 100644 index 000000000..940001f4a --- /dev/null +++ b/src/Bundle/ChillDocStoreBundle/GenericDoc/Twig/GenericDocRendererInterface.php @@ -0,0 +1,24 @@ + +

{{ 'Documents' }}

+ + {% if documents|length == 0 %} +

{{ 'No documents'|trans }}

+ {% else %} +
+ {% for document in documents %} + {{ document|chill_generic_doc_render }} + {% endfor %} +
+ {% endif %} + + {{ chill_pagination(pagination) }} + + {% if is_granted('CHILL_ACCOMPANYING_COURSE_DOCUMENT_CREATE', accompanyingCourse) %} + + {% endif %} + + +{% endblock %} diff --git a/src/Bundle/ChillDocStoreBundle/Tests/GenericDoc/ManagerTest.php b/src/Bundle/ChillDocStoreBundle/Tests/GenericDoc/ManagerTest.php index 59cc24bf2..2bda8e2ae 100644 --- a/src/Bundle/ChillDocStoreBundle/Tests/GenericDoc/ManagerTest.php +++ b/src/Bundle/ChillDocStoreBundle/Tests/GenericDoc/ManagerTest.php @@ -15,7 +15,7 @@ use Chill\DocStoreBundle\GenericDoc\FetchQuery; use Chill\DocStoreBundle\GenericDoc\FetchQueryInterface; use Chill\DocStoreBundle\GenericDoc\GenericDocDTO; use Chill\DocStoreBundle\GenericDoc\Manager; -use Chill\DocStoreBundle\GenericDoc\ProviderForAccompanyingPeriodInterface; +use Chill\DocStoreBundle\GenericDoc\GenericDocForAccompanyingPeriodProviderInterface; use Chill\PersonBundle\Entity\AccompanyingPeriod; use Doctrine\DBAL\Connection; use Doctrine\ORM\EntityManagerInterface; @@ -52,7 +52,7 @@ class ManagerTest extends KernelTestCase } $manager = new Manager( - [new SimpleProvider()], + [new SimpleGenericDocProvider()], $this->connection, ); @@ -72,7 +72,7 @@ class ManagerTest extends KernelTestCase } $manager = new Manager( - [new SimpleProvider()], + [new SimpleGenericDocProvider()], $this->connection, ); @@ -82,7 +82,7 @@ class ManagerTest extends KernelTestCase } } -final readonly class SimpleProvider implements ProviderForAccompanyingPeriodInterface +final readonly class SimpleGenericDocProvider implements GenericDocForAccompanyingPeriodProviderInterface { public function buildFetchQueryForAccompanyingPeriod(AccompanyingPeriod $accompanyingPeriod, ?\DateTimeImmutable $startDate = null, ?\DateTimeImmutable $endDate = null, ?string $content = null, ?string $origin = null): FetchQueryInterface { diff --git a/src/Bundle/ChillDocStoreBundle/Tests/GenericDoc/Providers/AccompanyingCourseDocumentProviderTest.php b/src/Bundle/ChillDocStoreBundle/Tests/GenericDoc/Providers/AccompanyingCourseDocumentProviderTest.php index b88f8e36f..ee9978735 100644 --- a/src/Bundle/ChillDocStoreBundle/Tests/GenericDoc/Providers/AccompanyingCourseDocumentProviderTest.php +++ b/src/Bundle/ChillDocStoreBundle/Tests/GenericDoc/Providers/AccompanyingCourseDocumentProviderTest.php @@ -12,7 +12,7 @@ declare(strict_types=1); namespace Chill\DocStoreBundle\Tests\GenericDoc\Providers; use Chill\DocStoreBundle\GenericDoc\FetchQueryToSqlBuilder; -use Chill\DocStoreBundle\GenericDoc\Providers\AccompanyingCourseDocumentProvider; +use Chill\DocStoreBundle\GenericDoc\Providers\AccompanyingProviderCourseDocumentGenericDoc; use Chill\DocStoreBundle\Security\Authorization\AccompanyingCourseDocumentVoter; use Chill\PersonBundle\Entity\AccompanyingPeriod; use Doctrine\DBAL\Types\Types; @@ -54,7 +54,7 @@ class AccompanyingCourseDocumentProviderTest extends KernelTestCase $security->isGranted(AccompanyingCourseDocumentVoter::SEE, $period) ->willReturn(true); - $provider = new AccompanyingCourseDocumentProvider( + $provider = new AccompanyingProviderCourseDocumentGenericDoc( $security->reveal(), $this->entityManager ); diff --git a/src/Bundle/ChillDocStoreBundle/config/services.yaml b/src/Bundle/ChillDocStoreBundle/config/services.yaml index 16b0365d4..f242acc1c 100644 --- a/src/Bundle/ChillDocStoreBundle/config/services.yaml +++ b/src/Bundle/ChillDocStoreBundle/config/services.yaml @@ -2,56 +2,71 @@ parameters: # cl_chill_person.example.class: Chill\PersonBundle\Example services: - Chill\DocStoreBundle\Repository\: - autowire: true - autoconfigure: true - resource: "../Repository/" + Chill\DocStoreBundle\Repository\: + autowire: true + autoconfigure: true + resource: "../Repository/" - Chill\DocStoreBundle\Form\DocumentCategoryType: - class: Chill\DocStoreBundle\Form\DocumentCategoryType - arguments: ["%kernel.bundles%"] - tags: - - { name: form.type } + Chill\DocStoreBundle\Form\DocumentCategoryType: + class: Chill\DocStoreBundle\Form\DocumentCategoryType + arguments: [ "%kernel.bundles%" ] + tags: + - { name: form.type } - Chill\DocStoreBundle\Form\PersonDocumentType: - class: Chill\DocStoreBundle\Form\PersonDocumentType - autowire: true - autoconfigure: true - # arguments: - # - "@chill.main.helper.translatable_string" - tags: - - { name: form.type, alias: chill_docstorebundle_form_document } + Chill\DocStoreBundle\Form\PersonDocumentType: + class: Chill\DocStoreBundle\Form\PersonDocumentType + autowire: true + autoconfigure: true + # arguments: + # - "@chill.main.helper.translatable_string" + tags: + - { name: form.type, alias: chill_docstorebundle_form_document } - Chill\DocStoreBundle\Security\Authorization\: - resource: "./../Security/Authorization" - autowire: true - autoconfigure: true - tags: - - { name: chill.role } + Chill\DocStoreBundle\Security\Authorization\: + resource: "./../Security/Authorization" + autowire: true + autoconfigure: true + tags: + - { name: chill.role } - Chill\DocStoreBundle\Workflow\: - resource: './../Workflow/' - autoconfigure: true - autowire: true + Chill\DocStoreBundle\Workflow\: + resource: './../Workflow/' + autoconfigure: true + autowire: true - Chill\DocStoreBundle\Serializer\Normalizer\: - autowire: true - resource: '../Serializer/Normalizer/' - tags: - - { name: 'serializer.normalizer', priority: 16 } + Chill\DocStoreBundle\Serializer\Normalizer\: + autowire: true + resource: '../Serializer/Normalizer/' + tags: + - { name: 'serializer.normalizer', priority: 16 } - Chill\DocStoreBundle\Service\: - autowire: true - autoconfigure: true - resource: '../Service/' + Chill\DocStoreBundle\Service\: + autowire: true + autoconfigure: true + resource: '../Service/' - Chill\DocStoreBundle\GenericDoc\Manager: - autowire: true - autoconfigure: true - arguments: - $providersForAccompanyingPeriod: !tagged_iterator chill_doc_store.generic_doc_accompanying_period_provider + Chill\DocStoreBundle\GenericDoc\Manager: + autowire: true + autoconfigure: true + arguments: + $providersForAccompanyingPeriod: !tagged_iterator chill_doc_store.generic_doc_accompanying_period_provider - Chill\DocStoreBundle\GenericDoc\Providers\: - autowire: true - autoconfigure: true - resource: '../GenericDoc/Providers/' + Chill\DocStoreBundle\GenericDoc\Twig\GenericDocExtension: + autoconfigure: true + autowire: true + + Chill\DocStoreBundle\GenericDoc\Twig\GenericDocExtensionRuntime: + autoconfigure: true + autowire: true + arguments: + $renderers: !tagged_iterator chill_doc_store.generic_doc_renderer + + Chill\DocStoreBundle\GenericDoc\Providers\: + autowire: true + autoconfigure: true + resource: '../GenericDoc/Providers/' + + Chill\DocStoreBundle\GenericDoc\Renderer\: + autowire: true + autoconfigure: true + resource: '../GenericDoc/Renderer/'