diff --git a/src/Bundle/ChillDocGeneratorBundle/Context/ContextManager.php b/src/Bundle/ChillDocGeneratorBundle/Context/ContextManager.php index 78b59fdc6..8dfecb730 100644 --- a/src/Bundle/ChillDocGeneratorBundle/Context/ContextManager.php +++ b/src/Bundle/ChillDocGeneratorBundle/Context/ContextManager.php @@ -40,6 +40,17 @@ class ContextManager throw new ContextNotFoundException($docGeneratorTemplate->getContext()); } + public function getContextByKey(string $searchedKey): DocGeneratorContextInterface + { + foreach ($this->contexts as $key => $context) { + if ($searchedKey === $key) { + return $context; + } + } + + throw new ContextNotFoundException($searchedKey); + } + public function getContexts(): array { return iterator_to_array($this->contexts); diff --git a/src/Bundle/ChillDocGeneratorBundle/Context/DocGeneratorContextInterface.php b/src/Bundle/ChillDocGeneratorBundle/Context/DocGeneratorContextInterface.php index f70aa0abf..d9faeeb3f 100644 --- a/src/Bundle/ChillDocGeneratorBundle/Context/DocGeneratorContextInterface.php +++ b/src/Bundle/ChillDocGeneratorBundle/Context/DocGeneratorContextInterface.php @@ -13,9 +13,10 @@ namespace Chill\DocGeneratorBundle\Context; use Chill\DocGeneratorBundle\Entity\DocGeneratorTemplate; use Chill\DocStoreBundle\Entity\StoredObject; +use Symfony\Component\Form\FormBuilderInterface; /** - * Interface for context for for document generation. + * Interface for context for document generation. */ interface DocGeneratorContextInterface { @@ -24,28 +25,37 @@ interface DocGeneratorContextInterface * * @param mixed $entity */ - public function getData($entity): array; + public function getData(DocGeneratorTemplate $template, $entity, array $contextGenerationData = []): array; /** * Generate the form that display. * * @param mixed $entity */ - public function getForm($entity); + public function buildPublicForm(FormBuilderInterface $builder, DocGeneratorTemplate $template, $entity): void; public static function getKey(): string; public function getName(): string; + public function getDescription(): string; + /** * has form. + * + * @param mixed $entity */ - public function hasForm(): bool; + public function hasPublicForm(DocGeneratorTemplate $template, $entity): bool; - public function storeGenerated(DocGeneratorTemplate $template, StoredObject $storedObject, object $entity): void; + public function hasAdminForm(): bool; - /** - * True of false which entity supports. - */ - public function supports(string $entityClass): bool; + public function buildAdminForm(FormBuilderInterface $builder): void; + + public function storeGenerated(DocGeneratorTemplate $template, StoredObject $storedObject, object $entity, array $contextGenerationData): void; + + public function getEntityClass(): string; + + public function adminFormTransform(array $data): array; + + public function adminFormReverseTransform(array $data): array; } diff --git a/src/Bundle/ChillDocGeneratorBundle/Context/HouseholdMemberSelectionContext.php b/src/Bundle/ChillDocGeneratorBundle/Context/HouseholdMemberSelectionContext.php index a9734d9cf..2197995a0 100644 --- a/src/Bundle/ChillDocGeneratorBundle/Context/HouseholdMemberSelectionContext.php +++ b/src/Bundle/ChillDocGeneratorBundle/Context/HouseholdMemberSelectionContext.php @@ -25,7 +25,7 @@ use function get_class; /** * Context that display a form to select a member of a houseHold. */ -class HouseholdMemberSelectionContext implements DocGeneratorContextInterface +class HouseholdMemberSelectionContext //implements DocGeneratorContextInterface { private EntityManagerInterface $em; diff --git a/src/Bundle/ChillDocGeneratorBundle/Controller/AdminDocGeneratorTemplateController.php b/src/Bundle/ChillDocGeneratorBundle/Controller/AdminDocGeneratorTemplateController.php index a7d24f127..aa0e34476 100644 --- a/src/Bundle/ChillDocGeneratorBundle/Controller/AdminDocGeneratorTemplateController.php +++ b/src/Bundle/ChillDocGeneratorBundle/Controller/AdminDocGeneratorTemplateController.php @@ -11,8 +11,55 @@ declare(strict_types=1); namespace Chill\DocGeneratorBundle\Controller; +use Chill\DocGeneratorBundle\Context\ContextManager; +use Chill\DocGeneratorBundle\Entity\DocGeneratorTemplate; use Chill\MainBundle\CRUD\Controller\CRUDController; +use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\HttpFoundation\Response; +use Symfony\Component\Routing\Annotation\Route; class AdminDocGeneratorTemplateController extends CRUDController { + private ContextManager $contextManager; + + public function __construct(ContextManager $contextManager) + { + $this->contextManager = $contextManager; + } + + public function new(Request $request): Response + { + if (!$request->query->has('context')) { + return $this->redirectToRoute("chill_docgen_admin_template_pick-context"); + } + + return parent::new($request); + } + + protected function createEntity(string $action, Request $request): object + { + /** @var DocGeneratorTemplate $entity */ + $entity = parent::createEntity($action, $request); + $key = $request->query->get('context'); + $context = $this->contextManager->getContextByKey($key); + + $entity->setContext($key)->setEntity($context->getEntityClass()); + + return $entity; + } + + /** + * @Route("{_locale}/admin/docgen/template/pick-context", name="chill_docgen_admin_template_pick-context") + * @param Request $request + * @return Response + */ + public function pickContext(Request $request): Response + { + $this->denyAccessUnlessGranted('ROLE_ADMIN'); + + return $this->render('ChillDocGeneratorBundle:Admin/DocGeneratorTemplate:pick-context.html.twig', [ + 'contexts' => $this->contextManager->getContexts() + ]); + } + } diff --git a/src/Bundle/ChillDocGeneratorBundle/Controller/DocGeneratorTemplateController.php b/src/Bundle/ChillDocGeneratorBundle/Controller/DocGeneratorTemplateController.php index 2a048d421..493bcb92e 100644 --- a/src/Bundle/ChillDocGeneratorBundle/Controller/DocGeneratorTemplateController.php +++ b/src/Bundle/ChillDocGeneratorBundle/Controller/DocGeneratorTemplateController.php @@ -30,6 +30,7 @@ use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; // TODO à mettre dans services +use Symfony\Component\HttpKernel\Exception\HttpException; use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; use Symfony\Component\HttpKernel\KernelInterface; use Symfony\Component\Routing\Annotation\Route; @@ -83,6 +84,35 @@ final class DocGeneratorTemplateController extends AbstractController int $entityId, Request $request ): Response { + $entity = $this->getDoctrine()->getRepository($entityClassName)->find($entityId); + + if (null === $entity) { + throw new NotFoundHttpException("Entity with classname $entityClassName and id $entityId is not found"); + } + + try { + $context = $this->contextManager->getContextByDocGeneratorTemplate($template); + } catch (ContextNotFoundException $e) { + throw new NotFoundHttpException($e->getMessage(), $e); + } + + if ($context->hasPublicForm($template, $entity)) { + $builder = $this->createFormBuilder(); + $context->buildPublicForm($builder, $template, $entity); + $form = $builder->getForm()->handleRequest($request); + + if ($form->isSubmitted() && $form->isValid()) { + $contextGenerationData = $form->getData(); + } elseif (!$form->isSubmitted() || ($form->isSubmitted() && !$form->isValid())) { + $template = '@ChillDocGenerator/Generator/basic_form.html.twig'; + $templateOptions = ['entity' => $entity, 'form' => $form->createView(), 'template' => $template]; + + return $this->render($template, $templateOptions); + } + } else { + $contextGenerationData = []; + } + $getUrlGen = $this->tempUrlGenerator->generate( 'GET', $template->getFile()->getFilename() @@ -107,30 +137,22 @@ final class DocGeneratorTemplateController extends AbstractController $tmpfnameDeCrypted = tempnam($this->kernel->getCacheDir(), 'DECRYPT_DOC_TEMPLATE'); // plus ou moins if (!$handle = fopen($tmpfnameDeCrypted, 'ab')) { - echo "Cannot open file ({$tmpfnameDeCrypted})"; + $this->logger->error("Cannot open file ({$tmpfnameDeCrypted})"); - exit; + throw new HttpException(500); } if (false === $ftemplate = fwrite($handle, $dataDecrypted)) { - echo "Cannot write to file ({$tmpfnameDeCrypted})"; + $this->logger->error("Cannot write to file ({$tmpfnameDeCrypted})"); - exit; + throw new HttpException(500); } dump("Success, wrote (to file ({$tmpfnameDeCrypted})"); fclose($handle); - $entity = $this->getDoctrine()->getRepository($entityClassName)->find($entityId); - - try { - $context = $this->contextManager->getContextByDocGeneratorTemplate($template); - } catch (ContextNotFoundException $e) { - throw new NotFoundHttpException($e->getMessage(), $e); - } - - $datas = $context->getData($entity); + $datas = $context->getData($template, $entity, $contextGenerationData); dump('process the data', $datas); @@ -182,7 +204,7 @@ final class DocGeneratorTemplateController extends AbstractController $em->persist($storedObject); try { - $context->storeGenerated($template, $storedObject, $entity); + $context->storeGenerated($template, $storedObject, $entity, $contextGenerationData); } catch (\Exception $e) { $this->logger->error('Could not store the associated document to entity', [ 'entityClassName' => $entityClassName, diff --git a/src/Bundle/ChillDocGeneratorBundle/Entity/DocGeneratorTemplate.php b/src/Bundle/ChillDocGeneratorBundle/Entity/DocGeneratorTemplate.php index 93be974ad..61e604757 100644 --- a/src/Bundle/ChillDocGeneratorBundle/Entity/DocGeneratorTemplate.php +++ b/src/Bundle/ChillDocGeneratorBundle/Entity/DocGeneratorTemplate.php @@ -24,6 +24,11 @@ use Symfony\Component\Serializer\Annotation as Serializer; */ class DocGeneratorTemplate { + /** + * @ORM\Column(type="boolean", options={"default":true}) + */ + private bool $active = true; + /** * Class name of the context to use. * @@ -38,20 +43,24 @@ class DocGeneratorTemplate * @ORM\Column(type="text", nullable=true) * @Serializer\Groups({"read"}) */ - private string $description; + private ?string $description = null; /** - * Class name of the entities for which this template can be used. + * Class name of the entity for which this template can be used. * - * so if $entities = ['Chill\PersonBundle\Entity\AccompanyingPeriod', 'Chill\PersonBundle\Entity\SocialWork\SocialAction'] - * this template can be selected for an AccompanyingPeriod or a SocialAction - * - * @ORM\Column(type="simple_array") + * @ORM\Column(type="string", options={"default":""}) */ - private array $entities = []; + private string $entity = ""; /** - * @ORM\ManyToOne(targetEntity=StoredObject::class, cascade={"persist"}).) + * Options for the template + * + * @ORM\Column(type="json", name="template_options", options={"default":"[]"}) + */ + private array $options = []; + + /** + * @ORM\ManyToOne(targetEntity=StoredObject::class, cascade={"persist"})) */ private ?StoredObject $file = null; @@ -69,6 +78,18 @@ class DocGeneratorTemplate */ private array $name = []; + public function isActive(): bool + { + return $this->active; + } + + public function setActive(bool $active): DocGeneratorTemplate + { + $this->active = $active; + + return $this; + } + public function getContext(): ?string { return $this->context; @@ -79,11 +100,6 @@ class DocGeneratorTemplate return $this->description; } - public function getEntities(): ?array - { - return $this->entities; - } - public function getFile(): ?StoredObject { return $this->file; @@ -113,13 +129,6 @@ class DocGeneratorTemplate return $this; } - public function setEntities(array $entities): self - { - $this->entities = $entities; - - return $this; - } - public function setFile(StoredObject $file): self { $this->file = $file; @@ -133,4 +142,28 @@ class DocGeneratorTemplate return $this; } + + public function getEntity(): string + { + return $this->entity; + } + + public function setEntity(string $entity): self + { + $this->entity = $entity; + + return $this; + } + + public function getOptions(): array + { + return $this->options; + } + + public function setOptions(array $options): self + { + $this->options = $options; + + return $this; + } } diff --git a/src/Bundle/ChillDocGeneratorBundle/Form/DocGeneratorTemplateType.php b/src/Bundle/ChillDocGeneratorBundle/Form/DocGeneratorTemplateType.php index e661c6d9e..474ac0571 100644 --- a/src/Bundle/ChillDocGeneratorBundle/Form/DocGeneratorTemplateType.php +++ b/src/Bundle/ChillDocGeneratorBundle/Form/DocGeneratorTemplateType.php @@ -18,6 +18,7 @@ use Chill\DocStoreBundle\Form\StoredObjectType; use Chill\MainBundle\Form\Type\TranslatableStringFormType; use Chill\PersonBundle\Entity\AccompanyingPeriod\AccompanyingPeriodWorkEvaluation; use Symfony\Component\Form\AbstractType; +use Symfony\Component\Form\CallbackTransformer; use Symfony\Component\Form\Extension\Core\Type\ChoiceType; use Symfony\Component\Form\FormBuilderInterface; use Symfony\Component\OptionsResolver\OptionsResolver; @@ -33,30 +34,34 @@ class DocGeneratorTemplateType extends AbstractType public function buildForm(FormBuilderInterface $builder, array $options) { - $contexts = array_flip(array_map(static function (DocGeneratorContextInterface $c) { - return $c->getName(); - }, $this->contextManager->getContexts())); + /** @var DocGeneratorTemplate $template */ + $template = $options['data']; + $context = $this->contextManager->getContextByKey($template->getContext()); $builder ->add('name', TranslatableStringFormType::class, [ 'label' => 'Nom', ]) - ->add('context', ChoiceType::class, [ - 'required' => true, - 'label' => 'Context', - 'choices' => $contexts, - ]) - ->add('entities', ChoiceType::class, [ - 'multiple' => true, - 'choices' => [ - 'AccompanyingPeriod' => 'Chill\PersonBundle\Entity\AccompanyingPeriod', - 'SocialWork\SocialAction' => 'Chill\PersonBundle\Entity\SocialWork\SocialAction', - 'AccompanyingPeriod\AccompanyingPeriodWorkEvaluation' => AccompanyingPeriodWorkEvaluation::class, - ], ]) ->add('description') ->add('file', StoredObjectType::class, [ 'error_bubbling' => true, - ]); + ]) + ; + + if ($context->hasAdminForm()) { + $sub = $builder + ->create('options', null, ['compound' => true]) + ->addModelTransformer(new CallbackTransformer( + function (array $data) use ($context) { + return $context->adminFormTransform($data); + }, + function (array $data) use ($context) { + return $context->adminFormReverseTransform($data); + } + )); + $context->buildAdminForm($sub); + $builder->add($sub); + } } public function configureOptions(OptionsResolver $resolver) diff --git a/src/Bundle/ChillDocGeneratorBundle/Repository/DocGeneratorTemplateRepository.php b/src/Bundle/ChillDocGeneratorBundle/Repository/DocGeneratorTemplateRepository.php index 007f2fabb..5d99efa94 100644 --- a/src/Bundle/ChillDocGeneratorBundle/Repository/DocGeneratorTemplateRepository.php +++ b/src/Bundle/ChillDocGeneratorBundle/Repository/DocGeneratorTemplateRepository.php @@ -31,8 +31,8 @@ final class DocGeneratorTemplateRepository implements ObjectRepository $builder ->select('count(t)') - ->where('t.entities LIKE :entity') - ->setParameter('entity', '%' . addslashes($entity) . '%'); + ->where('t.entity LIKE :entity') + ->setParameter('entity', addslashes($entity)); return $builder->getQuery()->getSingleScalarResult(); } @@ -69,8 +69,8 @@ final class DocGeneratorTemplateRepository implements ObjectRepository $builder = $this->repository->createQueryBuilder('t'); $builder - ->where('t.entities LIKE :entity') - ->setParameter('entity', '%' . addslashes($entity) . '%'); + ->where('t.entity LIKE :entity') + ->setParameter('entity', addslashes($entity)); return $builder ->getQuery() diff --git a/src/Bundle/ChillDocGeneratorBundle/Resources/views/Admin/DocGeneratorTemplate/pick-context.html.twig b/src/Bundle/ChillDocGeneratorBundle/Resources/views/Admin/DocGeneratorTemplate/pick-context.html.twig new file mode 100644 index 000000000..d43e88f8d --- /dev/null +++ b/src/Bundle/ChillDocGeneratorBundle/Resources/views/Admin/DocGeneratorTemplate/pick-context.html.twig @@ -0,0 +1,27 @@ +{% extends '@ChillDocGenerator/Admin/layout.html.twig' %} + +{% block title 'Pick template context'|trans %} + +{% block layout_wvm_content %} +
+ +

{{ block('title') }}

+
+ {% for key, context in contexts %} +
+ +
+ {{ context.description|trans|nl2br }} +
+
+ {% endfor %} +
+
+ +{% endblock %} diff --git a/src/Bundle/ChillDocGeneratorBundle/Resources/views/Generator/basic_form.html.twig b/src/Bundle/ChillDocGeneratorBundle/Resources/views/Generator/basic_form.html.twig new file mode 100644 index 000000000..58d4b059f --- /dev/null +++ b/src/Bundle/ChillDocGeneratorBundle/Resources/views/Generator/basic_form.html.twig @@ -0,0 +1,21 @@ +{% extends 'ChillMainBundle::layout.html.twig' %} + +{% block title 'Generate document'|trans %} + +{% block content %} +
+

{{ block('title') }}

+ + {{ form_start(form, { 'attr': { 'id': 'generate_doc_form' }}) }} + {{ form(form) }} + {{ form_end(form) }} + + +
+{% endblock %} diff --git a/src/Bundle/ChillDocGeneratorBundle/migrations/Version20211201191757.php b/src/Bundle/ChillDocGeneratorBundle/migrations/Version20211201191757.php new file mode 100644 index 000000000..2ce380d69 --- /dev/null +++ b/src/Bundle/ChillDocGeneratorBundle/migrations/Version20211201191757.php @@ -0,0 +1,34 @@ +addSql('ALTER TABLE chill_docgen_template ADD active BOOLEAN DEFAULT true NOT NULL'); + $this->addSql('ALTER TABLE chill_docgen_template ADD entity VARCHAR(255) NOT NULL DEFAULT \'\''); + $this->addSql('ALTER TABLE chill_docgen_template ADD template_options JSONB NOT NULL DEFAULT \'[]\'::jsonb '); + $this->addSql('COMMENT ON COLUMN chill_docgen_template.template_options IS \'(DC2Type:json)\''); + $this->addSql('ALTER TABLE chill_docgen_template DROP entities'); + } + + public function down(Schema $schema): void + { + $this->addSql('ALTER TABLE chill_docgen_template DROP active'); + $this->addSql('ALTER TABLE chill_docgen_template DROP entity'); + $this->addSql('ALTER TABLE chill_docgen_template DROP template_options'); + $this->addSql('ALTER TABLE chill_docgen_template ADD entities TEXT'); + $this->addSql('COMMENT ON COLUMN chill_docgen_template.entities IS \'(DC2Type:simple_array)\''); + } +} diff --git a/src/Bundle/ChillDocStoreBundle/Entity/DocumentCategory.php b/src/Bundle/ChillDocStoreBundle/Entity/DocumentCategory.php index 1ded5ccb2..cfe6e9643 100644 --- a/src/Bundle/ChillDocStoreBundle/Entity/DocumentCategory.php +++ b/src/Bundle/ChillDocStoreBundle/Entity/DocumentCategory.php @@ -15,7 +15,7 @@ use Doctrine\ORM\Mapping as ORM; /** * @ORM\Table("chill_doc.document_category") - * @ORM\Entity(repositoryClass="Chill\DocStoreBundle\EntityRepository\DocumentCategoryRepository") + * @ORM\Entity() */ class DocumentCategory { diff --git a/src/Bundle/ChillDocStoreBundle/EntityRepository/DocumentCategoryRepository.php b/src/Bundle/ChillDocStoreBundle/EntityRepository/DocumentCategoryRepository.php deleted file mode 100644 index fbf4acb15..000000000 --- a/src/Bundle/ChillDocStoreBundle/EntityRepository/DocumentCategoryRepository.php +++ /dev/null @@ -1,31 +0,0 @@ -getEntityManager() - ->createQuery( - 'SELECT MAX(c.idInsideBundle) + 1 FROM ChillDocStoreBundle:DocumentCategory c' - ) - ->getSingleResult(); - - return reset($array_res); - } -} diff --git a/src/Bundle/ChillDocStoreBundle/Repository/DocumentCategoryRepository.php b/src/Bundle/ChillDocStoreBundle/Repository/DocumentCategoryRepository.php new file mode 100644 index 000000000..09ae5075a --- /dev/null +++ b/src/Bundle/ChillDocStoreBundle/Repository/DocumentCategoryRepository.php @@ -0,0 +1,79 @@ +em = $em; + $this->repository = $em->getRepository(DocumentCategory::class); + } + + public function nextIdInsideBundle() + { + $array_res = $this->em + ->createQuery( + 'SELECT MAX(c.idInsideBundle) + 1 FROM ChillDocStoreBundle:DocumentCategory c' + ) + ->getSingleResult(); + + return reset($array_res); + } + + /** + * @return DocumentCategory|null + */ + public function find($id): ?DocumentCategory + { + return $this->repository->find($id); + } + + /** + * @return array|DocumentCategory[] + */ + public function findAll(): array + { + return $this->repository->findAll(); + } + + public function findBy(array $criteria, ?array $orderBy = null, $limit = null, $offset = null) + { + return $this->repository->findBy($criteria, $orderBy, $limit, $offset); + } + + public function findOneBy(array $criteria): ?DocumentCategory + { + return $this->findOneBy($criteria); + } + + public function getClassName() + { + return DocumentCategory::class; + } + + +} diff --git a/src/Bundle/ChillPersonBundle/Service/DocGenerator/AccompanyingPeriodContext.php b/src/Bundle/ChillPersonBundle/Service/DocGenerator/AccompanyingPeriodContext.php index 9c7ee70a6..31d237f1c 100644 --- a/src/Bundle/ChillPersonBundle/Service/DocGenerator/AccompanyingPeriodContext.php +++ b/src/Bundle/ChillPersonBundle/Service/DocGenerator/AccompanyingPeriodContext.php @@ -15,11 +15,21 @@ use Chill\DocGeneratorBundle\Context\DocGeneratorContextInterface; use Chill\DocGeneratorBundle\Context\Exception\UnexpectedTypeException; use Chill\DocGeneratorBundle\Entity\DocGeneratorTemplate; use Chill\DocStoreBundle\Entity\AccompanyingCourseDocument; +use Chill\DocStoreBundle\Entity\DocumentCategory; use Chill\DocStoreBundle\Entity\StoredObject; +use Chill\DocStoreBundle\Repository\DocumentCategoryRepository; +use Chill\EventBundle\Entity\Participation; use Chill\MainBundle\Templating\TranslatableStringHelperInterface; use Chill\PersonBundle\Entity\AccompanyingPeriod; +use Chill\PersonBundle\Entity\AccompanyingPeriodParticipation; +use Chill\PersonBundle\Entity\Person; +use Chill\PersonBundle\Templating\Entity\PersonRender; use DateTime; use Doctrine\ORM\EntityManagerInterface; +use Doctrine\ORM\EntityRepository; +use Symfony\Bridge\Doctrine\Form\Type\EntityType; +use Symfony\Component\Form\Extension\Core\Type\CheckboxType; +use Symfony\Component\Form\FormBuilderInterface; use Symfony\Component\Serializer\Normalizer\NormalizerInterface; class AccompanyingPeriodContext implements DocGeneratorContextInterface @@ -30,28 +40,62 @@ class AccompanyingPeriodContext implements DocGeneratorContextInterface private TranslatableStringHelperInterface $translatableStringHelper; + private DocumentCategoryRepository $documentCategoryRepository; + + private PersonRender $personRender; + public function __construct( + DocumentCategoryRepository $documentCategoryRepository, NormalizerInterface $normalizer, TranslatableStringHelperInterface $translatableStringHelper, - EntityManagerInterface $em + EntityManagerInterface $em, + PersonRender $personRender ) { + $this->documentCategoryRepository = $documentCategoryRepository; $this->normalizer = $normalizer; $this->translatableStringHelper = $translatableStringHelper; $this->em = $em; + $this->personRender = $personRender; } - public function getData($entity): array + public function getData(DocGeneratorTemplate $template, $entity, array $contextGenerationData = []): array { if (!$entity instanceof AccompanyingPeriod) { throw new UnexpectedTypeException($entity, AccompanyingPeriod::class); } + $options = $template->getOptions(); - return $this->normalizer->normalize($entity, 'docgen', ['docgen:expects' => AccompanyingPeriod::class]); + $data['course'] = $this->normalizer->normalize($entity, 'docgen', ['docgen:expects' => AccompanyingPeriod::class]); + + foreach (['mainPerson', 'person1', 'person2'] as $k) { + if ($options[$k]) { + $data[$k] = $this->normalizer->normalize($contextGenerationData[$k], 'docgen', ['docgen:expects' => Person::class]); + } + } + + return $data; } - public function getForm($entity) + /** + * @param AccompanyingPeriod $entity + */ + public function buildPublicForm(FormBuilderInterface $builder, DocGeneratorTemplate $template, $entity): void { - // TODO: Implement getForm() method. + $options = $template->getOptions(); + $persons = $entity->getCurrentParticipations()->map(function (AccompanyingPeriodParticipation $p) { return $p->getPerson(); }) + ->toArray(); + + foreach (['mainPerson', 'person1', 'person2'] as $key) { + if ($options[$key] ?? false) { + $builder->add($key, EntityType::class, [ + 'class' => Person::class, + 'choices' => $persons, + 'choice_label' => function (Person $p) { return $this->personRender->renderString($p, []); }, + 'multiple' => false, + 'expanded' => true, + ]); + } + } } public static function getKey(): string @@ -61,30 +105,104 @@ class AccompanyingPeriodContext implements DocGeneratorContextInterface public function getName(): string { - return 'Accompanying Period'; + return 'Accompanying Period basic'; } - public function hasForm(): bool + public function getDescription(): string { - return false; + return "A basic context for accompanying period"; + } + + public function hasPublicForm(DocGeneratorTemplate $template, $entity): bool + { + $options = $template->getOptions(); + + return $options['mainPerson'] || $options['person1'] || $options['person2']; } /** * @param AccompanyingPeriod $entity */ - public function storeGenerated(DocGeneratorTemplate $template, StoredObject $storedObject, object $entity): void + public function storeGenerated(DocGeneratorTemplate $template, StoredObject $storedObject, object $entity, array $contextGenerationData): void { $doc = new AccompanyingCourseDocument(); $doc->setTitle($this->translatableStringHelper->localize($template->getName())) ->setDate(new DateTime()) ->setDescription($this->translatableStringHelper->localize($template->getName())) ->setCourse($entity) - ->setObject($storedObject); + ->setObject($storedObject) + ; + + if (array_key_exists('category', $template->getOptions()['category'])) { + $doc + ->setCategory($this->documentCategoryRepository->find( + $template->getOptions()['category']) + ); + } + $this->em->persist($doc); } - public function supports(string $entityClass): bool + public function hasAdminForm(): bool { - return AccompanyingPeriod::class === $entityClass; + return true; + } + + public function buildAdminForm(FormBuilderInterface $builder): void + { + $builder + ->add('mainPerson', CheckboxType::class, [ + 'required' => false, + ]) + ->add('person1', CheckboxType::class, [ + 'required' => false, + ]) + ->add('person2', CheckboxType::class, [ + 'required' => false, + ]) + ->add('category', EntityType::class, [ + 'placeholder' => 'Choose a document category', + 'class' => 'ChillDocStoreBundle:DocumentCategory', + 'query_builder' => static function (EntityRepository $er) { + return $er->createQueryBuilder('c') + ->where('c.documentClass = :docClass') + ->setParameter('docClass', AccompanyingCourseDocument::class); + }, + 'choice_label' => function ($entity = null) { + return $entity ? $this->translatableStringHelper->localize($entity->getName()) : ''; + }, + ]); + ; + } + + public function adminFormTransform(array $data): array + { + return [ + 'mainPerson' => $data['mainPerson'] ?? false, + 'person1' => $data['person1'] ?? false, + 'person2' => $data['person2'] ?? false, + 'category' => + array_key_exists('category', $data) ? + $this->documentCategoryRepository->find($data['category']) : null, + ]; + } + + public function adminFormReverseTransform(array $data): array + { + return [ + 'mainPerson' => $data['mainPerson'], + 'person1' => $data['person1'], + 'person2' => $data['person2'], + 'category' => [ + 'idInsideBundle' => $data['category']->getIdInsideBundle(), + 'bundleId' => $data['category']->getBundleId() + ], + ]; + } + + + public function getEntityClass(): string + { + return AccompanyingPeriod::class; } }