diff --git a/core/modules/media/src/MediaSourceBase.php b/core/modules/media/src/MediaSourceBase.php index dea0140260..a82ab2ec2b 100644 --- a/core/modules/media/src/MediaSourceBase.php +++ b/core/modules/media/src/MediaSourceBase.php @@ -3,6 +3,8 @@ namespace Drupal\media; use Drupal\Component\Utility\NestedArray; +use Drupal\Core\Entity\Display\EntityFormDisplayInterface; +use Drupal\Core\Entity\Display\EntityViewDisplayInterface; use Drupal\Core\Entity\EntityFieldManagerInterface; use Drupal\Core\Entity\EntityTypeManagerInterface; use Drupal\Core\Field\FieldTypePluginManagerInterface; @@ -317,4 +319,18 @@ protected function getSourceFieldName() { return $id; } + /** + * {@inheritdoc} + */ + public function prepareViewDisplay(MediaTypeInterface $type, $field_name, EntityViewDisplayInterface $display) { + $display->setComponent($field_name); + } + + /** + * {@inheritdoc} + */ + public function prepareFormDisplay(MediaTypeInterface $type, $field_name, EntityFormDisplayInterface $display) { + $display->setComponent($field_name); + } + } diff --git a/core/modules/media/src/MediaSourceInterface.php b/core/modules/media/src/MediaSourceInterface.php index 723e0b9a8e..1c6f4d97dd 100644 --- a/core/modules/media/src/MediaSourceInterface.php +++ b/core/modules/media/src/MediaSourceInterface.php @@ -4,6 +4,8 @@ use Drupal\Component\Plugin\ConfigurablePluginInterface; use Drupal\Component\Plugin\PluginInspectionInterface; +use Drupal\Core\Entity\Display\EntityFormDisplayInterface; +use Drupal\Core\Entity\Display\EntityViewDisplayInterface; use Drupal\Core\Plugin\PluginFormInterface; /** @@ -139,4 +141,44 @@ public function getSourceFieldDefinition(MediaTypeInterface $type); */ public function createSourceField(MediaTypeInterface $type); + /** + * Prepares the source field in the view display. + * + * This method should normally call + * \Drupal\Core\Entity\Display\EntityDisplayInterface::setComponent() or + * \Drupal\Core\Entity\Display\EntityDisplayInterface::removeComponent() to + * configure the source field in the view display. + * + * @param \Drupal\media\MediaTypeInterface $type + * The media type which is using this source. + * @param string $field_name + * Field name of the source field. + * @param \Drupal\Core\Entity\Display\EntityViewDisplayInterface $display + * The display in which the field appears. + * + * @see \Drupal\Core\Entity\Display\EntityDisplayInterface::setComponent() + * @see \Drupal\Core\Entity\Display\EntityDisplayInterface::removeComponent() + */ + public function prepareViewDisplay(MediaTypeInterface $type, $field_name, EntityViewDisplayInterface $display); + + /** + * Prepares the source field in the form display. + * + * This method should normally call + * \Drupal\Core\Entity\Display\EntityDisplayInterface::setComponent() or + * \Drupal\Core\Entity\Display\EntityDisplayInterface::removeComponent() to + * configure the source field in the form display. + * + * @param \Drupal\media\MediaTypeInterface $type + * The media type which is using this source. + * @param string $field_name + * Field name of the source field. + * @param \Drupal\Core\Entity\Display\EntityFormDisplayInterface $display + * The display in which the field appears. + * + * @see \Drupal\Core\Entity\Display\EntityDisplayInterface::setComponent() + * @see \Drupal\Core\Entity\Display\EntityDisplayInterface::removeComponent() + */ + public function prepareFormDisplay(MediaTypeInterface $type, $field_name, EntityFormDisplayInterface $display); + } diff --git a/core/modules/media/src/MediaTypeForm.php b/core/modules/media/src/MediaTypeForm.php index 5f301d58ed..38b1035aa2 100644 --- a/core/modules/media/src/MediaTypeForm.php +++ b/core/modules/media/src/MediaTypeForm.php @@ -4,6 +4,7 @@ use Drupal\Core\Ajax\AjaxResponse; use Drupal\Core\Ajax\ReplaceCommand; +use Drupal\Core\Entity\Display\EntityDisplayInterface; use Drupal\Core\Entity\EntityFieldManagerInterface; use Drupal\Core\Entity\EntityForm; use Drupal\Core\Field\BaseFieldDefinition; @@ -328,29 +329,19 @@ public function save(array $form, FormStateInterface $form_state) { // Add the new field to the default form and view displays for this // media type. $field_name = $source_field->getName(); - $field_type = $source_field->getType(); - if ($source_field->isDisplayConfigurable('form')) { - // Use the default widget and settings. - $component = \Drupal::service('plugin.manager.field.widget') - ->prepareConfiguration($field_type, []); - // @todo Replace entity_get_form_display() when #2367933 is done. // https://www.drupal.org/node/2872159. - entity_get_form_display('media', $media_type->id(), 'default') - ->setComponent($field_name, $component) - ->save(); + $display = entity_get_form_display('media', $media_type->id(), 'default'); + $source->prepareFormDisplay($media_type, $field_name, $display); + $display->save(); } if ($source_field->isDisplayConfigurable('view')) { - // Use the default formatter and settings. - $component = \Drupal::service('plugin.manager.field.formatter') - ->prepareConfiguration($field_type, []); - // @todo Replace entity_get_display() when #2367933 is done. // https://www.drupal.org/node/2872159. - entity_get_display('media', $media_type->id(), 'default') - ->setComponent($field_name, $component) - ->save(); + $display = entity_get_display('media', $media_type->id(), 'default'); + $source->prepareViewDisplay($media_type, $field_name, $display); + $display->save(); } } diff --git a/core/modules/media/tests/modules/media_test_source/config/schema/media_test_source.schema.yml b/core/modules/media/tests/modules/media_test_source/config/schema/media_test_source.schema.yml index 089aeac35f..ab025640b4 100644 --- a/core/modules/media/tests/modules/media_test_source/config/schema/media_test_source.schema.yml +++ b/core/modules/media/tests/modules/media_test_source/config/schema/media_test_source.schema.yml @@ -13,3 +13,11 @@ media.source.test_translation: media.source.test_constraints: type: media.source.test label: 'Test media source with constraints configuration' + +media.source.test_hidden_source_field: + type: media.source.test + label: 'Test media source with hidden source field' + +media.source.test_different_displays: + type: media.source.test + label: 'Test media source with different source field displays' diff --git a/core/modules/media/tests/modules/media_test_source/src/Plugin/media/Source/TestDifferentDisplays.php b/core/modules/media/tests/modules/media_test_source/src/Plugin/media/Source/TestDifferentDisplays.php new file mode 100644 index 0000000000..736f7bacf6 --- /dev/null +++ b/core/modules/media/tests/modules/media_test_source/src/Plugin/media/Source/TestDifferentDisplays.php @@ -0,0 +1,42 @@ +setComponent($field_name, ['type' => 'entity_reference_entity_id']); + } + + /** + * {@inheritdoc} + */ + public function prepareFormDisplay(MediaTypeInterface $type, $field_name, EntityFormDisplayInterface $display) { + $display->setComponent($field_name, ['type' => 'entity_reference_autocomplete_tags']); + } + + /** + * {@inheritdoc} + */ + protected function getSourceFieldName() { + return 'field_media_different_display'; + } + +} diff --git a/core/modules/media/tests/modules/media_test_source/src/Plugin/media/Source/TestWithHiddenSourceField.php b/core/modules/media/tests/modules/media_test_source/src/Plugin/media/Source/TestWithHiddenSourceField.php new file mode 100644 index 0000000000..f915497853 --- /dev/null +++ b/core/modules/media/tests/modules/media_test_source/src/Plugin/media/Source/TestWithHiddenSourceField.php @@ -0,0 +1,42 @@ +removeComponent($field_name); + } + + /** + * {@inheritdoc} + */ + public function prepareFormDisplay(MediaTypeInterface $type, $field_name, EntityFormDisplayInterface $display) { + $display->removeComponent($field_name); + } + + /** + * {@inheritdoc} + */ + protected function getSourceFieldName() { + return 'field_media_hidden'; + } + +} diff --git a/core/modules/media/tests/src/Kernel/MediaSourceTest.php b/core/modules/media/tests/src/Kernel/MediaSourceTest.php index fc30326fb1..e985303566 100644 --- a/core/modules/media/tests/src/Kernel/MediaSourceTest.php +++ b/core/modules/media/tests/src/Kernel/MediaSourceTest.php @@ -442,4 +442,79 @@ public function testSourceConfigurationSubmit() { $this->assertEquals($expected, $source->getConfiguration(), 'Submitted values were saved correctly.'); } + /** + * Tests different display options for the source field. + */ + public function testDifferentSourceFieldDisplays() { + $id = 'test_different_displays'; + $field_name = 'field_media_different_display'; + + $this->createMediaTypeViaForm($id, $field_name); + + // Source field not in displays. + $display = entity_get_display('media', $id, 'default'); + $components = $display->getComponents(); + $this->assertArrayHasKey($field_name, $components); + $this->assertSame('entity_reference_entity_id', $components[$field_name]['type']); + + $display = entity_get_form_display('media', $id, 'default'); + $components = $display->getComponents(); + $this->assertArrayHasKey($field_name, $components); + $this->assertSame('entity_reference_autocomplete_tags', $components[$field_name]['type']); + } + + /** + * Tests hidden source field in media type. + */ + public function testHiddenSourceField() { + $id = 'test_hidden_source_field'; + $field_name = 'field_media_hidden'; + + $this->createMediaTypeViaForm($id, $field_name); + + // Source field not in displays. + $display = entity_get_display('media', $id, 'default'); + $this->assertArrayNotHasKey($field_name, $display->getComponents()); + + $display = entity_get_form_display('media', $id, 'default'); + $this->assertArrayNotHasKey($field_name, $display->getComponents()); + } + + /** + * Creates a media type via form submit. + * + * @param string $source_plugin_id + * Source plugin ID. + * @param string $field_name + * Source field name. + */ + protected function createMediaTypeViaForm($source_plugin_id, $field_name) { + /** @var \Drupal\media\MediaTypeInterface $type */ + $type = MediaType::create(['source' => $source_plugin_id]); + + $form = $this->container->get('entity_type.manager') + ->getFormObject('media_type', 'add') + ->setEntity($type); + + $form_state = new FormState(); + $form_state->setValues([ + 'label' => 'Test type', + 'id' => $source_plugin_id, + 'op' => t('Save'), + ]); + + /** @var \Drupal\Core\Entity\EntityFieldManagerInterface $field_manager */ + $field_manager = \Drupal::service('entity_field.manager'); + + // Source field not created yet. + $fields = $field_manager->getFieldDefinitions('media', $source_plugin_id); + $this->assertArrayNotHasKey($field_name, $fields); + + \Drupal::formBuilder()->submitForm($form, $form_state); + + // Source field exists now. + $fields = $field_manager->getFieldDefinitions('media', $source_plugin_id); + $this->assertArrayHasKey($field_name, $fields); + } + }