mirror of
https://gitlab.com/Chill-Projet/chill-bundles.git
synced 2025-06-12 13:24:25 +00:00
refactor: Use StoredObjectManager
.
This commit is contained in:
parent
62af980ea5
commit
35d723e5fb
@ -11,8 +11,6 @@ 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;
|
||||
@ -21,11 +19,11 @@ use Chill\DocGeneratorBundle\GeneratorDriver\DriverInterface;
|
||||
use Chill\DocGeneratorBundle\GeneratorDriver\Exception\TemplateException;
|
||||
use Chill\DocGeneratorBundle\Repository\DocGeneratorTemplateRepository;
|
||||
use Chill\DocStoreBundle\Entity\StoredObject;
|
||||
use Chill\DocStoreBundle\Service\StoredObjectManagerInterface;
|
||||
use Chill\MainBundle\Pagination\PaginatorFactory;
|
||||
use Chill\MainBundle\Serializer\Model\Collection;
|
||||
use Doctrine\ORM\EntityManagerInterface;
|
||||
use Exception;
|
||||
use GuzzleHttp\Client;
|
||||
use GuzzleHttp\Exception\TransferException;
|
||||
use Psr\Log\LoggerInterface;
|
||||
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
||||
use Symfony\Component\Form\Extension\Core\Type\FileType;
|
||||
@ -34,14 +32,14 @@ use Symfony\Component\HttpFoundation\RedirectResponse;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
// TODO à mettre dans services
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
use Symfony\Component\HttpFoundation\StreamedResponse;
|
||||
use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;
|
||||
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\Component\Serializer\Normalizer\ObjectNormalizer;
|
||||
use Symfony\Contracts\HttpClient\HttpClientInterface;
|
||||
use Throwable;
|
||||
use function strlen;
|
||||
|
||||
final class DocGeneratorTemplateController extends AbstractController
|
||||
{
|
||||
@ -53,13 +51,13 @@ final class DocGeneratorTemplateController extends AbstractController
|
||||
|
||||
private DriverInterface $driver;
|
||||
|
||||
private KernelInterface $kernel;
|
||||
private EntityManagerInterface $entityManager;
|
||||
|
||||
private LoggerInterface $logger;
|
||||
|
||||
private PaginatorFactory $paginatorFactory;
|
||||
|
||||
private TempUrlGeneratorInterface $tempUrlGenerator;
|
||||
private StoredObjectManagerInterface $storedObjectManager;
|
||||
|
||||
public function __construct(
|
||||
ContextManager $contextManager,
|
||||
@ -67,18 +65,18 @@ final class DocGeneratorTemplateController extends AbstractController
|
||||
DriverInterface $driver,
|
||||
LoggerInterface $logger,
|
||||
PaginatorFactory $paginatorFactory,
|
||||
TempUrlGeneratorInterface $tempUrlGenerator,
|
||||
KernelInterface $kernel,
|
||||
HttpClientInterface $client
|
||||
HttpClientInterface $client,
|
||||
StoredObjectManagerInterface $storedObjectManager,
|
||||
EntityManagerInterface $entityManager
|
||||
) {
|
||||
$this->contextManager = $contextManager;
|
||||
$this->docGeneratorTemplateRepository = $docGeneratorTemplateRepository;
|
||||
$this->driver = $driver;
|
||||
$this->logger = $logger;
|
||||
$this->paginatorFactory = $paginatorFactory;
|
||||
$this->tempUrlGenerator = $tempUrlGenerator;
|
||||
$this->kernel = $kernel;
|
||||
$this->client = $client;
|
||||
$this->storedObjectManager = $storedObjectManager;
|
||||
$this->entityManager = $entityManager;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -177,8 +175,10 @@ final class DocGeneratorTemplateController extends AbstractController
|
||||
|
||||
return $this->redirectToRoute(
|
||||
'chill_docgenerator_test_generate_from_template',
|
||||
['template' => $template, 'entityClassName' => $entityClassName, 'entityId' => $entityId,
|
||||
'returnPath' => $request->query->get('returnPath', '/'), ]
|
||||
[
|
||||
'template' => $template, 'entityClassName' => $entityClassName, 'entityId' => $entityId,
|
||||
'returnPath' => $request->query->get('returnPath', '/'),
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
@ -192,16 +192,26 @@ final class DocGeneratorTemplateController extends AbstractController
|
||||
try {
|
||||
$context = $this->contextManager->getContextByDocGeneratorTemplate($template);
|
||||
} catch (ContextNotFoundException $e) {
|
||||
throw new NotFoundHttpException($e->getMessage(), $e);
|
||||
throw new NotFoundHttpException(
|
||||
'Context not found.',
|
||||
$e
|
||||
);
|
||||
}
|
||||
|
||||
$entity = $this->getDoctrine()->getRepository($context->getEntityClass())->find($entityId);
|
||||
$entity = $this
|
||||
->entityManager
|
||||
->getRepository($context->getEntityClass())
|
||||
->find($entityId);
|
||||
|
||||
if (null === $entity) {
|
||||
throw new NotFoundHttpException("Entity with classname {$entityClassName} and id {$entityId} is not found");
|
||||
throw new NotFoundHttpException(
|
||||
sprintf('Entity with classname %s and id %s is not found', $entityClassName, $entityId)
|
||||
);
|
||||
}
|
||||
|
||||
$contextGenerationData = [];
|
||||
$contextGenerationData = [
|
||||
'test_file' => null,
|
||||
];
|
||||
|
||||
if (
|
||||
$context instanceof DocGeneratorContextWithPublicFormInterface
|
||||
@ -235,123 +245,109 @@ final class DocGeneratorTemplateController extends AbstractController
|
||||
$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, ];
|
||||
$templateOptions = [
|
||||
'entity' => $entity, 'form' => $form->createView(),
|
||||
'template' => $template, 'context' => $context,
|
||||
];
|
||||
|
||||
return $this->render($templatePath, $templateOptions);
|
||||
}
|
||||
}
|
||||
|
||||
if ($isTest && null !== $contextGenerationData['test_file']) {
|
||||
/** @var File $file */
|
||||
$file = $contextGenerationData['test_file'];
|
||||
$templateResource = fopen($file->getPathname(), 'rb');
|
||||
$document = $template->getFile();
|
||||
|
||||
if ($isTest && ($contextGenerationData['test_file'] instanceof File)) {
|
||||
$dataDecrypted = file_get_contents($contextGenerationData['test_file']->getPathname());
|
||||
} else {
|
||||
$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);
|
||||
try {
|
||||
$dataDecrypted = $this->storedObjectManager->read($document);
|
||||
} catch (Throwable $exception) {
|
||||
throw $exception;
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
try {
|
||||
$generatedResource = $this->driver->generateFromResource($templateResource, $template->getFile()->getType(), $datas, $template->getFile()->getFilename());
|
||||
$generatedResource = $this
|
||||
->driver
|
||||
->generateFromString(
|
||||
$dataDecrypted,
|
||||
$template->getFile()->getType(),
|
||||
$context->getData($template, $entity, $contextGenerationData),
|
||||
$template->getFile()->getFilename()
|
||||
);
|
||||
} catch (TemplateException $e) {
|
||||
$msg = implode("\n", $e->getErrors());
|
||||
|
||||
return new Response($msg, 400, [
|
||||
'Content-Type' => 'text/plain',
|
||||
]);
|
||||
return new Response(
|
||||
implode("\n", $e->getErrors()),
|
||||
400,
|
||||
[
|
||||
'Content-Type' => 'text/plain',
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
fclose($templateResource);
|
||||
|
||||
if ($isTest) {
|
||||
return new StreamedResponse(
|
||||
static function () use ($generatedResource) {
|
||||
fpassthru($generatedResource);
|
||||
fclose($generatedResource);
|
||||
},
|
||||
return new Response(
|
||||
$generatedResource,
|
||||
Response::HTTP_OK,
|
||||
[
|
||||
'Content-Transfer-Encoding', 'binary',
|
||||
'Content-Type' => 'application/vnd.oasis.opendocument.text',
|
||||
'Content-Disposition' => sprintf('attachment; filename="%s.odt"', 'generated'),
|
||||
'Content-Length' => fstat($generatedResource)['size'],
|
||||
'Content-Disposition' => 'attachment; filename="generated.odt"',
|
||||
'Content-Length' => strlen($generatedResource),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
$genDocName = 'doc_' . sprintf('%010d', mt_rand()) . 'odt';
|
||||
|
||||
$getUrlGen = $this->tempUrlGenerator->generate(
|
||||
'PUT',
|
||||
$genDocName
|
||||
);
|
||||
|
||||
$client = new Client();
|
||||
/** @var StoredObject $storedObject */
|
||||
$storedObject = (new ObjectNormalizer())
|
||||
->denormalize(
|
||||
[
|
||||
'type' => $template->getFile()->getType(),
|
||||
'filename' => sprintf('%s_odt', uniqid('doc_', true)),
|
||||
],
|
||||
StoredObject::class
|
||||
);
|
||||
|
||||
try {
|
||||
$putResponse = $client->request('PUT', $getUrlGen->url, [
|
||||
'body' => $generatedResource,
|
||||
]);
|
||||
$this->storedObjectManager->write($storedObject, $generatedResource);
|
||||
} catch (Throwable $exception) {
|
||||
throw $exception;
|
||||
}
|
||||
|
||||
if ($putResponse->getStatusCode() === 201) {
|
||||
$em = $this->getDoctrine()->getManager();
|
||||
$storedObject = new StoredObject();
|
||||
$storedObject
|
||||
->setType($template->getFile()->getType())
|
||||
->setFilename($genDocName);
|
||||
$this->entityManager->persist($storedObject);
|
||||
|
||||
$em->persist($storedObject);
|
||||
|
||||
try {
|
||||
$context->storeGenerated($template, $storedObject, $entity, $contextGenerationData);
|
||||
} catch (Exception $e) {
|
||||
$this->logger->error('Could not store the associated document to entity', [
|
||||
try {
|
||||
$context
|
||||
->storeGenerated(
|
||||
$template,
|
||||
$storedObject,
|
||||
$entity,
|
||||
$contextGenerationData
|
||||
);
|
||||
} catch (Exception $e) {
|
||||
$this
|
||||
->logger
|
||||
->error(
|
||||
'Unable to 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.');
|
||||
$this->entityManager->flush();
|
||||
|
||||
return $this
|
||||
->redirectToRoute(
|
||||
'chill_wopi_file_edit',
|
||||
[
|
||||
'fileId' => $storedObject->getUuid(),
|
||||
'returnPath' => $request->query->get('returnPath', '/'),
|
||||
]
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -11,12 +11,12 @@ declare(strict_types=1);
|
||||
|
||||
namespace Chill\WopiBundle\Service\Wopi;
|
||||
|
||||
use ChampsLibres\AsyncUploaderBundle\TempUrl\TempUrlGeneratorInterface;
|
||||
use ChampsLibres\WopiLib\Contract\Entity\Document;
|
||||
use ChampsLibres\WopiLib\Contract\Service\DocumentLockManagerInterface;
|
||||
use ChampsLibres\WopiLib\Contract\Service\DocumentManagerInterface;
|
||||
use Chill\DocStoreBundle\Entity\StoredObject;
|
||||
use Chill\DocStoreBundle\Repository\StoredObjectRepository;
|
||||
use Chill\DocStoreBundle\Service\StoredObjectManagerInterface;
|
||||
use DateTimeInterface;
|
||||
use Doctrine\ORM\EntityManagerInterface;
|
||||
use Error;
|
||||
@ -28,8 +28,6 @@ use Symfony\Bridge\PsrHttpMessage\HttpMessageFactoryInterface;
|
||||
use Symfony\Component\HttpFoundation\RequestStack;
|
||||
use Symfony\Component\Mime\MimeTypes;
|
||||
use Symfony\Component\Serializer\Normalizer\ObjectNormalizer;
|
||||
use Symfony\Contracts\HttpClient\HttpClientInterface;
|
||||
use Throwable;
|
||||
|
||||
use function strlen;
|
||||
|
||||
@ -39,33 +37,29 @@ final class ChillDocumentManager implements DocumentManagerInterface
|
||||
|
||||
private EntityManagerInterface $entityManager;
|
||||
|
||||
private HttpClientInterface $httpClient;
|
||||
|
||||
private Psr17Interface $psr17;
|
||||
|
||||
private RequestInterface $request;
|
||||
|
||||
private StoredObjectRepository $storedObjectRepository;
|
||||
|
||||
private TempUrlGeneratorInterface $tempUrlGenerator;
|
||||
private StoredObjectManagerInterface $storedObjectManager;
|
||||
|
||||
public function __construct(
|
||||
DocumentLockManagerInterface $documentLockManager,
|
||||
EntityManagerInterface $entityManager,
|
||||
HttpClientInterface $httpClient,
|
||||
Psr17Interface $psr17,
|
||||
StoredObjectRepository $storedObjectRepository,
|
||||
TempUrlGeneratorInterface $tempUrlGenerator,
|
||||
HttpMessageFactoryInterface $httpMessageFactory,
|
||||
RequestStack $requestStack
|
||||
Psr17Interface $psr17,
|
||||
RequestStack $requestStack,
|
||||
StoredObjectManagerInterface $storedObjectManager,
|
||||
StoredObjectRepository $storedObjectRepository
|
||||
) {
|
||||
$this->documentLockManager = $documentLockManager;
|
||||
$this->entityManager = $entityManager;
|
||||
$this->psr17 = $psr17;
|
||||
$this->storedObjectRepository = $storedObjectRepository;
|
||||
$this->documentLockManager = $documentLockManager;
|
||||
$this->tempUrlGenerator = $tempUrlGenerator;
|
||||
$this->httpClient = $httpClient;
|
||||
$this->request = $httpMessageFactory->createRequest($requestStack->getCurrentRequest());
|
||||
$this->storedObjectManager = $storedObjectManager;
|
||||
$this->storedObjectRepository = $storedObjectRepository;
|
||||
}
|
||||
|
||||
public function create(array $data): Document
|
||||
@ -197,18 +191,7 @@ final class ChillDocumentManager implements DocumentManagerInterface
|
||||
|
||||
public function remove(Document $document): void
|
||||
{
|
||||
$entityIsDeleted = false;
|
||||
|
||||
try {
|
||||
$this->entityManager->remove($document);
|
||||
$entityIsDeleted = true;
|
||||
} catch (Throwable $e) {
|
||||
$entityIsDeleted = false;
|
||||
}
|
||||
|
||||
if (true === $entityIsDeleted) {
|
||||
$this->deleteContent($document);
|
||||
}
|
||||
// TODO: To implement when we have a clearer view and API.
|
||||
}
|
||||
|
||||
public function write(Document $document, array $properties = []): void
|
||||
@ -216,42 +199,13 @@ final class ChillDocumentManager implements DocumentManagerInterface
|
||||
$this->setContent($document, $properties['content']);
|
||||
}
|
||||
|
||||
private function deleteContent(StoredObject $storedObject): void
|
||||
{
|
||||
/** @var StdClass $object */
|
||||
$object = $this->tempUrlGenerator->generate('DELETE', $storedObject->getFilename());
|
||||
|
||||
$response = $this->httpClient->request('DELETE', $object->url);
|
||||
|
||||
if (200 !== $response->getStatusCode()) {
|
||||
throw new Error('Unable to delete stored object.');
|
||||
}
|
||||
}
|
||||
|
||||
private function getContent(StoredObject $storedObject): string
|
||||
{
|
||||
/** @var StdClass $object */
|
||||
$object = $this->tempUrlGenerator->generate('GET', $storedObject->getFilename());
|
||||
|
||||
$response = $this->httpClient->request('GET', $object->url);
|
||||
|
||||
if (200 !== $response->getStatusCode()) {
|
||||
throw new Error('Unable to retrieve stored object.');
|
||||
}
|
||||
|
||||
return $response->getContent();
|
||||
return $this->storedObjectManager->read($storedObject);
|
||||
}
|
||||
|
||||
private function setContent(StoredObject $storedObject, string $content): void
|
||||
{
|
||||
// TODO: Add strict typing in champs-libres/async-uploader-bundle
|
||||
/** @var StdClass $object */
|
||||
$object = $this->tempUrlGenerator->generate('PUT', $storedObject->getFilename());
|
||||
|
||||
$response = $this->httpClient->request('PUT', $object->url, ['body' => $content]);
|
||||
|
||||
if (201 !== $response->getStatusCode()) {
|
||||
throw new Error('Unable to save stored object.');
|
||||
}
|
||||
$this->storedObjectManager->write($storedObject, $content);
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user