diff --git a/core/lib/Drupal/Core/Field/Plugin/Field/FieldFormatter/EntityReferenceEntityFormatter.php b/core/lib/Drupal/Core/Field/Plugin/Field/FieldFormatter/EntityReferenceEntityFormatter.php index 58ee673..fa83359 100644 --- a/core/lib/Drupal/Core/Field/Plugin/Field/FieldFormatter/EntityReferenceEntityFormatter.php +++ b/core/lib/Drupal/Core/Field/Plugin/Field/FieldFormatter/EntityReferenceEntityFormatter.php @@ -19,9 +19,7 @@ * label = @Translation("Rendered entity"), * description = @Translation("Display the referenced entities rendered by entity_view()."), * field_types = { - * "entity_reference", - * "file", - * "image" + * "entity_reference" * } * ) */ diff --git a/core/lib/Drupal/Core/Field/Plugin/Field/FieldFormatter/EntityReferenceIdFormatter.php b/core/lib/Drupal/Core/Field/Plugin/Field/FieldFormatter/EntityReferenceIdFormatter.php index 38dbc6e..62e54a7 100644 --- a/core/lib/Drupal/Core/Field/Plugin/Field/FieldFormatter/EntityReferenceIdFormatter.php +++ b/core/lib/Drupal/Core/Field/Plugin/Field/FieldFormatter/EntityReferenceIdFormatter.php @@ -12,9 +12,7 @@ * label = @Translation("Entity ID"), * description = @Translation("Display the ID of the referenced entities."), * field_types = { - * "entity_reference", - * "file", - * "image" + * "entity_reference" * } * ) */ diff --git a/core/lib/Drupal/Core/Field/Plugin/Field/FieldFormatter/EntityReferenceLabelFormatter.php b/core/lib/Drupal/Core/Field/Plugin/Field/FieldFormatter/EntityReferenceLabelFormatter.php index 6c37429..2084339 100644 --- a/core/lib/Drupal/Core/Field/Plugin/Field/FieldFormatter/EntityReferenceLabelFormatter.php +++ b/core/lib/Drupal/Core/Field/Plugin/Field/FieldFormatter/EntityReferenceLabelFormatter.php @@ -14,9 +14,7 @@ * label = @Translation("Label"), * description = @Translation("Display the label of the referenced entities."), * field_types = { - * "entity_reference", - * "file", - * "image" + * "entity_reference" * } * ) */ diff --git a/core/modules/file/file.module b/core/modules/file/file.module index c63fff4..00f1409 100644 --- a/core/modules/file/file.module +++ b/core/modules/file/file.module @@ -49,6 +49,26 @@ function file_help($route_name, RouteMatchInterface $route_match) { } /** + * Implements hook_field_formatter_info_alter(). + */ +function file_field_formatter_info_alter(&$info) { + // Allow the file formatters to be used on entity reference and image fields. + $info['file_default']['field_types'][] = 'entity_reference'; + $info['file_default']['field_types'][] = 'image'; + $info['file_table']['field_types'][] = 'entity_reference'; + $info['file_table']['field_types'][] = 'image'; + $info['file_url_plain']['field_types'][] = 'entity_reference'; + $info['file_url_plain']['field_types'][] = 'image'; + $info['file_rss_enclosure']['field_types'][] = 'entity_reference'; + $info['file_rss_enclosure']['field_types'][] = 'image'; + + // Allow entity reference formatters to be used on file fields. + $info['entity_reference_entity_id']['field_types'] += ['file']; + $info['entity_reference_entity_view']['field_types'] += ['file']; + $info['entity_reference_label']['field_types'] += ['file']; +} + +/** * Loads file entities from the database. * * @param array|null $fids diff --git a/core/modules/file/src/Plugin/Field/FieldFormatter/GenericFileFormatter.php b/core/modules/file/src/Plugin/Field/FieldFormatter/GenericFileFormatter.php index 9e3af70..a76d75a 100644 --- a/core/modules/file/src/Plugin/Field/FieldFormatter/GenericFileFormatter.php +++ b/core/modules/file/src/Plugin/Field/FieldFormatter/GenericFileFormatter.php @@ -11,9 +11,7 @@ * id = "file_default", * label = @Translation("Generic file"), * field_types = { - * "entity_reference", - * "file", - * "image" + * "file" * } * ) */ diff --git a/core/modules/file/src/Plugin/Field/FieldFormatter/RSSEnclosureFormatter.php b/core/modules/file/src/Plugin/Field/FieldFormatter/RSSEnclosureFormatter.php index 8125d60..46bbbde 100644 --- a/core/modules/file/src/Plugin/Field/FieldFormatter/RSSEnclosureFormatter.php +++ b/core/modules/file/src/Plugin/Field/FieldFormatter/RSSEnclosureFormatter.php @@ -11,9 +11,7 @@ * id = "file_rss_enclosure", * label = @Translation("RSS enclosure"), * field_types = { - * "entity_reference", - * "file", - * "image" + * "file" * } * ) */ diff --git a/core/modules/file/src/Plugin/Field/FieldFormatter/TableFormatter.php b/core/modules/file/src/Plugin/Field/FieldFormatter/TableFormatter.php index e8896c8..939329a 100644 --- a/core/modules/file/src/Plugin/Field/FieldFormatter/TableFormatter.php +++ b/core/modules/file/src/Plugin/Field/FieldFormatter/TableFormatter.php @@ -11,9 +11,7 @@ * id = "file_table", * label = @Translation("Table of files"), * field_types = { - * "entity_reference", - * "file", - * "image" + * "file" * } * ) */ diff --git a/core/modules/file/src/Plugin/Field/FieldFormatter/UrlPlainFormatter.php b/core/modules/file/src/Plugin/Field/FieldFormatter/UrlPlainFormatter.php index 4e11a1c..ccb97d5 100644 --- a/core/modules/file/src/Plugin/Field/FieldFormatter/UrlPlainFormatter.php +++ b/core/modules/file/src/Plugin/Field/FieldFormatter/UrlPlainFormatter.php @@ -11,9 +11,7 @@ * id = "file_url_plain", * label = @Translation("URL to file"), * field_types = { - * "entity_reference", - * "file", - * "image" + * "file" * } * ) */ diff --git a/core/modules/file/tests/src/Kernel/Formatter/FileEntityFormatterTest.php b/core/modules/file/tests/src/Kernel/Formatter/FileEntityFormatterTest.php index 743da80..db8e359 100644 --- a/core/modules/file/tests/src/Kernel/Formatter/FileEntityFormatterTest.php +++ b/core/modules/file/tests/src/Kernel/Formatter/FileEntityFormatterTest.php @@ -3,6 +3,7 @@ namespace Drupal\Tests\file\Kernel\Formatter; use Drupal\Core\Entity\Entity\EntityViewDisplay; +use Drupal\Core\Field\BaseFieldDefinition; use Drupal\Core\Url; use Drupal\file\Entity\File; use Drupal\KernelTests\KernelTestBase; @@ -165,4 +166,47 @@ public function testFormatterFileSize() { } } + /** + * Tests that file formatters can be used on entity reference fields. + */ + public function testFileFormattersOnEntityReferenceFields() { + /** @var \Drupal\Core\Field\FormatterPluginManager $formatter_plugin_manager */ + $formatter_plugin_manager = \Drupal::service('plugin.manager.field.formatter'); + + $applicable_field_definition = BaseFieldDefinition::create('entity_reference') + ->setSetting('target_type', 'file'); + $inapplicable_field_definition = BaseFieldDefinition::create('entity_reference') + ->setSetting('target_type', 'user'); + + $file_formatters = ['file_default', 'file_table', 'file_url_plain', 'file_rss_enclosure']; + foreach ($file_formatters as $file_formatter) { + $formatter_options = array( + 'field_definition' => $applicable_field_definition, + 'view_mode' => 'default', + 'configuration' => array( + 'type' => $file_formatter, + ), + ); + + // Check that file formatters can be used for an entity reference field + // that targets file entities. + $instance = $formatter_plugin_manager->getInstance($formatter_options); + $this->assertEquals($file_formatter, $instance->getPluginId()); + + // Check that file formatters can not be used for an entity reference + // field that doesn't targets file entities, and that the default + // formatter is used. + $formatter_options['field_definition'] = $inapplicable_field_definition; + $instance = $formatter_plugin_manager->getInstance($formatter_options); + $this->assertNotEquals($file_formatter, $instance->getPluginId()); + $this->assertEquals('entity_reference_label', $instance->getPluginId()); + } + + // Check that file reference fields can use the generic entity reference + // formatters. + $entity_reference_formatters = ['entity_reference_entity_id', 'entity_reference_entity_view', 'entity_reference_label']; + $available_formatters = array_keys($formatter_plugin_manager->getOptions('file')); + $this->assertTrue(!array_diff($entity_reference_formatters, $available_formatters), 'Entity reference formatters can be used by the file reference field.'); + } + } diff --git a/core/modules/image/image.module b/core/modules/image/image.module index 7f8314a..a563353 100644 --- a/core/modules/image/image.module +++ b/core/modules/image/image.module @@ -98,6 +98,20 @@ function image_help($route_name, RouteMatchInterface $route_match) { } /** + * Implements hook_field_formatter_info_alter(). + */ +function image_field_formatter_info_alter(&$info) { + // Allow the image formatter to be used on entity reference and file fields. + $info['image']['field_types'][] = 'entity_reference'; + $info['image']['field_types'][] = 'file'; + + // Allow entity reference formatters to be used on image fields. + $info['entity_reference_entity_id']['field_types'][] = 'image'; + $info['entity_reference_entity_view']['field_types'][] = 'image'; + $info['entity_reference_label']['field_types'][] = 'image'; +} + +/** * Implements hook_theme(). */ function image_theme() { diff --git a/core/modules/image/tests/src/Kernel/ImageFormatterTest.php b/core/modules/image/tests/src/Kernel/ImageFormatterTest.php index d1b132e..147861a 100644 --- a/core/modules/image/tests/src/Kernel/ImageFormatterTest.php +++ b/core/modules/image/tests/src/Kernel/ImageFormatterTest.php @@ -3,10 +3,13 @@ namespace Drupal\Tests\image\Kernel; use Drupal\Component\Utility\Unicode; +use Drupal\Core\Field\BaseFieldDefinition; use Drupal\Core\Field\FieldStorageDefinitionInterface; use Drupal\entity_test\Entity\EntityTest; use Drupal\field\Entity\FieldConfig; use Drupal\field\Entity\FieldStorageConfig; +use Drupal\file\Plugin\Field\FieldType\FileItem; +use Drupal\image\Plugin\Field\FieldType\ImageItem; use Drupal\Tests\field\Kernel\FieldKernelTestBase; /** @@ -99,4 +102,89 @@ function testImageFormatterCacheTags() { $this->assertEquals($entity->{$this->fieldName}[1]->entity->getCacheTags(), $build[$this->fieldName][1]['#cache']['tags'], 'Second image cache tags is as expected'); } + /** + * Tests that image formatters can be used on entity reference fields. + */ + public function testImageFormatterOnEntityReferenceFields() { + /** @var \Drupal\Core\Field\FormatterPluginManager $formatter_plugin_manager */ + $formatter_plugin_manager = \Drupal::service('plugin.manager.field.formatter'); + + $applicable_field_definition = BaseFieldDefinition::create('entity_reference') + ->setSetting('target_type', 'file'); + $inapplicable_field_definition = BaseFieldDefinition::create('entity_reference') + ->setSetting('target_type', 'user'); + + $formatter_options = array( + 'field_definition' => $applicable_field_definition, + 'view_mode' => 'default', + 'configuration' => array( + 'type' => 'image', + ), + ); + + // Check that image formatters can be used for an entity reference field + // that targets image entities. + $instance = $formatter_plugin_manager->getInstance($formatter_options); + $this->assertEquals('image', $instance->getPluginId()); + + // Check that image formatters can not be used for an entity reference + // field that doesn't targets image entities, and that the default + // formatter is used. + $formatter_options['field_definition'] = $inapplicable_field_definition; + $instance = $formatter_plugin_manager->getInstance($formatter_options); + $this->assertNotEquals('image', $instance->getPluginId()); + $this->assertEquals('entity_reference_label', $instance->getPluginId()); + + // Check that image reference fields can use the generic entity reference + // formatters. + $entity_reference_formatters = ['entity_reference_entity_id', 'entity_reference_entity_view', 'entity_reference_label']; + $available_formatters = array_keys($formatter_plugin_manager->getOptions('image')); + $this->assertTrue(!array_diff($entity_reference_formatters, $available_formatters), 'Entity reference formatters can be used by the image reference field.'); + + // Check that the image formatter only outputs relevant field items when + // used on a non-image reference field (e.g. file field). + $this->fieldName = Unicode::strtolower($this->randomMachineName()); + FieldStorageConfig::create(array( + 'entity_type' => $this->entityType, + 'field_name' => $this->fieldName, + 'type' => 'file', + 'cardinality' => FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED, + ))->save(); + $field_definition = FieldConfig::create([ + 'entity_type' => $this->entityType, + 'field_name' => $this->fieldName, + 'bundle' => $this->bundle, + 'settings' => [ + 'file_extensions' => 'txt jpg', + ], + ]); + $field_definition->save(); + + $this->display = entity_get_display($this->entityType, $this->bundle, 'default') + ->setComponent($this->fieldName, [ + 'type' => 'image', + 'label' => 'hidden', + ]); + $this->display->save(); + + // Create a test entity with the image field set. + $entity = EntityTest::create([ + 'name' => $this->randomMachineName(), + ]); + + // Add a image value. + $entity->{$this->fieldName}->appendItem(ImageItem::generateSampleValue($field_definition)); + + // Add a non-image value. + $entity->{$this->fieldName}->appendItem(FileItem::generateSampleValue($field_definition)); + + $entity->save(); + + // Generate the render array to verify that the second value of the field + // is not rendered. + $build = $this->display->build($entity); + $this->assertTrue(isset($build[$this->fieldName][0])); + $this->assertFalse(isset($build[$this->fieldName][1])); + } + } diff --git a/core/modules/responsive_image/responsive_image.module b/core/modules/responsive_image/responsive_image.module index 89ac37f..442eb99 100644 --- a/core/modules/responsive_image/responsive_image.module +++ b/core/modules/responsive_image/responsive_image.module @@ -56,6 +56,16 @@ function responsive_image_help($route_name, RouteMatchInterface $route_match) { } /** + * Implements hook_field_formatter_info_alter(). + */ +function responsive_image_field_formatter_info_alter(&$info) { + // Allow the responsive_image formatter to be used on entity reference and + // file fields. + $info['responsive_image']['field_types'][] = 'entity_reference'; + $info['responsive_image']['field_types'][] = 'file'; +} + +/** * Implements hook_theme(). */ function responsive_image_theme() { diff --git a/core/modules/responsive_image/src/Plugin/Field/FieldFormatter/ResponsiveImageFormatter.php b/core/modules/responsive_image/src/Plugin/Field/FieldFormatter/ResponsiveImageFormatter.php index 143e9f4..ff91e68 100644 --- a/core/modules/responsive_image/src/Plugin/Field/FieldFormatter/ResponsiveImageFormatter.php +++ b/core/modules/responsive_image/src/Plugin/Field/FieldFormatter/ResponsiveImageFormatter.php @@ -22,8 +22,6 @@ * id = "responsive_image", * label = @Translation("Responsive image"), * field_types = { - * "entity_reference", - * "file", * "image", * } * )