mirror of
https://gitlab.com/Chill-Projet/chill-bundles.git
synced 2025-06-07 18:44:08 +00:00
Merge remote-tracking branch 'origin/docgenerator_oct_nov_21' into features/docgen-widget-generate-template
This commit is contained in:
commit
0710d6572b
@ -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();
|
||||
|
||||
|
@ -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']);
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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 %}
|
||||
|
@ -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 %}
|
||||
|
@ -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 %}
|
||||
|
@ -15,3 +15,8 @@ services:
|
||||
resource: '../Serializer/Normalizer/'
|
||||
tags:
|
||||
- { name: 'serializer.normalizer', priority: -152 }
|
||||
|
||||
Chill\DocGeneratorBundle\Controller\:
|
||||
resource: "../Controller"
|
||||
autowire: true
|
||||
autoconfigure: true
|
||||
|
@ -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');
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user