mirror of
https://gitlab.com/Chill-Projet/chill-bundles.git
synced 2025-06-07 18:44:08 +00:00
234 lines
8.2 KiB
PHP
234 lines
8.2 KiB
PHP
<?php
|
|
|
|
/**
|
|
* 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.
|
|
*/
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace Chill\DocGeneratorBundle\Controller;
|
|
|
|
use Base64Url\Base64Url;
|
|
use ChampsLibres\AsyncUploaderBundle\TempUrl\TempUrlGeneratorInterface;
|
|
use Chill\DocGeneratorBundle\Context\ContextManager;
|
|
use Chill\DocGeneratorBundle\Context\DocGeneratorContextWithPublicFormInterface;
|
|
use Chill\DocGeneratorBundle\Context\Exception\ContextNotFoundException;
|
|
use Chill\DocGeneratorBundle\Entity\DocGeneratorTemplate;
|
|
use Chill\DocGeneratorBundle\GeneratorDriver\DriverInterface;
|
|
use Chill\DocGeneratorBundle\Repository\DocGeneratorTemplateRepository;
|
|
use Chill\DocStoreBundle\Entity\StoredObject;
|
|
use Chill\MainBundle\Pagination\PaginatorFactory;
|
|
use Chill\MainBundle\Serializer\Model\Collection;
|
|
use Exception;
|
|
use GuzzleHttp\Client;
|
|
use GuzzleHttp\Exception\TransferException;
|
|
use Psr\Log\LoggerInterface;
|
|
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
|
|
|
use Symfony\Component\HttpFoundation\Request;
|
|
|
|
// TODO à mettre dans services
|
|
use Symfony\Component\HttpFoundation\Response;
|
|
use Symfony\Component\HttpKernel\Exception\HttpException;
|
|
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
|
|
use Symfony\Component\HttpKernel\KernelInterface;
|
|
use Symfony\Component\Routing\Annotation\Route;
|
|
|
|
use Symfony\Component\Serializer\Normalizer\AbstractNormalizer;
|
|
use Symfony\Contracts\HttpClient\HttpClientInterface;
|
|
|
|
final class DocGeneratorTemplateController extends AbstractController
|
|
{
|
|
private HttpClientInterface $client;
|
|
|
|
private ContextManager $contextManager;
|
|
|
|
private DocGeneratorTemplateRepository $docGeneratorTemplateRepository;
|
|
|
|
private DriverInterface $driver;
|
|
|
|
private KernelInterface $kernel;
|
|
|
|
private LoggerInterface $logger;
|
|
|
|
private PaginatorFactory $paginatorFactory;
|
|
|
|
private TempUrlGeneratorInterface $tempUrlGenerator;
|
|
|
|
public function __construct(
|
|
ContextManager $contextManager,
|
|
DocGeneratorTemplateRepository $docGeneratorTemplateRepository,
|
|
DriverInterface $driver,
|
|
LoggerInterface $logger,
|
|
PaginatorFactory $paginatorFactory,
|
|
TempUrlGeneratorInterface $tempUrlGenerator,
|
|
KernelInterface $kernel,
|
|
HttpClientInterface $client
|
|
) {
|
|
$this->contextManager = $contextManager;
|
|
$this->docGeneratorTemplateRepository = $docGeneratorTemplateRepository;
|
|
$this->driver = $driver;
|
|
$this->logger = $logger;
|
|
$this->paginatorFactory = $paginatorFactory;
|
|
$this->tempUrlGenerator = $tempUrlGenerator;
|
|
$this->kernel = $kernel;
|
|
$this->client = $client;
|
|
}
|
|
|
|
/**
|
|
* @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 {
|
|
try {
|
|
$context = $this->contextManager->getContextByDocGeneratorTemplate($template);
|
|
} catch (ContextNotFoundException $e) {
|
|
throw new NotFoundHttpException($e->getMessage(), $e);
|
|
}
|
|
|
|
$entity = $this->getDoctrine()->getRepository($context->getEntityClass())->find($entityId);
|
|
|
|
if (null === $entity) {
|
|
throw new NotFoundHttpException("Entity with classname {$entityClassName} and id {$entityId} is not found");
|
|
}
|
|
|
|
$contextGenerationData = [];
|
|
|
|
if ($context instanceof DocGeneratorContextWithPublicFormInterface
|
|
&& $context->hasPublicForm($template, $entity)) {
|
|
$builder = $this->createFormBuilder($context->getFormData($template, $entity));
|
|
$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())) {
|
|
$templatePath = '@ChillDocGenerator/Generator/basic_form.html.twig';
|
|
$templateOptions = ['entity' => $entity, 'form' => $form->createView(),
|
|
'template' => $template, 'context' => $context, ];
|
|
|
|
return $this->render($templatePath, $templateOptions);
|
|
}
|
|
}
|
|
|
|
$getUrlGen = $this->tempUrlGenerator->generate(
|
|
'GET',
|
|
$template->getFile()->getFilename()
|
|
);
|
|
|
|
$data = $this->client->request('GET', $getUrlGen->url);
|
|
|
|
$iv = $template->getFile()->getIv(); // iv as an Array
|
|
$ivGoodFormat = pack('C*', ...$iv); // iv as a String (ok for openssl_decrypt)
|
|
|
|
$method = 'AES-256-CBC';
|
|
|
|
$key = $template->getFile()->getKeyInfos()['k'];
|
|
$keyGoodFormat = Base64Url::decode($key);
|
|
|
|
$dataDecrypted = openssl_decrypt($data->getContent(), $method, $keyGoodFormat, 1, $ivGoodFormat);
|
|
|
|
if (false === $dataDecrypted) {
|
|
throw new Exception('Error during Decrypt ', 1);
|
|
}
|
|
|
|
if (false === $templateResource = fopen('php://memory', 'r+b')) {
|
|
$this->logger->error('Could not write data to memory');
|
|
|
|
throw new HttpException(500);
|
|
}
|
|
|
|
fwrite($templateResource, $dataDecrypted);
|
|
rewind($templateResource);
|
|
|
|
$datas = $context->getData($template, $entity, $contextGenerationData);
|
|
dump('datas compiled', $datas);
|
|
|
|
$generatedResource = $this->driver->generateFromResource($templateResource, $template->getFile()->getType(), $datas, $template->getFile()->getFilename());
|
|
|
|
fclose($templateResource);
|
|
|
|
$genDocName = 'doc_' . sprintf('%010d', mt_rand()) . 'odt';
|
|
|
|
$getUrlGen = $this->tempUrlGenerator->generate(
|
|
'PUT',
|
|
$genDocName
|
|
);
|
|
|
|
$client = new Client();
|
|
|
|
try {
|
|
$putResponse = $client->request('PUT', $getUrlGen->url, [
|
|
'body' => $generatedResource,
|
|
]);
|
|
|
|
if ($putResponse->getStatusCode() === 201) {
|
|
$em = $this->getDoctrine()->getManager();
|
|
$storedObject = new StoredObject();
|
|
$storedObject
|
|
->setType($template->getFile()->getType())
|
|
->setFilename($genDocName);
|
|
|
|
$em->persist($storedObject);
|
|
|
|
try {
|
|
$context->storeGenerated($template, $storedObject, $entity, $contextGenerationData);
|
|
} catch (Exception $e) {
|
|
$this->logger->error('Could not store the associated document to entity', [
|
|
'entityClassName' => $entityClassName,
|
|
'entityId' => $entityId,
|
|
'contextKey' => $context->getName(),
|
|
]);
|
|
|
|
throw $e;
|
|
}
|
|
|
|
$em->flush();
|
|
|
|
return $this->redirectToRoute('chill_wopi_file_edit', [
|
|
'fileId' => $storedObject->getUuid(),
|
|
'returnPath' => $request->query->get('returnPath', '/'),
|
|
]);
|
|
}
|
|
} catch (TransferException $e) {
|
|
throw $e;
|
|
}
|
|
|
|
throw new Exception('Unable to generate document.');
|
|
}
|
|
|
|
/**
|
|
* @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']]
|
|
);
|
|
}
|
|
}
|