Skip to content
Snippets Groups Projects
Commit 07411880 authored by Bernd Oliver Suenderhauf's avatar Bernd Oliver Suenderhauf
Browse files

Issue #3057046 by Pancho: Image stamping broken for taxonomy_terms

parent a67d71f0
No related branches found
No related tags found
No related merge requests found
......@@ -35,7 +35,7 @@ services:
fillpdf.token_resolver:
class: Drupal\fillpdf\TokenResolver
arguments: ["@token"]
arguments: ["@token", "@token.entity_mapper"]
fillpdf.entity_helper:
class: Drupal\fillpdf\EntityHelper
......
......@@ -153,20 +153,18 @@ class HandlePdfController extends ControllerBase {
$is_image_token = FALSE;
foreach ($entities as $entity_type => $entities_of_that_type) {
$lifo_entities = array_reverse($entities_of_that_type);
/** @var \Drupal\Core\Entity\EntityInterface $entity */
foreach ($lifo_entities as $entity) {
if (method_exists($entity, 'getFields')) {
// Translate entity type into token type.
$token_type = $this->tokenResolver->getEntityMapper()->getTokenTypeForEntityType($entity_type);
/** @var \Drupal\Core\Entity\ContentEntityInterface $entity */
/** @var string $field_name */
/** @var \Drupal\Core\Field\FieldDefinitionInterface $field_definition */
foreach ($entity->getFields() as $field_name => $field_data) {
$field_definition = $field_data->getFieldDefinition();
if ($field_definition->getType() === 'image') {
if ($fill_pattern === "[{$entity_type}:{$field_name}]") {
if ($fill_pattern === "[{$token_type}:{$field_name}]") {
// It's a match!
$is_image_token = TRUE;
if (count($entity->{$field_name})) {
/** @var \Drupal\file\FileInterface $image_file */
$image_file = File::load($entity->{$field_name}->target_id);
$this->processImageTokens($image_file, $mapped_fields, $pdf_key, $image_data);
}
......@@ -180,7 +178,7 @@ class HandlePdfController extends ControllerBase {
// We can iterate over this submission's Webform's elements and
// manually match for patterns. We support signature and image
// fields.
/** @var \Drupal\webform\Entity\Webform $webform */
/** @var \Drupal\webform\WebformSubmissionInterface $entity */
$webform = $entity->getWebform();
$webform_field_data = array_filter($webform->getElementsInitializedFlattenedAndHasValue(), function ($value) {
return (!empty($value) && $value['#type'] === 'webform_image_file');
......
......@@ -4,6 +4,7 @@ namespace Drupal\fillpdf;
use Drupal\Core\Utility\Token;
use Drupal\Component\Render\PlainTextOutput;
use Drupal\token\TokenEntityMapperInterface;
/**
* Class TokenResolver.
......@@ -13,17 +14,30 @@ use Drupal\Component\Render\PlainTextOutput;
class TokenResolver implements TokenResolverInterface {
/**
* Drupal\Core\Utility\Token definition.
* Token replacement instance.
*
* @var \Drupal\Core\Utility\Token
*/
protected $token;
/**
* Constructor.
* The token entity mapper.
*
* @var \Drupal\token\TokenEntityMapperInterface
*/
protected $tokenEntityMapper;
/**
* Constructs a TokenResolver object.
*
* @param \Drupal\Core\Utility\Token $token
* The token replacement instance.
* @param \Drupal\token\TokenEntityMapperInterface $token_entity_mapper
* The token entity mapper.
*/
public function __construct(Token $token) {
public function __construct(Token $token, TokenEntityMapperInterface $token_entity_mapper) {
$this->token = $token;
$this->tokenEntityMapper = $token_entity_mapper;
}
/**
......@@ -51,4 +65,11 @@ class TokenResolver implements TokenResolverInterface {
return PlainTextOutput::renderFromHtml($clean_replaced_string);
}
/**
* {@inheritdoc}
*/
public function getEntityMapper() {
return $this->tokenEntityMapper;
}
}
......@@ -10,19 +10,29 @@ namespace Drupal\fillpdf;
interface TokenResolverInterface {
/**
* @param string $original
* The string containing the tokens to replace.
* Replaces all tokens in a given string with appropriate values.
*
* @param array $entities
* An array of entities to be used as arguments to Token::replace
* @param string $original
* The string containing the tokens to replace.
* @param \Drupal\Core\Entity\EntityInterface[][] $entities
* Multidimensional array of entities, keyed by entity ID and grouped by
* entity type.
*
* @return string
* The passed-in string after replacing all possible tokens. The default
* implementation of this interface removes any non-matched tokens.
* The passed-in string after replacing all possible tokens. The default
* implementation of this interface removes any non-matched tokens.
*
* @see \Drupal\Core\Utility\Token::replace()
* @see TokenResolver
*/
public function replace($original, array $entities);
/**
* Returns the token entity mapper.
*
* @return \Drupal\token\TokenEntityMapperInterface
* The token entity mapper.
*/
public function getEntityMapper();
}
......@@ -3,13 +3,13 @@
namespace Drupal\Tests\fillpdf\Functional;
use Drupal\Core\Url;
use Drupal\Tests\taxonomy\Functional\TaxonomyTestTrait;
use Drupal\file\Entity\File;
use Drupal\fillpdf\Component\Utility\FillPdf;
use Drupal\fillpdf\Entity\FillPdfForm;
use Drupal\fillpdf\FieldMapping\ImageFieldMapping;
use Drupal\fillpdf\FieldMapping\TextFieldMapping;
use Drupal\fillpdf_test\Plugin\FillPdfBackend\TestFillPdfBackend;
use Drupal\node\Entity\Node;
use Drupal\user\Entity\Role;
/**
......@@ -19,6 +19,8 @@ use Drupal\user\Entity\Role;
*/
class PdfPopulationTest extends FillPdfTestBase {
use TaxonomyTestTrait;
/**
* Modules to enable.
*
......@@ -30,7 +32,14 @@ class PdfPopulationTest extends FillPdfTestBase {
*
* @see \Drupal\Tests\BrowserTestBase::installDrupal()
*/
public static $modules = ['filter'];
public static $modules = ['filter', 'taxonomy'];
/**
* A test vocabulary.
*
* @var \Drupal\taxonomy\Entity\Vocabulary
*/
protected $testVocabulary;
/**
* {@inheritdoc}
......@@ -46,6 +55,8 @@ class PdfPopulationTest extends FillPdfTestBase {
'use text format restricted_html',
]);
$this->testVocabulary = $this->createVocabulary();
$this->configureFillPdf();
}
......@@ -63,7 +74,7 @@ class PdfPopulationTest extends FillPdfTestBase {
// Get the field definitions for the form that was created and configure
// them.
$this->mapFillPdfFieldsToNodeFields($fillpdf_form->getFormFields());
$this->mapFillPdfFieldsToEntityFields('node', $fillpdf_form->getFormFields());
// Create a node to populate the FillPdf Form.
$node = $this->createNode([
......@@ -111,56 +122,64 @@ class PdfPopulationTest extends FillPdfTestBase {
$this->assertSession()->pageTextContains('New FillPDF form has been created.');
$fillpdf_form = FillPdfForm::load($this->getLatestFillPdfForm());
$this->createImageField('field_fillpdf_test_image', 'node', 'article');
$testCases = [
'node' => 'article',
'taxonomy_term' => $this->testVocabulary->id(),
'user' => 'user',
];
foreach ($testCases as $entity_type => $bundle) {
$this->createImageField('field_fillpdf_test_image', $entity_type, $bundle);
$node = Node::load(
$this->createImageFieldEntity(
$storage = \Drupal::entityTypeManager()->getStorage($entity_type);
$entity = $storage->load($this->createImageFieldEntity(
$this->testImage,
'field_fillpdf_test_image',
'node',
'article',
$entity_type,
$bundle,
'FillPDF Test image'
)
);
// Get the field definitions for the form that was created and configure
// them.
$this->mapFillPdfFieldsToNodeFields($fillpdf_form->getFormFields());
// Hit the generation route, check the results from the test backend plugin.
$fillpdf_route = Url::fromRoute('fillpdf.populate_pdf', [], [
'query' => [
'fid' => $fillpdf_form->id(),
'entity_id' => "node:{$node->id()}",
],
]);
$this->drupalGet($fillpdf_route);
// We don't actually care about downloading the fake PDF. We just want to
// check what happened in the backend.
$populate_result = $this->container->get('state')
->get('fillpdf_test.last_populated_metadata');
$node_file = File::load($node->field_fillpdf_test_image->target_id);
self::assertEquals(
$populate_result['field_mapping']['images']['ImageField']['data'],
base64_encode(file_get_contents($node_file->getFileUri())),
'Encoded image matches known image.'
);
$path_info = pathinfo($node_file->getFileUri());
$expected_file_hash = md5($path_info['filename']) . '.' . $path_info['extension'];
self::assertEquals(
$populate_result['field_mapping']['images']['ImageField']['filenamehash'],
$expected_file_hash,
'Hashed filename matches known hash.'
);
self::assertEquals(
$populate_result['field_mapping']['fields']['ImageField'],
"{image}{$node_file->getFileUri()}",
'URI in metadata matches expected URI.'
);
));
// Get the field definitions for the form that was created and configure
// them.
$this->mapFillPdfFieldsToEntityFields($entity_type, $fillpdf_form->getFormFields());
// Hit the generation route, check results from the test backend plugin.
$fillpdf_route = Url::fromRoute('fillpdf.populate_pdf', [], [
'query' => [
'fid' => $fillpdf_form->id(),
'entity_id' => "{$entity_type}:{$entity->id()}",
],
]);
$this->drupalGet($fillpdf_route);
// We don't actually care about downloading the fake PDF. We just want to
// check what happened in the backend.
$populate_result = $this->container->get('state')
->get('fillpdf_test.last_populated_metadata');
$file = File::load($entity->field_fillpdf_test_image->target_id);
self::assertArrayHasKey('ImageField', $populate_result['field_mapping']['images'], "$entity_type isn't populated with an image.");
self::assertEquals(
$populate_result['field_mapping']['images']['ImageField']['data'],
base64_encode(file_get_contents($file->getFileUri())),
'Encoded image matches known image.'
);
$path_info = pathinfo($file->getFileUri());
$expected_file_hash = md5($path_info['filename']) . '.' . $path_info['extension'];
self::assertEquals(
$populate_result['field_mapping']['images']['ImageField']['filenamehash'],
$expected_file_hash,
'Hashed filename matches known hash.'
);
self::assertEquals(
$populate_result['field_mapping']['fields']['ImageField'],
"{image}{$file->getFileUri()}",
'URI in metadata matches expected URI.'
);
}
}
/**
......@@ -229,28 +248,40 @@ class PdfPopulationTest extends FillPdfTestBase {
}
/**
* Maps FillPdf fields to node fields.
* Maps FillPdf fields to entity fields.
*
* @param string $entity_type
* The entity type.
* @param \Drupal\fillpdf\Entity\FillPdfFormField[] $fields
* Array of FillPdfFormFields.
*/
protected function mapFillPdfFieldsToNodeFields(array $fields) {
protected function mapFillPdfFieldsToEntityFields($entity_type, array $fields) {
/** @var \Drupal\token\TokenEntityMapperInterface $token_entity_mapper */
$token_entity_mapper = \Drupal::service('token.entity_mapper');
$token_type = $token_entity_mapper->getTokenTypeForEntityType($entity_type);
foreach ($fields as $pdf_key => $field) {
switch ($pdf_key) {
case 'ImageField':
case 'Button2':
$field->value = '[node:field_fillpdf_test_image]';
$field->value = "[$token_type:field_fillpdf_test_image]";
break;
case 'TextField1':
case 'Text1':
$field->value = '[node:title]';
$label_key = \Drupal::entityTypeManager()->getDefinition($entity_type)->getKey('label');
$field->value = "[$token_type:$label_key]";
$field->replacements = 'Hello & how are you?|Hello & how are you doing?';
break;
case 'TextField2':
case 'Text2':
$field->value = '[node:body]';
if ($token_type == 'node') {
$field->value = '[node:body]';
}
elseif ($token_type == 'term') {
$field->value = '[term:description]';
}
break;
}
$field->save();
......@@ -304,7 +335,7 @@ class PdfPopulationTest extends FillPdfTestBase {
// Get the field definitions for the form that was created and configure
// them.
$fields = $fillpdf_form->getFormFields();
$this->mapFillPdfFieldsToNodeFields($fields);
$this->mapFillPdfFieldsToEntityFields('node', $fields);
// Set up a test node.
$node = $this->createNode([
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment