diff --git a/core/modules/media/src/Attribute/MediaSource.php b/core/modules/media/src/Attribute/MediaSource.php new file mode 100644 index 0000000000000000000000000000000000000000..13289419f1f34d128b7b9d048cbd853643c7d745 --- /dev/null +++ b/core/modules/media/src/Attribute/MediaSource.php @@ -0,0 +1,87 @@ +<?php + +declare(strict_types=1); + +namespace Drupal\media\Attribute; + +use Drupal\Component\Plugin\Attribute\Plugin; +use Drupal\Core\StringTranslation\TranslatableMarkup; + +/** + * Defines a MediaSource attribute. + * + * Media sources are responsible for implementing all the logic for dealing + * with a particular type of media. They provide various universal and + * type-specific metadata about media of the type they handle. + * + * Plugin namespace: Plugin\media\Source + * + * For a working example, see \Drupal\media\Plugin\media\Source\File. + * + * @see \Drupal\media\MediaSourceInterface + * @see \Drupal\media\MediaSourceBase + * @see \Drupal\media\MediaSourceManager + * @see hook_media_source_info_alter() + * @see plugin_api + */ +#[\Attribute(\Attribute::TARGET_CLASS)] +class MediaSource extends Plugin { + + /** + * Constructs a new MediaSource attribute. + * + * @param string $id + * The attribute class ID. + * @param \Drupal\Core\StringTranslation\TranslatableMarkup $label + * The human-readable name of the media source. + * @param \Drupal\Core\StringTranslation\TranslatableMarkup|null $description + * (optional) A brief description of the media source. + * @param string[] $allowed_field_types + * (optional) The field types that can be used as a source field for this + * media source. + * @param class-string[] $forms + * (optional) The classes used to define media source-specific forms. An + * array of form class names, keyed by ID. The ID represents the operation + * the form is used for, for example, 'media_library_add'. + * @param string $default_thumbnail_filename + * (optional) A filename for the default thumbnail. + * The thumbnails are placed in the directory defined by the config setting + * 'media.settings.icon_base_uri'. When using custom icons, make sure the + * module provides a hook_install() implementation to copy the custom icons + * to this directory. The media_install() function provides a clear example + * of how to do this. + * @param string $thumbnail_uri_metadata_attribute + * (optional) The metadata attribute name to provide the thumbnail URI. + * @param string $thumbnail_width_metadata_attribute + * (optional) The metadata attribute name to provide the thumbnail width. + * @param string $thumbnail_height_metadata_attribute + * (optional) The metadata attribute name to provide the thumbnail height. + * @param string|null $thumbnail_alt_metadata_attribute + * (optional) The metadata attribute name to provide the thumbnail alt. + * "Thumbnail" will be used if the attribute name is not provided. + * @param string|null $thumbnail_title_metadata_attribute + * (optional) The metadata attribute name to provide the thumbnail title. + * The name of the media item will be used if the attribute name is not + * provided. + * @param string $default_name_metadata_attribute + * (optional) The metadata attribute name to provide the default name. + * @param class-string|null $deriver + * (optional) The deriver class. + */ + public function __construct( + public readonly string $id, + public readonly TranslatableMarkup $label, + public readonly ?TranslatableMarkup $description = NULL, + public readonly array $allowed_field_types = [], + public readonly array $forms = [], + public readonly string $default_thumbnail_filename = 'generic.png', + public readonly string $thumbnail_uri_metadata_attribute = 'thumbnail_uri', + public readonly string $thumbnail_width_metadata_attribute = 'thumbnail_width', + public readonly string $thumbnail_height_metadata_attribute = 'thumbnail_height', + public readonly ?string $thumbnail_alt_metadata_attribute = NULL, + public readonly ?string $thumbnail_title_metadata_attribute = NULL, + public readonly string $default_name_metadata_attribute = 'default_name', + public readonly ?string $deriver = NULL + ) {} + +} diff --git a/core/modules/media/src/Attribute/OEmbedMediaSource.php b/core/modules/media/src/Attribute/OEmbedMediaSource.php new file mode 100644 index 0000000000000000000000000000000000000000..3de756bb9d7c2323701dcf1d1c59fbd5721126f9 --- /dev/null +++ b/core/modules/media/src/Attribute/OEmbedMediaSource.php @@ -0,0 +1,86 @@ +<?php + +declare(strict_types=1); + +namespace Drupal\media\Attribute; + +use Drupal\Core\StringTranslation\TranslatableMarkup; + +/** + * Defines a OEmbedMediaSource attribute. + * + * Plugin namespace: Plugin\media\Source + * + * For a working example, see \Drupal\media\Plugin\media\Source\OEmbed. + * + * @see \Drupal\media\MediaSourceInterface + * @see \Drupal\media\MediaSourceBase + * @see \Drupal\media\MediaSourceManager + * @see hook_media_source_info_alter() + * @see plugin_api + */ +#[\Attribute(\Attribute::TARGET_CLASS)] +class OEmbedMediaSource extends MediaSource { + + /** + * Constructs a new OEmbedMediaSource attribute. + * + * @param string $id + * The attribute class ID. + * @param \Drupal\Core\StringTranslation\TranslatableMarkup $label + * The human-readable name of the media source. + * @param \Drupal\Core\StringTranslation\TranslatableMarkup|null $description + * (optional) A brief description of the media source. + * @param string[] $allowed_field_types + * (optional) The field types that can be used as a source field for this + * media source. + * @param class-string[] $forms + * (optional) The classes used to define media source-specific forms. An + * array of form class names, keyed by ID. The ID represents the operation + * the form is used for, for example, 'media_library_add'. + * @param string[] $providers + * (optional) A set of provider names, exactly as they appear in the + * canonical oEmbed provider database at https://oembed.com/providers.json. + * @param string $default_thumbnail_filename + * (optional) A filename for the default thumbnail. + * The thumbnails are placed in the directory defined by the config setting + * 'media.settings.icon_base_uri'. When using custom icons, make sure the + * module provides a hook_install() implementation to copy the custom icons + * to this directory. The media_install() function provides a clear example + * of how to do this. + * @param string $thumbnail_uri_metadata_attribute + * (optional) The metadata attribute name to provide the thumbnail URI. + * @param string $thumbnail_width_metadata_attribute + * (optional) The metadata attribute name to provide the thumbnail width. + * @param string $thumbnail_height_metadata_attribute + * (optional) The metadata attribute name to provide the thumbnail height. + * @param string|null $thumbnail_alt_metadata_attribute + * (optional) The metadata attribute name to provide the thumbnail alt. + * "Thumbnail" will be used if the attribute name is not provided. + * @param string|null $thumbnail_title_metadata_attribute + * (optional) The metadata attribute name to provide the thumbnail title. + * The name of the media item will be used if the attribute name is not + * provided. + * @param string $default_name_metadata_attribute + * (optional) The metadata attribute name to provide the default name. + * @param class-string|null $deriver + * (optional) The deriver class. + */ + public function __construct( + public readonly string $id, + public readonly TranslatableMarkup $label, + public readonly ?TranslatableMarkup $description = NULL, + public readonly array $allowed_field_types = [], + public readonly array $forms = [], + public readonly array $providers = [], + public readonly string $default_thumbnail_filename = 'generic.png', + public readonly string $thumbnail_uri_metadata_attribute = 'thumbnail_uri', + public readonly string $thumbnail_width_metadata_attribute = 'thumbnail_width', + public readonly string $thumbnail_height_metadata_attribute = 'thumbnail_height', + public readonly ?string $thumbnail_alt_metadata_attribute = NULL, + public readonly ?string $thumbnail_title_metadata_attribute = NULL, + public readonly string $default_name_metadata_attribute = 'default_name', + public readonly ?string $deriver = NULL + ) {} + +} diff --git a/core/modules/media/src/MediaSourceManager.php b/core/modules/media/src/MediaSourceManager.php index 5b8778721c76632ca82008d37cf0dad1974dd678..302a5ef553061f546884dd595690503b5a8d02dc 100644 --- a/core/modules/media/src/MediaSourceManager.php +++ b/core/modules/media/src/MediaSourceManager.php @@ -5,7 +5,7 @@ use Drupal\Core\Cache\CacheBackendInterface; use Drupal\Core\Extension\ModuleHandlerInterface; use Drupal\Core\Plugin\DefaultPluginManager; -use Drupal\media\Annotation\MediaSource; +use Drupal\media\Attribute\MediaSource; /** * Manages media source plugins. @@ -24,7 +24,7 @@ class MediaSourceManager extends DefaultPluginManager { * The module handler. */ public function __construct(\Traversable $namespaces, CacheBackendInterface $cache_backend, ModuleHandlerInterface $module_handler) { - parent::__construct('Plugin/media/Source', $namespaces, $module_handler, MediaSourceInterface::class, MediaSource::class); + parent::__construct('Plugin/media/Source', $namespaces, $module_handler, MediaSourceInterface::class, MediaSource::class, '\Drupal\media\Annotation\MediaSource'); $this->alterInfo('media_source_info'); $this->setCacheBackend($cache_backend, 'media_source_plugins'); diff --git a/core/modules/media/src/Plugin/media/Source/AudioFile.php b/core/modules/media/src/Plugin/media/Source/AudioFile.php index 1e215930851d2da5f3dc262d0e5fdd04195ecba5..d2f2035fc6072acbd42836cb6361546727159180 100644 --- a/core/modules/media/src/Plugin/media/Source/AudioFile.php +++ b/core/modules/media/src/Plugin/media/Source/AudioFile.php @@ -3,21 +3,22 @@ namespace Drupal\media\Plugin\media\Source; use Drupal\Core\Entity\Display\EntityViewDisplayInterface; +use Drupal\Core\StringTranslation\TranslatableMarkup; +use Drupal\media\Attribute\MediaSource; use Drupal\media\MediaTypeInterface; /** * Media source wrapping around an audio file. * * @see \Drupal\file\FileInterface - * - * @MediaSource( - * id = "audio_file", - * label = @Translation("Audio file"), - * description = @Translation("Use audio files for reusable media."), - * allowed_field_types = {"file"}, - * default_thumbnail_filename = "audio.png" - * ) */ +#[MediaSource( + id: "audio_file", + label: new TranslatableMarkup("Audio file"), + description: new TranslatableMarkup("Use audio files for reusable media."), + allowed_field_types: ["file"], + default_thumbnail_filename: "audio.png" +)] class AudioFile extends File { /** diff --git a/core/modules/media/src/Plugin/media/Source/File.php b/core/modules/media/src/Plugin/media/Source/File.php index 1c963ef9636b948c9c3bf5715b6d43376e5977bb..ba42d9a49686d8ce6311baa30053bbb9b3254467 100644 --- a/core/modules/media/src/Plugin/media/Source/File.php +++ b/core/modules/media/src/Plugin/media/Source/File.php @@ -2,7 +2,9 @@ namespace Drupal\media\Plugin\media\Source; +use Drupal\Core\StringTranslation\TranslatableMarkup; use Drupal\file\FileInterface; +use Drupal\media\Attribute\MediaSource; use Drupal\media\MediaInterface; use Drupal\media\MediaTypeInterface; use Drupal\media\MediaSourceBase; @@ -11,15 +13,13 @@ * File entity media source. * * @see \Drupal\file\FileInterface - * - * @MediaSource( - * id = "file", - * label = @Translation("File"), - * description = @Translation("Use local files for reusable media."), - * allowed_field_types = {"file"}, - * default_thumbnail_filename = "generic.png" - * ) */ +#[MediaSource( + id: "file", + label: new TranslatableMarkup("File"), + description: new TranslatableMarkup("Use local files for reusable media."), + allowed_field_types: ["file"], +)] class File extends MediaSourceBase { /** diff --git a/core/modules/media/src/Plugin/media/Source/Image.php b/core/modules/media/src/Plugin/media/Source/Image.php index 4b6d48bd01cbb139405d8673c3bc0991ec3a40b3..e896f3b41a22238dbde40decb6f50e90914ac790 100644 --- a/core/modules/media/src/Plugin/media/Source/Image.php +++ b/core/modules/media/src/Plugin/media/Source/Image.php @@ -9,6 +9,8 @@ use Drupal\Core\Field\FieldTypePluginManagerInterface; use Drupal\Core\File\FileSystemInterface; use Drupal\Core\Image\ImageFactory; +use Drupal\Core\StringTranslation\TranslatableMarkup; +use Drupal\media\Attribute\MediaSource; use Drupal\media\MediaInterface; use Drupal\media\MediaTypeInterface; use Symfony\Component\DependencyInjection\ContainerInterface; @@ -17,16 +19,15 @@ * Image entity media source. * * @see \Drupal\Core\Image\ImageInterface - * - * @MediaSource( - * id = "image", - * label = @Translation("Image"), - * description = @Translation("Use local images for reusable media."), - * allowed_field_types = {"image"}, - * default_thumbnail_filename = "no-thumbnail.png", - * thumbnail_alt_metadata_attribute = "thumbnail_alt_value" - * ) */ +#[MediaSource( + id: "image", + label: new TranslatableMarkup("Image"), + description: new TranslatableMarkup("Use local images for reusable media."), + allowed_field_types: ["image"], + default_thumbnail_filename: "no-thumbnail.png", + thumbnail_alt_metadata_attribute: "thumbnail_alt_value" +)] class Image extends File { /** diff --git a/core/modules/media/src/Plugin/media/Source/OEmbed.php b/core/modules/media/src/Plugin/media/Source/OEmbed.php index 34b8581a1df29c9d6851f00230b135605707355d..671e1800c7f6b00ef85fe8b2e390a48fa4d691eb 100644 --- a/core/modules/media/src/Plugin/media/Source/OEmbed.php +++ b/core/modules/media/src/Plugin/media/Source/OEmbed.php @@ -14,8 +14,10 @@ use Drupal\Core\File\FileSystemInterface; use Drupal\Core\Form\FormStateInterface; use Drupal\Core\Messenger\MessengerInterface; +use Drupal\Core\StringTranslation\TranslatableMarkup; use Drupal\Core\Url; use Drupal\Core\Utility\Token; +use Drupal\media\Attribute\OEmbedMediaSource; use Drupal\media\IFrameUrlHelper; use Drupal\media\OEmbed\Resource; use Drupal\media\OEmbed\ResourceException; @@ -65,17 +67,15 @@ * define a new class which extends it. With the code above, you will able to * create media types which use the "Artwork" source plugin, and use those media * types to link to assets on Deviantart and Flickr. - * - * @MediaSource( - * id = "oembed", - * label = @Translation("oEmbed source"), - * description = @Translation("Use oEmbed URL for reusable media."), - * allowed_field_types = {"string"}, - * default_thumbnail_filename = "no-thumbnail.png", - * deriver = "Drupal\media\Plugin\media\Source\OEmbedDeriver", - * providers = {}, - * ) */ +#[OEmbedMediaSource( + id: "oembed", + label: new TranslatableMarkup("oEmbed source"), + description: new TranslatableMarkup("Use oEmbed URL for reusable media."), + allowed_field_types: ["string"], + default_thumbnail_filename: "no-thumbnail.png", + deriver: OEmbedDeriver::class, +)] class OEmbed extends MediaSourceBase implements OEmbedInterface { /** diff --git a/core/modules/media/src/Plugin/media/Source/VideoFile.php b/core/modules/media/src/Plugin/media/Source/VideoFile.php index ebcf2f474a38353c76094e6e8e3292c24264bc72..6c796e58ee37b960e17e22be84df90a88e6f332f 100644 --- a/core/modules/media/src/Plugin/media/Source/VideoFile.php +++ b/core/modules/media/src/Plugin/media/Source/VideoFile.php @@ -3,21 +3,22 @@ namespace Drupal\media\Plugin\media\Source; use Drupal\Core\Entity\Display\EntityViewDisplayInterface; +use Drupal\Core\StringTranslation\TranslatableMarkup; +use Drupal\media\Attribute\MediaSource; use Drupal\media\MediaTypeInterface; /** * Media source wrapping around a video file. * * @see \Drupal\file\FileInterface - * - * @MediaSource( - * id = "video_file", - * label = @Translation("Video file"), - * description = @Translation("Use video files for reusable media."), - * allowed_field_types = {"file"}, - * default_thumbnail_filename = "video.png" - * ) */ +#[MediaSource( + id: "video_file", + label: new TranslatableMarkup("Video file"), + description: new TranslatableMarkup("Use video files for reusable media."), + allowed_field_types: ["file"], + default_thumbnail_filename: "video.png" +)] class VideoFile extends File { /** diff --git a/core/modules/media/tests/modules/media_test_source/src/Plugin/media/Source/Test.php b/core/modules/media/tests/modules/media_test_source/src/Plugin/media/Source/Test.php index b7baaa55578122386ea8ff347e58c945a7e6e33c..3cf8a3e0e36cba2b271deb96d83841ab6c42f766 100644 --- a/core/modules/media/tests/modules/media_test_source/src/Plugin/media/Source/Test.php +++ b/core/modules/media/tests/modules/media_test_source/src/Plugin/media/Source/Test.php @@ -4,19 +4,20 @@ use Drupal\Component\Utility\NestedArray; use Drupal\Core\Form\FormStateInterface; +use Drupal\Core\StringTranslation\TranslatableMarkup; +use Drupal\media\Attribute\MediaSource; use Drupal\media\MediaInterface; use Drupal\media\MediaSourceBase; /** * Provides test media source. - * - * @MediaSource( - * id = "test", - * label = @Translation("Test source"), - * description = @Translation("Test media source."), - * allowed_field_types = {"string"}, - * ) */ +#[MediaSource( + id: "test", + label: new TranslatableMarkup("Test source"), + description: new TranslatableMarkup("Test media source."), + allowed_field_types: ["string"] +)] class Test extends MediaSourceBase { /** 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 index e2389f5301d415c5f91a6f37bec236c205addf4d..61007c31c2ea5d1b6d8c1e68fac0999f0e71d1b8 100644 --- 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 @@ -4,18 +4,19 @@ use Drupal\Core\Entity\Display\EntityFormDisplayInterface; use Drupal\Core\Entity\Display\EntityViewDisplayInterface; +use Drupal\Core\StringTranslation\TranslatableMarkup; +use Drupal\media\Attribute\MediaSource; use Drupal\media\MediaTypeInterface; /** * Provides test media source. - * - * @MediaSource( - * id = "test_different_displays", - * label = @Translation("Test source with different displays"), - * description = @Translation("Test source with different displays."), - * allowed_field_types = {"entity_reference"}, - * ) */ +#[MediaSource( + id: "test_different_displays", + label: new TranslatableMarkup("Test source with different displays"), + description: new TranslatableMarkup("Test source with different displays."), + allowed_field_types: ["entity_reference"] +)] class TestDifferentDisplays extends Test { /** diff --git a/core/modules/media/tests/modules/media_test_source/src/Plugin/media/Source/TestTranslation.php b/core/modules/media/tests/modules/media_test_source/src/Plugin/media/Source/TestTranslation.php index 947f06733b651654ee2459d8a4ca340fd62286a4..9565b724494b40a8c7ddc90ed5563de9e0ef5fa6 100644 --- a/core/modules/media/tests/modules/media_test_source/src/Plugin/media/Source/TestTranslation.php +++ b/core/modules/media/tests/modules/media_test_source/src/Plugin/media/Source/TestTranslation.php @@ -2,19 +2,20 @@ namespace Drupal\media_test_source\Plugin\media\Source; +use Drupal\Core\StringTranslation\TranslatableMarkup; +use Drupal\media\Attribute\MediaSource; use Drupal\media\MediaInterface; /** * Provides test media source. - * - * @MediaSource( - * id = "test_translation", - * label = @Translation("Test source with translations"), - * description = @Translation("Test media source with translations."), - * allowed_field_types = {"string"}, - * thumbnail_alt_metadata_attribute = "test_thumbnail_alt", - * ) */ +#[MediaSource( + id: "test_translation", + label: new TranslatableMarkup("Test source with translations"), + description: new TranslatableMarkup("Test media source with translations."), + allowed_field_types: ["string"], + thumbnail_alt_metadata_attribute: "test_thumbnail_alt" +)] class TestTranslation extends Test { /** diff --git a/core/modules/media/tests/modules/media_test_source/src/Plugin/media/Source/TestWithConstraints.php b/core/modules/media/tests/modules/media_test_source/src/Plugin/media/Source/TestWithConstraints.php index 98039ca2d2a2859db931239c57a8906a2b603ef6..beb9b023e78dacab79045d88a76673912cdde5a3 100644 --- a/core/modules/media/tests/modules/media_test_source/src/Plugin/media/Source/TestWithConstraints.php +++ b/core/modules/media/tests/modules/media_test_source/src/Plugin/media/Source/TestWithConstraints.php @@ -2,19 +2,20 @@ namespace Drupal\media_test_source\Plugin\media\Source; +use Drupal\Core\StringTranslation\TranslatableMarkup; +use Drupal\media\Attribute\MediaSource; use Drupal\media\MediaSourceEntityConstraintsInterface; use Drupal\media\MediaSourceFieldConstraintsInterface; /** * Provides generic media type. - * - * @MediaSource( - * id = "test_constraints", - * label = @Translation("Test source with constraints"), - * description = @Translation("Test media source that provides constraints."), - * allowed_field_types = {"string_long"}, - * ) */ +#[MediaSource( + id: "test_constraints", + label: new TranslatableMarkup("Test source with constraints"), + description: new TranslatableMarkup("Test media source that provides constraints."), + allowed_field_types: ["string_long"], +)] class TestWithConstraints extends Test implements MediaSourceEntityConstraintsInterface, MediaSourceFieldConstraintsInterface { /** 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 index e5ac525eb0e6e839925a97703e74b38e560459bf..ac4754f2818f22958e48bc0429fdbf244e611e2d 100644 --- 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 @@ -4,18 +4,19 @@ use Drupal\Core\Entity\Display\EntityFormDisplayInterface; use Drupal\Core\Entity\Display\EntityViewDisplayInterface; +use Drupal\Core\StringTranslation\TranslatableMarkup; +use Drupal\media\Attribute\MediaSource; use Drupal\media\MediaTypeInterface; /** * Provides test media source. - * - * @MediaSource( - * id = "test_hidden_source_field", - * label = @Translation("Test source with hidden source field"), - * description = @Translation("Test media source with hidden source field."), - * allowed_field_types = {"string"}, - * ) */ +#[MediaSource( + id: "test_hidden_source_field", + label: new TranslatableMarkup("Test source with hidden source field"), + description: new TranslatableMarkup("Test media source with hidden source field."), + allowed_field_types: ["string"], +)] class TestWithHiddenSourceField extends Test { /** diff --git a/core/modules/media_library/media_library.api.php b/core/modules/media_library/media_library.api.php index 5c33600ff53f1c145e434a50918039770cd16831..4979fd1ae2e2759ba6bee8861522f45a51350bbd 100644 --- a/core/modules/media_library/media_library.api.php +++ b/core/modules/media_library/media_library.api.php @@ -60,16 +60,15 @@ * source plugin definition which provides an add form for the media library: * * @code - * @MediaSource( - * id = "file", - * label = @Translation("File"), - * description = @Translation("Use local files for reusable media."), - * allowed_field_types = {"file"}, - * default_thumbnail_filename = "generic.png", - * forms = { - * "media_library_add" = "\Drupal\media_library\Form\FileUploadForm", - * }, - * ) + * #[MediaSource( + * id: "file", + * label: new TranslatableMarkup("File"), + * description: new TranslatableMarkup("Use local files for reusable media."), + * allowed_field_types: ["file"], + * forms = [ + * "media_library_add" => "\Drupal\media_library\Form\FileUploadForm", + * ] + * )] * @endcode * * This can also be done in hook_media_source_info_alter(). For example: