From 328bb474d7ae3aa378fa6d42d8ef2b951a54bea1 Mon Sep 17 00:00:00 2001 From: Alex Pott <alex.a.pott@googlemail.com> Date: Wed, 28 Feb 2024 23:40:17 +0000 Subject: [PATCH] Issue #3420992 by kim.pepper, mstrelan, larowlan: Convert ImageToolkitOperation plugin discovery to attributes --- .../Attribute/ImageToolkitOperation.php | 71 +++++++++++++++++++ .../ImageToolkitOperationManager.php | 16 +++-- .../ImageToolkit/Operation/gd/Convert.php | 18 ++--- .../ImageToolkit/Operation/gd/CreateNew.php | 17 ++--- .../Plugin/ImageToolkit/Operation/gd/Crop.php | 18 ++--- .../ImageToolkit/Operation/gd/Desaturate.php | 18 ++--- .../ImageToolkit/Operation/gd/Resize.php | 18 ++--- .../ImageToolkit/Operation/gd/Rotate.php | 17 ++--- .../ImageToolkit/Operation/gd/Scale.php | 18 ++--- .../Operation/gd/ScaleAndCrop.php | 18 ++--- .../ImageToolkit/Operation/test/Bar.php | 18 ++--- .../ImageToolkit/Operation/test/Failing.php | 18 ++--- .../ImageToolkit/Operation/test/Foo.php | 18 ++--- .../Operation/test/FooDerived.php | 18 ++--- 14 files changed, 201 insertions(+), 100 deletions(-) create mode 100644 core/lib/Drupal/Core/ImageToolkit/Attribute/ImageToolkitOperation.php diff --git a/core/lib/Drupal/Core/ImageToolkit/Attribute/ImageToolkitOperation.php b/core/lib/Drupal/Core/ImageToolkit/Attribute/ImageToolkitOperation.php new file mode 100644 index 000000000000..705a64ca0e16 --- /dev/null +++ b/core/lib/Drupal/Core/ImageToolkit/Attribute/ImageToolkitOperation.php @@ -0,0 +1,71 @@ +<?php + +declare(strict_types=1); + +namespace Drupal\Core\ImageToolkit\Attribute; + +use Drupal\Component\Plugin\Attribute\Plugin; +use Drupal\Core\StringTranslation\TranslatableMarkup; + +/** + * Defines a Plugin attribute for the image toolkit plugin. + * + * An image toolkit operation plugin provides a self-contained image + * manipulation routine, for a specific image toolkit. Examples of image + * toolkit operations are scaling, cropping, rotating, etc. + * + * Plugin namespace: Plugin\ImageToolkit\Operation + * + * For a working example, see + * \Drupal\system\Plugin\ImageToolkit\Operation\gd\Crop + * + * @see \Drupal\Core\ImageToolkit\Annotation\ImageToolkit + * @see \Drupal\image\Annotation\ImageEffect + * @see \Drupal\Core\ImageToolkit\ImageToolkitOperationInterface + * @see \Drupal\Core\ImageToolkit\ImageToolkitOperationBase + * @see \Drupal\Core\ImageToolkit\ImageToolkitOperationManager + * @see plugin_api + * + * @Annotation + */ +#[\Attribute(\Attribute::TARGET_CLASS)] +class ImageToolkitOperation extends Plugin { + + /** + * Constructs a new ImageToolkitOperation instance. + * + * @param string $id + * The plugin ID. + * There are no strict requirements as to the string to be used to identify + * the plugin, since discovery of the appropriate operation plugin to be + * used to apply an operation is based on the values of the 'toolkit' and + * the 'operation' annotation values. + * However, it is recommended that the following patterns be used: + * - '{toolkit}_{operation}' for the first implementation of an operation + * by a toolkit. + * - '{module}_{toolkit}_{operation}' for overrides of existing + * implementations supplied by an alternative module, and for new + * module-supplied operations. + * @param string $toolkit + * The id of the image toolkit plugin for which the operation is + * implemented. + * @param string $operation + * The machine name of the image toolkit operation implemented + * (e.g. "crop"). + * @param \Drupal\Core\StringTranslation\TranslatableMarkup $label + * The human-readable name of the image toolkit operation. + * @param \Drupal\Core\StringTranslation\TranslatableMarkup|null $description + * (optional) The description of the image toolkit operation. + * @param string|null $deriver + * (optional) The deriver class for the image toolkit operation. + */ + public function __construct( + public readonly string $id, + public readonly string $toolkit, + public readonly string $operation, + public readonly TranslatableMarkup $label, + public readonly ?TranslatableMarkup $description = NULL, + public readonly ?string $deriver = NULL, + ) {} + +} diff --git a/core/lib/Drupal/Core/ImageToolkit/ImageToolkitOperationManager.php b/core/lib/Drupal/Core/ImageToolkit/ImageToolkitOperationManager.php index 3eeb7867e4ce..4c1536eac7ff 100644 --- a/core/lib/Drupal/Core/ImageToolkit/ImageToolkitOperationManager.php +++ b/core/lib/Drupal/Core/ImageToolkit/ImageToolkitOperationManager.php @@ -2,12 +2,13 @@ namespace Drupal\Core\ImageToolkit; -use Drupal\Core\Cache\CacheBackendInterface; -use Drupal\Core\Extension\ModuleHandlerInterface; -use Drupal\Core\Plugin\DefaultPluginManager; use Drupal\Component\Plugin\Exception\PluginNotFoundException; use Drupal\Component\Plugin\Factory\DefaultFactory; use Drupal\Component\Render\FormattableMarkup; +use Drupal\Core\Cache\CacheBackendInterface; +use Drupal\Core\Extension\ModuleHandlerInterface; +use Drupal\Core\ImageToolkit\Attribute\ImageToolkitOperation; +use Drupal\Core\Plugin\DefaultPluginManager; use Psr\Log\LoggerInterface; /** @@ -50,7 +51,14 @@ class ImageToolkitOperationManager extends DefaultPluginManager implements Image * The image toolkit manager. */ public function __construct(\Traversable $namespaces, CacheBackendInterface $cache_backend, ModuleHandlerInterface $module_handler, LoggerInterface $logger, ImageToolkitManager $toolkit_manager) { - parent::__construct('Plugin/ImageToolkit/Operation', $namespaces, $module_handler, 'Drupal\Core\ImageToolkit\ImageToolkitOperationInterface', 'Drupal\Core\ImageToolkit\Annotation\ImageToolkitOperation'); + parent::__construct( + 'Plugin/ImageToolkit/Operation', + $namespaces, + $module_handler, + ImageToolkitOperationInterface::class, + ImageToolkitOperation::class, + 'Drupal\Core\ImageToolkit\Annotation\ImageToolkitOperation', + ); $this->alterInfo('image_toolkit_operation'); $this->setCacheBackend($cache_backend, 'image_toolkit_operation_plugins'); diff --git a/core/modules/system/src/Plugin/ImageToolkit/Operation/gd/Convert.php b/core/modules/system/src/Plugin/ImageToolkit/Operation/gd/Convert.php index a7d00573927c..81648a4cdc31 100644 --- a/core/modules/system/src/Plugin/ImageToolkit/Operation/gd/Convert.php +++ b/core/modules/system/src/Plugin/ImageToolkit/Operation/gd/Convert.php @@ -2,17 +2,19 @@ namespace Drupal\system\Plugin\ImageToolkit\Operation\gd; +use Drupal\Core\ImageToolkit\Attribute\ImageToolkitOperation; +use Drupal\Core\StringTranslation\TranslatableMarkup; + /** * Defines GD2 convert operation. - * - * @ImageToolkitOperation( - * id = "gd_convert", - * toolkit = "gd", - * operation = "convert", - * label = @Translation("Convert"), - * description = @Translation("Instructs the toolkit to save the image with a specified extension.") - * ) */ +#[ImageToolkitOperation( + id: "gd_convert", + toolkit: "gd", + operation: "convert", + label: new TranslatableMarkup("Convert"), + description: new TranslatableMarkup("Instructs the toolkit to save the image with a specified extension.") +)] class Convert extends GDImageToolkitOperationBase { /** diff --git a/core/modules/system/src/Plugin/ImageToolkit/Operation/gd/CreateNew.php b/core/modules/system/src/Plugin/ImageToolkit/Operation/gd/CreateNew.php index 282380ffb1ce..7b15796dbce4 100644 --- a/core/modules/system/src/Plugin/ImageToolkit/Operation/gd/CreateNew.php +++ b/core/modules/system/src/Plugin/ImageToolkit/Operation/gd/CreateNew.php @@ -3,18 +3,19 @@ namespace Drupal\system\Plugin\ImageToolkit\Operation\gd; use Drupal\Component\Utility\Color; +use Drupal\Core\ImageToolkit\Attribute\ImageToolkitOperation; +use Drupal\Core\StringTranslation\TranslatableMarkup; /** * Defines GD2 create_new image operation. - * - * @ImageToolkitOperation( - * id = "gd_create_new", - * toolkit = "gd", - * operation = "create_new", - * label = @Translation("Set a new image"), - * description = @Translation("Creates a new transparent object and sets it for the image.") - * ) */ +#[ImageToolkitOperation( + id: "gd_create_new", + toolkit: "gd", + operation: "create_new", + label: new TranslatableMarkup("Set a new image"), + description: new TranslatableMarkup("Creates a new transparent object and sets it for the image.") +)] class CreateNew extends GDImageToolkitOperationBase { /** diff --git a/core/modules/system/src/Plugin/ImageToolkit/Operation/gd/Crop.php b/core/modules/system/src/Plugin/ImageToolkit/Operation/gd/Crop.php index 315cda2e2bca..e1105e9e31e8 100644 --- a/core/modules/system/src/Plugin/ImageToolkit/Operation/gd/Crop.php +++ b/core/modules/system/src/Plugin/ImageToolkit/Operation/gd/Crop.php @@ -2,17 +2,19 @@ namespace Drupal\system\Plugin\ImageToolkit\Operation\gd; +use Drupal\Core\ImageToolkit\Attribute\ImageToolkitOperation; +use Drupal\Core\StringTranslation\TranslatableMarkup; + /** * Defines GD2 Crop operation. - * - * @ImageToolkitOperation( - * id = "gd_crop", - * toolkit = "gd", - * operation = "crop", - * label = @Translation("Crop"), - * description = @Translation("Crops an image to a rectangle specified by the given dimensions.") - * ) */ +#[ImageToolkitOperation( + id: "gd_crop", + toolkit: "gd", + operation: "crop", + label: new TranslatableMarkup("Crop"), + description: new TranslatableMarkup("Crops an image to a rectangle specified by the given dimensions.") +)] class Crop extends GDImageToolkitOperationBase { /** diff --git a/core/modules/system/src/Plugin/ImageToolkit/Operation/gd/Desaturate.php b/core/modules/system/src/Plugin/ImageToolkit/Operation/gd/Desaturate.php index 076f21a6f2fa..466864aa8732 100644 --- a/core/modules/system/src/Plugin/ImageToolkit/Operation/gd/Desaturate.php +++ b/core/modules/system/src/Plugin/ImageToolkit/Operation/gd/Desaturate.php @@ -2,17 +2,19 @@ namespace Drupal\system\Plugin\ImageToolkit\Operation\gd; +use Drupal\Core\ImageToolkit\Attribute\ImageToolkitOperation; +use Drupal\Core\StringTranslation\TranslatableMarkup; + /** * Defines GD2 Desaturate operation. - * - * @ImageToolkitOperation( - * id = "gd_desaturate", - * toolkit = "gd", - * operation = "desaturate", - * label = @Translation("Desaturate"), - * description = @Translation("Converts an image to grayscale.") - * ) */ +#[ImageToolkitOperation( + id: "gd_desaturate", + toolkit: "gd", + operation: "desaturate", + label: new TranslatableMarkup("Desaturate"), + description: new TranslatableMarkup("Converts an image to grayscale.") +)] class Desaturate extends GDImageToolkitOperationBase { /** diff --git a/core/modules/system/src/Plugin/ImageToolkit/Operation/gd/Resize.php b/core/modules/system/src/Plugin/ImageToolkit/Operation/gd/Resize.php index 317bc14bda26..e76104ffa351 100644 --- a/core/modules/system/src/Plugin/ImageToolkit/Operation/gd/Resize.php +++ b/core/modules/system/src/Plugin/ImageToolkit/Operation/gd/Resize.php @@ -2,17 +2,19 @@ namespace Drupal\system\Plugin\ImageToolkit\Operation\gd; +use Drupal\Core\ImageToolkit\Attribute\ImageToolkitOperation; +use Drupal\Core\StringTranslation\TranslatableMarkup; + /** * Defines GD2 resize operation. - * - * @ImageToolkitOperation( - * id = "gd_resize", - * toolkit = "gd", - * operation = "resize", - * label = @Translation("Resize"), - * description = @Translation("Resizes an image to the given dimensions (ignoring aspect ratio).") - * ) */ +#[ImageToolkitOperation( + id: "gd_resize", + toolkit: "gd", + operation: "resize", + label: new TranslatableMarkup("Resize"), + description: new TranslatableMarkup("Resizes an image to the given dimensions (ignoring aspect ratio).") +)] class Resize extends GDImageToolkitOperationBase { /** diff --git a/core/modules/system/src/Plugin/ImageToolkit/Operation/gd/Rotate.php b/core/modules/system/src/Plugin/ImageToolkit/Operation/gd/Rotate.php index db20c726cf79..19f393ce4ae2 100644 --- a/core/modules/system/src/Plugin/ImageToolkit/Operation/gd/Rotate.php +++ b/core/modules/system/src/Plugin/ImageToolkit/Operation/gd/Rotate.php @@ -3,18 +3,19 @@ namespace Drupal\system\Plugin\ImageToolkit\Operation\gd; use Drupal\Component\Utility\Color; +use Drupal\Core\ImageToolkit\Attribute\ImageToolkitOperation; +use Drupal\Core\StringTranslation\TranslatableMarkup; /** * Defines GD2 rotate operation. - * - * @ImageToolkitOperation( - * id = "gd_rotate", - * toolkit = "gd", - * operation = "rotate", - * label = @Translation("Rotate"), - * description = @Translation("Rotates an image by the given number of degrees.") - * ) */ +#[ImageToolkitOperation( + id: "gd_rotate", + toolkit: "gd", + operation: "rotate", + label: new TranslatableMarkup("Rotate"), + description: new TranslatableMarkup("Rotates an image by the given number of degrees.") +)] class Rotate extends GDImageToolkitOperationBase { /** diff --git a/core/modules/system/src/Plugin/ImageToolkit/Operation/gd/Scale.php b/core/modules/system/src/Plugin/ImageToolkit/Operation/gd/Scale.php index 37097d864ee9..85cc7442b027 100644 --- a/core/modules/system/src/Plugin/ImageToolkit/Operation/gd/Scale.php +++ b/core/modules/system/src/Plugin/ImageToolkit/Operation/gd/Scale.php @@ -2,17 +2,19 @@ namespace Drupal\system\Plugin\ImageToolkit\Operation\gd; +use Drupal\Core\ImageToolkit\Attribute\ImageToolkitOperation; +use Drupal\Core\StringTranslation\TranslatableMarkup; + /** * Defines GD2 Scale operation. - * - * @ImageToolkitOperation( - * id = "gd_scale", - * toolkit = "gd", - * operation = "scale", - * label = @Translation("Scale"), - * description = @Translation("Scales an image while maintaining aspect ratio. The resulting image can be smaller for one or both target dimensions.") - * ) */ +#[ImageToolkitOperation( + id: "gd_scale", + toolkit: "gd", + operation: "scale", + label: new TranslatableMarkup("Scale"), + description: new TranslatableMarkup("Scales an image while maintaining aspect ratio. The resulting image can be smaller for one or both target dimensions.") +)] class Scale extends Resize { /** diff --git a/core/modules/system/src/Plugin/ImageToolkit/Operation/gd/ScaleAndCrop.php b/core/modules/system/src/Plugin/ImageToolkit/Operation/gd/ScaleAndCrop.php index ad53ec3fa156..d502b2136731 100644 --- a/core/modules/system/src/Plugin/ImageToolkit/Operation/gd/ScaleAndCrop.php +++ b/core/modules/system/src/Plugin/ImageToolkit/Operation/gd/ScaleAndCrop.php @@ -2,17 +2,19 @@ namespace Drupal\system\Plugin\ImageToolkit\Operation\gd; +use Drupal\Core\ImageToolkit\Attribute\ImageToolkitOperation; +use Drupal\Core\StringTranslation\TranslatableMarkup; + /** * Defines GD2 Scale and crop operation. - * - * @ImageToolkitOperation( - * id = "gd_scale_and_crop", - * toolkit = "gd", - * operation = "scale_and_crop", - * label = @Translation("Scale and crop"), - * description = @Translation("Scales an image to the exact width and height given. This plugin achieves the target aspect ratio by cropping the original image equally on both sides, or equally on the top and bottom. This function is useful to create uniform sized avatars from larger images.") - * ) */ +#[ImageToolkitOperation( + id: "gd_scale_and_crop", + toolkit: "gd", + operation: "scale_and_crop", + label: new TranslatableMarkup("Scale and crop"), + description: new TranslatableMarkup("Scales an image to the exact width and height given. This plugin achieves the target aspect ratio by cropping the original image equally on both sides, or equally on the top and bottom. This function is useful to create uniform sized avatars from larger images.") +)] class ScaleAndCrop extends GDImageToolkitOperationBase { /** diff --git a/core/modules/system/tests/modules/image_test/src/Plugin/ImageToolkit/Operation/test/Bar.php b/core/modules/system/tests/modules/image_test/src/Plugin/ImageToolkit/Operation/test/Bar.php index ecd4aaafdefc..960c88862084 100644 --- a/core/modules/system/tests/modules/image_test/src/Plugin/ImageToolkit/Operation/test/Bar.php +++ b/core/modules/system/tests/modules/image_test/src/Plugin/ImageToolkit/Operation/test/Bar.php @@ -2,15 +2,17 @@ namespace Drupal\image_test\Plugin\ImageToolkit\Operation\test; +use Drupal\Core\ImageToolkit\Attribute\ImageToolkitOperation; +use Drupal\Core\StringTranslation\TranslatableMarkup; + /** * Builds an image toolkit operation. - * - * @ImageToolkitOperation( - * id = "bar", - * toolkit = "test", - * operation = "invert", - * label = @Translation("Invert"), - * description = @Translation("Bar.") - * ) */ +#[ImageToolkitOperation( + id: "bar", + toolkit: "test", + operation: "invert", + label: new TranslatableMarkup("Invert"), + description: new TranslatableMarkup("Bar.") +)] class Bar extends OperationBase {} diff --git a/core/modules/system/tests/modules/image_test/src/Plugin/ImageToolkit/Operation/test/Failing.php b/core/modules/system/tests/modules/image_test/src/Plugin/ImageToolkit/Operation/test/Failing.php index eb37d9f07d48..03b492f6140f 100644 --- a/core/modules/system/tests/modules/image_test/src/Plugin/ImageToolkit/Operation/test/Failing.php +++ b/core/modules/system/tests/modules/image_test/src/Plugin/ImageToolkit/Operation/test/Failing.php @@ -2,17 +2,19 @@ namespace Drupal\image_test\Plugin\ImageToolkit\Operation\test; +use Drupal\Core\ImageToolkit\Attribute\ImageToolkitOperation; +use Drupal\Core\StringTranslation\TranslatableMarkup; + /** * An image toolkit operation that throws a \RuntimeException. - * - * @ImageToolkitOperation( - * id = "failing", - * toolkit = "test", - * operation = "failing", - * label = @Translation("An image toolkit operation that throws a \\RuntimeException"), - * description = @Translation("An image toolkit operation that throws a \\RuntimeException.") - * ) */ +#[ImageToolkitOperation( + id: "failing", + toolkit: "test", + operation: "failing", + label: new TranslatableMarkup("An image toolkit operation that throws a \\RuntimeException"), + description: new TranslatableMarkup("An image toolkit operation that throws a \\RuntimeException.") +)] class Failing extends OperationBase { /** diff --git a/core/modules/system/tests/modules/image_test/src/Plugin/ImageToolkit/Operation/test/Foo.php b/core/modules/system/tests/modules/image_test/src/Plugin/ImageToolkit/Operation/test/Foo.php index 3b067d5919c3..35671d03c958 100644 --- a/core/modules/system/tests/modules/image_test/src/Plugin/ImageToolkit/Operation/test/Foo.php +++ b/core/modules/system/tests/modules/image_test/src/Plugin/ImageToolkit/Operation/test/Foo.php @@ -2,15 +2,17 @@ namespace Drupal\image_test\Plugin\ImageToolkit\Operation\test; +use Drupal\Core\ImageToolkit\Attribute\ImageToolkitOperation; +use Drupal\Core\StringTranslation\TranslatableMarkup; + /** * Builds an image toolkit operation. - * - * @ImageToolkitOperation( - * id = "foo", - * toolkit = "test", - * operation = "blur", - * label = @Translation("Blur"), - * description = @Translation("Foo.") - * ) */ +#[ImageToolkitOperation( + id: "foo", + toolkit: "test", + operation: "blur", + label: new TranslatableMarkup("Blur"), + description: new TranslatableMarkup("Foo."), +)] class Foo extends OperationBase {} diff --git a/core/modules/system/tests/modules/image_test/src/Plugin/ImageToolkit/Operation/test/FooDerived.php b/core/modules/system/tests/modules/image_test/src/Plugin/ImageToolkit/Operation/test/FooDerived.php index bf38dfddf54e..058c25b5de2d 100644 --- a/core/modules/system/tests/modules/image_test/src/Plugin/ImageToolkit/Operation/test/FooDerived.php +++ b/core/modules/system/tests/modules/image_test/src/Plugin/ImageToolkit/Operation/test/FooDerived.php @@ -2,15 +2,17 @@ namespace Drupal\image_test\Plugin\ImageToolkit\Operation\test; +use Drupal\Core\ImageToolkit\Attribute\ImageToolkitOperation; +use Drupal\Core\StringTranslation\TranslatableMarkup; + /** * Builds an image toolkit operation. - * - * @ImageToolkitOperation( - * id = "foo_derived", - * toolkit = "test:derived_toolkit", - * operation = "blur", - * label = @Translation("Blur Derived"), - * description = @Translation("Foo derived.") - * ) */ +#[ImageToolkitOperation( + id: "foo_derived", + toolkit: "test:derived_toolkit", + operation: "blur", + label: new TranslatableMarkup("Blur Derived"), + description: new TranslatableMarkup("Foo derived.") +)] class FooDerived extends OperationBase {} -- GitLab