From c5a9a705925dd60e308cd3063ba7610e64fe77dc Mon Sep 17 00:00:00 2001 From: wizonesolutions <wizonesolutions@739994.no-reply.drupal.org> Date: Sun, 16 Feb 2020 21:33:43 +0100 Subject: [PATCH] Issue #3044467 by wizonesolutions, khaldoon_masud, jasonschweb, Pancho: Webform Signature Field doesn't work with FillPDF --- composer.json | 6 ++-- src/TokenResolver.php | 35 ++++++++++++++++++- .../Functional/PdfWebformPopulationTest.php | 21 ++++++++++- 3 files changed, 58 insertions(+), 4 deletions(-) diff --git a/composer.json b/composer.json index 26f1411..897d11c 100644 --- a/composer.json +++ b/composer.json @@ -10,8 +10,10 @@ } ], "minimum-stability": "dev", - "require-dev": { - "drupal/webform": "^5.0", + "require": { "drupal/token": "^1.0" + }, + "require-dev": { + "drupal/webform": "^5.0" } } diff --git a/src/TokenResolver.php b/src/TokenResolver.php index e789c61..9428f4f 100644 --- a/src/TokenResolver.php +++ b/src/TokenResolver.php @@ -161,14 +161,27 @@ class TokenResolver implements TokenResolverInterface { // Loop through the tokens, starting with the last one. foreach (array_reverse($tokens) as $token) { $name = strtr($token, ['values:' => '']); - if (array_key_exists($name, $elements) && isset($elements[$name]['#type']) && $elements[$name]['#type'] === 'webform_image_file') { + if (!array_key_exists($name, $elements) || !isset($elements[$name]['#type'])) { + continue; + } + if ($elements[$name]['#type'] === 'webform_image_file') { $file = File::load($entity->getElementData($name)); if ($file) { $uri = $file->getFileUri(); return new ImageFieldMapping(file_get_contents($uri), NULL, $uri); } } + elseif ($elements[$name]['#type'] === 'webform_signature') { + $signature_data = $entity->getElementData($name); + $signature_image = static::getSignatureImage($signature_data); + if (!$signature_image) { + continue; + } + return new ImageFieldMapping($signature_image, NULL, 'webform_signature.png'); + } } + + return NULL; } /** @@ -186,6 +199,8 @@ class TokenResolver implements TokenResolverInterface { * * @return \Drupal\fillpdf\FieldMapping\ImageFieldMapping|null * An ImageFieldMapping, or NULL if the tokens were no image field tokens. + * + * @throws \Drupal\Core\TypedData\Exception\MissingDataException */ protected static function parseImageFieldTokens(array $tokens, FieldableEntityInterface $entity) { // Loop through the tokens, starting with the last one. @@ -223,4 +238,22 @@ class TokenResolver implements TokenResolverInterface { return $this->tokenEntityMapper; } + /** + * Convert the base64-encoded signature image into regular image data. + * + * The result can be fed into an ImageFieldMapping. + * + * @param string $webform_element_value + * The value from the Webform submission, retrieved using + * the getElementData() method. + * + * @see \Drupal\fillpdf\FieldMapping\ImageFieldMapping + * + * @return string + * The signature image as a string to save to a file or stream. + */ + public static function getSignatureImage($webform_element_value) { + return base64_decode(preg_replace('#^data:image/\w+;base64,#i', '', $webform_element_value)); + } + } diff --git a/tests/src/Functional/PdfWebformPopulationTest.php b/tests/src/Functional/PdfWebformPopulationTest.php index 9ad698b..61ab615 100644 --- a/tests/src/Functional/PdfWebformPopulationTest.php +++ b/tests/src/Functional/PdfWebformPopulationTest.php @@ -6,10 +6,11 @@ use Drupal\Component\Utility\UrlHelper; use Drupal\Core\Url; use Drupal\file\Entity\File; use Drupal\fillpdf\Entity\FillPdfForm; +use Drupal\fillpdf\TokenResolver; use Drupal\user\Entity\Role; -use Drupal\webform\WebformInterface; use Drupal\webform\Entity\Webform; use Drupal\webform\Entity\WebformSubmission; +use Drupal\webform\WebformInterface; /** * Tests Webform population and image stamping. @@ -117,6 +118,18 @@ class PdfWebformPopulationTest extends FillPdfTestBase { "{image}{$submission_file->getFileUri()}", 'URI in metadata matches expected URI.' ); + + self::assertEquals( + '{image}webform_signature.png', + $populate_result['field_mapping']['fields']['TestButton'], + 'Signature matches signature from Webform.' + ); + $signature_image = TokenResolver::getSignatureImage($submission_values['test_signature']); + self::assertEquals( + base64_encode($signature_image), + $populate_result['field_mapping']['images']['TestButton']['data'], + 'Signature matches signature from Webform.' + ); } /** @@ -149,6 +162,8 @@ class PdfWebformPopulationTest extends FillPdfTestBase { * * @param \Drupal\fillpdf\Entity\FillPdfFormField[] $fields * Array of FillPdfFormFields. + * + * @throws \Drupal\Core\Entity\EntityStorageException */ protected function mapFillPdfFieldsToWebformFields(array $fields) { foreach ($fields as $pdf_key => $field) { @@ -160,6 +175,10 @@ class PdfWebformPopulationTest extends FillPdfTestBase { case 'TextField1': $field->value = '[webform_submission:webform:title]'; break; + + case 'TestButton': + $field->value = '[webform_submission:values:test_signature]'; + break; } $field->save(); } -- GitLab