diff --git a/phpstan-baseline.neon b/phpstan-baseline.neon index 6c8a18c960ad25a4b48f7c2da140813f1db4c032..45a349d63322ec21c7a7767ffdde2a80a45d75c1 100644 --- a/phpstan-baseline.neon +++ b/phpstan-baseline.neon @@ -345,11 +345,6 @@ parameters: count: 1 path: src/Plugin/diff/Field/ImageFieldBuilder.php - - - message: "#^Implicit array creation is not allowed \\- variable \\$image_style might not exist\\.$#" - count: 1 - path: src/Plugin/diff/Field/ImageFieldBuilder.php - - message: "#^Method Drupal\\\\diff\\\\Plugin\\\\diff\\\\Field\\\\ImageFieldBuilder\\:\\:build\\(\\) has parameter \\$field_items with generic interface Drupal\\\\Core\\\\Field\\\\FieldItemListInterface but does not specify its types\\: T$#" count: 1 @@ -575,4 +570,3 @@ parameters: message: "#^Property Drupal\\\\Tests\\\\diff\\\\Unit\\\\VisualDiffThemeNegotiatorTest\\:\\:\\$configFactory with generic interface Prophecy\\\\Prophecy\\\\ProphecyInterface does not specify its types\\: T$#" count: 1 path: tests/src/Unit/VisualDiffThemeNegotiatorTest.php - diff --git a/src/DiffEntityComparison.php b/src/DiffEntityComparison.php index c8c7a036a99268624d2dec0cb8cb9aed399f285e..25668a9844fb4681766b7a3b4ad6e8bef5d10d8a 100644 --- a/src/DiffEntityComparison.php +++ b/src/DiffEntityComparison.php @@ -116,19 +116,17 @@ class DiffEntityComparison { $value = $left_values[$delta]; if (isset($value['#thumbnail'])) { $result['#left_thumbnail'][] = $value['#thumbnail']; + $value = $value['data']; } - else { - $result['#left'][] = \is_array($value) ? \implode("\n", $value) : $value; - } + $result['#left'][] = \is_array($value) ? \implode("\n", $value) : $value; } if (isset($right_values[$delta])) { $value = $right_values[$delta]; if (isset($value['#thumbnail'])) { $result['#right_thumbnail'][] = $value['#thumbnail']; + $value = $value['data']; } - else { - $result['#right'][] = \is_array($value) ? \implode("\n", $value) : $value; - } + $result['#right'][] = \is_array($value) ? \implode("\n", $value) : $value; } } diff --git a/src/Plugin/diff/Field/ImageFieldBuilder.php b/src/Plugin/diff/Field/ImageFieldBuilder.php index 24b920d52bd2342cb12e28e54adc76fc778a2415..b9264bd2a56b04611c3b0ddcca10dc05e595dc9f 100644 --- a/src/Plugin/diff/Field/ImageFieldBuilder.php +++ b/src/Plugin/diff/Field/ImageFieldBuilder.php @@ -30,13 +30,14 @@ class ImageFieldBuilder extends FieldDiffBuilderBase { // Every item from $field_items is of type FieldItemInterface. foreach ($field_items as $field_key => $field_item) { if (!$field_item->isEmpty()) { + $item_data = []; $values = $field_item->getValue(); // Compare file names. if (isset($values['target_id'])) { /** @var \Drupal\file\Entity\File $image */ $image = $fileManager->load($values['target_id']); - $result[$field_key][] = $this->t('Image: @image', [ + $item_data[] = (string) $this->t('Image: @image', [ '@image' => $image->getFilename(), ]); } @@ -44,7 +45,7 @@ class ImageFieldBuilder extends FieldDiffBuilderBase { // Compare Alt fields. if ($this->configuration['compare_alt_field']) { if (isset($values['alt'])) { - $result[$field_key][] = $this->t('Alt: @alt', [ + $item_data[] = (string) $this->t('Alt: @alt', [ '@alt' => $values['alt'], ]); } @@ -53,7 +54,7 @@ class ImageFieldBuilder extends FieldDiffBuilderBase { // Compare Title fields. if ($this->configuration['compare_title_field']) { if (!empty($values['title'])) { - $result[$field_key][] = $this->t('Title: @title', [ + $item_data[] = (string) $this->t('Title: @title', [ '@title' => $values['title'], ]); } @@ -62,32 +63,38 @@ class ImageFieldBuilder extends FieldDiffBuilderBase { // Compare file id. if ($this->configuration['show_id']) { if (isset($values['target_id'])) { - $result[$field_key][] = $this->t('File ID: @fid', [ + $item_data[] = (string) $this->t('File ID: @fid', [ '@fid' => $values['target_id'], ]); } } - $separator = $this->configuration['property_separator'] == 'nl' ? "\n" : $this->configuration['property_separator']; - $result[$field_key] = \implode($separator, $result[$field_key]); - // EXPERIMENTAL: Attach thumbnail image data. if ($this->configuration['show_thumbnail']) { if (isset($values['target_id'])) { $storage = $this->entityTypeManager->getStorage('entity_form_display'); $display = $storage->load($field_items->getFieldDefinition()->getTargetEntityTypeId() . '.' . $field_items->getEntity()->bundle() . '.default'); if ($image_field = $display->getComponent($field_item->getFieldDefinition()->getName())) { + /** @var \Drupal\file\Entity\File $image */ $image = $fileManager->load($values['target_id']); - - $image_style[$field_key]['#thumbnail'] = [ + $thumbnail = [ '#theme' => 'image_style', '#uri' => $image->getFileUri(), '#style_name' => $image_field['settings']['preview_image_style'], ]; - $result = \array_merge($result, $image_style); } } } + + $separator = $this->configuration['property_separator'] == 'nl' ? "\n" : $this->configuration['property_separator']; + $properties = \implode($separator, $item_data); + if (isset($thumbnail)) { + $result[$field_key]['#thumbnail'] = $thumbnail; + $result[$field_key]['data'] = $properties; + } + else { + $result[$field_key] = $properties; + } } } diff --git a/tests/src/Functional/DiffPluginFileTest.php b/tests/src/Functional/DiffPluginFileTest.php index 40f40b4ef0cbcdc431b09bbe1834275543a45a3c..9c6d1204f29ee8a8ec34c96074bc4ebff07efa2f 100644 --- a/tests/src/Functional/DiffPluginFileTest.php +++ b/tests/src/Functional/DiffPluginFileTest.php @@ -126,44 +126,13 @@ class DiffPluginFileTest extends DiffPluginTestBase { } /** - * Tests the Image plugin. + * Tests the Image plugin for singe value fields. * * @see \Drupal\diff\Plugin\diff\Field\ImageFieldBuilder */ - public function testImagePlugin(): void { + public function testImagePluginSingleValue(): void { // Add image field to the article content type. - $image_field_name = 'field_image'; - FieldStorageConfig::create([ - 'field_name' => $image_field_name, - 'entity_type' => 'node', - 'type' => 'image', - 'settings' => [], - 'cardinality' => 1, - ])->save(); - - $field_config = FieldConfig::create([ - 'field_name' => $image_field_name, - 'label' => 'Image', - 'entity_type' => 'node', - 'bundle' => 'article', - 'required' => FALSE, - 'settings' => ['alt_field' => 1], - ]); - $field_config->save(); - - $this->formDisplay->load('node.article.default') - ->setComponent($image_field_name, [ - 'type' => 'image_image', - 'settings' => [], - ]) - ->save(); - - $this->viewDisplay->load('node.article.default') - ->setComponent($image_field_name, [ - 'type' => 'image', - 'settings' => [], - ]) - ->save(); + $this->setUpImageField('field_image'); // Create an article. $node = $this->drupalCreateNode([ @@ -296,4 +265,91 @@ class DiffPluginFileTest extends DiffPluginTestBase { $this->assertSession()->responseNotContains($image_url); } + /** + * Tests the Image plugin for multi value fields. + * + * @see \Drupal\diff\Plugin\diff\Field\ImageFieldBuilder + */ + public function testImagePluginMultiValue(): void { + // Add image field to the article content type. + $this->setUpImageField('field_image', 10); + + // Create an article. + $node = $this->drupalCreateNode([ + 'type' => 'article', + 'title' => 'Test article', + ]); + + // Upload first image to the article. + $test_files = $this->drupalGetTestFiles('image'); + $edit = ['files[field_image_0][]' => $this->fileSystem->realpath($test_files['1']->uri)]; + $this->drupalPostNodeForm('node/' . $node->id() . '/edit', $edit, 'Save'); + $edit = [ + 'field_image[0][alt]' => 'Image alt', + 'revision' => TRUE, + ]; + $this->submitForm($edit, 'Save'); + + // Upload new image to the article. + $edit = ['files[field_image_1][]' => $this->fileSystem->realpath($test_files['2']->uri)]; + $this->drupalPostNodeForm('node/' . $node->id() . '/edit', $edit, 'Save'); + $edit = [ + 'field_image[1][alt]' => 'Image two alt', + 'revision' => TRUE, + ]; + $this->submitForm($edit, 'Save'); + + $this->drupalGet('node/' . $node->id() . '/revisions'); + $this->submitForm([], 'Compare selected revisions'); + // Assert alt text of both images are visible. First image added in previous + // revision would have its alt text visible twice on both sides as context. + // Alt text of the second image should only be present once on right. + $this->assertSession()->pageTextMatchesCount(2, '/Alt: Image alt/'); + $this->assertSession()->pageTextMatchesCount(1, '/Alt: Image two alt/'); + } + + /** + * Sets image with on the "article". + * + * @param string $field_name + * Field name. + * @param int $cardinality + * Field cardinality. + * @param string $label + * Field label. + */ + protected function setUpImageField(string $field_name, int $cardinality = 1, string $label = 'Image'): void { + FieldStorageConfig::create([ + 'field_name' => $field_name, + 'entity_type' => 'node', + 'type' => 'image', + 'settings' => [], + 'cardinality' => $cardinality, + ])->save(); + + $field_config = FieldConfig::create([ + 'field_name' => $field_name, + 'label' => $label, + 'entity_type' => 'node', + 'bundle' => 'article', + 'required' => FALSE, + 'settings' => ['alt_field' => 1], + ]); + $field_config->save(); + + $this->formDisplay->load('node.article.default') + ->setComponent($field_name, [ + 'type' => 'image_image', + 'settings' => [], + ]) + ->save(); + + $this->viewDisplay->load('node.article.default') + ->setComponent($field_name, [ + 'type' => 'image', + 'settings' => [], + ]) + ->save(); + } + }