mirror of
https://gitlab.com/Chill-Projet/chill-bundles.git
synced 2025-06-07 18:44:08 +00:00
generate document with relatorio: config and driver
This commit is contained in:
parent
475b40e896
commit
2245f83631
@ -16,6 +16,7 @@ use ChampsLibres\AsyncUploaderBundle\TempUrl\TempUrlGeneratorInterface;
|
||||
use Chill\DocGeneratorBundle\Context\ContextManager;
|
||||
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;
|
||||
@ -54,17 +55,22 @@ final class DocGeneratorTemplateController extends AbstractController
|
||||
|
||||
private TempUrlGeneratorInterface $tempUrlGenerator;
|
||||
|
||||
private DriverInterface $driver;
|
||||
|
||||
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;
|
||||
@ -134,71 +140,41 @@ final class DocGeneratorTemplateController extends AbstractController
|
||||
throw new \Exception('Error during Decrypt ', 1);
|
||||
}
|
||||
|
||||
$tmpfnameDeCrypted = tempnam($this->kernel->getCacheDir(), 'DECRYPT_DOC_TEMPLATE'); // plus ou moins
|
||||
|
||||
if (!$handle = fopen($tmpfnameDeCrypted, 'ab')) {
|
||||
$this->logger->error("Cannot open file ({$tmpfnameDeCrypted})");
|
||||
if (false === $templateResource = fopen('php://memory', 'r+')) {
|
||||
$this->logger->error("Could not write data to memory");
|
||||
|
||||
throw new HttpException(500);
|
||||
}
|
||||
|
||||
if (false === $ftemplate = fwrite($handle, $dataDecrypted)) {
|
||||
$this->logger->error("Cannot write to file ({$tmpfnameDeCrypted})");
|
||||
|
||||
throw new HttpException(500);
|
||||
}
|
||||
|
||||
dump("Success, wrote (to file ({$tmpfnameDeCrypted})");
|
||||
|
||||
fclose($handle);
|
||||
fwrite($templateResource, $dataDecrypted);
|
||||
rewind($templateResource);
|
||||
|
||||
$datas = $context->getData($template, $entity, $contextGenerationData);
|
||||
dump('datas compiled', $datas);
|
||||
|
||||
dump('process the data', $datas);
|
||||
$generatedResource = $this->driver->generateFromResource($templateResource, $template->getFile()->getType(), $datas, $template->getFile()->getFilename());
|
||||
|
||||
/*
|
||||
$templateProcessor = new TemplateProcessor($tmpfnameDeCrypted);
|
||||
fclose($templateResource);
|
||||
|
||||
foreach ($datas['setValues'] as $setValuesConf) {
|
||||
$templateProcessor->setValues($setValuesConf);
|
||||
}
|
||||
|
||||
foreach ($datas['cloneRowAndSetValues'] as $cloneRowAndSetValues) {
|
||||
$templateProcessor->cloneRowAndSetValues($cloneRowAndSetValues[0], $cloneRowAndSetValues[1]);
|
||||
}
|
||||
$tmpfnameGenerated = tempnam($this->kernel->getCacheDir(), 'DOC_GENERATED');
|
||||
|
||||
$fileContent = fopen($tmpfnameGenerated, 'rb'); // the generated file content
|
||||
*/
|
||||
|
||||
$genDocName = 'doc_' . sprintf('%010d', mt_rand()) . '.docx';
|
||||
$genDocName = 'doc_' . sprintf('%010d', mt_rand()).'odt';
|
||||
|
||||
$getUrlGen = $this->tempUrlGenerator->generate(
|
||||
'PUT',
|
||||
$genDocName
|
||||
);
|
||||
|
||||
unlink($tmpfnameDeCrypted);
|
||||
//unlink($tmpfnameGenerated);
|
||||
|
||||
$client = new Client();
|
||||
|
||||
try {
|
||||
/*
|
||||
$putResponse = $client->request('PUT', $getUrlGen->url, [
|
||||
'body' => $fileContent,
|
||||
]);
|
||||
*/
|
||||
$putResponse = $client->request('PUT', $getUrlGen->url, [
|
||||
'body' => $ftemplate,
|
||||
'body' => $generatedResource,
|
||||
]);
|
||||
|
||||
if ($putResponse->getStatusCode() === 201) {
|
||||
$em = $this->getDoctrine()->getManager();
|
||||
$storedObject = new StoredObject();
|
||||
$storedObject
|
||||
// currently, only docx is supported
|
||||
->setType('application/vnd.openxmlformats-officedocument.wordprocessingml.document')
|
||||
->setType($template->getFile()->getType())
|
||||
->setFilename($genDocName);
|
||||
|
||||
$em->persist($storedObject);
|
||||
|
@ -26,6 +26,10 @@ class ChillDocGeneratorExtension extends Extension implements PrependExtensionIn
|
||||
{
|
||||
public function load(array $configs, ContainerBuilder $container)
|
||||
{
|
||||
$configuration = new Configuration();
|
||||
$config = $this->processConfiguration($configuration, $configs);
|
||||
$container->setParameter('chill_doc_generator', $config);
|
||||
|
||||
$loader = new Loader\YamlFileLoader($container, new FileLocator(__DIR__ . '/../config'));
|
||||
$loader->load('services.yaml');
|
||||
$loader->load('services/controller.yaml');
|
||||
@ -37,6 +41,26 @@ class ChillDocGeneratorExtension extends Extension implements PrependExtensionIn
|
||||
{
|
||||
$this->preprendRoutes($container);
|
||||
$this->prependCruds($container);
|
||||
$this->prependClientConfig($container);
|
||||
}
|
||||
|
||||
private function prependClientConfig(ContainerBuilder $container)
|
||||
{
|
||||
$configs = $container->getExtensionConfig($this->getAlias());
|
||||
$resolvingBag = $container->getParameterBag();
|
||||
$configs = $resolvingBag->resolveValue($configs);
|
||||
|
||||
$config = $this->processConfiguration(new Configuration(), $configs);
|
||||
|
||||
$container->prependExtensionConfig('framework', [
|
||||
'http_client' => [
|
||||
'scoped_clients' => [
|
||||
'relatorio.client' => [
|
||||
'scope' => $config['driver']['relatorio']['url'],
|
||||
]
|
||||
]
|
||||
]
|
||||
]);
|
||||
}
|
||||
|
||||
protected function prependCruds(ContainerBuilder $container)
|
||||
|
@ -14,21 +14,36 @@ namespace Chill\DocGeneratorBundle\DependencyInjection;
|
||||
use Symfony\Component\Config\Definition\Builder\TreeBuilder;
|
||||
use Symfony\Component\Config\Definition\ConfigurationInterface;
|
||||
|
||||
/**
|
||||
* This is the class that validates and merges configuration from your app/config files.
|
||||
*
|
||||
* To learn more see {@link http://symfony.com/doc/current/cookbook/bundles/configuration.html}
|
||||
*/
|
||||
class Configuration implements ConfigurationInterface
|
||||
{
|
||||
public function getConfigTreeBuilder()
|
||||
{
|
||||
$treeBuilder = new TreeBuilder('chill_calendar');
|
||||
$rootNode = $treeBuilder->getRootNode('chill_calendar');
|
||||
$treeBuilder = new TreeBuilder('chill_doc_generator');
|
||||
$rootNode = $treeBuilder->getRootNode();
|
||||
|
||||
// Here you should define the parameters that are allowed to
|
||||
// configure your bundle. See the documentation linked above for
|
||||
// more information on that topic.
|
||||
$rootNode
|
||||
->children()
|
||||
->arrayNode('driver')
|
||||
->addDefaultsIfNotSet()
|
||||
->children()
|
||||
->enumNode('type')
|
||||
->isRequired()
|
||||
->values(['relatorio'])
|
||||
->defaultValue('relatorio')
|
||||
->end()
|
||||
->arrayNode('relatorio')
|
||||
->addDefaultsIfNotSet()
|
||||
->children()
|
||||
->scalarNode('url')
|
||||
->isRequired()
|
||||
->defaultValue('http://relatorio:8888/')
|
||||
->end()
|
||||
->end()
|
||||
->end()
|
||||
->end()
|
||||
->end()
|
||||
->end()
|
||||
;
|
||||
|
||||
return $treeBuilder;
|
||||
}
|
||||
|
@ -0,0 +1,12 @@
|
||||
<?php
|
||||
|
||||
namespace Chill\DocGeneratorBundle\GeneratorDriver;
|
||||
|
||||
interface DriverInterface
|
||||
{
|
||||
/**
|
||||
* @param resource $template
|
||||
* @return resource
|
||||
*/
|
||||
public function generateFromResource($template, string $resourceType, array $data, string $templateName = null);
|
||||
}
|
@ -0,0 +1,73 @@
|
||||
<?php
|
||||
|
||||
namespace Chill\DocGeneratorBundle\GeneratorDriver;
|
||||
|
||||
use Nelmio\Alice\ParameterBag;
|
||||
use Psr\Log\LoggerInterface;
|
||||
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
|
||||
use Symfony\Component\HttpClient\Exception\TransportException;
|
||||
use Symfony\Component\Mime\Part\DataPart;
|
||||
use Symfony\Component\Mime\Part\Multipart\FormDataPart;
|
||||
use Symfony\Contracts\HttpClient\Exception\DecodingExceptionInterface;
|
||||
use Symfony\Contracts\HttpClient\Exception\HttpExceptionInterface;
|
||||
use Symfony\Contracts\HttpClient\Exception\TransportExceptionInterface;
|
||||
use Symfony\Contracts\HttpClient\HttpClientInterface;
|
||||
|
||||
class RelatorioDriver implements DriverInterface
|
||||
{
|
||||
private LoggerInterface $logger;
|
||||
|
||||
private HttpClientInterface $relatorioClient;
|
||||
|
||||
private string $url;
|
||||
|
||||
public function __construct(
|
||||
HttpClientInterface $relatorioClient,
|
||||
ParameterBagInterface $parameterBag,
|
||||
LoggerInterface $logger
|
||||
) {
|
||||
$this->relatorioClient = $relatorioClient;
|
||||
$this->logger = $logger;
|
||||
$this->url = $parameterBag->get('chill_doc_generator')['driver']['relatorio']['url'];
|
||||
}
|
||||
|
||||
public function generateFromResource($template, string $resourceType, array $data, string $templateName = null)
|
||||
{
|
||||
$formFields = [
|
||||
'variables' => \json_encode($data),
|
||||
'template' => new DataPart($template, $templateName ?? uniqid('template_'), $resourceType),
|
||||
];
|
||||
$form = new FormDataPart($formFields);
|
||||
|
||||
try {
|
||||
$response = $this->relatorioClient->request('POST', $this->url, [
|
||||
'headers' => $form->getPreparedHeaders()->toArray(),
|
||||
'body' => $form->bodyToIterable(),
|
||||
]);
|
||||
|
||||
return $response->toStream();
|
||||
} catch (HttpExceptionInterface $e) {
|
||||
$this->logger->error("relatorio: error while generating document", [
|
||||
'msg' => $e->getMessage(),
|
||||
'response' => $e->getResponse()->getStatusCode(),
|
||||
'content' => $e->getResponse()->getContent(false),
|
||||
]);
|
||||
|
||||
throw $e;
|
||||
} catch (TransportExceptionInterface $e) {
|
||||
$this->logger->error("relatorio: transport exception", [
|
||||
'msg' => $e->getMessage(),
|
||||
'e' => $e->getTraceAsString(),
|
||||
]);
|
||||
|
||||
throw $e;
|
||||
} catch (DecodingExceptionInterface $e) {
|
||||
$this->logger->error("relatorio: could not decode response", [
|
||||
'msg' => $e->getMessage(),
|
||||
'e' => $e->getTraceAsString(),
|
||||
]);
|
||||
|
||||
throw $e;
|
||||
}
|
||||
}
|
||||
}
|
@ -26,6 +26,13 @@ services:
|
||||
autowire: true
|
||||
autoconfigure: true
|
||||
|
||||
Chill\DocGeneratorBundle\GeneratorDriver\:
|
||||
resource: "../GeneratorDriver/"
|
||||
autowire: true
|
||||
autoconfigure: true
|
||||
|
||||
Chill\DocGeneratorBundle\Driver\RelatorioDriver: '@Chill\DocGeneratorBundle\Driver\DriverInterface'
|
||||
|
||||
Chill\DocGeneratorBundle\Context\ContextManager:
|
||||
arguments:
|
||||
$contexts: !tagged_iterator { tag: chill_docgen.context, default_index_method: getKey }
|
||||
|
@ -5,7 +5,7 @@ var algo = 'AES-CBC';
|
||||
var initializeButtons = (root) => {
|
||||
var
|
||||
buttons = root.querySelectorAll('a[data-download-button]');
|
||||
|
||||
|
||||
for (let i = 0; i < buttons.length; i ++) {
|
||||
initialize(buttons[i]);
|
||||
}
|
||||
@ -33,9 +33,12 @@ var download = (button) => {
|
||||
fetchError = "Error while fetching file",
|
||||
key, url
|
||||
;
|
||||
|
||||
|
||||
console.log('keyData', keyData);
|
||||
console.log('ivData', ivData);
|
||||
|
||||
button.textContent = labelPreparing;
|
||||
|
||||
|
||||
window.fetch(urlGenerator)
|
||||
.then((r) => {
|
||||
if (r.ok) {
|
||||
@ -46,26 +49,19 @@ var download = (button) => {
|
||||
})
|
||||
.then(data => {
|
||||
url = data.url;
|
||||
|
||||
return window.crypto.subtle.importKey('jwk', keyData, { name: algo, iv: iv}, false, ['decrypt']);
|
||||
})
|
||||
.catch(e => {
|
||||
console.error("error while importing key");
|
||||
console.error(e);
|
||||
button.appendChild(document.createTextNode(decryptError));
|
||||
|
||||
if (keyData.length > 0) {
|
||||
return window.crypto.subtle.importKey('jwk', keyData, { name: algo, iv: iv}, false, ['decrypt']);
|
||||
}
|
||||
return Promise.resolve(undefined);
|
||||
})
|
||||
.then(nKey => {
|
||||
key = nKey;
|
||||
|
||||
return window.fetch(url);
|
||||
})
|
||||
.catch(e => {
|
||||
console.error("error while fetching data");
|
||||
console.error(e);
|
||||
button.textContent = "";
|
||||
button.appendChild(document.createTextNode(fetchError));
|
||||
})
|
||||
.then(r => {
|
||||
console.log('r', r);
|
||||
if (r.ok) {
|
||||
return r.arrayBuffer();
|
||||
} else {
|
||||
@ -73,16 +69,16 @@ var download = (button) => {
|
||||
}
|
||||
})
|
||||
.then(buffer => {
|
||||
return window.crypto.subtle.decrypt({ name: algo, iv: iv }, key, buffer);
|
||||
})
|
||||
.catch(e => {
|
||||
console.error("error while importing key");
|
||||
console.error(e);
|
||||
button.textContent = "";
|
||||
button.appendChild(document.createTextNode(decryptError));
|
||||
console.log('buffer', buffer);
|
||||
if (keyData.length > 0) {
|
||||
return window.crypto.subtle.decrypt({ name: algo, iv: iv }, key, buffer);
|
||||
}
|
||||
|
||||
return Promise.resolve(buffer);
|
||||
})
|
||||
.then(decrypted => {
|
||||
var
|
||||
console.log('decrypted', decrypted);
|
||||
var
|
||||
blob = new Blob([decrypted], { type: mimeType }),
|
||||
url = window.URL.createObjectURL(blob)
|
||||
;
|
||||
|
Loading…
x
Reference in New Issue
Block a user