From 0dcc2512b890e4fc696c7e8c6ce22501bc8bc06f Mon Sep 17 00:00:00 2001 From: wizonesolutions <wizonesolutions@739994.no-reply.drupal.org> Date: Sat, 18 Jan 2020 19:52:11 +0100 Subject: [PATCH] Issue #3105191 by wizonesolutions, liquidcms: Add API call to create PDFs --- fillpdf.services.yml | 3 + src/Controller/HandlePdfController.php | 69 ++++-------- src/Entity/FillPdfForm.php | 16 +++ src/FillPdfLinkManipulatorInterface.php | 2 +- src/Form/FillPdfFormForm.php | 16 +-- src/Service/BackendProxy.php | 105 ++++++++++++++++++ src/Service/BackendProxyInterface.php | 38 +++++++ src/Service/FillPdfLinkManipulator.php | 6 +- .../Functional/FillPdfFormDeleteFormTest.php | 2 +- .../FillPdfFormDuplicateFormTest.php | 2 +- .../Functional/FillPdfFormImportFormTest.php | 2 +- tests/src/Functional/FillPdfTestBase.php | 4 +- .../src/Functional/FillPdfUploadTestBase.php | 19 +++- tests/src/Functional/LinkManipulatorTest.php | 6 +- tests/src/Functional/PdfPopulationTest.php | 58 +++++++++- tests/src/Functional/UninstallTest.php | 3 +- 16 files changed, 277 insertions(+), 74 deletions(-) create mode 100644 src/Service/BackendProxy.php create mode 100644 src/Service/BackendProxyInterface.php diff --git a/fillpdf.services.yml b/fillpdf.services.yml index 7cac75c..b8912c3 100644 --- a/fillpdf.services.yml +++ b/fillpdf.services.yml @@ -53,3 +53,6 @@ services: class: Drupal\fillpdf\ShellManager arguments: ['@config.factory'] + fillpdf.backend_proxy: + class: Drupal\fillpdf\Service\BackendProxy + arguments: ['@fillpdf.token_resolver', '@plugin.manager.fillpdf.pdf_backend', '@config.factory'] diff --git a/src/Controller/HandlePdfController.php b/src/Controller/HandlePdfController.php index e476ab6..784b7f9 100644 --- a/src/Controller/HandlePdfController.php +++ b/src/Controller/HandlePdfController.php @@ -10,6 +10,7 @@ use Drupal\file\Entity\File; use Drupal\fillpdf\FillPdfContextManagerInterface; use Drupal\fillpdf\FillPdfFormInterface; use Drupal\fillpdf\FillPdfLinkManipulatorInterface; +use Drupal\fillpdf\Service\BackendProxyInterface; use Drupal\fillpdf\TokenResolverInterface; use Drupal\fillpdf\Component\Helper\FillPdfMappingHelper; use Drupal\fillpdf\Entity\FillPdfForm; @@ -67,6 +68,13 @@ class HandlePdfController extends ControllerBase { */ protected $actionManager; + /** + * The backend proxy. + * + * @var \Drupal\fillpdf\Service\BackendProxyInterface + */ + protected $backendProxy; + /** * Constructs a FillPdfBackendManager object. * @@ -82,6 +90,8 @@ class HandlePdfController extends ControllerBase { * The FillPDF backend manager. * @param \Drupal\fillpdf\Plugin\FillPdfActionPluginManager $action_manager * The FillPDF action manager. + * @param \Drupal\fillpdf\Service\BackendProxyInterface $backend_proxy + * The backend proxy. */ public function __construct( FillPdfLinkManipulatorInterface $link_manipulator, @@ -89,7 +99,8 @@ class HandlePdfController extends ControllerBase { TokenResolverInterface $token_resolver, RequestStack $request_stack, PdfBackendManager $backend_manager, - FillPdfActionPluginManager $action_manager + FillPdfActionPluginManager $action_manager, + BackendProxyInterface $backend_proxy ) { $this->linkManipulator = $link_manipulator; $this->contextManager = $context_manager; @@ -97,6 +108,7 @@ class HandlePdfController extends ControllerBase { $this->requestStack = $request_stack; $this->backendManager = $backend_manager; $this->actionManager = $action_manager; + $this->backendProxy = $backend_proxy; } /** @@ -109,7 +121,8 @@ class HandlePdfController extends ControllerBase { $container->get('fillpdf.token_resolver'), $container->get('request_stack'), $container->get('plugin.manager.fillpdf.pdf_backend'), - $container->get('plugin.manager.fillpdf_action.processor') + $container->get('plugin.manager.fillpdf_action.processor'), + $container->get('fillpdf.backend_proxy') ); } @@ -120,66 +133,28 @@ class HandlePdfController extends ControllerBase { * The action plugin's response object. * * @throws \InvalidArgumentException + * @throws \Drupal\Component\Plugin\Exception\PluginException * If one of the passed arguments is missing or does not pass the * validation. */ public function populatePdf() { - $config = $this->config('fillpdf.settings'); - $context = $this->linkManipulator->parseRequest($this->requestStack->getCurrentRequest()); - $entities = $this->contextManager->loadEntities($context); - $fillpdf_form = FillPdfForm::load($context['fid']); - $form_replacements = FillPdfMappingHelper::parseReplacements($fillpdf_form->replacements->value); - - // Populate mappings array. - $field_mappings = []; - foreach ($fillpdf_form->getFormFields() as $pdf_key => $field) { - if ($context['sample']) { - $field_mappings[$pdf_key] = new TextFieldMapping($pdf_key); - } - else { - $options = []; - // Our pdftk backend doesn't support image stamping, so at least for - // this backend we already know which type of content we can expect. - $options['content'] = $config->get('backend') == 'pdftk' ? 'text' : ''; - - // Prepare transformations with field-level replacements taking - // precedence over form-level replacements. - $options['replacements'] = FillPdfMappingHelper::parseReplacements($field->replacements->value) + $form_replacements; + $entities = $this->contextManager->loadEntities($context); - // Add prefix and suffix. - $options['prefix'] = $field->prefix->value; - $options['suffix'] = $field->suffix->value; + $populated_pdf = $this->backendProxy->merge($fillpdf_form, $entities, $context); - // Resolve tokens. - $text = count($field->value) ? $field->value->value : ''; - $field_mappings[$pdf_key] = $this->tokenResolver->replace($text, $entities, $options); - } + if (empty($populated_pdf)) { + $this->messenger()->addError($this->t('Merging the FillPDF Form failed.')); + return new RedirectResponse(Url::fromRoute('<front>')->toString()); } // Generate the filename of downloaded PDF from title of the PDF set in // admin/structure/fillpdf/%fid. $filename = $this->buildFilename($fillpdf_form->title->value, $entities); - // Now load the backend plugin. - $backend = $this->backendManager->createInstance($config->get('backend'), $config->get()); - - // @todo: Emit event (or call alter hook?) before populating PDF. - // Rename fillpdf_merge_fields_alter() to fillpdf_populate_fields_alter(). - $template_file = File::load($fillpdf_form->file->target_id); - /** @var \Drupal\fillpdf\FillPdfBackendPluginInterface $backend */ - $populated_pdf = $backend->mergeFile($template_file, $field_mappings, $context); - - if (empty($populated_pdf)) { - $this->messenger()->addError($this->t('Merging the FillPDF Form failed.')); - return new RedirectResponse(Url::fromRoute('<front>')->toString()); - } - // @todo: When Rules integration ported, emit an event or whatever. - $action_response = $this->handlePopulatedPdf($fillpdf_form, $populated_pdf, $context, $filename, $entities); - - return $action_response; + return $this->handlePopulatedPdf($fillpdf_form, $populated_pdf, $context, $filename, $entities); } /** diff --git a/src/Entity/FillPdfForm.php b/src/Entity/FillPdfForm.php index 70977c0..fb9da6d 100644 --- a/src/Entity/FillPdfForm.php +++ b/src/Entity/FillPdfForm.php @@ -50,6 +50,22 @@ use Drupal\fillpdf\Service\FillPdfAdminFormHelper; */ class FillPdfForm extends ContentEntityBase implements FillPdfFormInterface { + /** + * Load a FillPDF Form. + * + * @param int $id + * The ID of the form. + * + * @return \Drupal\fillpdf\FillPdfFormInterface|null + * The FillPDF Form, or NULL if the ID didn't match any. + */ + public static function load($id) { + /** @var \Drupal\fillpdf\FillPdfFormInterface $fillpdf_form */ + $fillpdf_form = parent::load($id); + + return $fillpdf_form; + } + /** * {@inheritdoc} */ diff --git a/src/FillPdfLinkManipulatorInterface.php b/src/FillPdfLinkManipulatorInterface.php index cedd944..b17f670 100644 --- a/src/FillPdfLinkManipulatorInterface.php +++ b/src/FillPdfLinkManipulatorInterface.php @@ -48,7 +48,7 @@ interface FillPdfLinkManipulatorInterface { * * @param \Drupal\Core\Url $link * The valid URL containing the FillPDF generation metadata. - * e.g. 'http://example.com/fillpdf?entities[]=node:1&entities[]=contact:7'. + * e.g. 'http://example.com/fillpdf?entity_ids[]=node:1&entity_ids[]=contact:7'. * * @return array * An associative array representing the request context and containing the diff --git a/src/Form/FillPdfFormForm.php b/src/Form/FillPdfFormForm.php index 0c8f9c6..92037e7 100644 --- a/src/Form/FillPdfFormForm.php +++ b/src/Form/FillPdfFormForm.php @@ -281,20 +281,20 @@ class FillPdfFormForm extends ContentEntityForm { '#type' => 'item', '#title' => $this->t('Sample PDF'), '#description' => $this->l( - $this->t('See which fields are which in this PDF.'), - $this->linkManipulator->generateLink([ - 'fid' => $fid, - 'sample' => TRUE, - ])) . '<br />' . - $this->t('If you have set a custom path on this PDF, the sample will be saved there silently.'), + $this->t('See which fields are which in this PDF.'), + $this->linkManipulator->generateLink([ + 'fid' => $fid, + 'sample' => TRUE, + ])) . '<br />' . $this->t('If you have set a custom path on this PDF, the sample will be saved there silently.'), '#weight' => $pdf_info_weight++, ]; $form['pdf_info']['form_id'] = [ '#type' => 'item', '#title' => $this->t('Form info'), - '#description' => $this->t("Form ID: [@fid]. Populate this form with entity IDs, such as @path<br/>", [ + '#description' => $this->t('Form ID: [@fid]. Populate this form with entity IDs, such as %path . For more usage examples, see <a href="@documentation">the documentation</a>.', [ '@fid' => $fid, - '@path' => "/fillpdf?fid={$fid}&entity_type=node&entity_id=10", + '%path' => "/fillpdf?fid={$fid}&entity_ids[]=node:10&entity_ids[]=user:7", + '@documentation' => 'https://www.drupal.org/docs/8/modules/fillpdf/usage#makelink', ]), '#weight' => $pdf_info_weight, ]; diff --git a/src/Service/BackendProxy.php b/src/Service/BackendProxy.php new file mode 100644 index 0000000..b7899ed --- /dev/null +++ b/src/Service/BackendProxy.php @@ -0,0 +1,105 @@ +<?php + +namespace Drupal\fillpdf\Service; + +use Drupal\Core\Config\ConfigFactoryInterface; +use Drupal\file\Entity\File; +use Drupal\fillpdf\Component\Helper\FillPdfMappingHelper; +use Drupal\fillpdf\FieldMapping\TextFieldMapping; +use Drupal\fillpdf\FillPdfFormInterface; +use Drupal\fillpdf\Plugin\PdfBackendManager; +use Drupal\fillpdf\TokenResolverInterface; + +/** + * BackendProxy service. + */ +class BackendProxy implements BackendProxyInterface { + + /** + * The fillpdf.token_resolver service. + * + * @var \Drupal\fillpdf\TokenResolverInterface + */ + protected $tokenResolver; + + /** + * The plugin.manager.fillpdf.pdf_backend service. + * + * @var \Drupal\fillpdf\Plugin\PdfBackendManager + */ + protected $backendManager; + /** + * The configuration factory. + * + * @var \Drupal\Core\Config\ConfigFactoryInterface + */ + protected $configFactory; + + /** + * Constructs a BackendProxy object. + * + * @param \Drupal\fillpdf\TokenResolverInterface $tokenResolver + * The fillpdf.token_resolver service. + * @param \Drupal\fillpdf\Plugin\PdfBackendManager $backendManager + * The plugin.manager.fillpdf.pdf_backend service. + * @param \Drupal\Core\Config\ConfigFactoryInterface $configFactory + * The configuration factory. + */ + public function __construct(TokenResolverInterface $tokenResolver, PdfBackendManager $backendManager, ConfigFactoryInterface $configFactory) { + $this->tokenResolver = $tokenResolver; + $this->backendManager = $backendManager; + $this->configFactory = $configFactory; + } + + /** + * {@inheritdoc} + * + * @throws \Drupal\Component\Plugin\Exception\PluginException + */ + public function merge(FillPdfFormInterface $fillPdfForm, array $entities, array $mergeOptions = []): string { + $config = $this->configFactory->get('fillpdf.settings'); + + $form_replacements = FillPdfMappingHelper::parseReplacements($fillPdfForm->replacements->value); + + $mergeOptions += [ + 'sample' => FALSE, + 'flatten' => TRUE, + ]; + + // Populate mappings array. + $field_mappings = []; + foreach ($fillPdfForm->getFormFields() as $pdf_key => $field) { + if ($mergeOptions['sample']) { + $field_mappings[$pdf_key] = new TextFieldMapping($pdf_key); + } + else { + $options = []; + // Our pdftk backend doesn't support image stamping, so at least for + // this backend we already know which type of content we can expect. + $options['content'] = $config->get('backend') === 'pdftk' ? 'text' : ''; + + // Prepare transformations with field-level replacements taking + // precedence over form-level replacements. + $options['replacements'] = FillPdfMappingHelper::parseReplacements($field->replacements->value) + $form_replacements; + + // Add prefix and suffix. + $options['prefix'] = $field->prefix->value; + $options['suffix'] = $field->suffix->value; + + // Resolve tokens. + $text = count($field->value) ? $field->value->value : ''; + $field_mappings[$pdf_key] = $this->tokenResolver->replace($text, $entities, $options); + } + } + + // Now load the backend plugin. + /** @var \Drupal\fillpdf\FillPdfBackendPluginInterface|\Drupal\fillpdf\Plugin\PdfBackendInterface $backend */ + $backend = $this->backendManager->createInstance($config->get('backend'), $config->get()); + + // @todo: Emit event (or call alter hook?) before populating PDF. + // Rename fillpdf_merge_fields_alter() to fillpdf_populate_fields_alter(). + $template_file = File::load($fillPdfForm->file->target_id); + return $backend->mergeFile($template_file, $field_mappings, $mergeOptions); + } + +} diff --git a/src/Service/BackendProxyInterface.php b/src/Service/BackendProxyInterface.php new file mode 100644 index 0000000..41a236c --- /dev/null +++ b/src/Service/BackendProxyInterface.php @@ -0,0 +1,38 @@ +<?php + +namespace Drupal\fillpdf\Service; + +use Drupal\fillpdf\FillPdfFormInterface; + +/** + * The backend proxy allows backend-agnostic PDF operations. + * + * It uses the backend configured on the site to operate on the PDF. Currently, + * only merging is supported. Other modules can use this to integrate with + * FillPDF more simply and without having to make sub-requests. + */ +interface BackendProxyInterface { + + /** + * Merge data into a PDF using the supplied form configuration and entities. + * + * @param \Drupal\fillpdf\FillPdfFormInterface $fillPdfForm + * The form configuration to use. Will be processed the same way as the + * fillpdf.populate_pdf route, including replacements, token mappings, etc. + * @param \Drupal\Core\Entity\EntityInterface[][] $entities + * The entity data to use. The entities should be keyed by entity type. + * Under each key, there should be an array of entities keyed by their IDs. + * @param array $mergeOptions + * Configure how the merge should work. Valid keys are: + * - sample: (boolean, default: FALSE) whether to output a sample PDF + * - flatten: (boolean, default: TRUE) whether the merged PDF should have + * its fields made permanent and no longer editable. + * It is safe to pass in a FillPDF $context array. Merge options are a + * subset of that. + * + * @return string + * The merged PDF data. + */ + public function merge(FillPdfFormInterface $fillPdfForm, array $entities, array $mergeOptions = []): string; + +} diff --git a/src/Service/FillPdfLinkManipulator.php b/src/Service/FillPdfLinkManipulator.php index 7499c71..e39f3bc 100644 --- a/src/Service/FillPdfLinkManipulator.php +++ b/src/Service/FillPdfLinkManipulator.php @@ -66,12 +66,12 @@ class FillPdfLinkManipulator implements FillPdfLinkManipulatorInterface { } if (empty($query['fid'])) { - throw new \InvalidArgumentException('No FillPdfForm was specified in the query string, so failing.'); + throw new \InvalidArgumentException('No FillPDF Form was specified in the query string, so failing.'); } $fillpdf_form = FillPdfForm::load($query['fid']); if (!$fillpdf_form) { - throw new \InvalidArgumentException("The requested FillPdfForm doesn't exist, so failing."); + throw new \InvalidArgumentException("The requested FillPDF Form doesn't exist, so failing."); } // Set the fid, merging in evaluated boolean flags. @@ -175,7 +175,7 @@ class FillPdfLinkManipulator implements FillPdfLinkManipulatorInterface { */ public function generateLink(array $parameters) { if (!isset($parameters['fid'])) { - throw new \InvalidArgumentException("The $parameters argument must contain the fid key (the FillPdfForm's ID)."); + throw new \InvalidArgumentException("The \$parameters argument must contain the fid key (the FillPDF Form's ID)."); } $query = [ diff --git a/tests/src/Functional/FillPdfFormDeleteFormTest.php b/tests/src/Functional/FillPdfFormDeleteFormTest.php index 0ab7173..8387fc0 100644 --- a/tests/src/Functional/FillPdfFormDeleteFormTest.php +++ b/tests/src/Functional/FillPdfFormDeleteFormTest.php @@ -17,7 +17,7 @@ class FillPdfFormDeleteFormTest extends BrowserTestBase { use TestFillPdfTrait; static public $modules = ['fillpdf_test']; - protected $profile = 'minimal'; + protected $defaultTheme = 'stark'; /** * {@inheritdoc} diff --git a/tests/src/Functional/FillPdfFormDuplicateFormTest.php b/tests/src/Functional/FillPdfFormDuplicateFormTest.php index 6eb38ce..4365952 100644 --- a/tests/src/Functional/FillPdfFormDuplicateFormTest.php +++ b/tests/src/Functional/FillPdfFormDuplicateFormTest.php @@ -17,7 +17,7 @@ class FillPdfFormDuplicateFormTest extends BrowserTestBase { use TestFillPdfTrait; static public $modules = ['fillpdf_test']; - protected $profile = 'minimal'; + protected $defaultTheme = 'stark'; /** * {@inheritdoc} diff --git a/tests/src/Functional/FillPdfFormImportFormTest.php b/tests/src/Functional/FillPdfFormImportFormTest.php index 045bbcc..bff0cc5 100644 --- a/tests/src/Functional/FillPdfFormImportFormTest.php +++ b/tests/src/Functional/FillPdfFormImportFormTest.php @@ -15,7 +15,7 @@ class FillPdfFormImportFormTest extends BrowserTestBase { use TestFillPdfTrait; static public $modules = ['fillpdf_test']; - protected $profile = 'minimal'; + protected $defaultTheme = 'stark'; /** * {@inheritdoc} diff --git a/tests/src/Functional/FillPdfTestBase.php b/tests/src/Functional/FillPdfTestBase.php index fcf6dae..c097733 100644 --- a/tests/src/Functional/FillPdfTestBase.php +++ b/tests/src/Functional/FillPdfTestBase.php @@ -16,11 +16,9 @@ abstract class FillPdfTestBase extends FileFieldTestBase { use TestImageFieldTrait; /** - * The profile to install as a basis for testing. - * * @var string */ - protected $profile = 'minimal'; + protected $defaultTheme = 'stark'; /** * Modules to enable. diff --git a/tests/src/Functional/FillPdfUploadTestBase.php b/tests/src/Functional/FillPdfUploadTestBase.php index 2a12821..8a1f679 100644 --- a/tests/src/Functional/FillPdfUploadTestBase.php +++ b/tests/src/Functional/FillPdfUploadTestBase.php @@ -2,6 +2,8 @@ namespace Drupal\Tests\fillpdf\Functional; +use Drupal; +use Drupal\Component\Version\Constraint; use Drupal\file\Entity\File; use Drupal\fillpdf\Component\Utility\FillPdf; use Drupal\Component\Render\FormattableMarkup; @@ -90,9 +92,16 @@ abstract class FillPdfUploadTestBase extends FillPdfTestBase { // Whether submitted or just uploaded, at least temporarily the file should // exist now both as an object and physically on the disk. + /** @var \Drupal\file\FileInterface $new_file */ $new_file = File::load($this->getLastFileId()); $new_filename = $new_file->getFilename(); - $this->assertFileExists($new_file); + if (version_compare(Drupal::VERSION, '8.8.0', '<')) { + // @todo: REMOVE when Drupal 8.7.x is no longer supported. + $this->assertFileExists($new_file); + } + else { + $this->assertFileExists($new_file->getFileUri()); + } $this->assertLessThan((int) $new_file->id(), $previous_file_id); // If the same file was previously uploaded, it should have a "_0" appendix. @@ -112,7 +121,13 @@ abstract class FillPdfUploadTestBase extends FillPdfTestBase { // Now remove the PDF file again. The temporary file should now be // removed both from the disk and the database. $this->drupalPostForm(NULL, NULL, self::OP_REMOVE); - $this->assertFileNotExists($new_file); + if (version_compare(Drupal::VERSION, '8.8.0', '<')) { + // @todo: REMOVE when Drupal 8.7.x is no longer supported. + $this->assertFileNotExists($new_file); + } + else { + $this->assertFileNotExists($new_file->getFileUri()); + } // @todo Simplify once Core bug gets fixed. // See: https://www.drupal.org/project/drupal/issues/3043127. $this->assertFileEntryNotExists($new_file, NULL); diff --git a/tests/src/Functional/LinkManipulatorTest.php b/tests/src/Functional/LinkManipulatorTest.php index ac21a19..e682ff1 100644 --- a/tests/src/Functional/LinkManipulatorTest.php +++ b/tests/src/Functional/LinkManipulatorTest.php @@ -18,7 +18,7 @@ class LinkManipulatorTest extends BrowserTestBase { use TestFillPdfTrait; static public $modules = ['fillpdf_test']; - protected $profile = 'minimal'; + protected $defaultTheme = 'stark'; /** * The FillPDF link manipulator service. @@ -58,7 +58,7 @@ class LinkManipulatorTest extends BrowserTestBase { $this->drupalGet($fillpdf_route); // Ensure the exception is converted to an error and access is denied. $this->assertSession()->statusCodeEquals(403); - $this->assertSession()->pageTextContains("No FillPdfForm was specified in the query string, so failing."); + $this->assertSession()->pageTextContains("No FillPDF Form was specified in the query string, so failing."); // Hit the generation route with a non-existing fid set. $fillpdf_route = Url::fromRoute('fillpdf.populate_pdf', [], [ @@ -69,7 +69,7 @@ class LinkManipulatorTest extends BrowserTestBase { $this->drupalGet($fillpdf_route); // Ensure the exception is converted to an error and access is denied. $this->assertSession()->statusCodeEquals(403); - $this->assertSession()->pageTextContains("The requested FillPdfForm doesn't exist, so failing."); + $this->assertSession()->pageTextContains("The requested FillPDF Form doesn't exist, so failing."); } /** diff --git a/tests/src/Functional/PdfPopulationTest.php b/tests/src/Functional/PdfPopulationTest.php index 21d5106..1425cb2 100644 --- a/tests/src/Functional/PdfPopulationTest.php +++ b/tests/src/Functional/PdfPopulationTest.php @@ -2,7 +2,6 @@ namespace Drupal\Tests\fillpdf\Functional; -use Drupal\Tests\taxonomy\Functional\TaxonomyTestTrait; use Drupal\file\Entity\File; use Drupal\fillpdf\Component\Utility\FillPdf; use Drupal\fillpdf\Entity\FillPdfForm; @@ -11,6 +10,14 @@ use Drupal\fillpdf\FieldMapping\TextFieldMapping; use Drupal\fillpdf_test\Plugin\FillPdfBackend\TestFillPdfBackend; use Drupal\user\Entity\Role; +// When 8.7.x is fully EOL, this can be removed. +use Drupal\Tests\taxonomy\Traits\TaxonomyTestTrait; + +if (!trait_exists('\Drupal\Tests\taxonomy\Traits\TaxonomyTestTrait')) { + class_alias('\Drupal\Tests\taxonomy\Functional\TaxonomyTestTrait', '\Drupal\Tests\taxonomy\Traits\TaxonomyTestTrait'); +} + + /** * Tests Core entity population and image stamping. * @@ -19,7 +26,6 @@ use Drupal\user\Entity\Role; class PdfPopulationTest extends FillPdfTestBase { use TaxonomyTestTrait; - /** * Modules to enable. * @@ -242,6 +248,53 @@ class PdfPopulationTest extends FillPdfTestBase { self::assertInstanceOf(ImageFieldMapping::class, $merge_state['field_mapping']['Image1'], 'Field "Image1" was mapped to an ImageFieldMapping object.'); } + /** + * Tests that merging with the backend proxy works. + */ + public function testProxyMerge() { + $this->uploadTestPdf('fillpdf_test_v3.pdf'); + $fillpdf_form = FillPdfForm::load($this->getLatestFillPdfForm()); + + // Instantiate the backend proxy (which uses the configured backend). + /** @var \Drupal\fillpdf\Service\BackendProxyInterface $merge_proxy */ + $merge_proxy = $this->container->get('fillpdf.backend_proxy'); + + $original_pdf = file_get_contents($this->getTestPdfPath('fillpdf_test_v3.pdf')); + + $this->mapFillPdfFieldsToEntityFields('node', $fillpdf_form->getFormFields()); + + // Create a node to populate the FillPdf Form. + // The content of this node is not important; we just need an entity to + // pass. + $node = $this->createNode([ + 'title' => 'Hello & how are you?', + 'type' => 'article', + 'body' => [ + [ + 'value' => "<p>PDF form fields don't accept <em>any</em> HTML.</p>", + 'format' => 'restricted_html', + ], + ], + ]); + $entities['node'] = [$node->id() => $node]; + + // Test merging via the proxy. + $merged_pdf = $merge_proxy->merge($fillpdf_form, $entities); + self::assertEquals($original_pdf, $merged_pdf); + + $merge_state = $this->container->get('state') + ->get('fillpdf_test.last_populated_metadata'); + self::assertInternalType('array', $merge_state, 'Test backend was used.'); + self::assertArrayHasKey('field_mapping', $merge_state, 'field_mapping key from test backend is present.'); + self::assertArrayHasKey('context', $merge_state, 'context key from test backend is present.'); + + // These are not that important. They just work because of other tests. + // We're just testing that token replacement works in general, not the + // details of it. We have other tests for that. + self::assertEquals('Hello & how are you doing?', $merge_state['field_mapping']['fields']['TextField1']); + self::assertEquals("PDF form fields don't accept any HTML.\n", $merge_state['field_mapping']['fields']['TextField2']); + } + /** * Maps FillPdf fields to entity fields. * @@ -259,6 +312,7 @@ class PdfPopulationTest extends FillPdfTestBase { switch ($pdf_key) { case 'ImageField': case 'Button2': + case 'TestButton': $field->value = "[$token_type:field_fillpdf_test_image]"; break; diff --git a/tests/src/Functional/UninstallTest.php b/tests/src/Functional/UninstallTest.php index 63da225..703a8a2 100644 --- a/tests/src/Functional/UninstallTest.php +++ b/tests/src/Functional/UninstallTest.php @@ -16,8 +16,7 @@ class UninstallTest extends BrowserTestBase { use TestFillPdfTrait; static public $modules = ['fillpdf_test']; - - protected $profile = 'minimal'; + protected $defaultTheme = 'stark'; /** * A user with administrative permissions. -- GitLab