diff --git a/core/modules/media/config/schema/media.schema.yml b/core/modules/media/config/schema/media.schema.yml index dad5189..27e0768 100644 --- a/core/modules/media/config/schema/media.schema.yml +++ b/core/modules/media/config/schema/media.schema.yml @@ -52,6 +52,14 @@ media.source.image: type: media.source.field_aware label: '"Image" media source configuration' +media.source.file_audio: + type: media.source.field_aware + label: '"Audio" media source configuration' + +media.source.file_video: + type: media.source.field_aware + label: '"Video" media source configuration' + media.source.field_aware: type: mapping mapping: diff --git a/core/modules/media/images/icons/audio.png b/core/modules/media/images/icons/audio.png new file mode 100755 index 0000000..56b3d00 --- /dev/null +++ b/core/modules/media/images/icons/audio.png @@ -0,0 +1,15 @@ +PNG + + IHDRetEXtSoftwareAdobe ImageReadyqe< iTXtXML:com.adobe.xmp E:CIDATx]WEeovADdSWE@Ň?QYmaEGdiim=]9LEdu7V5qa̓TWފy_~CC 9BC 9BC !@!r!@!r!@W`6+W/-- 9.5NgCCCFFILL+**Y__rI-3ΐׯ 9.0-BK͖Eʑl!BBB֞3 HIIr\"pF&`#$zM`8 菫W +9'O8/_<9mKKKtt#8uǏ?}d?[QQQUU#bmm-L1B3?zWWe(,,rGLL̽{@(?ct!Bϼ<88TE!aN|RO>sP}ʏ\""??ٳgxq}~cqq9r[}Y&LV;0 ͜!9߿t{{)>7r\v Ooo/ uDVHJJzIqqq1VTT 9 ?sssRB\_rKҦaBb+ZpyLB?p!sR͛ bcczx<#l{_|d$5ϟ[PMTj,..ˁ fqp:L$]??.[j޽k 3-0۷olHxq&0&|7n y1~rz|9-I]Ong#A~KhqF{`=rZ<~8@:@^p#pa ǹa/94n^ |>?ξwd9 p2@`܌5U)C`FEAS LwKB塡!~suuuiiv) ߳gϬU3???00MMM~ ׯ9a itO9Abaa_ƀ((++NX4 f֪x<8䰄9!2- +v`?XagrU-oFrGՙĢ1LLL0cuj. $o0ۇuE`bLo߾lYH@OճO>$-޽ Ƈx^GTKoӄ;AI?g^s.VWWGZ$tJX0ÇH䀄njj +$<8i+͹n!qdMܥѷBVwXvv6YЏ?~§ϲ(9~g~߈BVYWQx'x8d,B=YE u NWMk{DPPAH"1–՝=NX T =D#ɜTCЛ̋,&U~,,,iM$%ςg&`6m/P5CiC0өT)r!?S kxn+q!f!e,677 oM444(B:Uڧ"Sg s +9|Y$ķa8u~ 3 p5rz===%P^^T앐ďY@8$b##I!`1K__3 s]VV$K].9''8>)hVȡ_y&x|18|R,$v +eo{{,y 3(C XAN;%/؄g!㋴4~a:xLN'2vvvaXH/Ȝ7RI!)h'3ANIIr@9lj\v;_EYJ 87s 9 beeL4l{SAvR)ʩ/r_|||LܫW7~a9p} 9e٘'nkɏf1ܟvp|A֊jnAEL,%j,,?AjR!(rk_ +ABppp@; KHQC /r,'P*L m!g-?H%B#/KQ\ bΥngޢ_!0BNv ~pACtr`K'PNc ؃fcB3!rn|:2>#::,8C4QSS Ԧf,݌`Hr@ *++9#rĝqsvsrj#Zό:HYflBByFb9X(--eCQy +~nEiN0B=Yxyyyu9Ç o(i`y!`>ql`w7_YY AZ=@!5 مC9L<#( >9V*INN.,,$mll(Y,2GyK 9r0/ZC:00z}LQQyXQR22AN!/~26p5Φ?VOfff.rK~kkk^R;3o޼Q, >FxZ$}LOOó{V(P,?ΙMF?\_7( +>xuꨨ~Ii_SkY 5"G+ՠ9hW}Am ?AB arh溧gjjwP9K{Ilc9 ]n~@ɶ2@8 +z3330!>ڼS_ϷϫB(*eHk_|IZ՜0`>!9/[͘>7Y19P666TD.i6<RQHiV;;;w̞q*O?c6Txz}}}Axp8<`!CaDZzWztt9<_6JX^z?lfW`6#_|Y\\4bzSHT?֛(1Аu?8S)vaLp|f^?N3I^cE+Utww0 yҷ7PE=--tʪUBvOȌ80 0#w%!Л5#aҩ)O0'9׸`@rV-0^ZZ4fC9+PRR٦qWH,3!L+La|?Jg ?n]~E\$x'unǘu2 4VB6ԅqRͷ~",.`4S+ÞOOO~fІہ Hv8LצTg9z<f ݏ~>98#TOMs|ns0kKK ?|*:p#GW<a9ƶrj%Xyp;+믿MF h`0+0nwOOD܊@!r!@!r!@!rBC 9BC 9a 0-5^5IENDB` \ No newline at end of file diff --git a/core/modules/media/images/icons/video.png b/core/modules/media/images/icons/video.png new file mode 100755 index 0000000..17b4816 --- /dev/null +++ b/core/modules/media/images/icons/video.png @@ -0,0 +1,7 @@ +PNG + + IHDRYIDATxܧz0\m: +[zJ;L0!#1#3پӝGe`\f,{Or'XCSeORΏgFhKB rюFh] Z 4ГZԂ!S<#zKhNqǟWG[[?S7ghaz +s39 +`z{D 4u>%m57,hh.m.hCq2?ZR)xY^SS Ձ])*{y$RG 4@ 4hhZ[fd hi\P/a)aL~햪 -kA˛o.]~twvQ\PchُdG2zV:L<-u›Kn4@ 4@ 4@ 4@ք5eJ֞xI~IOsetComponent($this->getSourceFieldDefinition($type)->getName()); + } + + /** + * {@inheritdoc} + */ + public function prepareFormDisplay(MediaTypeInterface $type, EntityFormDisplayInterface $display) { + $display->setComponent($this->getSourceFieldDefinition($type)->getName()); + } + } diff --git a/core/modules/media/src/MediaSourceInterface.php b/core/modules/media/src/MediaSourceInterface.php index 723e0b9..43dd8aa 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,40 @@ public function getSourceFieldDefinition(MediaTypeInterface $type); */ public function createSourceField(MediaTypeInterface $type); + /** + * Prepares the media type fields for this source 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 media type fields in the view display. + * + * @param \Drupal\media\MediaTypeInterface $type + * The media type which is using this source. + * @param \Drupal\Core\Entity\Display\EntityViewDisplayInterface $display + * The display which should be prepared. + * + * @see \Drupal\Core\Entity\Display\EntityDisplayInterface::setComponent() + * @see \Drupal\Core\Entity\Display\EntityDisplayInterface::removeComponent() + */ + public function prepareViewDisplay(MediaTypeInterface $type, EntityViewDisplayInterface $display); + + /** + * Prepares the media type fields for this source 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 media type fields in the form display. + * + * @param \Drupal\media\MediaTypeInterface $type + * The media type which is using this source. + * @param \Drupal\Core\Entity\Display\EntityFormDisplayInterface $display + * The display which should be prepared. + * + * @see \Drupal\Core\Entity\Display\EntityDisplayInterface::setComponent() + * @see \Drupal\Core\Entity\Display\EntityDisplayInterface::removeComponent() + */ + public function prepareFormDisplay(MediaTypeInterface $type, EntityFormDisplayInterface $display); + } diff --git a/core/modules/media/src/MediaTypeForm.php b/core/modules/media/src/MediaTypeForm.php index 5f301d5..04ac4ba 100644 --- a/core/modules/media/src/MediaTypeForm.php +++ b/core/modules/media/src/MediaTypeForm.php @@ -327,30 +327,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, $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, $display); + $display->save(); } } diff --git a/core/modules/media/src/Plugin/media/Source/LocalAudio.php b/core/modules/media/src/Plugin/media/Source/LocalAudio.php new file mode 100644 index 0000000..0fbb650 --- /dev/null +++ b/core/modules/media/src/Plugin/media/Source/LocalAudio.php @@ -0,0 +1,39 @@ +set('settings', ['file_extensions' => 'mp3 ogg wav wma aiff aac m4a']); + } + + /** + * {@inheritdoc} + */ + public function prepareViewDisplay(MediaTypeInterface $type, EntityViewDisplayInterface $display) { + $display->setComponent($this->getSourceFieldDefinition($type)->getName(), [ + 'type' => 'file_audio', + ]); + } + +} diff --git a/core/modules/media/src/Plugin/media/Source/LocalVideo.php b/core/modules/media/src/Plugin/media/Source/LocalVideo.php new file mode 100644 index 0000000..a285d3c --- /dev/null +++ b/core/modules/media/src/Plugin/media/Source/LocalVideo.php @@ -0,0 +1,39 @@ +set('settings', ['file_extensions' => 'mp4 webm ogg ogv']); + } + + /** + * {@inheritdoc} + */ + public function prepareViewDisplay(MediaTypeInterface $type, EntityViewDisplayInterface $display) { + $display->setComponent($this->getSourceFieldDefinition($type)->getName(), [ + 'type' => 'file_video', + ]); + } + +} 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 089aeac..ab02564 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 0000000..19dde8b --- /dev/null +++ b/core/modules/media/tests/modules/media_test_source/src/Plugin/media/Source/TestDifferentDisplays.php @@ -0,0 +1,46 @@ +setComponent($this->getSourceFieldDefinition($type)->getName(), [ + 'type' => 'entity_reference_entity_id', + ]); + } + + /** + * {@inheritdoc} + */ + public function prepareFormDisplay(MediaTypeInterface $type, EntityFormDisplayInterface $display) { + $display->setComponent($this->getSourceFieldDefinition($type)->getName(), [ + '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 0000000..e5ac525 --- /dev/null +++ b/core/modules/media/tests/modules/media_test_source/src/Plugin/media/Source/TestWithHiddenSourceField.php @@ -0,0 +1,42 @@ +removeComponent($this->getSourceFieldDefinition($type)->getName()); + } + + /** + * {@inheritdoc} + */ + public function prepareFormDisplay(MediaTypeInterface $type, EntityFormDisplayInterface $display) { + $display->removeComponent($this->getSourceFieldDefinition($type)->getName()); + } + + /** + * {@inheritdoc} + */ + protected function getSourceFieldName() { + return 'field_media_hidden'; + } + +} diff --git a/core/modules/media/tests/src/FunctionalJavascript/MediaSourceAudioVideoTest.php b/core/modules/media/tests/src/FunctionalJavascript/MediaSourceAudioVideoTest.php new file mode 100644 index 0000000..3b53952 --- /dev/null +++ b/core/modules/media/tests/src/FunctionalJavascript/MediaSourceAudioVideoTest.php @@ -0,0 +1,62 @@ +doTestCreateMediaType($type_name, $source_id); + + // Check that the source field was created with the correct settings. + $storage = FieldStorageConfig::load("media.$field_name"); + $this->assertNotNull($storage); + $field = FieldConfig::load("media.$type_name.$field_name"); + $this->assertNotNull($field); + $this->assertSame('mp3 ogg wav wma aiff aac m4a', FieldConfig::load("media.$type_name.$field_name")->get('settings')['file_extensions']); + + // Check that the display holds the correct formatter configuration. + $display = EntityViewDisplay::load("media.$type_name.default"); + $this->assertNotNull($display); + $formatter = $display->getComponent($field_name)['type']; + $this->assertSame('file_audio', $formatter); + } + + /** + * Check the Local Video source functionality. + */ + public function testVideoTypeCreation() { + $source_id = 'file_video'; + $type_name = 'video_type'; + $field_name = 'field_media_' . $source_id; + $this->doTestCreateMediaType($type_name, $source_id); + + // Check that the source field was created with the correct settings. + $storage = FieldStorageConfig::load("media.$field_name"); + $this->assertNotNull($storage); + $field = FieldConfig::load("media.$type_name.$field_name"); + $this->assertNotNull($field); + $this->assertSame('mp4 webm ogg ogv', FieldConfig::load("media.$type_name.$field_name")->get('settings')['file_extensions']); + + // Check that the display holds the correct formatter configuration. + $display = EntityViewDisplay::load("media.$type_name.default"); + $this->assertNotNull($display); + $formatter = $display->getComponent($field_name)['type']; + $this->assertSame('file_video', $formatter); + } + +} diff --git a/core/modules/media/tests/src/Kernel/MediaSourceTest.php b/core/modules/media/tests/src/Kernel/MediaSourceTest.php index fc30326..e985303 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); + } + }