Commit e4dcadd6 authored by alexpott's avatar alexpott

Issue #2357119 by claudiu.cristea, mondrake, attiks: Allow image toolkit derivatives

parent e693ef36
......@@ -1256,7 +1256,7 @@ services:
- { name: plugin_manager_cache_clear }
image.toolkit.operation.manager:
class: Drupal\Core\ImageToolkit\ImageToolkitOperationManager
arguments: ['@logger.channel.image']
arguments: ['@logger.channel.image', '@image.toolkit.manager']
parent: default_plugin_manager
tags:
- { name: plugin_manager_cache_clear }
......
......@@ -32,6 +32,13 @@ class ImageToolkitOperationManager extends DefaultPluginManager implements Image
*/
protected $logger;
/**
* The image toolkit manager.
*
* @var \Drupal\Core\ImageToolkit\ImageToolkitManager
*/
protected $toolkitManager;
/**
* Constructs the ImageToolkitOperationManager object.
*
......@@ -44,20 +51,23 @@ class ImageToolkitOperationManager extends DefaultPluginManager implements Image
* The module handler to invoke the alter hook with.
* @param \Psr\Log\LoggerInterface $logger
* A logger instance.
* @param \Drupal\Core\ImageToolkit\ImageToolkitManager $toolkit_manager
* The image toolkit manager.
*/
public function __construct(\Traversable $namespaces, CacheBackendInterface $cache_backend, ModuleHandlerInterface $module_handler, LoggerInterface $logger) {
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');
$this->alterInfo('image_toolkit_operation');
$this->setCacheBackend($cache_backend, 'image_toolkit_operation_plugins');
$this->logger = $logger;
$this->toolkitManager = $toolkit_manager;
}
/**
* Returns the plugin ID for a given toolkit and operation.
*
* @param string $toolkit_id
* The toolkit plugin ID.
* @param \Drupal\Core\ImageToolkit\ImageToolkitInterface $toolkit
* The toolkit instance.
* @param string $operation
* The operation (e.g. "crop").
*
......@@ -67,7 +77,8 @@ public function __construct(\Traversable $namespaces, CacheBackendInterface $cac
* @throws \Drupal\Component\Plugin\Exception\PluginNotFoundException
* When no plugin is available.
*/
protected function getToolkitOperationPluginId($toolkit_id, $operation) {
protected function getToolkitOperationPluginId(ImageToolkitInterface $toolkit, $operation) {
$toolkit_id = $toolkit->getPluginId();
$definitions = $this->getDefinitions();
$definitions = array_filter($definitions,
......@@ -77,6 +88,14 @@ function ($definition) use ($toolkit_id, $operation) {
);
if (!$definitions) {
// If this image toolkit plugin is a derivative and returns no operation,
// try once again with its base plugin.
$base_toolkit_id = $toolkit->getBaseId();
if (($toolkit_id != $base_toolkit_id) && !empty($base_toolkit_id)) {
$base_toolkit = $this->toolkitManager->createInstance($base_toolkit_id);
return $this->getToolkitOperationPluginId($base_toolkit, $operation);
}
$message = SafeMarkup::format("No image operation plugin for '@toolkit' toolkit and '@operation' operation.", array('@toolkit' => $toolkit_id, '@operation' => $operation));
throw new PluginNotFoundException($toolkit_id . '.' . $operation, $message);
}
......@@ -102,7 +121,7 @@ public function createInstance($plugin_id, array $configuration = array(), Image
* {@inheritdoc}
*/
public function getToolkitOperation(ImageToolkitInterface $toolkit, $operation) {
$plugin_id = $this->getToolkitOperationPluginId($toolkit->getPluginId(), $operation);
$plugin_id = $this->getToolkitOperationPluginId($toolkit, $operation);
return $this->createInstance($plugin_id, array(), $toolkit);
}
......
......@@ -21,6 +21,7 @@ function testGetAvailableToolkits() {
$manager = $this->container->get('image.toolkit.manager');
$toolkits = $manager->getAvailableToolkits();
$this->assertTrue(isset($toolkits['test']), 'The working toolkit was returned.');
$this->assertTrue(isset($toolkits['test:derived_toolkit']), 'The derived toolkit was returned.');
$this->assertFalse(isset($toolkits['broken']), 'The toolkit marked unavailable was not returned');
$this->assertToolkitOperationsCalled(array());
}
......@@ -71,4 +72,22 @@ function testApplyNoParameters() {
$this->assertEqual($calls['apply'][0][0], 'my_operation', "'my_operation' was passed correctly as operation");
$this->assertEqual($calls['apply'][0][1], array(), 'passing no parameters was handled correctly');
}
/**
* Tests image toolkit operations inheritance by derivative toolkits.
*/
public function testDerivative() {
$toolkit_manager = $this->container->get('image.toolkit.manager');
$operation_manager = $this->container->get('image.toolkit.operation.manager');
$toolkit = $toolkit_manager->createInstance('test:derived_toolkit');
// Load an overwritten and an inherited operation.
$blur = $operation_manager->getToolkitOperation($toolkit, 'blur');
$invert = $operation_manager->getToolkitOperation($toolkit, 'invert');
$this->assertIdentical('foo_derived', $blur->getPluginId(), "'Blur' operation overwritten by derivative.");
$this->assertIdentical('bar', $invert->getPluginId(), '"Invert" operation inherited from base plugin.');
}
}
<?php
/**
* @file
* Contains \Drupal\image_test\Plugin\ImageToolkit\DerivedToolkit.
*/
namespace Drupal\image_test\Plugin\ImageToolkit;
/**
* Provides a derivative of TestToolkit.
*
* @ImageToolkit(
* id = "test:derived_toolkit",
* title = @Translation("A dummy toolkit, derivative of 'test'.")
* )
*/
class DerivedToolkit extends TestToolkit { }
<?php
/**
* @file
* Contains \Drupal\image_test\Plugin\ImageToolkit\Operation\test\Bar
*/
namespace Drupal\image_test\Plugin\ImageToolkit\Operation\test;
/**
* Builds an image toolkit operation.
*
* @ImageToolkitOperation(
* id = "bar",
* toolkit = "test",
* operation = "invert",
* label = @Translation("Invert"),
* description = @Translation("Bar.")
* )
*/
class Bar extends OperationBase { }
<?php
/**
* @file
* Contains \Drupal\image_test\Plugin\ImageToolkit\Operation\test\Foo
*/
namespace Drupal\image_test\Plugin\ImageToolkit\Operation\test;
/**
* Builds an image toolkit operation.
*
* @ImageToolkitOperation(
* id = "foo",
* toolkit = "test",
* operation = "blur",
* label = @Translation("Blur"),
* description = @Translation("Foo.")
* )
*/
class Foo extends OperationBase { }
<?php
/**
* @file
* Contains \Drupal\image_test\Plugin\ImageToolkit\Operation\test\FooDerived
*/
namespace Drupal\image_test\Plugin\ImageToolkit\Operation\test;
/**
* Builds an image toolkit operation.
*
* @ImageToolkitOperation(
* id = "foo_derived",
* toolkit = "test:derived_toolkit",
* operation = "blur",
* label = @Translation("Blur Derived"),
* description = @Translation("Foo derived.")
* )
*/
class FooDerived extends OperationBase { }
<?php
/**
* @file
* Contains \Drupal\image_test\Plugin\ImageToolkit\Operation\test\OperationBase.
*/
namespace Drupal\image_test\Plugin\ImageToolkit\Operation\test;
use Drupal\Core\ImageToolkit\ImageToolkitOperationBase;
/**
* Provides a base class for test operations.
*/
abstract class OperationBase extends ImageToolkitOperationBase {
/**
* {@inheritdoc}
*/
public function arguments() {
return array();
}
/**
* {@inheritdoc}
*/
public function execute(array $arguments) {
// Nothing to do.
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment