From 03fe9a6d863f305d21aff6cea57da5901d65fc05 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Fri, 15 Nov 2024 14:17:26 +0100 Subject: [PATCH] Update Signature App.vue to use a converted pdf Introduced a new helper ts function to download documents as PDFs and integrated with the existing workflow. Enhanced `PDFSignatureZoneAvailable` to implement `LocaleAwareInterface` for better locale management and added PDF conversion handling for non-PDF documents. Updated App.vue to use the new PDF download method. --- .../public/vuejs/DocumentSignature/App.vue | 7 ++--- .../vuejs/StoredObjectButton/helpers.ts | 27 +++++++++++++++++++ .../Signature/PDFSignatureZoneAvailable.php | 27 ++++++++++++++++--- .../PDFSignatureZoneAvailableTest.php | 2 ++ 4 files changed, 55 insertions(+), 8 deletions(-) diff --git a/src/Bundle/ChillDocStoreBundle/Resources/public/vuejs/DocumentSignature/App.vue b/src/Bundle/ChillDocStoreBundle/Resources/public/vuejs/DocumentSignature/App.vue index d10f13a97..b46ecae3a 100644 --- a/src/Bundle/ChillDocStoreBundle/Resources/public/vuejs/DocumentSignature/App.vue +++ b/src/Bundle/ChillDocStoreBundle/Resources/public/vuejs/DocumentSignature/App.vue @@ -277,7 +277,7 @@ console.log(PdfWorker); // incredible but this is needed // pdfjsLib.GlobalWorkerOptions.workerSrc = PdfWorker; import Modal from "ChillMainAssets/vuejs/_components/Modal.vue"; -import { download_and_decrypt_doc } from "../StoredObjectButton/helpers"; +import {download_and_decrypt_doc, download_doc_as_pdf} from "../StoredObjectButton/helpers"; pdfjsLib.GlobalWorkerOptions.workerSrc = "pdfjs-dist/build/pdf.worker.mjs"; @@ -385,10 +385,7 @@ const init = () => downloadAndOpen().then(initPdf); async function downloadAndOpen(): Promise { let raw; try { - raw = await download_and_decrypt_doc( - signature.storedObject, - signature.storedObject.currentVersion - ); + raw = await download_doc_as_pdf(signature.storedObject); } catch (e) { console.error("error while downloading and decrypting document", e); throw e; diff --git a/src/Bundle/ChillDocStoreBundle/Resources/public/vuejs/StoredObjectButton/helpers.ts b/src/Bundle/ChillDocStoreBundle/Resources/public/vuejs/StoredObjectButton/helpers.ts index a5a520597..2fb55f71c 100644 --- a/src/Bundle/ChillDocStoreBundle/Resources/public/vuejs/StoredObjectButton/helpers.ts +++ b/src/Bundle/ChillDocStoreBundle/Resources/public/vuejs/StoredObjectButton/helpers.ts @@ -197,6 +197,32 @@ async function download_and_decrypt_doc(storedObject: StoredObject, atVersion: n } } +/** + * Fetch the stored object as a pdf. + * + * If the document is already in a pdf on the server side, the document is retrieved "as is" from the usual + * storage. + */ +async function download_doc_as_pdf(storedObject: StoredObject): Promise +{ + if (null === storedObject.currentVersion) { + throw new Error("the stored object does not count any version"); + } + + if (storedObject.currentVersion?.type === 'application/pdf') { + return download_and_decrypt_doc(storedObject, storedObject.currentVersion); + } + + const convertLink = build_convert_link(storedObject.uuid); + const response = await fetch(convertLink); + + if (!response.ok) { + throw new Error("Could not convert the document: " + response.status); + } + + return response.blob(); +} + async function is_object_ready(storedObject: StoredObject): Promise { const new_status_response = await window @@ -214,6 +240,7 @@ export { build_wopi_editor_link, download_and_decrypt_doc, download_doc, + download_doc_as_pdf, is_extension_editable, is_extension_viewable, is_object_ready, diff --git a/src/Bundle/ChillDocStoreBundle/Service/Signature/PDFSignatureZoneAvailable.php b/src/Bundle/ChillDocStoreBundle/Service/Signature/PDFSignatureZoneAvailable.php index d4109632a..67fbd89ba 100644 --- a/src/Bundle/ChillDocStoreBundle/Service/Signature/PDFSignatureZoneAvailable.php +++ b/src/Bundle/ChillDocStoreBundle/Service/Signature/PDFSignatureZoneAvailable.php @@ -17,15 +17,30 @@ use Chill\MainBundle\Entity\Workflow\EntityWorkflowSignatureStateEnum; use Chill\MainBundle\Entity\Workflow\EntityWorkflowStep; use Chill\MainBundle\Entity\Workflow\EntityWorkflowStepSignature; use Chill\MainBundle\Workflow\EntityWorkflowManager; +use Chill\WopiBundle\Service\WopiConverter; +use Symfony\Contracts\Translation\LocaleAwareInterface; -class PDFSignatureZoneAvailable +class PDFSignatureZoneAvailable implements LocaleAwareInterface { + private string $locale; + public function __construct( private readonly EntityWorkflowManager $entityWorkflowManager, private readonly PDFSignatureZoneParser $pdfSignatureZoneParser, private readonly StoredObjectManagerInterface $storedObjectManager, + private readonly WopiConverter $converter, ) {} + public function setLocale(string $locale) + { + $this->locale = $locale; + } + + public function getLocale() + { + return $this->locale; + } + /** * @return list */ @@ -38,10 +53,16 @@ class PDFSignatureZoneAvailable } if ('application/pdf' !== $storedObject->getType()) { - throw new \RuntimeException('Only PDF documents are supported'); + $content = $this->converter->convert($this->getLocale(), $this->storedObjectManager->read($storedObject), $storedObject->getType()); + } else { + $content = $this->storedObjectManager->read($storedObject); } - $zones = $this->pdfSignatureZoneParser->findSignatureZones($this->storedObjectManager->read($storedObject)); + $zones = $this->pdfSignatureZoneParser->findSignatureZones($content); + + // free some memory as soon as possible... + unset($content); + $signatureZonesIndexes = array_map( fn (EntityWorkflowStepSignature $step) => $step->getZoneSignatureIndex(), $this->collectSignaturesInUse($entityWorkflow) diff --git a/src/Bundle/ChillDocStoreBundle/Tests/Service/Signature/PDFSignatureZoneAvailableTest.php b/src/Bundle/ChillDocStoreBundle/Tests/Service/Signature/PDFSignatureZoneAvailableTest.php index ecc96bf89..ab4157936 100644 --- a/src/Bundle/ChillDocStoreBundle/Tests/Service/Signature/PDFSignatureZoneAvailableTest.php +++ b/src/Bundle/ChillDocStoreBundle/Tests/Service/Signature/PDFSignatureZoneAvailableTest.php @@ -22,6 +22,7 @@ use Chill\MainBundle\Entity\Workflow\EntityWorkflowSignatureStateEnum; use Chill\MainBundle\Workflow\EntityWorkflowManager; use Chill\MainBundle\Workflow\WorkflowTransitionContextDTO; use Chill\PersonBundle\Entity\Person; +use Chill\WopiBundle\Service\WopiConverter; use PHPUnit\Framework\TestCase; use Prophecy\PhpUnit\ProphecyTrait; use Symfony\Component\Clock\MockClock; @@ -65,6 +66,7 @@ class PDFSignatureZoneAvailableTest extends TestCase $entityWorkflowManager->reveal(), $parser->reveal(), $storedObjectManager->reveal(), + $this->prophesize(WopiConverter::class)->reveal(), ); $actual = $filter->getAvailableSignatureZones($entityWorkflow);