mirror of
https://gitlab.com/Chill-Projet/chill-bundles.git
synced 2025-06-07 18:44:08 +00:00
295 lines
10 KiB
PHP
295 lines
10 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
/*
|
|
* Chill is a software for social workers
|
|
*
|
|
* For the full copyright and license information, please view
|
|
* the LICENSE file that was distributed with this source code.
|
|
*/
|
|
|
|
namespace Chill\DocGeneratorBundle\Controller;
|
|
|
|
use Chill\DocGeneratorBundle\Context\ContextManager;
|
|
use Chill\DocGeneratorBundle\Context\DocGeneratorContextWithPublicFormInterface;
|
|
use Chill\DocGeneratorBundle\Context\Exception\ContextNotFoundException;
|
|
use Chill\DocGeneratorBundle\Entity\DocGeneratorTemplate;
|
|
use Chill\DocGeneratorBundle\Repository\DocGeneratorTemplateRepository;
|
|
use Chill\DocGeneratorBundle\Service\Generator\GeneratorInterface;
|
|
use Chill\DocGeneratorBundle\Service\Messenger\RequestGenerationMessage;
|
|
use Chill\DocStoreBundle\Entity\StoredObject;
|
|
use Chill\MainBundle\Pagination\PaginatorFactory;
|
|
use Chill\MainBundle\Security\ChillSecurity;
|
|
use Chill\MainBundle\Serializer\Model\Collection;
|
|
use Doctrine\ORM\EntityManagerInterface;
|
|
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
|
use Symfony\Component\Form\Extension\Core\Type\CheckboxType;
|
|
use Symfony\Component\Form\Extension\Core\Type\FileType;
|
|
use Symfony\Component\HttpFoundation\RedirectResponse;
|
|
use Symfony\Component\HttpFoundation\Request;
|
|
// TODO à mettre dans services
|
|
use Symfony\Component\HttpFoundation\Response;
|
|
use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;
|
|
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
|
|
use Symfony\Component\Messenger\MessageBusInterface;
|
|
use Symfony\Component\Routing\Annotation\Route;
|
|
use Symfony\Component\Serializer\Normalizer\AbstractNormalizer;
|
|
|
|
final class DocGeneratorTemplateController extends AbstractController
|
|
{
|
|
public function __construct(
|
|
private readonly ContextManager $contextManager,
|
|
private readonly DocGeneratorTemplateRepository $docGeneratorTemplateRepository,
|
|
private readonly GeneratorInterface $generator,
|
|
private readonly MessageBusInterface $messageBus,
|
|
private readonly PaginatorFactory $paginatorFactory,
|
|
private readonly EntityManagerInterface $entityManager,
|
|
private readonly ChillSecurity $security
|
|
) {}
|
|
|
|
/**
|
|
* @Route(
|
|
* "{_locale}/admin/doc/gen/generate/test/from/{template}/for/{entityClassName}/{entityId}",
|
|
* name="chill_docgenerator_test_generate_from_template"
|
|
* )
|
|
*/
|
|
public function adminTestGenerateDocFromTemplateAction(
|
|
DocGeneratorTemplate $template,
|
|
string $entityClassName,
|
|
int $entityId,
|
|
Request $request
|
|
): Response {
|
|
return $this->generateDocFromTemplate(
|
|
$template,
|
|
$entityId,
|
|
$request,
|
|
true
|
|
);
|
|
}
|
|
|
|
/**
|
|
* @Route(
|
|
* "{_locale}/doc/gen/generate/from/{template}/for/{entityClassName}/{entityId}",
|
|
* name="chill_docgenerator_generate_from_template"
|
|
* )
|
|
*/
|
|
public function generateDocFromTemplateAction(
|
|
DocGeneratorTemplate $template,
|
|
string $entityClassName,
|
|
int $entityId,
|
|
Request $request
|
|
): Response {
|
|
return $this->generateDocFromTemplate(
|
|
$template,
|
|
$entityId,
|
|
$request,
|
|
false
|
|
);
|
|
}
|
|
|
|
/**
|
|
* @Route(
|
|
* "/api/1.0/docgen/templates/by-entity/{entityClassName}",
|
|
* name="chill_docgenerator_templates_for_entity_api"
|
|
* )
|
|
*/
|
|
public function listTemplateApiAction(string $entityClassName): Response
|
|
{
|
|
$nb = $this->docGeneratorTemplateRepository->countByEntity($entityClassName);
|
|
$paginator = $this->paginatorFactory->create($nb);
|
|
$entities = $this->docGeneratorTemplateRepository->findByEntity(
|
|
$entityClassName,
|
|
$paginator->getCurrentPageFirstItemNumber(),
|
|
$paginator->getItemsPerPage()
|
|
);
|
|
|
|
return $this->json(
|
|
new Collection($entities, $paginator),
|
|
Response::HTTP_OK,
|
|
[],
|
|
[AbstractNormalizer::GROUPS => ['read']]
|
|
);
|
|
}
|
|
|
|
/**
|
|
* @Route(
|
|
* "{_locale}/admin/doc/gen/generate/test/redirect",
|
|
* name="chill_docgenerator_test_generate_redirect"
|
|
* )
|
|
*
|
|
* @return void
|
|
*/
|
|
public function redirectToTestGenerate(Request $request): RedirectResponse
|
|
{
|
|
$template = $request->query->getInt('template');
|
|
|
|
if (null === $template) {
|
|
throw new BadRequestHttpException('template parameter is missing');
|
|
}
|
|
|
|
$entityClassName = $request->query->get('entityClassName');
|
|
|
|
if (null === $entityClassName) {
|
|
throw new BadRequestHttpException('entityClassName is missing');
|
|
}
|
|
|
|
$entityId = $request->query->get('entityId');
|
|
|
|
if (null === $entityId) {
|
|
throw new BadRequestHttpException('entityId is missing');
|
|
}
|
|
|
|
return $this->redirectToRoute(
|
|
'chill_docgenerator_test_generate_from_template',
|
|
[
|
|
'template' => $template, 'entityClassName' => $entityClassName, 'entityId' => $entityId,
|
|
'returnPath' => $request->query->get('returnPath', '/'),
|
|
]
|
|
);
|
|
}
|
|
|
|
private function generateDocFromTemplate(
|
|
DocGeneratorTemplate $template,
|
|
int $entityId,
|
|
Request $request,
|
|
bool $isTest
|
|
): Response {
|
|
try {
|
|
$context = $this->contextManager->getContextByDocGeneratorTemplate($template);
|
|
} catch (ContextNotFoundException $e) {
|
|
throw new NotFoundHttpException('Context not found.', $e);
|
|
}
|
|
|
|
$entity = $this
|
|
->entityManager
|
|
->getRepository($context->getEntityClass())
|
|
->find($entityId);
|
|
|
|
if (null === $entity) {
|
|
throw new NotFoundHttpException(sprintf('Entity with classname %s and id %s is not found', $context->getEntityClass(), $entityId));
|
|
}
|
|
|
|
$contextGenerationData = [
|
|
'test_file' => null,
|
|
];
|
|
|
|
if (
|
|
$context instanceof DocGeneratorContextWithPublicFormInterface
|
|
&& $context->hasPublicForm($template, $entity) || $isTest
|
|
) {
|
|
if ($context instanceof DocGeneratorContextWithPublicFormInterface && $context->hasPublicForm($template, $entity)) {
|
|
$builder = $this->createFormBuilder(
|
|
array_merge(
|
|
$context->getFormData($template, $entity),
|
|
$isTest ? ['test_file' => null, 'show_data' => false] : []
|
|
)
|
|
);
|
|
|
|
$context->buildPublicForm($builder, $template, $entity);
|
|
} else {
|
|
$builder = $this->createFormBuilder(
|
|
['test_file' => null, 'show_data' => false]
|
|
);
|
|
}
|
|
|
|
if ($isTest) {
|
|
$builder->add('test_file', FileType::class, [
|
|
'label' => 'Template file',
|
|
'required' => false,
|
|
]);
|
|
$builder->add('show_data', CheckboxType::class, [
|
|
'label' => 'Show data instead of generating',
|
|
'required' => false,
|
|
]);
|
|
}
|
|
|
|
$form = $builder->getForm()->handleRequest($request);
|
|
|
|
if ($form->isSubmitted() && $form->isValid()) {
|
|
$contextGenerationData = $form->getData();
|
|
} elseif (!$form->isSubmitted() || ($form->isSubmitted() && !$form->isValid())) {
|
|
$templatePath = '@ChillDocGenerator/Generator/basic_form.html.twig';
|
|
$templateOptions = [
|
|
'entity' => $entity, 'form' => $form->createView(),
|
|
'template' => $template, 'context' => $context,
|
|
];
|
|
|
|
return $this->render($templatePath, $templateOptions);
|
|
}
|
|
}
|
|
|
|
// transform context generation data
|
|
$contextGenerationDataSanitized =
|
|
$context instanceof DocGeneratorContextWithPublicFormInterface ?
|
|
$context->contextGenerationDataNormalize($template, $entity, $contextGenerationData)
|
|
: [];
|
|
|
|
// if is test, render the data or generate the doc
|
|
if ($isTest && isset($form) && true === $form['show_data']->getData()) {
|
|
return $this->render('@ChillDocGenerator/Generator/debug_value.html.twig', [
|
|
'datas' => json_encode($context->getData($template, $entity, $contextGenerationData), \JSON_PRETTY_PRINT),
|
|
]);
|
|
}
|
|
if ($isTest) {
|
|
$generated = $this->generator->generateDocFromTemplate(
|
|
$template,
|
|
$entityId,
|
|
$contextGenerationDataSanitized,
|
|
null,
|
|
true,
|
|
isset($form) ? $form['test_file']->getData() : null
|
|
);
|
|
|
|
return new Response(
|
|
$generated,
|
|
Response::HTTP_OK,
|
|
[
|
|
'Content-Transfer-Encoding', 'binary',
|
|
'Content-Type' => 'application/vnd.oasis.opendocument.text',
|
|
'Content-Disposition' => 'attachment; filename="generated.odt"',
|
|
'Content-Length' => \strlen($generated),
|
|
],
|
|
);
|
|
}
|
|
|
|
// this is not a test
|
|
// we prepare the object to store the document
|
|
$storedObject = (new StoredObject())
|
|
->setStatus(StoredObject::STATUS_PENDING)
|
|
;
|
|
|
|
$this->entityManager->persist($storedObject);
|
|
|
|
// we store the generated document
|
|
$context
|
|
->storeGenerated(
|
|
$template,
|
|
$storedObject,
|
|
$entity,
|
|
$contextGenerationData
|
|
);
|
|
|
|
$this->entityManager->flush();
|
|
|
|
$this->messageBus->dispatch(
|
|
new RequestGenerationMessage(
|
|
$this->security->getUser(),
|
|
$template,
|
|
$entityId,
|
|
$storedObject,
|
|
$contextGenerationDataSanitized,
|
|
)
|
|
);
|
|
|
|
return $this
|
|
->redirectToRoute(
|
|
'chill_wopi_file_edit',
|
|
[
|
|
'fileId' => $storedObject->getUuid(),
|
|
'returnPath' => $request->query->get('returnPath', '/'),
|
|
]
|
|
);
|
|
}
|
|
}
|