From c8ccce83fda19699c427db88f38639c1bc76f09b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Tue, 18 Jun 2024 17:47:16 +0200 Subject: [PATCH 1/5] add a dependency on smalot/pdfparser to parse signature zone within pdf --- composer.json | 1 + 1 file changed, 1 insertion(+) diff --git a/composer.json b/composer.json index 34f9bbfc7..05068125d 100644 --- a/composer.json +++ b/composer.json @@ -32,6 +32,7 @@ "phpoffice/phpspreadsheet": "^1.16", "ramsey/uuid-doctrine": "^1.7", "sensio/framework-extra-bundle": "^5.5", + "smalot/pdfparser": "^2.10", "spomky-labs/base64url": "^2.0", "symfony/asset": "^5.4", "symfony/browser-kit": "^5.4", From 5bc542a5676ae595fa4d1ea6ac2210d383e84c4a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Wed, 19 Jun 2024 12:16:51 +0200 Subject: [PATCH 2/5] remove symfony/phpunit-bridge --- composer.json | 1 - 1 file changed, 1 deletion(-) diff --git a/composer.json b/composer.json index 05068125d..edd382445 100644 --- a/composer.json +++ b/composer.json @@ -98,7 +98,6 @@ "symfony/debug-bundle": "^5.4", "symfony/dotenv": "^5.4", "symfony/maker-bundle": "^1.20", - "symfony/phpunit-bridge": "^5.4", "symfony/runtime": "^5.4", "symfony/stopwatch": "^5.4", "symfony/var-dumper": "^5.4" From a9f00597430ef44be59e388575afd9e65c96f083 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Wed, 19 Jun 2024 12:17:25 +0200 Subject: [PATCH 3/5] Add PDF signature zone parsing functionality This update introduces new services into the ChillDocStoreBundle for signature zone parsing within PDFs. The PDFSignatureZoneParser service identifies signature zones within PDF content while the additional classes, PDFPage and PDFSignatureZone, help define these zones and pages. Corresponding tests have also been --- .../Service/Signature/PDFPage.php | 28 +++++++ .../Service/Signature/PDFSignatureZone.php | 33 ++++++++ .../Signature/PDFSignatureZoneParser.php | 57 +++++++++++++ .../Signature/PDFSignatureZoneParserTest.php | 77 ++++++++++++++++++ .../data/signature_2_signature_page_1.pdf | Bin 0 -> 16589 bytes 5 files changed, 195 insertions(+) create mode 100644 src/Bundle/ChillDocStoreBundle/Service/Signature/PDFPage.php create mode 100644 src/Bundle/ChillDocStoreBundle/Service/Signature/PDFSignatureZone.php create mode 100644 src/Bundle/ChillDocStoreBundle/Service/Signature/PDFSignatureZoneParser.php create mode 100644 src/Bundle/ChillDocStoreBundle/Tests/Service/Signature/PDFSignatureZoneParserTest.php create mode 100644 src/Bundle/ChillDocStoreBundle/Tests/Service/Signature/data/signature_2_signature_page_1.pdf diff --git a/src/Bundle/ChillDocStoreBundle/Service/Signature/PDFPage.php b/src/Bundle/ChillDocStoreBundle/Service/Signature/PDFPage.php new file mode 100644 index 000000000..138c4e1c8 --- /dev/null +++ b/src/Bundle/ChillDocStoreBundle/Service/Signature/PDFPage.php @@ -0,0 +1,28 @@ +index === $this->index + && round($page->width, 2) === round($this->width, 2) + && round($page->height, 2) === round($this->height, 2); + } +} diff --git a/src/Bundle/ChillDocStoreBundle/Service/Signature/PDFSignatureZone.php b/src/Bundle/ChillDocStoreBundle/Service/Signature/PDFSignatureZone.php new file mode 100644 index 000000000..515356e52 --- /dev/null +++ b/src/Bundle/ChillDocStoreBundle/Service/Signature/PDFSignatureZone.php @@ -0,0 +1,33 @@ +x == $other->x + && $this->y == $other->y + && $this->height == $other->height + && $this->width == $other->width + && $this->PDFPage->equals($other->PDFPage); + } +} diff --git a/src/Bundle/ChillDocStoreBundle/Service/Signature/PDFSignatureZoneParser.php b/src/Bundle/ChillDocStoreBundle/Service/Signature/PDFSignatureZoneParser.php new file mode 100644 index 000000000..3aade2fcc --- /dev/null +++ b/src/Bundle/ChillDocStoreBundle/Service/Signature/PDFSignatureZoneParser.php @@ -0,0 +1,57 @@ +parser = new Parser(); + } + + /** + * @return list + */ + public function findSignatureZones(string $fileContent): array + { + $pdf = $this->parser->parseContent($fileContent); + $zones = []; + + $defaults = $pdf->getObjectsByType('Pages'); + $defaultPage = reset($defaults); + $defaultPageDetails = $defaultPage->getDetails(); + + foreach ($pdf->getPages() as $index => $page) { + $pdfPage = new PDFPage( + $index, + $page['MediaBox'][2] ?? $defaultPageDetails['MediaBox'][2], + $page['MediaBox'][3] ?? $defaultPageDetails['MediaBox'][3], + ); + + foreach ($page->getDataTm() as $dataTm) { + if (str_starts_with($dataTm[1], self::ZONE_SIGNATURE_START)) { + $zones[] = new PDFSignatureZone($dataTm[0][4], $dataTm[0][5], $this->defaultHeight, $this->defaultWidth, $pdfPage); + } + } + } + + return $zones; + } +} diff --git a/src/Bundle/ChillDocStoreBundle/Tests/Service/Signature/PDFSignatureZoneParserTest.php b/src/Bundle/ChillDocStoreBundle/Tests/Service/Signature/PDFSignatureZoneParserTest.php new file mode 100644 index 000000000..5a78c8bbf --- /dev/null +++ b/src/Bundle/ChillDocStoreBundle/Tests/Service/Signature/PDFSignatureZoneParserTest.php @@ -0,0 +1,77 @@ + $expected + */ + public function testFindSignatureZones(string $filePath, array $expected): void + { + $content = file_get_contents($filePath); + + if (false === $content) { + throw new \LogicException("Unable to read file {$filePath}"); + } + + $actual = self::$parser->findSignatureZones($content); + + self::assertEquals(count($expected), count($actual)); + + foreach ($actual as $index => $signatureZone) { + self::assertObjectEquals($expected[$index], $signatureZone); + } + } + + public static function provideFiles(): iterable + { + yield [ + __DIR__.'/data/signature_2_signature_page_1.pdf', + [ + new PDFSignatureZone( + 127.7, + 95.289, + 180.0, + 180.0, + $page = new PDFPage(0, 595.30393, 841.8897) + ), + new PDFSignatureZone( + 269.5, + 95.289, + 180.0, + 180.0, + $page, + ), + ], + ]; + } +} diff --git a/src/Bundle/ChillDocStoreBundle/Tests/Service/Signature/data/signature_2_signature_page_1.pdf b/src/Bundle/ChillDocStoreBundle/Tests/Service/Signature/data/signature_2_signature_page_1.pdf new file mode 100644 index 0000000000000000000000000000000000000000..89d91e67cffe721456aa7c0c870a49e7c3b4b278 GIT binary patch literal 16589 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 PWMM@lCl`?wMg0E&^Ql1< literal 0 HcmV?d00001 From 99818c211d39ebd7c12751e9144c93e0a3a5bb40 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Wed, 19 Jun 2024 12:18:20 +0200 Subject: [PATCH 4/5] Fix cs: upgrade of php-cs-fixer --- .../Tests/Form/Type/TranslatableActivityTypeTest.php | 2 +- .../Connector/MSGraph/RemoteEventConverter.php | 4 ++-- .../CompilerPass/ShortMessageCompilerPass.php | 2 +- src/Bundle/ChillMainBundle/Export/ExportManager.php | 4 ++-- .../ChillMainBundle/Search/Utils/ExtractDateFromPattern.php | 6 +++--- .../Search/Utils/ExtractPhonenumberFromPattern.php | 2 +- .../Tests/Controller/AccompanyingCourseControllerTest.php | 4 ++-- .../Tests/DependencyInjection/ChillReportExtensionTest.php | 2 +- .../ChillWopiBundle/src/Resources/config/services.php | 4 ++-- 9 files changed, 15 insertions(+), 15 deletions(-) diff --git a/src/Bundle/ChillActivityBundle/Tests/Form/Type/TranslatableActivityTypeTest.php b/src/Bundle/ChillActivityBundle/Tests/Form/Type/TranslatableActivityTypeTest.php index c6ecc377c..6715af3ed 100644 --- a/src/Bundle/ChillActivityBundle/Tests/Form/Type/TranslatableActivityTypeTest.php +++ b/src/Bundle/ChillActivityBundle/Tests/Form/Type/TranslatableActivityTypeTest.php @@ -60,7 +60,7 @@ final class TranslatableActivityTypeTest extends KernelTestCase $this->assertInstanceOf( ActivityType::class, $form->getData()['type'], - 'The data is an instance of Chill\\ActivityBundle\\Entity\\ActivityType' + 'The data is an instance of Chill\ActivityBundle\Entity\ActivityType' ); $this->assertEquals($type->getId(), $form->getData()['type']->getId()); diff --git a/src/Bundle/ChillCalendarBundle/RemoteCalendar/Connector/MSGraph/RemoteEventConverter.php b/src/Bundle/ChillCalendarBundle/RemoteCalendar/Connector/MSGraph/RemoteEventConverter.php index 94b488ddd..84797f6f1 100644 --- a/src/Bundle/ChillCalendarBundle/RemoteCalendar/Connector/MSGraph/RemoteEventConverter.php +++ b/src/Bundle/ChillCalendarBundle/RemoteCalendar/Connector/MSGraph/RemoteEventConverter.php @@ -37,12 +37,12 @@ class RemoteEventConverter * valid when the remote string contains also a timezone, like in * lastModifiedDate. */ - final public const REMOTE_DATETIMEZONE_FORMAT = 'Y-m-d\\TH:i:s.u?P'; + final public const REMOTE_DATETIMEZONE_FORMAT = 'Y-m-d\TH:i:s.u?P'; /** * Same as above, but sometimes the date is expressed with only 6 milliseconds. */ - final public const REMOTE_DATETIMEZONE_FORMAT_ALT = 'Y-m-d\\TH:i:s.uP'; + final public const REMOTE_DATETIMEZONE_FORMAT_ALT = 'Y-m-d\TH:i:s.uP'; private const REMOTE_DATE_FORMAT = 'Y-m-d\TH:i:s.u0'; diff --git a/src/Bundle/ChillMainBundle/DependencyInjection/CompilerPass/ShortMessageCompilerPass.php b/src/Bundle/ChillMainBundle/DependencyInjection/CompilerPass/ShortMessageCompilerPass.php index ebbfcee1b..9da9154b3 100644 --- a/src/Bundle/ChillMainBundle/DependencyInjection/CompilerPass/ShortMessageCompilerPass.php +++ b/src/Bundle/ChillMainBundle/DependencyInjection/CompilerPass/ShortMessageCompilerPass.php @@ -43,7 +43,7 @@ class ShortMessageCompilerPass implements CompilerPassInterface $defaultTransporter = new Reference(NullShortMessageSender::class); } elseif ('ovh' === $dsn['scheme']) { if (!class_exists('\\'.\Ovh\Api::class)) { - throw new RuntimeException('Class \\Ovh\\Api not found'); + throw new RuntimeException('Class \Ovh\Api not found'); } foreach (['user', 'host', 'pass'] as $component) { diff --git a/src/Bundle/ChillMainBundle/Export/ExportManager.php b/src/Bundle/ChillMainBundle/Export/ExportManager.php index 9cb2a54ba..d4e87d449 100644 --- a/src/Bundle/ChillMainBundle/Export/ExportManager.php +++ b/src/Bundle/ChillMainBundle/Export/ExportManager.php @@ -190,7 +190,7 @@ class ExportManager // throw an error if the export require other modifier, which is // not allowed when the export return a `NativeQuery` if (\count($export->supportsModifiers()) > 0) { - throw new \LogicException("The export with alias `{$exportAlias}` return ".'a `\\Doctrine\\ORM\\NativeQuery` and supports modifiers, which is not allowed. Either the method `supportsModifiers` should return an empty array, or return a `Doctrine\\ORM\\QueryBuilder`'); + throw new \LogicException("The export with alias `{$exportAlias}` return ".'a `\Doctrine\ORM\NativeQuery` and supports modifiers, which is not allowed. Either the method `supportsModifiers` should return an empty array, or return a `Doctrine\ORM\QueryBuilder`'); } } elseif ($query instanceof QueryBuilder) { // handle filters @@ -203,7 +203,7 @@ class ExportManager 'dql' => $query->getDQL(), ]); } else { - throw new \UnexpectedValueException('The method `intiateQuery` should return a `\\Doctrine\\ORM\\NativeQuery` or a `Doctrine\\ORM\\QueryBuilder` object.'); + throw new \UnexpectedValueException('The method `intiateQuery` should return a `\Doctrine\ORM\NativeQuery` or a `Doctrine\ORM\QueryBuilder` object.'); } $result = $export->getResult($query, $data[ExportType::EXPORT_KEY]); diff --git a/src/Bundle/ChillMainBundle/Search/Utils/ExtractDateFromPattern.php b/src/Bundle/ChillMainBundle/Search/Utils/ExtractDateFromPattern.php index f858797f5..9cce3fa13 100644 --- a/src/Bundle/ChillMainBundle/Search/Utils/ExtractDateFromPattern.php +++ b/src/Bundle/ChillMainBundle/Search/Utils/ExtractDateFromPattern.php @@ -14,9 +14,9 @@ namespace Chill\MainBundle\Search\Utils; class ExtractDateFromPattern { private const DATE_PATTERN = [ - ['([12]\\d{3}-(0[1-9]|1[0-2])-(0[1-9]|[12]\\d|3[01]))', 'Y-m-d'], // 1981-05-12 - ['((0[1-9]|[12]\\d|3[01])\\/(0[1-9]|1[0-2])\\/([12]\\d{3}))', 'd/m/Y'], // 15/12/1980 - ['((0[1-9]|[12]\\d|3[01])-(0[1-9]|1[0-2])-([12]\\d{3}))', 'd-m-Y'], // 15/12/1980 + ['([12]\d{3}-(0[1-9]|1[0-2])-(0[1-9]|[12]\d|3[01]))', 'Y-m-d'], // 1981-05-12 + ['((0[1-9]|[12]\d|3[01])\/(0[1-9]|1[0-2])\/([12]\d{3}))', 'd/m/Y'], // 15/12/1980 + ['((0[1-9]|[12]\d|3[01])-(0[1-9]|1[0-2])-([12]\d{3}))', 'd-m-Y'], // 15/12/1980 ]; public function extractDates(string $subject): SearchExtractionResult diff --git a/src/Bundle/ChillMainBundle/Search/Utils/ExtractPhonenumberFromPattern.php b/src/Bundle/ChillMainBundle/Search/Utils/ExtractPhonenumberFromPattern.php index 1823e462c..2be3d54db 100644 --- a/src/Bundle/ChillMainBundle/Search/Utils/ExtractPhonenumberFromPattern.php +++ b/src/Bundle/ChillMainBundle/Search/Utils/ExtractPhonenumberFromPattern.php @@ -16,7 +16,7 @@ use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface; class ExtractPhonenumberFromPattern { - private const PATTERN = '([\\+]{0,1}[0-9\\ ]{5,})'; + private const PATTERN = '([\+]{0,1}[0-9\ ]{5,})'; private readonly string $defaultCarrierCode; diff --git a/src/Bundle/ChillPersonBundle/Tests/Controller/AccompanyingCourseControllerTest.php b/src/Bundle/ChillPersonBundle/Tests/Controller/AccompanyingCourseControllerTest.php index 4f8f1453d..240c3ab98 100644 --- a/src/Bundle/ChillPersonBundle/Tests/Controller/AccompanyingCourseControllerTest.php +++ b/src/Bundle/ChillPersonBundle/Tests/Controller/AccompanyingCourseControllerTest.php @@ -74,7 +74,7 @@ final class AccompanyingCourseControllerTest extends WebTestCase $this->assertResponseRedirects(); $location = $this->client->getResponse()->headers->get('Location'); - $this->assertEquals(1, \preg_match('|^\\/[^\\/]+\\/parcours/([\\d]+)/edit$|', (string) $location)); + $this->assertEquals(1, \preg_match('|^\/[^\/]+\/parcours/([\d]+)/edit$|', (string) $location)); } /** @@ -93,7 +93,7 @@ final class AccompanyingCourseControllerTest extends WebTestCase $location = $this->client->getResponse()->headers->get('Location'); $matches = []; - $this->assertEquals(1, \preg_match('|^\\/[^\\/]+\\/parcours/([\\d]+)/edit$|', (string) $location, $matches)); + $this->assertEquals(1, \preg_match('|^\/[^\/]+\/parcours/([\d]+)/edit$|', (string) $location, $matches)); $id = $matches[1]; $period = self::getContainer()->get(EntityManagerInterface::class) diff --git a/src/Bundle/ChillReportBundle/Tests/DependencyInjection/ChillReportExtensionTest.php b/src/Bundle/ChillReportBundle/Tests/DependencyInjection/ChillReportExtensionTest.php index ae01d8d90..db938f0bf 100644 --- a/src/Bundle/ChillReportBundle/Tests/DependencyInjection/ChillReportExtensionTest.php +++ b/src/Bundle/ChillReportBundle/Tests/DependencyInjection/ChillReportExtensionTest.php @@ -41,7 +41,7 @@ final class ChillReportExtensionTest extends KernelTestCase } if (!$reportFounded) { - throw new \Exception('Class Chill\\ReportBundle\\Entity\\Report not found in chill_custom_fields.customizables_entities', 1); + throw new \Exception('Class Chill\ReportBundle\Entity\Report not found in chill_custom_fields.customizables_entities', 1); } } } diff --git a/src/Bundle/ChillWopiBundle/src/Resources/config/services.php b/src/Bundle/ChillWopiBundle/src/Resources/config/services.php index 005994bb6..d29f33205 100644 --- a/src/Bundle/ChillWopiBundle/src/Resources/config/services.php +++ b/src/Bundle/ChillWopiBundle/src/Resources/config/services.php @@ -32,10 +32,10 @@ return static function (ContainerConfigurator $container) { ->autoconfigure(); $services - ->load('Chill\\WopiBundle\\Service\\', __DIR__.'/../../Service'); + ->load('Chill\WopiBundle\Service\\', __DIR__.'/../../Service'); $services - ->load('Chill\\WopiBundle\\Controller\\', __DIR__.'/../../Controller') + ->load('Chill\WopiBundle\Controller\\', __DIR__.'/../../Controller') ->tag('controller.service_arguments'); $services From 89f5231649c9ae1a76dc513d985d023f9c29ae85 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Tue, 25 Jun 2024 13:25:49 +0200 Subject: [PATCH 5/5] Refactor PDFSignatureZoneParser to use float values This update changes how we handle values in PDFSignatureZoneParser class. Specifically, we've modified the 'MediaBox' and 'PDFSignatureZone' variables to use float values. The helps ensure greater precision, minimize errors, and maintain data consistency across the application. --- .../Service/Signature/PDFSignatureZoneParser.php | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/Bundle/ChillDocStoreBundle/Service/Signature/PDFSignatureZoneParser.php b/src/Bundle/ChillDocStoreBundle/Service/Signature/PDFSignatureZoneParser.php index 3aade2fcc..d57b98abf 100644 --- a/src/Bundle/ChillDocStoreBundle/Service/Signature/PDFSignatureZoneParser.php +++ b/src/Bundle/ChillDocStoreBundle/Service/Signature/PDFSignatureZoneParser.php @@ -39,15 +39,16 @@ class PDFSignatureZoneParser $defaultPageDetails = $defaultPage->getDetails(); foreach ($pdf->getPages() as $index => $page) { + $details = $page->getDetails(); $pdfPage = new PDFPage( $index, - $page['MediaBox'][2] ?? $defaultPageDetails['MediaBox'][2], - $page['MediaBox'][3] ?? $defaultPageDetails['MediaBox'][3], + (float) ($details['MediaBox'][2] ?? $defaultPageDetails['MediaBox'][2]), + (float) ($details['MediaBox'][3] ?? $defaultPageDetails['MediaBox'][3]), ); foreach ($page->getDataTm() as $dataTm) { if (str_starts_with($dataTm[1], self::ZONE_SIGNATURE_START)) { - $zones[] = new PDFSignatureZone($dataTm[0][4], $dataTm[0][5], $this->defaultHeight, $this->defaultWidth, $pdfPage); + $zones[] = new PDFSignatureZone((float) $dataTm[0][4], (float) $dataTm[0][5], $this->defaultHeight, $this->defaultWidth, $pdfPage); } } }