Commit 428d0f0a authored by webchick's avatar webchick

Issue #2053153 by tim.plunkett, dawehner, damiankloip, aspilicious: Allow...

Issue #2053153 by tim.plunkett, dawehner, damiankloip, aspilicious: Allow contrib modules to provide plugins on behalf of optional modules.
parent f0f543f0
......@@ -605,7 +605,7 @@ services:
- { name: event_subscriber }
image.toolkit.manager:
class: Drupal\Core\ImageToolkit\ImageToolkitManager
arguments: ['@container.namespaces', '@cache.cache', '@language_manager', '@config.factory']
arguments: ['@container.namespaces', '@cache.cache', '@language_manager', '@config.factory', '@module_handler']
image.toolkit:
class: Drupal\Core\ImageToolkit\ImageToolkitInterface
factory_method: getDefaultToolkit
......
......@@ -31,8 +31,8 @@ class ArchiverManager extends DefaultPluginManager {
* The module handler to invoke the alter hook with.
*/
public function __construct(\Traversable $namespaces, CacheBackendInterface $cache_backend, LanguageManager $language_manager, ModuleHandlerInterface $module_handler) {
parent::__construct('Plugin/Archiver', $namespaces, 'Drupal\Core\Archiver\Annotation\Archiver');
$this->alterInfo($module_handler, 'archiver_info');
parent::__construct('Plugin/Archiver', $namespaces, $module_handler, 'Drupal\Core\Archiver\Annotation\Archiver');
$this->alterInfo('archiver_info');
$this->setCacheBackend($cache_backend, $language_manager, 'archiver_info_plugins');
}
......
......@@ -33,10 +33,10 @@ class ConditionManager extends DefaultPluginManager implements ExecutableManager
* The module handler to invoke the alter hook with.
*/
public function __construct(\Traversable $namespaces, CacheBackendInterface $cache_backend, LanguageManager $language_manager, ModuleHandlerInterface $module_handler) {
$this->alterInfo($module_handler, 'condition_info');
$this->alterInfo('condition_info');
$this->setCacheBackend($cache_backend, $language_manager, 'condition_plugins');
parent::__construct('Plugin/Condition', $namespaces, 'Drupal\Core\Condition\Annotation\Condition');
parent::__construct('Plugin/Condition', $namespaces, $module_handler, 'Drupal\Core\Condition\Annotation\Condition');
}
/**
......
......@@ -41,8 +41,8 @@ class FieldTypePluginManager extends DefaultPluginManager implements FieldTypePl
* The module handler.
*/
public function __construct(\Traversable $namespaces, CacheBackendInterface $cache_backend, LanguageManager $language_manager, ModuleHandlerInterface $module_handler) {
parent::__construct('Plugin/Field/FieldType', $namespaces, 'Drupal\Core\Field\Annotation\FieldType');
$this->alterInfo($module_handler, 'field_info');
parent::__construct('Plugin/Field/FieldType', $namespaces, $module_handler, 'Drupal\Core\Field\Annotation\FieldType');
$this->alterInfo('field_info');
$this->setCacheBackend($cache_backend, $language_manager, 'field_types_plugins');
}
......
......@@ -49,10 +49,10 @@ class FormatterPluginManager extends DefaultPluginManager {
*/
public function __construct(\Traversable $namespaces, CacheBackendInterface $cache_backend, ModuleHandlerInterface $module_handler, LanguageManager $language_manager, FieldTypePluginManagerInterface $field_type_manager) {
parent::__construct('Plugin/Field/FieldFormatter', $namespaces, 'Drupal\Core\Field\Annotation\FieldFormatter');
parent::__construct('Plugin/Field/FieldFormatter', $namespaces, $module_handler, 'Drupal\Core\Field\Annotation\FieldFormatter');
$this->setCacheBackend($cache_backend, $language_manager, 'field_formatter_types_plugins');
$this->alterInfo($module_handler, 'field_formatter_info');
$this->alterInfo('field_formatter_info');
$this->fieldTypeManager = $field_type_manager;
}
......
......@@ -48,10 +48,10 @@ class WidgetPluginManager extends DefaultPluginManager {
* The 'field type' plugin manager.
*/
public function __construct(\Traversable $namespaces, CacheBackendInterface $cache_backend, ModuleHandlerInterface $module_handler, LanguageManager $language_manager, FieldTypePluginManagerInterface $field_type_manager) {
parent::__construct('Plugin/Field/FieldWidget', $namespaces, 'Drupal\Core\Field\Annotation\FieldWidget');
parent::__construct('Plugin/Field/FieldWidget', $namespaces, $module_handler, 'Drupal\Core\Field\Annotation\FieldWidget');
$this->setCacheBackend($cache_backend, $language_manager, 'field_widget_types_plugins');
$this->alterInfo($module_handler, 'field_widget_info');
$this->alterInfo('field_widget_info');
$this->factory = new WidgetFactory($this);
$this->fieldTypeManager = $field_type_manager;
......
......@@ -9,6 +9,7 @@
use Drupal\Core\Cache\CacheBackendInterface;
use Drupal\Core\Config\ConfigFactoryInterface;
use Drupal\Core\Extension\ModuleHandlerInterface;
use Drupal\Core\Language\LanguageManager;
use Drupal\Core\Plugin\DefaultPluginManager;
......@@ -36,9 +37,11 @@ class ImageToolkitManager extends DefaultPluginManager {
* The language manager.
* @param \Drupal\Core\Config\ConfigFactoryInterface $config_factory
* The config factory.
* @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler
* The module handler.
*/
public function __construct(\Traversable $namespaces, CacheBackendInterface $cache_backend, LanguageManager $language_manager, ConfigFactoryInterface $config_factory) {
parent::__construct('Plugin/ImageToolkit', $namespaces, 'Drupal\Core\ImageToolkit\Annotation\ImageToolkit');
public function __construct(\Traversable $namespaces, CacheBackendInterface $cache_backend, LanguageManager $language_manager, ConfigFactoryInterface $config_factory, ModuleHandlerInterface $module_handler) {
parent::__construct('Plugin/ImageToolkit', $namespaces, $module_handler, 'Drupal\Core\ImageToolkit\Annotation\ImageToolkit');
$this->setCacheBackend($cache_backend, $language_manager, 'image_toolkit_plugins');
$this->configFactory = $config_factory;
......
......@@ -50,8 +50,8 @@ class MailManager extends DefaultPluginManager {
* The configuration factory.
*/
public function __construct(\Traversable $namespaces, CacheBackendInterface $cache_backend, LanguageManagerInterface $language_manager, ModuleHandlerInterface $module_handler, ConfigFactoryInterface $config_factory) {
parent::__construct('Plugin/Mail', $namespaces, 'Drupal\Core\Annotation\Mail');
$this->alterInfo($module_handler, 'mail_backend_info');
parent::__construct('Plugin/Mail', $namespaces, $module_handler, 'Drupal\Core\Annotation\Mail');
$this->alterInfo('mail_backend_info');
$this->setCacheBackend($cache_backend, $language_manager, 'mail_backend_plugins');
$this->mailConfig = $config_factory->get('system.mail');
}
......
......@@ -100,7 +100,8 @@ public function __construct(ControllerResolverInterface $controller_resolver, Mo
$this->controllerResolver = $controller_resolver;
$this->accessManager = $access_manager;
$this->account = $account;
$this->alterInfo($module_handler, 'contextual_links_plugins');
$this->moduleHandler = $module_handler;
$this->alterInfo('contextual_links_plugins');
$this->setCacheBackend($cache_backend, $language_manager, 'contextual_links_plugins');
}
......
......@@ -128,12 +128,12 @@ public function __construct(ControllerResolverInterface $controller_resolver, Re
$this->factory = new ContainerFactory($this);
$this->routeProvider = $route_provider;
$this->accessManager = $access_manager;
$this->moduleHandler = $module_handler;
$this->account = $account;
$this->controllerResolver = $controller_resolver;
$this->request = $request;
$this->alterInfo($module_handler, 'menu_local_actions');
$this->alterInfo('menu_local_actions');
$this->setCacheBackend($cache_backend, $language_manager, 'local_action_plugins', array('local_action' => TRUE));
}
/**
......
......@@ -137,7 +137,8 @@ public function __construct(ControllerResolverInterface $controller_resolver, Re
$this->routeBuilder = $route_builder;
$this->accessManager = $access_manager;
$this->account = $account;
$this->alterInfo($module_handler, 'local_tasks');
$this->moduleHandler = $module_handler;
$this->alterInfo('local_tasks');
$this->setCacheBackend($cache, $language_manager, 'local_task_plugins', array('local_task' => TRUE));
}
......
......@@ -106,15 +106,18 @@ class DefaultPluginManager extends PluginManagerBase implements PluginManagerInt
* @param \Traversable $namespaces
* An object that implements \Traversable which contains the root paths
* keyed by the corresponding namespace to look for plugin implementations.
* @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler
* The module handler.
* @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, $plugin_definition_annotation_name = 'Drupal\Component\Annotation\Plugin') {
public function __construct($subdir, \Traversable $namespaces, ModuleHandlerInterface $module_handler, $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->moduleHandler = $module_handler;
}
/**
......@@ -150,13 +153,10 @@ public function setCacheBackend(CacheBackendInterface $cache_backend, LanguageMa
/**
* Initializes the alter hook.
*
* @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler
* The module handler to invoke the alter hook with.
* @param string $alter_hook
* Name of the alter hook.
*/
protected function alterInfo(ModuleHandlerInterface $module_handler, $alter_hook) {
$this->moduleHandler = $module_handler;
protected function alterInfo($alter_hook) {
$this->alterHook = $alter_hook;
}
......@@ -267,6 +267,13 @@ protected function findDefinitions() {
if ($this->alterHook) {
$this->moduleHandler->alter($this->alterHook, $definitions);
}
// If this plugin was provided by a module that does not exist, remove the
// plugin definition.
foreach ($definitions as $plugin_id => $plugin_definition) {
if (isset($plugin_definition['provider']) && !in_array($plugin_definition['provider'], array('Core', 'Component')) && !$this->moduleHandler->moduleExists($plugin_definition['provider'])) {
unset($definitions[$plugin_id]);
}
}
return $definitions;
}
......
......@@ -45,11 +45,24 @@ class TypedDataManager extends DefaultPluginManager {
*/
protected $prototypes = array();
/**
* Constructs a new TypedDataManager.
*
* @param \Traversable $namespaces
* An object that implements \Traversable which contains the root paths
* keyed by the corresponding namespace to look for plugin implementations.
* @param \Drupal\Core\Cache\CacheBackendInterface $cache_backend
* Cache backend instance to use.
* @param \Drupal\Core\Language\LanguageManager $language_manager
* The language manager.
* @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler
* The module handler.
*/
public function __construct(\Traversable $namespaces, CacheBackendInterface $cache_backend, LanguageManager $language_manager, ModuleHandlerInterface $module_handler) {
$this->alterInfo($module_handler, 'data_type_info');
$this->alterInfo('data_type_info');
$this->setCacheBackend($cache_backend, $language_manager, 'typed_data_types_plugins');
parent::__construct('Plugin/DataType', $namespaces, 'Drupal\Core\TypedData\Annotation\DataType');
parent::__construct('Plugin/DataType', $namespaces, $module_handler, 'Drupal\Core\TypedData\Annotation\DataType');
}
/**
......
......@@ -47,9 +47,9 @@ class ConstraintManager extends DefaultPluginManager {
* The module handler to invoke the alter hook with.
*/
public function __construct(\Traversable $namespaces, CacheBackendInterface $cache_backend, LanguageManager $language_manager, ModuleHandlerInterface $module_handler) {
parent::__construct('Plugin/Validation/Constraint', $namespaces);
parent::__construct('Plugin/Validation/Constraint', $namespaces, $module_handler);
$this->discovery = new StaticDiscoveryDecorator($this->discovery, array($this, 'registerDefinitions'));
$this->alterInfo($module_handler, 'validation_constraint');
$this->alterInfo('validation_constraint');
$this->setCacheBackend($cache_backend, $language_manager, 'validation_constraint_plugins');
}
......
services:
plugin.manager.aggregator.fetcher:
class: Drupal\aggregator\Plugin\AggregatorPluginManager
arguments: [fetcher, '@container.namespaces', '@cache.cache', '@language_manager']
arguments: [fetcher, '@container.namespaces', '@cache.cache', '@language_manager', '@module_handler']
plugin.manager.aggregator.parser:
class: Drupal\aggregator\Plugin\AggregatorPluginManager
arguments: [parser, '@container.namespaces', '@cache.cache', '@language_manager']
arguments: [parser, '@container.namespaces', '@cache.cache', '@language_manager', '@module_handler']
plugin.manager.aggregator.processor:
class: Drupal\aggregator\Plugin\AggregatorPluginManager
arguments: [processor, '@container.namespaces', '@cache.cache', '@language_manager']
arguments: [processor, '@container.namespaces', '@cache.cache', '@language_manager', '@module_handler']
......@@ -8,6 +8,7 @@
namespace Drupal\aggregator\Plugin;
use Drupal\Core\Cache\CacheBackendInterface;
use Drupal\Core\Extension\ModuleHandlerInterface;
use Drupal\Core\Language\LanguageManager;
use Drupal\Core\Plugin\DefaultPluginManager;
......@@ -28,15 +29,17 @@ class AggregatorPluginManager extends DefaultPluginManager {
* Cache backend instance to use.
* @param \Drupal\Core\Language\LanguageManager $language_manager
* The language manager.
* @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler
* The module handler.
*/
public function __construct($type, \Traversable $namespaces, CacheBackendInterface $cache_backend, LanguageManager $language_manager) {
public function __construct($type, \Traversable $namespaces, CacheBackendInterface $cache_backend, LanguageManager $language_manager, ModuleHandlerInterface $module_handler) {
$type_annotations = array(
'fetcher' => 'Drupal\aggregator\Annotation\AggregatorFetcher',
'parser' => 'Drupal\aggregator\Annotation\AggregatorParser',
'processor' => 'Drupal\aggregator\Annotation\AggregatorProcessor',
);
parent::__construct("Plugin/aggregator/$type", $namespaces, $type_annotations[$type]);
parent::__construct("Plugin/aggregator/$type", $namespaces, $module_handler, $type_annotations[$type]);
$this->setCacheBackend($cache_backend, $language_manager, 'aggregator_' . $type . '_plugins');
}
......
......@@ -52,9 +52,9 @@ class BlockManager extends DefaultPluginManager {
* The translation manager.
*/
public function __construct(\Traversable $namespaces, CacheBackendInterface $cache_backend, LanguageManager $language_manager, ModuleHandlerInterface $module_handler, TranslationInterface $translation_manager) {
parent::__construct('Plugin/Block', $namespaces, 'Drupal\block\Annotation\Block');
parent::__construct('Plugin/Block', $namespaces, $module_handler, 'Drupal\block\Annotation\Block');
$this->alterInfo($module_handler, 'block');
$this->alterInfo('block');
$this->setCacheBackend($cache_backend, $language_manager, 'block_plugins');
$this->translationManager = $translation_manager;
}
......
......@@ -33,8 +33,8 @@ class CKEditorPluginManager extends DefaultPluginManager {
* The module handler to invoke the alter hook with.
*/
public function __construct(\Traversable $namespaces, CacheBackendInterface $cache_backend, LanguageManager $language_manager, ModuleHandlerInterface $module_handler) {
parent::__construct('Plugin/CKEditorPlugin', $namespaces, 'Drupal\ckeditor\Annotation\CKEditorPlugin');
$this->alterInfo($module_handler, 'ckeditor_plugin_info');
parent::__construct('Plugin/CKEditorPlugin', $namespaces, $module_handler, 'Drupal\ckeditor\Annotation\CKEditorPlugin');
$this->alterInfo('ckeditor_plugin_info');
$this->setCacheBackend($cache_backend, $language_manager, 'ckeditor_plugins');
}
......
......@@ -34,6 +34,13 @@ class ConfigMapperManager extends DefaultPluginManager implements ConfigMapperMa
*/
protected $typedConfigManager;
/**
* The theme handler.
*
* @var \Drupal\Core\Extension\ThemeHandlerInterface
*/
protected $themeHandler;
/**
* {@inheritdoc}
*/
......@@ -77,7 +84,10 @@ public function __construct(CacheBackendInterface $cache_backend, LanguageManage
$this->factory = new ContainerFactory($this);
// Let others alter definitions with hook_config_translation_info_alter().
$this->alterInfo($module_handler, 'config_translation_info');
$this->moduleHandler = $module_handler;
$this->themeHandler = $theme_handler;
$this->alterInfo('config_translation_info');
$this->setCacheBackend($cache_backend, $language_manager, 'config_translation_info_plugins');
}
......@@ -104,6 +114,28 @@ public function processDefinition(&$definition, $plugin_id) {
}
}
/**
* {@inheritdoc}
*/
protected function findDefinitions() {
$definitions = $this->discovery->getDefinitions();
foreach ($definitions as $plugin_id => &$definition) {
$this->processDefinition($definition, $plugin_id);
}
if ($this->alterHook) {
$this->moduleHandler->alter($this->alterHook, $definitions);
}
// If this plugin was provided by a module that does not exist, remove the
// plugin definition.
foreach ($definitions as $plugin_id => $plugin_definition) {
if (isset($plugin_definition['provider']) && !in_array($plugin_definition['provider'], array('Core', 'Component')) && (!$this->moduleHandler->moduleExists($plugin_definition['provider']) && !in_array($plugin_definition['provider'], array_keys($this->themeHandler->listInfo())))) {
unset($definitions[$plugin_id]);
}
}
return $definitions;
}
/**
* {@inheritdoc}
*/
......
......@@ -31,8 +31,8 @@ class EditorManager extends DefaultPluginManager {
* The module handler to invoke the alter hook with.
*/
public function __construct(\Traversable $namespaces, CacheBackendInterface $cache_backend, LanguageManager $language_manager, ModuleHandlerInterface $module_handler) {
parent::__construct('Plugin/Editor', $namespaces, 'Drupal\editor\Annotation\Editor');
$this->alterInfo($module_handler, 'editor_info');
parent::__construct('Plugin/Editor', $namespaces, $module_handler, 'Drupal\editor\Annotation\Editor');
$this->alterInfo('editor_info');
$this->setCacheBackend($cache_backend, $language_manager, 'editor_plugins');
}
......
......@@ -33,7 +33,8 @@ public function __construct(\Traversable $namespaces, CacheBackendInterface $cac
// method and don't need the derivative discovery decorator.
$this->factory = new ReflectionFactory($this);
$this->alterInfo($module_handler, 'entity_reference_selection');
$this->moduleHandler = $module_handler;
$this->alterInfo('entity_reference_selection');
$this->setCacheBackend($cache_backend, $language_manager, 'entity_reference_selection_plugins');
}
......
......@@ -39,8 +39,8 @@ class FilterPluginManager extends DefaultPluginManager {
* The module handler to invoke the alter hook with.
*/
public function __construct(\Traversable $namespaces, CacheBackendInterface $cache_backend, LanguageManager $language_manager, ModuleHandlerInterface $module_handler) {
parent::__construct('Plugin/Filter', $namespaces, 'Drupal\filter\Annotation\Filter');
$this->alterInfo($module_handler, 'filter_info');
parent::__construct('Plugin/Filter', $namespaces, $module_handler, 'Drupal\filter\Annotation\Filter');
$this->alterInfo('filter_info');
$this->setCacheBackend($cache_backend, $language_manager, 'filter_plugins', array('filter_formats' => TRUE));
}
......
......@@ -18,12 +18,22 @@
class ImageEffectManager extends DefaultPluginManager {
/**
* {@inheritdoc}
* Constructs a new ImageEffectManager.
*
* @param \Traversable $namespaces
* An object that implements \Traversable which contains the root paths
* keyed by the corresponding namespace to look for plugin implementations.
* @param \Drupal\Core\Cache\CacheBackendInterface $cache_backend
* Cache backend instance to use.
* @param \Drupal\Core\Language\LanguageManager $language_manager
* The language manager.
* @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler
* The module handler.
*/
public function __construct(\Traversable $namespaces, CacheBackendInterface $cache_backend, LanguageManager $language_manager, ModuleHandlerInterface $module_handler) {
parent::__construct('Plugin/ImageEffect', $namespaces, 'Drupal\image\Annotation\ImageEffect');
parent::__construct('Plugin/ImageEffect', $namespaces, $module_handler, 'Drupal\image\Annotation\ImageEffect');
$this->alterInfo($module_handler, 'image_effect_info');
$this->alterInfo('image_effect_info');
$this->setCacheBackend($cache_backend, $language_manager, 'image_effect_plugins');
}
......
......@@ -28,11 +28,11 @@ 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);
parent::__construct('Plugin/LanguageNegotiation', $namespaces, $module_handler);
$this->cacheBackend = $cache_backend;
$this->cacheKeyPrefix = 'language_negotiation_plugins';
$this->cacheKey = 'language_negotiation_plugins';
$this->alterInfo($module_handler, 'language_negotiation_info');
$this->alterInfo('language_negotiation_info');
}
}
......@@ -39,8 +39,8 @@ class MigratePluginManager extends DefaultPluginManager {
* The annotation class name.
*/
public function __construct($type, \Traversable $namespaces, CacheBackendInterface $cache_backend, LanguageManager $language_manager, ModuleHandlerInterface $module_handler, $annotation = 'Drupal\Component\Annotation\PluginID') {
parent::__construct("Plugin/migrate/$type", $namespaces, $annotation);
$this->alterInfo($module_handler, 'migrate_' . $type . '_info');
parent::__construct("Plugin/migrate/$type", $namespaces, $module_handler, $annotation);
$this->alterInfo('migrate_' . $type . '_info');
$this->setCacheBackend($cache_backend, $language_manager, 'migrate_plugins_' . $type);
}
......
......@@ -31,10 +31,10 @@ class ResourcePluginManager extends DefaultPluginManager {
* The module handler to invoke the alter hook with.
*/
public function __construct(\Traversable $namespaces, CacheBackendInterface $cache_backend, LanguageManagerInterface $language_manager, ModuleHandlerInterface $module_handler) {
parent::__construct('Plugin/rest/resource', $namespaces, 'Drupal\rest\Annotation\RestResource');
parent::__construct('Plugin/rest/resource', $namespaces, $module_handler, 'Drupal\rest\Annotation\RestResource');
$this->setCacheBackend($cache_backend, $language_manager, 'rest_plugins');
$this->alterInfo($module_handler, 'rest_resource');
$this->alterInfo('rest_resource');
}
/**
......
......@@ -31,7 +31,7 @@ class SearchPluginManager extends DefaultPluginManager {
* The module handler to invoke the alter hook with.
*/
public function __construct(\Traversable $namespaces, CacheBackendInterface $cache_backend, LanguageManager $language_manager, ModuleHandlerInterface $module_handler) {
parent::__construct('Plugin/Search', $namespaces, 'Drupal\search\Annotation\SearchPlugin');
parent::__construct('Plugin/Search', $namespaces, $module_handler, 'Drupal\search\Annotation\SearchPlugin');
$this->setCacheBackend($cache_backend, $language_manager, 'search_plugins');
// @todo Set an alter hook.
......
......@@ -11,6 +11,7 @@
use Drupal\plugin_test\Plugin\TestPluginManager;
use Drupal\plugin_test\Plugin\MockBlockManager;
use Drupal\plugin_test\Plugin\DefaultsTestPluginManager;
use Drupal\Core\Extension\ModuleHandler;
/**
* Base class for Plugin API unit tests.
......@@ -36,7 +37,8 @@ public function setUp() {
// as derivatives and ReflectionFactory.
$this->testPluginManager = new TestPluginManager();
$this->mockBlockManager = new MockBlockManager();
$this->defaultsTestPluginManager = new DefaultsTestPluginManager();
$module_handler = new ModuleHandler();
$this->defaultsTestPluginManager = new DefaultsTestPluginManager($module_handler);
// The expected plugin definitions within each manager. Several tests assert
// that these plugins and their definitions are found and returned by the
......
......@@ -9,6 +9,7 @@
use Drupal\Component\Plugin\Discovery\StaticDiscovery;
use Drupal\Component\Plugin\Factory\DefaultFactory;
use Drupal\Core\Extension\ModuleHandlerInterface;
use Drupal\Core\Plugin\DefaultPluginManager;
/**
......@@ -16,13 +17,20 @@
*/
class DefaultsTestPluginManager extends DefaultPluginManager {
public function __construct() {
/**
* Constructs a new DefaultsTestPluginManager instance.
*
* @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler
* The module handler.
*/
public function __construct(ModuleHandlerInterface $module_handler) {
// Create the object that can be used to return definitions for all the
// plugins available for this type. Most real plugin managers use a richer
// discovery implementation, but StaticDiscovery lets us add some simple
// mock plugins for unit testing.
$this->discovery = new StaticDiscovery();
$this->factory = new DefaultFactory($this);
$this->moduleHandler = $module_handler;
// Specify default values.
$this->defaults = array(
......
......@@ -31,9 +31,9 @@ class TipPluginManager extends DefaultPluginManager {
* The module handler to invoke the alter hook with.
*/
public function __construct(\Traversable $namespaces, CacheBackendInterface $cache_backend, LanguageManager $language_manager, ModuleHandlerInterface $module_handler) {
parent::__construct('Plugin/tour/tip', $namespaces, 'Drupal\tour\Annotation\Tip');
parent::__construct('Plugin/tour/tip', $namespaces, $module_handler, 'Drupal\tour\Annotation\Tip');
$this->alterInfo($module_handler, 'tour_tips_info');
$this->alterInfo('tour_tips_info');
$this->setCacheBackend($cache_backend, $language_manager, 'tour_plugins');
}
......
......@@ -35,7 +35,7 @@ class ViewsPluginManager extends DefaultPluginManager {
*/
public function __construct($type, \Traversable $namespaces, CacheBackendInterface $cache_backend, LanguageManager $language_manager, ModuleHandlerInterface $module_handler) {
$plugin_definition_annotation_name = 'Drupal\views\Annotation\Views' . Container::camelize($type);
parent::__construct("Plugin/views/$type", $namespaces, $plugin_definition_annotation_name);
parent::__construct("Plugin/views/$type", $namespaces, $module_handler, $plugin_definition_annotation_name);
$this->defaults += array(
'parent' => 'parent',
......@@ -43,7 +43,7 @@ public function __construct($type, \Traversable $namespaces, CacheBackendInterfa
'register_theme' => TRUE,
);
$this->alterInfo($module_handler, 'views_plugins_' . $type);
$this->alterInfo('views_plugins_' . $type);
$this->setCacheBackend($cache_backend, $language_manager, 'views_' . $type . '_plugins');
}
......
......@@ -7,10 +7,6 @@
namespace Drupal\Tests\Core\Extension;
if (!defined('DRUPAL_ROOT')) {
define('DRUPAL_ROOT', dirname(dirname(substr(__DIR__, 0, -strlen(__NAMESPACE__)))));
}
use Drupal\Core\Extension\ModuleHandler;
use Drupal\Tests\UnitTestCase;
use PHPUnit_Framework_Error_Notice;
......
......@@ -88,6 +88,7 @@ protected function setUp() {
$this->pluginDiscovery = $this->getMock('Drupal\Component\Plugin\Discovery\DiscoveryInterface');
$this->factory = $this->getMock('Drupal\Component\Plugin\Factory\FactoryInterface');
$this->cacheBackend = $this->getMock('Drupal\Core\Cache\CacheBackendInterface');
$this->moduleHandler = $this->getMock('\Drupal\Core\Extension\ModuleHandlerInterface');
$this->accessManager = $this->getMockBuilder('Drupal\Core\Access\AccessManager')
->disableOriginalConstructor()
->getMock();
......@@ -113,16 +114,18 @@ protected function setUp() {
$property->setAccessible(TRUE);
$property->setValue($this->contextualLinkManager, $this->accessManager);
$property = new \ReflectionProperty('Drupal\Core\Menu\ContextualLinkManager', 'moduleHandler');
$property->setAccessible(TRUE);
$property->setValue($this->contextualLinkManager, $this->moduleHandler);
$language_manager = $this->getMock('Drupal\Core\Language\LanguageManagerInterface');
$language_manager->expects($this->any())
->method('getCurrentLanguage')
->will($this->returnValue(new Language(array('id' => 'en'))));
$this->moduleHandler = $this->getMock('\Drupal\Core\Extension\ModuleHandlerInterface');
$method = new \ReflectionMethod('Drupal\Core\Menu\ContextualLinkManager', 'alterInfo');
$method->setAccessible(TRUE);
$method->invoke($this->contextualLinkManager, $this->moduleHandler, 'contextual_links_plugins');
$method->invoke($this->contextualLinkManager, 'contextual_links_plugins');
$this->contextualLinkManager->setCacheBackend($this->cacheBackend, $language_manager, 'contextual_links_plugins');
}
......
......@@ -379,7 +379,8 @@ public function __construct(ControllerResolverInterface $controller_resolver, Re
$this->account = $account;
$this->controllerResolver = $controller_resolver;
$this->request = $request;
$this->alterInfo($module_handler, 'menu_local_actions');
$this->moduleHandler = $module_handler;
$this->alterInfo('menu_local_actions');
$this->setCacheBackend($cache_backend, $language_manager, 'local_action_plugins', array('local_action' => TRUE));
}
......
......@@ -83,9 +83,18 @@ protected function getLocalTaskManager($module_dirs, $route_name, $route_params)
$property->setAccessible(TRUE);
$property->setValue($manager, $route_builder);
$this->moduleHandler = $this->getMockBuilder('Drupal\Core\Extension\ModuleHandlerInterface')
$module_handler = $this->getMockBuilder('Drupal\Core\Extension\ModuleHandlerInterface')
->disableOriginalConstructor()
->getMock();
$property = new \ReflectionProperty('Drupal\Core\Menu\LocalTaskManager', 'moduleHandler');
$property->setAccessible(TRUE);
$property->setValue($manager, $module_handler);
// Set all the modules as being existant.
$module_handler->expects($this->any())
->method('moduleExists')
->will($this->returnCallback(function ($module) use ($module_dirs) {
return isset($module_dirs[$module]);
}));
$pluginDiscovery = new YamlDiscovery('local_tasks', $module_dirs);
$pluginDiscovery = new ContainerDerivativeDiscoveryDecorator($pluginDiscovery);
......@@ -95,7 +104,7 @@ protected function getLocalTaskManager($module_dirs, $route_name, $route_params)
$method = new \ReflectionMethod('Drupal\Core\Menu\LocalTaskManager', 'alterInfo');
$method->setAccessible(TRUE);
$method->invoke($manager, $this->moduleHandler, 'local_tasks');
$method->invoke($manager, 'local_tasks');
$plugin_stub = $this->getMock('Drupal\Core\Menu\LocalTaskInterface');
$factory = $this->getMock('Drupal\Component\Plugin\Factory\FactoryInterface');
......
......@@ -67,6 +67,31 @@ protected function setUp() {
$this->namespaces = new \ArrayObject(array('Drupal\plugin_test' => DRUPAL_ROOT . '/core/modules/system/tests/modules/plugin_test/lib'));
}
/**
* Tests the plugin manager with a disabled module.
*/
public function testDefaultPluginManagerWithDisabledModule() {
$definitions = $this->expectedDefinitions;
$definitions['cherry'] = array(
'id' => 'cherry',
'label' => 'Cherry',
'color' => 'red',
'class' => 'Drupal\plugin_test\Plugin\plugin_test\fruit\Cherry',
'provider' => 'disabled_module',
);
$module_handler = $this->getMock('Drupal\Core\Extension\ModuleHandlerInterface');
$module_handler->expects($this->once())
->method('moduleExists')
->with('disabled_module')
->will($this->returnValue(FALSE));
$plugin_manager = new TestPluginManager($this->namespaces, $definitions, $module_handler, 'test_alter_hook');
$this->assertEmpty($plugin_manager->getDefinition('cherry'), 'Plugin information of a disabled module is not available');
}
/**
* Tests the plugin manager with no cache and altering.
*/
......@@ -188,3 +213,7 @@ public function testCacheClearWithTags() {
}
}
if (!defined('DRUPAL_ROOT')) {
define('DRUPAL_ROOT', dirname(dirname(substr(__DIR__, 0, -strlen(__NAMESPACE__)))));