Commit 840cd4c8 authored by alexpott's avatar alexpott

Issue #2318281 by tim.plunkett, dawehner | kim.pepper: Provide a standard way...

Issue #2318281 by tim.plunkett, dawehner | kim.pepper: Provide a standard way to check a plugin is an instance of the required interface.
parent 2f17715c
......@@ -8,7 +8,6 @@
use Drupal\Component\Plugin\Discovery\DiscoveryInterface;
use Drupal\Component\Plugin\Exception\PluginException;
use Drupal\Component\Plugin\Derivative\DeriverInterface;
/**
* Default plugin factory.
......@@ -30,11 +29,24 @@ class DefaultFactory implements FactoryInterface {
*/
protected $discovery;
/**
* Defines an interface each plugin should implement.
*
* @var string|null
*/
protected $interface;
/**
* Constructs a Drupal\Component\Plugin\Factory\DefaultFactory object.
*
* @param \Drupal\Component\Plugin\Discovery\DiscoveryInterface $discovery
* The plugin discovery.
* @param string|null $plugin_interface
* (optional) The interface each plugin should implement.
*/
public function __construct(DiscoveryInterface $discovery) {
public function __construct(DiscoveryInterface $discovery, $plugin_interface = NULL) {
$this->discovery = $discovery;
$this->interface = $plugin_interface;
}
/**
......@@ -42,7 +54,7 @@ public function __construct(DiscoveryInterface $discovery) {
*/
public function createInstance($plugin_id, array $configuration = array()) {
$plugin_definition = $this->discovery->getDefinition($plugin_id);
$plugin_class = static::getPluginClass($plugin_id, $plugin_definition);
$plugin_class = static::getPluginClass($plugin_id, $plugin_definition, $this->interface);
return new $plugin_class($configuration, $plugin_id, $plugin_definition);
}
......@@ -53,13 +65,18 @@ public function createInstance($plugin_id, array $configuration = array()) {
* The id of a plugin.
* @param mixed $plugin_definition
* The plugin definition associated with the plugin ID.
* @param string $required_interface
* (optional) THe required plugin interface.
*
* @return string
* The appropriate class name.
*
* @throws \Drupal\Component\Plugin\Exception\PluginException
* Thrown when there is no class specified, the class doesn't exist, or
* the class does not implement the specified required interface.
*
*/
public static function getPluginClass($plugin_id, $plugin_definition = NULL) {
public static function getPluginClass($plugin_id, $plugin_definition = NULL, $required_interface = NULL) {
if (empty($plugin_definition['class'])) {
throw new PluginException(sprintf('The plugin (%s) did not specify an instance class.', $plugin_id));
}
......@@ -70,6 +87,10 @@ public static function getPluginClass($plugin_id, $plugin_definition = NULL) {
throw new PluginException(sprintf('Plugin (%s) instance class "%s" does not exist.', $plugin_id, $class));
}
if ($required_interface && !is_subclass_of($plugin_definition['class'], $required_interface)) {
throw new PluginException(sprintf('Plugin "%s" (%s) in %s should implement interface %s.', $plugin_id, $plugin_definition['class'], $plugin_definition['provider'], $required_interface));
}
return $class;
}
}
......@@ -19,7 +19,7 @@ class ReflectionFactory extends DefaultFactory {
*/
public function createInstance($plugin_id, array $configuration = array()) {
$plugin_definition = $this->discovery->getDefinition($plugin_id);
$plugin_class = static::getPluginClass($plugin_id, $plugin_definition);
$plugin_class = static::getPluginClass($plugin_id, $plugin_definition, $this->interface);
// Lets figure out of there's a constructor for this class and pull
// arguments from the $options array if so to populate it.
......
......@@ -33,7 +33,7 @@ class ActionManager extends DefaultPluginManager {
* The module handler to invoke the alter hook with.
*/
public function __construct(\Traversable $namespaces, CacheBackendInterface $cache_backend, ModuleHandlerInterface $module_handler) {
parent::__construct('Plugin/Action', $namespaces, $module_handler, 'Drupal\Core\Annotation\Action');
parent::__construct('Plugin/Action', $namespaces, $module_handler, 'Drupal\Core\Action\ActionInterface', 'Drupal\Core\Annotation\Action');
$this->alterInfo('action_info');
$this->setCacheBackend($cache_backend, 'action_info');
}
......
<?php
/**
* @file
* Contains \Drupal\Core\Archiver\ArchiverManager.
*/
......@@ -32,7 +33,7 @@ class ArchiverManager extends DefaultPluginManager {
* The module handler to invoke the alter hook with.
*/
public function __construct(\Traversable $namespaces, CacheBackendInterface $cache_backend, ModuleHandlerInterface $module_handler) {
parent::__construct('Plugin/Archiver', $namespaces, $module_handler, 'Drupal\Core\Archiver\Annotation\Archiver');
parent::__construct('Plugin/Archiver', $namespaces, $module_handler, 'Drupal\Core\Archiver\ArchiverInterface', 'Drupal\Core\Archiver\Annotation\Archiver');
$this->alterInfo('archiver_info');
$this->setCacheBackend($cache_backend, 'archiver_info_plugins');
}
......@@ -42,7 +43,7 @@ public function __construct(\Traversable $namespaces, CacheBackendInterface $cac
*/
public function createInstance($plugin_id, array $configuration = array()) {
$plugin_definition = $this->getDefinition($plugin_id);
$plugin_class = DefaultFactory::getPluginClass($plugin_id, $plugin_definition);
$plugin_class = DefaultFactory::getPluginClass($plugin_id, $plugin_definition, 'Drupal\Core\Archiver\ArchiverInterface');
return new $plugin_class($configuration['filepath']);
}
......
......@@ -44,7 +44,7 @@ class BlockManager extends DefaultPluginManager implements BlockManagerInterface
* The module handler to invoke the alter hook with.
*/
public function __construct(\Traversable $namespaces, CacheBackendInterface $cache_backend, ModuleHandlerInterface $module_handler) {
parent::__construct('Plugin/Block', $namespaces, $module_handler, 'Drupal\Core\Block\Annotation\Block');
parent::__construct('Plugin/Block', $namespaces, $module_handler, 'Drupal\Core\Block\BlockPluginInterface', 'Drupal\Core\Block\Annotation\Block');
$this->alterInfo('block');
$this->setCacheBackend($cache_backend, 'block_plugins');
......
......@@ -42,7 +42,7 @@ public function __construct(\Traversable $namespaces, CacheBackendInterface $cac
$this->alterInfo('condition_info');
$this->setCacheBackend($cache_backend, 'condition_plugins');
parent::__construct('Plugin/Condition', $namespaces, $module_handler, 'Drupal\Core\Condition\Annotation\Condition');
parent::__construct('Plugin/Condition', $namespaces, $module_handler, 'Drupal\Core\Condition\ConditionInterface', 'Drupal\Core\Condition\Annotation\Condition');
}
/**
......
......@@ -31,7 +31,7 @@ class VariantManager extends DefaultPluginManager {
* The module handler to invoke the alter hook with.
*/
public function __construct(\Traversable $namespaces, CacheBackendInterface $cache_backend, ModuleHandlerInterface $module_handler) {
parent::__construct('Plugin/DisplayVariant', $namespaces, $module_handler, 'Drupal\Core\Display\Annotation\DisplayVariant');
parent::__construct('Plugin/DisplayVariant', $namespaces, $module_handler, 'Drupal\Core\Display\VariantInterface', 'Drupal\Core\Display\Annotation\DisplayVariant');
$this->setCacheBackend($cache_backend, 'variant_plugins');
$this->alterInfo('display_variant_plugin');
......
......@@ -171,7 +171,7 @@ class EntityManager extends DefaultPluginManager implements EntityManagerInterfa
* The class resolver.
*/
public function __construct(\Traversable $namespaces, ModuleHandlerInterface $module_handler, CacheBackendInterface $cache, LanguageManagerInterface $language_manager, TranslationInterface $translation_manager, ClassResolverInterface $class_resolver, TypedDataManager $typed_data_manager) {
parent::__construct('Entity', $namespaces, $module_handler, 'Drupal\Core\Entity\Annotation\EntityType');
parent::__construct('Entity', $namespaces, $module_handler, 'Drupal\Core\Entity\EntityInterface', 'Drupal\Core\Entity\Annotation\EntityType');
$this->setCacheBackend($cache, 'entity_type', array('entity_types' => TRUE));
$this->alterInfo('entity_type');
......
......@@ -31,7 +31,7 @@ class FieldTypePluginManager extends DefaultPluginManager implements FieldTypePl
* The module handler.
*/
public function __construct(\Traversable $namespaces, CacheBackendInterface $cache_backend, ModuleHandlerInterface $module_handler) {
parent::__construct('Plugin/Field/FieldType', $namespaces, $module_handler, 'Drupal\Core\Field\Annotation\FieldType');
parent::__construct('Plugin/Field/FieldType', $namespaces, $module_handler, 'Drupal\Core\Field\FieldItemInterface', 'Drupal\Core\Field\Annotation\FieldType');
$this->alterInfo('field_info');
$this->setCacheBackend($cache_backend, 'field_types_plugins');
}
......
......@@ -47,8 +47,7 @@ class FormatterPluginManager extends DefaultPluginManager {
* The 'field type' plugin manager.
*/
public function __construct(\Traversable $namespaces, CacheBackendInterface $cache_backend, ModuleHandlerInterface $module_handler, FieldTypePluginManagerInterface $field_type_manager) {
parent::__construct('Plugin/Field/FieldFormatter', $namespaces, $module_handler, 'Drupal\Core\Field\Annotation\FieldFormatter');
parent::__construct('Plugin/Field/FieldFormatter', $namespaces, $module_handler, 'Drupal\Core\Field\FormatterInterface', 'Drupal\Core\Field\Annotation\FieldFormatter');
$this->setCacheBackend($cache_backend, 'field_formatter_types_plugins');
$this->alterInfo('field_formatter_info');
......
......@@ -19,7 +19,7 @@ class WidgetFactory extends DefaultFactory {
*/
public function createInstance($plugin_id, array $configuration = array()) {
$plugin_definition = $this->discovery->getDefinition($plugin_id);
$plugin_class = static::getPluginClass($plugin_id, $plugin_definition);
$plugin_class = static::getPluginClass($plugin_id, $plugin_definition, $this->interface);
return new $plugin_class($plugin_id, $plugin_definition, $configuration['field_definition'], $configuration['settings']);
}
}
......@@ -47,7 +47,7 @@ class WidgetPluginManager extends DefaultPluginManager {
* The 'field type' plugin manager.
*/
public function __construct(\Traversable $namespaces, CacheBackendInterface $cache_backend, ModuleHandlerInterface $module_handler, FieldTypePluginManagerInterface $field_type_manager) {
parent::__construct('Plugin/Field/FieldWidget', $namespaces, $module_handler, 'Drupal\Core\Field\Annotation\FieldWidget');
parent::__construct('Plugin/Field/FieldWidget', $namespaces, $module_handler, 'Drupal\Core\Field\WidgetInterface', 'Drupal\Core\Field\Annotation\FieldWidget');
$this->setCacheBackend($cache_backend, 'field_widget_types_plugins');
$this->alterInfo('field_widget_info');
......
......@@ -43,7 +43,7 @@ class ImageToolkitManager extends DefaultPluginManager {
* The config factory.
*/
public function __construct(\Traversable $namespaces, CacheBackendInterface $cache_backend, ModuleHandlerInterface $module_handler, ConfigFactoryInterface $config_factory) {
parent::__construct('Plugin/ImageToolkit', $namespaces, $module_handler, 'Drupal\Core\ImageToolkit\Annotation\ImageToolkit');
parent::__construct('Plugin/ImageToolkit', $namespaces, $module_handler, 'Drupal\Core\ImageToolkit\ImageToolkitInterface', 'Drupal\Core\ImageToolkit\Annotation\ImageToolkit');
$this->setCacheBackend($cache_backend, 'image_toolkit_plugins');
$this->configFactory = $config_factory;
......
......@@ -46,7 +46,7 @@ class ImageToolkitOperationManager extends DefaultPluginManager implements Image
* A logger instance.
*/
public function __construct(\Traversable $namespaces, CacheBackendInterface $cache_backend, ModuleHandlerInterface $module_handler, LoggerInterface $logger) {
parent::__construct('Plugin/ImageToolkit/Operation', $namespaces, $module_handler, 'Drupal\Core\ImageToolkit\Annotation\ImageToolkitOperation');
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');
......
......@@ -12,8 +12,6 @@
use Drupal\Core\Cache\CacheBackendInterface;
use Drupal\Core\Extension\ModuleHandlerInterface;
use Drupal\Core\Config\ConfigFactoryInterface;
use Drupal\Component\Utility\String;
use Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException;
use Drupal\Core\StringTranslation\StringTranslationTrait;
use Drupal\Core\StringTranslation\TranslationInterface;
......@@ -67,7 +65,7 @@ class MailManager extends DefaultPluginManager implements MailManagerInterface {
* The string translation service.
*/
public function __construct(\Traversable $namespaces, CacheBackendInterface $cache_backend, ModuleHandlerInterface $module_handler, ConfigFactoryInterface $config_factory, LoggerChannelFactoryInterface $logger_factory, TranslationInterface $string_translation) {
parent::__construct('Plugin/Mail', $namespaces, $module_handler, 'Drupal\Core\Annotation\Mail');
parent::__construct('Plugin/Mail', $namespaces, $module_handler, 'Drupal\Core\Mail\MailInterface', 'Drupal\Core\Annotation\Mail');
$this->alterInfo('mail_backend_info');
$this->setCacheBackend($cache_backend, 'mail_backend_plugins');
$this->configFactory = $config_factory;
......@@ -149,16 +147,7 @@ public function getInstance(array $options) {
}
if (empty($this->instances[$plugin_id])) {
$plugin = $this->createInstance($plugin_id);
if (is_subclass_of($plugin, '\Drupal\Core\Mail\MailInterface')) {
$this->instances[$plugin_id] = $plugin;
}
else {
throw new InvalidPluginDefinitionException($plugin_id, String::format('Class %class does not implement interface %interface', array(
'%class' => get_class($plugin),
'%interface' => 'Drupal\Core\Mail\MailInterface',
)));
}
$this->instances[$plugin_id] = $this->createInstance($plugin_id);
}
return $this->instances[$plugin_id];
}
......
......@@ -105,7 +105,7 @@ class ContextualLinkManager extends DefaultPluginManager implements ContextualLi
public function __construct(ControllerResolverInterface $controller_resolver, ModuleHandlerInterface $module_handler, CacheBackendInterface $cache_backend, LanguageManagerInterface $language_manager, AccessManagerInterface $access_manager, AccountInterface $account, RequestStack $request_stack) {
$this->discovery = new YamlDiscovery('links.contextual', $module_handler->getModuleDirectories());
$this->discovery = new ContainerDerivativeDiscoveryDecorator($this->discovery);
$this->factory = new ContainerFactory($this);
$this->factory = new ContainerFactory($this, '\Drupal\Core\Menu\ContextualLinkInterface');
$this->controllerResolver = $controller_resolver;
$this->accessManager = $access_manager;
......
......@@ -116,7 +116,7 @@ public function __construct(ControllerResolverInterface $controller_resolver, Re
// discovery.
$this->discovery = new YamlDiscovery('links.action', $module_handler->getModuleDirectories());
$this->discovery = new ContainerDerivativeDiscoveryDecorator($this->discovery);
$this->factory = new ContainerFactory($this);
$this->factory = new ContainerFactory($this, 'Drupal\Core\Menu\LocalActionInterface');
$this->controllerResolver = $controller_resolver;
$this->requestStack = $request_stack;
$this->routeProvider = $route_provider;
......
......@@ -126,7 +126,7 @@ class LocalTaskManager extends DefaultPluginManager implements LocalTaskManagerI
public function __construct(ControllerResolverInterface $controller_resolver, RequestStack $request_stack, RouteProviderInterface $route_provider, RouteBuilderInterface $route_builder, ModuleHandlerInterface $module_handler, CacheBackendInterface $cache, LanguageManagerInterface $language_manager, AccessManagerInterface $access_manager, AccountInterface $account) {
$this->discovery = new YamlDiscovery('links.task', $module_handler->getModuleDirectories());
$this->discovery = new ContainerDerivativeDiscoveryDecorator($this->discovery);
$this->factory = new ContainerFactory($this);
$this->factory = new ContainerFactory($this, '\Drupal\Core\Menu\LocalTaskInterface');
$this->controllerResolver = $controller_resolver;
$this->requestStack = $request_stack;
$this->routeProvider = $route_provider;
......
......@@ -9,7 +9,6 @@
use Drupal\Component\Plugin\Discovery\CachedDiscoveryInterface;
use Drupal\Component\Plugin\Discovery\DiscoveryCachedTrait;
use Drupal\Component\Plugin\Exception\PluginNotFoundException;
use Drupal\Core\Plugin\Discovery\ContainerDerivativeDiscoveryDecorator;
use Drupal\Component\Plugin\PluginManagerBase;
use Drupal\Component\Plugin\PluginManagerInterface;
......@@ -17,7 +16,6 @@
use Drupal\Core\Cache\Cache;
use Drupal\Core\Cache\CacheBackendInterface;
use Drupal\Core\Extension\ModuleHandlerInterface;
use Drupal\Core\Language\LanguageManagerInterface;
use Drupal\Core\Plugin\Discovery\AnnotatedClassDiscovery;
use Drupal\Core\Plugin\Factory\ContainerFactory;
......@@ -92,15 +90,17 @@ class DefaultPluginManager extends PluginManagerBase implements PluginManagerInt
* keyed by the corresponding namespace to look for plugin implementations.
* @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler
* The module handler.
* @param string|null $plugin_interface
* (optional) The interface each plugin should implement.
* @param string $plugin_definition_annotation_name
* (optional) The name of the annotation that contains the plugin definition.
* Defaults to 'Drupal\Component\Annotation\Plugin'.
*/
public function __construct($subdir, \Traversable $namespaces, ModuleHandlerInterface $module_handler, $plugin_definition_annotation_name = 'Drupal\Component\Annotation\Plugin') {
public function __construct($subdir, \Traversable $namespaces, ModuleHandlerInterface $module_handler, $plugin_interface = NULL, $plugin_definition_annotation_name = 'Drupal\Component\Annotation\Plugin') {
$this->subdir = $subdir;
$this->discovery = new AnnotatedClassDiscovery($subdir, $namespaces, $plugin_definition_annotation_name);
$this->discovery = new ContainerDerivativeDiscoveryDecorator($this->discovery);
$this->factory = new ContainerFactory($this);
$this->factory = new ContainerFactory($this, $plugin_interface);
$this->moduleHandler = $module_handler;
}
......
......@@ -18,7 +18,7 @@ class ContainerFactory extends DefaultFactory {
*/
public function createInstance($plugin_id, array $configuration = array()) {
$plugin_definition = $this->discovery->getDefinition($plugin_id);
$plugin_class = static::getPluginClass($plugin_id, $plugin_definition);
$plugin_class = static::getPluginClass($plugin_id, $plugin_definition, $this->interface);
// If the plugin provides a factory method, pass the container to it.
if (is_subclass_of($plugin_class, 'Drupal\Core\Plugin\ContainerFactoryPluginInterface')) {
......
......@@ -12,7 +12,7 @@
*
* @RenderElement("page")
*/
class Page {
class Page extends RenderElement {
/**
* {@inheritdoc}
......
......@@ -46,7 +46,7 @@ class ElementInfoManager extends DefaultPluginManager implements ElementInfoMana
public function __construct(\Traversable $namespaces, CacheBackendInterface $cache_backend, ModuleHandlerInterface $module_handler) {
$this->setCacheBackend($cache_backend, 'element_info');
parent::__construct('Element', $namespaces, $module_handler, 'Drupal\Core\Render\Annotation\RenderElement');
parent::__construct('Element', $namespaces, $module_handler, 'Drupal\Core\Render\Element\ElementInterface', 'Drupal\Core\Render\Annotation\RenderElement');
}
/**
......
......@@ -59,7 +59,7 @@ public function __construct(\Traversable $namespaces, CacheBackendInterface $cac
$this->alterInfo('data_type_info');
$this->setCacheBackend($cache_backend, 'typed_data_types_plugins');
parent::__construct('Plugin/DataType', $namespaces, $module_handler, 'Drupal\Core\TypedData\Annotation\DataType');
parent::__construct('Plugin/DataType', $namespaces, $module_handler, NULL, 'Drupal\Core\TypedData\Annotation\DataType');
}
/**
......
......@@ -44,8 +44,13 @@ public function __construct($type, \Traversable $namespaces, CacheBackendInterfa
'parser' => 'Drupal\aggregator\Annotation\AggregatorParser',
'processor' => 'Drupal\aggregator\Annotation\AggregatorProcessor',
);
$plugin_interfaces = array(
'fetcher' => 'Drupal\aggregator\Plugin\FetcherInterface',
'parser' => 'Drupal\aggregator\Plugin\ParserInterface',
'processor' => 'Drupal\aggregator\Plugin\ProcessorInterface',
);
parent::__construct("Plugin/aggregator/$type", $namespaces, $module_handler, $type_annotations[$type]);
parent::__construct("Plugin/aggregator/$type", $namespaces, $module_handler, $plugin_interfaces[$type], $type_annotations[$type]);
$this->setCacheBackend($cache_backend, 'aggregator_' . $type . '_plugins');
}
......
......@@ -39,7 +39,7 @@ class CKEditorPluginManager extends DefaultPluginManager {
* The module handler to invoke the alter hook with.
*/
public function __construct(\Traversable $namespaces, CacheBackendInterface $cache_backend, ModuleHandlerInterface $module_handler) {
parent::__construct('Plugin/CKEditorPlugin', $namespaces, $module_handler, 'Drupal\ckeditor\Annotation\CKEditorPlugin');
parent::__construct('Plugin/CKEditorPlugin', $namespaces, $module_handler, 'Drupal\ckeditor\CKEditorPluginInterface', 'Drupal\ckeditor\Annotation\CKEditorPlugin');
$this->alterInfo('ckeditor_plugin_info');
$this->setCacheBackend($cache_backend, 'ckeditor_plugins');
}
......
......@@ -90,7 +90,7 @@ public function __construct(CacheBackendInterface $cache_backend, LanguageManage
$this->discovery = new InfoHookDecorator($this->discovery, 'config_translation_info');
$this->discovery = new ContainerDerivativeDiscoveryDecorator($this->discovery);
$this->factory = new ContainerFactory($this);
$this->factory = new ContainerFactory($this, '\Drupal\config_translation\ConfigMapperInterface');
// Let others alter definitions with hook_config_translation_info_alter().
$this->moduleHandler = $module_handler;
......
......@@ -33,7 +33,7 @@ class EditorManager extends DefaultPluginManager {
* The module handler to invoke the alter hook with.
*/
public function __construct(\Traversable $namespaces, CacheBackendInterface $cache_backend, ModuleHandlerInterface $module_handler) {
parent::__construct('Plugin/Editor', $namespaces, $module_handler, 'Drupal\editor\Annotation\Editor');
parent::__construct('Plugin/Editor', $namespaces, $module_handler, 'Drupal\editor\Plugin\EditorPluginInterface', 'Drupal\editor\Annotation\Editor');
$this->alterInfo('editor_info');
$this->setCacheBackend($cache_backend, 'editor_plugins');
}
......
......@@ -36,7 +36,7 @@ public function __construct(\Traversable $namespaces, CacheBackendInterface $cac
// We're not using the parent constructor because we use a different factory
// method and don't need the derivative discovery decorator.
$this->factory = new ReflectionFactory($this);
$this->factory = new ReflectionFactory($this, '\Drupal\entity_reference\Plugin\Type\Selection\SelectionInterface');
$this->moduleHandler = $module_handler;
$this->alterInfo('entity_reference_selection');
......
......@@ -34,7 +34,7 @@ class FilterPluginManager extends DefaultPluginManager {
* The module handler to invoke the alter hook with.
*/
public function __construct(\Traversable $namespaces, CacheBackendInterface $cache_backend, ModuleHandlerInterface $module_handler) {
parent::__construct('Plugin/Filter', $namespaces, $module_handler, 'Drupal\filter\Annotation\Filter');
parent::__construct('Plugin/Filter', $namespaces, $module_handler, 'Drupal\filter\Plugin\FilterInterface', 'Drupal\filter\Annotation\Filter');
$this->alterInfo('filter_info');
$this->setCacheBackend($cache_backend, 'filter_plugins', array('filter_formats' => TRUE));
}
......
......@@ -36,7 +36,7 @@ class ImageEffectManager extends DefaultPluginManager {
* The module handler.
*/
public function __construct(\Traversable $namespaces, CacheBackendInterface $cache_backend, ModuleHandlerInterface $module_handler) {
parent::__construct('Plugin/ImageEffect', $namespaces, $module_handler, 'Drupal\image\Annotation\ImageEffect');
parent::__construct('Plugin/ImageEffect', $namespaces, $module_handler, 'Drupal\image\ImageEffectInterface', 'Drupal\image\Annotation\ImageEffect');
$this->alterInfo('image_effect_info');
$this->setCacheBackend($cache_backend, 'image_effect_plugins');
......
......@@ -28,7 +28,7 @@ class LanguageNegotiationMethodManager extends DefaultPluginManager {
* An object that implements ModuleHandlerInterface
*/
public function __construct(\Traversable $namespaces, CacheBackendInterface $cache_backend, ModuleHandlerInterface $module_handler) {
parent::__construct('Plugin/LanguageNegotiation', $namespaces, $module_handler);
parent::__construct('Plugin/LanguageNegotiation', $namespaces, $module_handler, 'Drupal\language\LanguageNegotiationMethodInterface');
$this->cacheBackend = $cache_backend;
$this->cacheKeyPrefix = 'language_negotiation_plugins';
$this->cacheKey = 'language_negotiation_plugins';
......
......@@ -2,7 +2,7 @@
/**
* @file
* Contains \Drupal\migrate\MigraterPluginManager.
* Contains \Drupal\migrate\Plugin\MigratePluginManager.
*/
namespace Drupal\migrate\Plugin;
......@@ -46,7 +46,15 @@ class MigratePluginManager extends DefaultPluginManager {
* The annotation class name.
*/
public function __construct($type, \Traversable $namespaces, CacheBackendInterface $cache_backend, ModuleHandlerInterface $module_handler, $annotation = 'Drupal\Component\Annotation\PluginID') {
parent::__construct("Plugin/migrate/$type", $namespaces, $module_handler, $annotation);
$plugin_interface_map = array(
'destination' => 'Drupal\migrate\Plugin\MigrateDestinationInterface',
'process' => 'Drupal\migrate\Plugin\MigrateProcessInterface',
'source' => 'Drupal\migrate\Plugin\MigrateSourceInterface',
'id_map' => 'Drupal\migrate\Plugin\MigrateIdMapInterface',
'entity_field' => 'Drupal\migrate\Plugin\MigrateEntityDestinationFieldInterface',
);
$plugin_interface = isset($plugin_interface_map[$type]) ? $plugin_interface_map[$type] : NULL;
parent::__construct("Plugin/migrate/$type", $namespaces, $module_handler, $plugin_interface, $annotation);
$this->alterInfo('migrate_' . $type . '_info');
$this->setCacheBackend($cache_backend, 'migrate_plugins_' . $type);
}
......
services:
plugin.manager.migrate.load:
class: Drupal\migrate\Plugin\MigratePluginManager
class: Drupal\migrate_drupal\Plugin\MigratePluginManager
arguments: [load, '@container.namespaces', '@cache.discovery', '@module_handler']
......@@ -2,11 +2,12 @@
/**
* @file
* Contains Drupal\migrate\Plugin\MigrateLoadInterface
* Contains Drupal\migrate_drupal\Plugin\MigrateLoadInterface
*/
namespace Drupal\migrate_drupal\Plugin;
use Drupal\Component\Plugin\PluginInspectionInterface;
use Drupal\Core\Entity\EntityStorageInterface;
/**
......@@ -16,7 +17,7 @@
*
* @ingroup migration
*/
interface MigrateLoadInterface {
interface MigrateLoadInterface extends PluginInspectionInterface {
/**
* Load an additional migration.
......
<?php
/**
* @file
* Contains \Drupal\migrate_drupal\Plugin\MigratePluginManager.
*/
namespace Drupal\migrate_drupal\Plugin;
use Drupal\Core\Cache\CacheBackendInterface;
use Drupal\Core\Extension\ModuleHandlerInterface;
use Drupal\Core\Plugin\Factory\ContainerFactory;
use Drupal\migrate\Plugin\MigratePluginManager as BaseMigratePluginManager;
/**
* Manages migrate_drupal plugins.
*
* @see plugin_api
*
* @ingroup migration
*/
class MigratePluginManager extends BaseMigratePluginManager {
/**
* {@inheritdoc}
*/
public function __construct($type, \Traversable $namespaces, CacheBackendInterface $cache_backend, ModuleHandlerInterface $module_handler, $annotation = 'Drupal\Component\Annotation\PluginID') {
parent::__construct($type, $namespaces, $cache_backend, $module_handler, $annotation);
$this->factory = new ContainerFactory($this, 'Drupal\migrate_drupal\Plugin\MigrateLoadInterface');
}
}
......@@ -35,7 +35,7 @@ class InPlaceEditorManager extends DefaultPluginManager {
* The module handler to invoke the alter hook with.
*/
public function __construct(\Traversable $namespaces, CacheBackendInterface $cache_backend, ModuleHandlerInterface $module_handler) {
parent::__construct('Plugin/InPlaceEditor', $namespaces, $module_handler, 'Drupal\quickedit\Annotation\InPlaceEditor');
parent::__construct('Plugin/InPlaceEditor', $namespaces, $module_handler, 'Drupal\quickedit\Plugin\InPlaceEditorInterface', 'Drupal\quickedit\Annotation\InPlaceEditor');
$this->alterInfo('quickedit_editor');
$this->setCacheBackend($cache_backend, 'quickedit:editor');
}
......
......@@ -33,7 +33,7 @@ class ResourcePluginManager extends DefaultPluginManager {
* The module handler to invoke the alter hook with.
*/
public function __construct(\Traversable $namespaces, CacheBackendInterface $cache_backend, ModuleHandlerInterface $module_handler) {
parent::__construct('Plugin/rest/resource', $namespaces, $module_handler, 'Drupal\rest\Annotation\RestResource');
parent::__construct('Plugin/rest/resource', $namespaces, $module_handler, 'Drupal\rest\Plugin\ResourceInterface', 'Drupal\rest\Annotation\RestResource');
$this->setCacheBackend($cache_backend, 'rest_plugins');
$this->alterInfo('rest_resource');
......
......@@ -28,7 +28,7 @@ class SearchPluginManager extends DefaultPluginManager {
* The module handler to invoke the alter hook with.
*/
public function __construct(\Traversable $namespaces, CacheBackendInterface $cache_backend, ModuleHandlerInterface $module_handler) {
parent::__construct('Plugin/Search', $namespaces, $module_handler, 'Drupal\search\Annotation\SearchPlugin');
parent::__construct('Plugin/Search', $namespaces, $module_handler, 'Drupal\search\Plugin\SearchInterface', 'Drupal\search\Annotation\SearchPlugin');
$this->setCacheBackend($cache_backend, 'search_plugins');
$this->alterInfo('search_plugin');
}
......
......@@ -43,6 +43,13 @@ protected function setUp() {
'class' => 'Drupal\plugin_test\Plugin\plugin_test\fruit\Cherry',
'provider' => 'plugin_test',
),
'kale' => array(
'id' => 'kale',
'label' => 'Kale',
'color' => 'green',
'class' => 'Drupal\plugin_test\Plugin\plugin_test\fruit\Kale',
'provider' => 'plugin_test',
),
'orange' => array(
'id' => 'orange',
'label' => 'Orange',
......
......@@ -57,6 +57,13 @@ protected function setUp() {
'class' => 'Drupal\plugin_test\Plugin\plugin_test\fruit\Cherry',
'provider' => 'plugin_test',
),
'kale' => array(
'id' => 'kale',
'label' => 'Kale',
'color' => 'green',
'class' => 'Drupal\plugin_test\Plugin\plugin_test\fruit\Kale',
'provider' => 'plugin_test',
),
'orange' => array(
'id' => 'orange',
'label' => 'Orange',
......
......@@ -29,7 +29,7 @@ public function __construct(ModuleHandlerInterface $module_handler) {
// discovery implementation, but StaticDiscovery lets us add some simple
// mock plugins for unit testing.
$this->discovery = new StaticDiscovery();
$this->factory = new DefaultFactory($this);
$this->factory = new DefaultFactory($this, 'Drupal\Component\Plugin\PluginInspectionInterface');
$this->moduleHandler = $module_handler;
// Specify default values.
......
......@@ -14,4 +14,4 @@
* color = "green"
* )
*/
class Apple {}
class Apple implements FruitInterface {}
......@@ -17,6 +17,6 @@
* }
* )
*/
class Banana {
class Banana implements FruitInterface {
}
......@@ -14,4 +14,4 @@
* color = "red"
* )
*/
class Cherry {}
class Cherry implements FruitInterface {}
<?php
/**
* @file
* Contains \Drupal\plugin_test\Plugin\plugin_test\fruit\FruitInterface.
*/
namespace Drupal\plugin_test\Plugin\plugin_test\fruit;
/**
* Provides an interface for test plugins.
*/
interface FruitInterface { }
<?php
/**
* @file
* Contains \Drupal\plugin_test\Plugin\plugin_test\fruit\Kale.
*/
namespace Drupal\plugin_test\Plugin\plugin_test\fruit;
/**
* @Plugin(
* id = "kale",
* label = "Kale",
* color = "green"
* )
*/
class Kale {}
......@@ -14,4 +14,4 @@
* color = "orange"
* )
*/
class Orange {}
class Orange implements FruitInterface {}