Merge remote-tracking branch 'origin/docgenerator_oct_nov_21' into features/docgen-widget-generate-template

This commit is contained in:
Julien Fastré 2021-11-30 18:31:33 +01:00
commit 0710d6572b
9 changed files with 178 additions and 30 deletions

View File

@ -20,29 +20,47 @@ use Chill\MainBundle\Pagination\PaginatorFactory;
use Chill\MainBundle\Serializer\Model\Collection;
use Chill\PersonBundle\Entity\AccompanyingPeriod\AccompanyingPeriodWorkEvaluation;
use Chill\PersonBundle\Entity\AccompanyingPeriod\AccompanyingPeriodWorkEvaluationDocument;
use Chill\PersonBundle\Entity\SocialWork\Evaluation;
use Exception;
use GuzzleHttp\Client;
use GuzzleHttp\Exception\TransferException;
use PhpOffice\PhpWord\TemplateProcessor;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\HeaderUtils;
use ChampsLibres\AsyncUploaderBundle\TempUrl\TempUrlOpenstackGenerator;
use Jose\Component\Core\JWK;
use Base64Url\Base64Url;
use Symfony\Component\HttpKernel\KernelInterface;
// TODO à mettre dans services
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\Serializer\Normalizer\AbstractNormalizer;
class DocGeneratorTemplateController extends AbstractController
use Symfony\Contracts\HttpClient\HttpClientInterface;
final class DocGeneratorTemplateController extends AbstractController
{
private DocGeneratorTemplateRepository $docGeneratorTemplateRepository;
private PaginatorFactory $paginatorFactory;
public function __construct(DocGeneratorTemplateRepository $docGeneratorTemplateRepository, PaginatorFactory $paginatorFactory)
{
private KernelInterface $kernel;
private HttpClientInterface $client;
public function __construct(
DocGeneratorTemplateRepository $docGeneratorTemplateRepository,
PaginatorFactory $paginatorFactory,
KernelInterface $kernel,
HttpClientInterface $client
) {
$this->docGeneratorTemplateRepository = $docGeneratorTemplateRepository;
$this->paginatorFactory = $paginatorFactory;
$this->kernel = $kernel;
$this->client = $client;
}
/**
@ -60,11 +78,39 @@ class DocGeneratorTemplateController extends AbstractController
): Response {
$getUrlGen = $tempUrlGenerator->generate(
'GET',
$template->getFile()
);
$template->getFile()->getFilename());
$tmpfname = tempnam(sys_get_temp_dir(), 'DOC_TEMPLATE');
file_put_contents($tmpfname, file_get_contents($getUrlGen->url));
$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 ($dataDecrypted === FALSE) {
throw new \Exception("Error during Decrypt ", 1);
}
$tmpfnameDeCrypted = tempnam($this->kernel->getCacheDir(), 'DECRYPT_DOC_TEMPLATE'); // plus ou moins
if (!$handle = fopen($tmpfnameDeCrypted, 'a')) {
echo "Cannot open file ($tmpfnameDeCrypted)";
exit;
}
if (fwrite($handle, $dataDecrypted) === FALSE) {
echo "Cannot write to file ($tmpfnameDeCrypted)";
exit;
}
dump("Success, wrote ($dataDecrypted) to file ($tmpfnameDeCrypted)");
fclose($handle);
$entity = $this->getDoctrine()->getRepository($entityClassName)->find($entityId);
@ -72,10 +118,10 @@ class DocGeneratorTemplateController extends AbstractController
$context = new HouseholdMemberSelectionContext();
$datas = $context->getData($entity);
} else {
throw new Exception('Not implemented', 1);
throw new \Exception('Not implemented', 1);
}
$templateProcessor = new TemplateProcessor($tmpfname);
$templateProcessor = new TemplateProcessor($tmpfnameDeCrypted);
foreach ($datas['setValues'] as $setValuesConf) {
$templateProcessor->setValues($setValuesConf);
@ -85,12 +131,10 @@ class DocGeneratorTemplateController extends AbstractController
$templateProcessor->cloneRowAndSetValues($cloneRowAndSetValues[0], $cloneRowAndSetValues[1]);
}
$tmpfname2 = tempnam(sys_get_temp_dir(), 'DOC_GENERATED');
$templateProcessor->saveAs($tmpfname2);
$tmpfnameGenerated = tempnam($this->kernel->getCacheDir(), 'DOC_GENERATED');
$templateProcessor->saveAs($tmpfnameGenerated);
unlink($tmpfname);
$fileContent = fopen($tmpfname2, 'rb'); // the generated file content
$fileContent = fopen($tmpfnameGenerated, 'rb'); // the generated file content
$genDocName = 'doc_' . sprintf('%010d', mt_rand()) . '.docx';
@ -99,7 +143,8 @@ class DocGeneratorTemplateController extends AbstractController
$genDocName
);
unlink($tmpfname2);
unlink($tmpfnameDeCrypted);
unlink($tmpfnameGenerated);
$client = new Client();

View File

@ -14,8 +14,8 @@ namespace Chill\DocGeneratorBundle\DataFixtures\ORM;
use Chill\DocGeneratorBundle\Entity\DocGeneratorTemplate;
use Chill\PersonBundle\Entity\AccompanyingPeriod\AccompanyingPeriodWorkEvaluation;
use Doctrine\Common\DataFixtures\AbstractFixture;
use Doctrine\Persistence\ObjectManager;
use Chill\DocStoreBundle\Entity\StoredObject;
/**
* Load DocGeneratorTemplate.
@ -28,13 +28,23 @@ class LoadDocGeneratorTemplate extends AbstractFixture
[
'name' => ['fr' => 'FORMULAIRE AEB'],
'desc' => 'stocké sur openstack comedienbe',
'file' => 'FORMULAIRE_AEB_WITH_DATA_INJ.docx',
'file' => [
'filename' => 'pKNlhCrQDCRsAuC8vYHDKa',
'key' => '{"alg":"A256CBC","ext":true,"k":"_VihnD41-VDHlpS-ouwtbMPnu-OXVdtA7ENQWWtAQYM","key_ops":["encrypt","decrypt"],"kty":"oct"}',
'iv' => '[86,231,83,148,117,107,149,173,130,19,105,194,224,145,8,48]',
'type' => 'application/vnd.openxmlformats-officedocument.wordprocessingml.document'
],
'context' => 'Chill\DocGeneratorBundle\Context\HouseholdMemberSelectionContext',
'entities' => [AccompanyingPeriodWorkEvaluation::class],
], [
'name' => ['fr' => 'AIDE ALIMENTAIRE'],
'desc' => 'stocké sur openstack comedienbe',
'file' => 'AIDE_ALIMENTAIRE.docx',
'file' => [
'filename' => 'pKNlhCrQDCRsAuC8vYHDKa',
'key' => '{"alg":"A256CBC","ext":true,"k":"_VihnD41-VDHlpS-ouwtbMPnu-OXVdtA7ENQWWtAQYM","key_ops":["encrypt","decrypt"],"kty":"oct"}',
'iv' => '[86,231,83,148,117,107,149,173,130,19,105,194,224,145,8,48]',
'type' => 'application/vnd.openxmlformats-officedocument.wordprocessingml.document'
],
'context' => 'Chill\DocGeneratorBundle\Context\HouseholdMemberSelectionContext',
'entities' => ['Chill\PersonBundle\Entity\AccompanyingPeriod', 'Chill\PersonBundle\Entity\SocialWork\SocialAction', AccompanyingPeriodWorkEvaluation::class],
],
@ -43,10 +53,19 @@ class LoadDocGeneratorTemplate extends AbstractFixture
foreach ($templates as $template) {
echo 'Adding doc generator templates ' . $template['file'] . ")\n";
$newStoredObj = (new StoredObject())
->setFilename($template['file']['filename'])
->setKeyInfos(json_decode($template['file']['key'], true))
->setIv(json_decode($template['file']['iv'], true))
->setCreationDate(new \DateTime('today'))
->setType($template['file']['type']);
$manager->persist($newStoredObj);
$newTemplate = (new DocGeneratorTemplate())
->setName($template['name'])
->setDescription($template['desc'])
->setFile($template['file'])
->setFile($newStoredObj)
->setContext($template['context'])
->setEntities($template['entities']);

View File

@ -13,6 +13,7 @@ namespace Chill\DocGeneratorBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Serializer\Annotation as Serializer;
use Chill\DocStoreBundle\Entity\StoredObject;
/**
* @ORM\Entity
@ -50,9 +51,9 @@ class DocGeneratorTemplate
private array $entities = [];
/**
* @ORM\Column(type="string", length=255)
* @ORM\ManyToOne(targetEntity=StoredObject::class, cascade={"persist"}).)
*/
private string $file;
private ?StoredObject $file = null;
/**
* @ORM\Id
@ -62,6 +63,7 @@ class DocGeneratorTemplate
*/
private int $id;
/**
* @ORM\Column(type="json")
* @Serializer\Groups({"read"})
@ -83,7 +85,7 @@ class DocGeneratorTemplate
return $this->entities;
}
public function getFile(): ?string
public function getFile(): ?StoredObject
{
return $this->file;
}
@ -98,6 +100,7 @@ class DocGeneratorTemplate
return $this->name;
}
public function setContext(string $context): self
{
$this->context = $context;
@ -119,7 +122,7 @@ class DocGeneratorTemplate
return $this;
}
public function setFile(string $file): self
public function setFile(StoredObject $file): self
{
$this->file = $file;

View File

@ -14,8 +14,12 @@ namespace Chill\DocGeneratorBundle\Form;
use Chill\DocGeneratorBundle\Entity\DocGeneratorTemplate;
use Chill\MainBundle\Form\Type\TranslatableStringFormType;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Chill\DocStoreBundle\Form\StoredObjectType;
use Chill\PersonBundle\Entity\AccompanyingPeriod\AccompanyingPeriodWorkEvaluation;
use Chill\MainBundle\Form\Type\TranslatableStringFormType;
class DocGeneratorTemplateType extends AbstractType
{
@ -25,8 +29,19 @@ class DocGeneratorTemplateType extends AbstractType
->add('name', TranslatableStringFormType::class, [
'label' => 'Nom',
])
->add('context')
->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');
->add('file', StoredObjectType::class, [
'error_bubbling' => true
])
;
}
public function configureOptions(OptionsResolver $resolver)

View File

@ -10,3 +10,12 @@
{% block content_form_actions_save_and_show %}{% endblock %}
{% endembed %}
{% endblock %}
{% block js %}
{{ parent() }}
{{ encore_entry_script_tags('mod_async_upload') }}
{% endblock %}
{% block css %}
{{ encore_entry_link_tags('mod_async_upload') }}
{% endblock %}

View File

@ -5,7 +5,7 @@
{% block table_entities_thead_tr %}
<th></th>
<th>{{ 'Title'|trans }}</th>
<th>{{ 'File'|trans }}</th>
<th>{{ 'Edit'|trans }}</th>
{% endblock %}
{% block table_entities_tbody %}
@ -13,7 +13,11 @@
<tr>
<td>{{ entity.id }}</td>
<td>{{ entity.name | localize_translatable_string }}</td>
<td>{{ entity.file }}</td>
<td>
<a href="{{ chill_path_add_return_path('chill_crud_docgen_template_edit', { 'id': entity.id }) }}" class="btn btn-edit">
{{ 'Edit'|trans }}
</a>
</td>
</tr>
{% endfor %}
{% endblock %}

View File

@ -9,3 +9,12 @@
{% block content_form_actions_save_and_show %}{% endblock %}
{% endembed %}
{% endblock %}
{% block js %}
{{ parent() }}
{{ encore_entry_script_tags('mod_async_upload') }}
{% endblock %}
{% block css %}
{{ encore_entry_link_tags('mod_async_upload') }}
{% endblock %}

View File

@ -15,3 +15,8 @@ services:
resource: '../Serializer/Normalizer/'
tags:
- { name: 'serializer.normalizer', priority: -152 }
Chill\DocGeneratorBundle\Controller\:
resource: "../Controller"
autowire: true
autoconfigure: true

View File

@ -0,0 +1,39 @@
<?php
declare(strict_types=1);
namespace Chill\Migrations\DocGenerator;
use Doctrine\DBAL\Schema\Schema;
use Doctrine\Migrations\AbstractMigration;
/**
* Using DocStore objects inside the DocGenTemplate
*/
final class Version20211103111010 extends AbstractMigration
{
public function getDescription(): string
{
return 'Using DocStore objects inside the DocGenTemplate';
}
public function up(Schema $schema): void
{
$this->addSql('ALTER TABLE chill_docgen_template ADD file_id INT DEFAULT NULL');
$this->addSql('ALTER TABLE chill_docgen_template DROP file');
$this->addSql('ALTER TABLE chill_docgen_template ALTER entities SET NOT NULL');
$this->addSql('ALTER TABLE chill_docgen_template ALTER context SET NOT NULL');
$this->addSql('ALTER TABLE chill_docgen_template ADD CONSTRAINT FK_49A347E893CB796C FOREIGN KEY (file_id) REFERENCES chill_doc.stored_object (id) NOT DEFERRABLE INITIALLY IMMEDIATE');
$this->addSql('CREATE INDEX IDX_49A347E893CB796C ON chill_docgen_template (file_id)');
}
public function down(Schema $schema): void
{
$this->addSql('ALTER TABLE chill_docgen_template DROP CONSTRAINT FK_49A347E893CB796C');
$this->addSql('DROP INDEX IDX_49A347E893CB796C');
$this->addSql('ALTER TABLE chill_docgen_template ADD file VARCHAR(255) NOT NULL');
$this->addSql('ALTER TABLE chill_docgen_template DROP file_id');
$this->addSql('ALTER TABLE chill_docgen_template ALTER entities DROP NOT NULL');
$this->addSql('ALTER TABLE chill_docgen_template ALTER context DROP NOT NULL');
}
}