Issue #2028511 by damiankloip, dawehner: Allow plugin derivative classes to use services from the container.
parent
535ed4185b
commit
bd51e51a90
|
@ -8,7 +8,7 @@
|
||||||
namespace Drupal\Core\Plugin;
|
namespace Drupal\Core\Plugin;
|
||||||
|
|
||||||
use Drupal\Component\Plugin\Discovery\CachedDiscoveryInterface;
|
use Drupal\Component\Plugin\Discovery\CachedDiscoveryInterface;
|
||||||
use Drupal\Component\Plugin\Discovery\DerivativeDiscoveryDecorator;
|
use Drupal\Core\Plugin\Discovery\ContainerDerivativeDiscoveryDecorator;
|
||||||
use Drupal\Component\Plugin\PluginManagerBase;
|
use Drupal\Component\Plugin\PluginManagerBase;
|
||||||
use Drupal\Component\Plugin\PluginManagerInterface;
|
use Drupal\Component\Plugin\PluginManagerInterface;
|
||||||
use Drupal\Component\Utility\NestedArray;
|
use Drupal\Component\Utility\NestedArray;
|
||||||
|
@ -98,7 +98,7 @@ class DefaultPluginManager extends PluginManagerBase implements PluginManagerInt
|
||||||
public function __construct($subdir, \Traversable $namespaces, $annotation_namespaces = array(), $plugin_definition_annotation_name = 'Drupal\Component\Annotation\Plugin') {
|
public function __construct($subdir, \Traversable $namespaces, $annotation_namespaces = array(), $plugin_definition_annotation_name = 'Drupal\Component\Annotation\Plugin') {
|
||||||
$this->subdir = $subdir;
|
$this->subdir = $subdir;
|
||||||
$this->discovery = new AnnotatedClassDiscovery($subdir, $namespaces, $annotation_namespaces, $plugin_definition_annotation_name);
|
$this->discovery = new AnnotatedClassDiscovery($subdir, $namespaces, $annotation_namespaces, $plugin_definition_annotation_name);
|
||||||
$this->discovery = new DerivativeDiscoveryDecorator($this->discovery);
|
$this->discovery = new ContainerDerivativeDiscoveryDecorator($this->discovery);
|
||||||
$this->factory = new ContainerFactory($this);
|
$this->factory = new ContainerFactory($this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,35 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @file
|
||||||
|
* Contains \Drupal\Core\Plugin\Discovery\ContainerDerivativeDiscoveryDecorator.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Drupal\Core\Plugin\Discovery;
|
||||||
|
|
||||||
|
use Drupal\Component\Plugin\Discovery\DerivativeDiscoveryDecorator;
|
||||||
|
|
||||||
|
class ContainerDerivativeDiscoveryDecorator extends DerivativeDiscoveryDecorator {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
protected function getDerivativeFetcher($base_plugin_id, array $base_definition) {
|
||||||
|
if (!isset($this->derivativeFetchers[$base_plugin_id])) {
|
||||||
|
$this->derivativeFetchers[$base_plugin_id] = FALSE;
|
||||||
|
if (isset($base_definition['derivative'])) {
|
||||||
|
$class = $base_definition['derivative'];
|
||||||
|
// If the derivative class provides a factory method, pass the container
|
||||||
|
// to it.
|
||||||
|
if (is_subclass_of($class, 'Drupal\Core\Plugin\Discovery\ContainerDerivativeInterface')) {
|
||||||
|
$this->derivativeFetchers[$base_plugin_id] = $class::create(\Drupal::getContainer(), $base_plugin_id);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$this->derivativeFetchers[$base_plugin_id] = new $class($base_plugin_id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $this->derivativeFetchers[$base_plugin_id] ?: NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,30 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @file
|
||||||
|
* Contains \Drupal\Core\Plugin\Discovery\ContainerDerivativeInterface.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Drupal\Core\Plugin\Discovery;
|
||||||
|
|
||||||
|
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Derivative fetcher interface to pass the container to static create method.
|
||||||
|
*/
|
||||||
|
interface ContainerDerivativeInterface {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates an instance of the derivative fetcher.
|
||||||
|
*
|
||||||
|
* @param \Symfony\Component\DependencyInjection\ContainerInterface $container
|
||||||
|
* The container to pull out services used in the fetcher.
|
||||||
|
* @param string $plugin_id
|
||||||
|
* The base plugin ID for the plugin ID.
|
||||||
|
*
|
||||||
|
* @return static
|
||||||
|
* Returns an instance of this fetcher.
|
||||||
|
*/
|
||||||
|
public static function create(ContainerInterface $container, $base_plugin_id);
|
||||||
|
|
||||||
|
}
|
|
@ -7,14 +7,16 @@
|
||||||
|
|
||||||
namespace Drupal\views\Plugin\Derivative;
|
namespace Drupal\views\Plugin\Derivative;
|
||||||
|
|
||||||
use Drupal\Component\Plugin\Derivative\DerivativeInterface;
|
use Drupal\Core\Entity\EntityStorageControllerInterface;
|
||||||
|
use Drupal\Core\Plugin\Discovery\ContainerDerivativeInterface;
|
||||||
|
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Provides block plugin definitions for all Views block displays.
|
* Provides block plugin definitions for all Views block displays.
|
||||||
*
|
*
|
||||||
* @see \Drupal\views\Plugin\block\block\ViewsBlock
|
* @see \Drupal\views\Plugin\block\block\ViewsBlock
|
||||||
*/
|
*/
|
||||||
class ViewsBlock implements DerivativeInterface {
|
class ViewsBlock implements ContainerDerivativeInterface {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* List of derivative definitions.
|
* List of derivative definitions.
|
||||||
|
@ -23,6 +25,43 @@ class ViewsBlock implements DerivativeInterface {
|
||||||
*/
|
*/
|
||||||
protected $derivatives = array();
|
protected $derivatives = array();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The base plugin ID.
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected $base_plugin_id;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The view storage controller.
|
||||||
|
*
|
||||||
|
* @var \Drupal\Core\Entity\EntityStorageControllerInterface
|
||||||
|
*/
|
||||||
|
protected $viewStorageController;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public static function create(ContainerInterface $container, $base_plugin_id) {
|
||||||
|
return new static(
|
||||||
|
$base_plugin_id,
|
||||||
|
$container->get('plugin.manager.entity')->getStorageController('view')
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs a ViewsBlock object.
|
||||||
|
*
|
||||||
|
* @param string $base_plugin_id
|
||||||
|
* The base plugin ID.
|
||||||
|
* @param \Drupal\Core\Entity\EntityStorageControllerInterface $view_storage_controller
|
||||||
|
* The entity storage controller to load views.
|
||||||
|
*/
|
||||||
|
public function __construct($base_plugin_id, EntityStorageControllerInterface $view_storage_controller) {
|
||||||
|
$this->basePluginId = $base_plugin_id;
|
||||||
|
$this->viewStorageController = $view_storage_controller;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Implements \Drupal\Component\Plugin\Derivative\DerivativeInterface::getDerivativeDefinition().
|
* Implements \Drupal\Component\Plugin\Derivative\DerivativeInterface::getDerivativeDefinition().
|
||||||
*/
|
*/
|
||||||
|
@ -39,7 +78,7 @@ class ViewsBlock implements DerivativeInterface {
|
||||||
*/
|
*/
|
||||||
public function getDerivativeDefinitions(array $base_plugin_definition) {
|
public function getDerivativeDefinitions(array $base_plugin_definition) {
|
||||||
// Check all Views for block displays.
|
// Check all Views for block displays.
|
||||||
foreach (views_get_all_views() as $view) {
|
foreach ($this->viewStorageController->loadMultiple() as $view) {
|
||||||
// Do not return results for disabled views.
|
// Do not return results for disabled views.
|
||||||
if (!$view->status()) {
|
if (!$view->status()) {
|
||||||
continue;
|
continue;
|
||||||
|
|
|
@ -0,0 +1,68 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @file
|
||||||
|
* Contains \Drupal\Tests\Core\Plugin\Discovery\ContainerDerivativeDiscoveryDecoratorTest.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Drupal\Tests\Core\Plugin\Discovery;
|
||||||
|
|
||||||
|
use Drupal\Core\Plugin\Discovery\ContainerDerivativeDiscoveryDecorator;
|
||||||
|
use Drupal\Tests\UnitTestCase;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests the container aware derivative discovery decorator.
|
||||||
|
*/
|
||||||
|
class ContainerDerivativeDiscoveryDecoratorTest extends UnitTestCase {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public static function getInfo() {
|
||||||
|
return array(
|
||||||
|
'name' => 'Container aware derivative discovery decorator.',
|
||||||
|
'description' => 'Tests the container aware derivative discovery decorator.',
|
||||||
|
'group' => 'Plugin',
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests the getDerivativeFetcher method.
|
||||||
|
*
|
||||||
|
* @see \Drupal\Core\Plugin\Discovery\ContainerDerivativeDiscoveryDecorator::getDerivativeFetcher().
|
||||||
|
*/
|
||||||
|
public function testGetDerivativeFetcher() {
|
||||||
|
$example_service = $this->getMock('Symfony\Component\EventDispatcher\EventDispatcherInterface');
|
||||||
|
$example_container = $this->getMockBuilder('Symfony\Component\DependencyInjection\ContainerBuilder')
|
||||||
|
->setMethods(array('get'))
|
||||||
|
->getMock();
|
||||||
|
$example_container->expects($this->once())
|
||||||
|
->method('get')
|
||||||
|
->with($this->equalTo('example_service'))
|
||||||
|
->will($this->returnValue($example_service));
|
||||||
|
|
||||||
|
\Drupal::setContainer($example_container);
|
||||||
|
|
||||||
|
$definitions = array();
|
||||||
|
$definitions['container_aware_discovery'] = array(
|
||||||
|
'id' => 'container_aware_discovery',
|
||||||
|
'derivative' => '\Drupal\Tests\Core\Plugin\Discovery\TestContainerDerivativeDiscovery',
|
||||||
|
);
|
||||||
|
$definitions['non_container_aware_discovery'] = array(
|
||||||
|
'id' => 'non_container_aware_discovery',
|
||||||
|
'derivative' => '\Drupal\Tests\Core\Plugin\Discovery\TestDerivativeDiscovery',
|
||||||
|
);
|
||||||
|
|
||||||
|
$discovery_main = $this->getMock('Drupal\Component\Plugin\Discovery\DiscoveryInterface');
|
||||||
|
$discovery_main->expects($this->any())
|
||||||
|
->method('getDefinitions')
|
||||||
|
->will($this->returnValue($definitions));
|
||||||
|
|
||||||
|
$discovery = new ContainerDerivativeDiscoveryDecorator($discovery_main);
|
||||||
|
$definitions = $discovery->getDefinitions();
|
||||||
|
|
||||||
|
// Ensure that both the instances from container and non-container test derivatives got added.
|
||||||
|
$this->assertEquals(4, count($definitions));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,35 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @file
|
||||||
|
* Contains \Drupal\Tests\Core\Plugin\Discovery\TestContainerDerivativeDiscovery.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Drupal\Tests\Core\Plugin\Discovery;
|
||||||
|
|
||||||
|
use Drupal\Core\Plugin\Discovery\ContainerDerivativeInterface;
|
||||||
|
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||||
|
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Defines container test derivative discovery.
|
||||||
|
*/
|
||||||
|
class TestContainerDerivativeDiscovery extends TestDerivativeDiscovery implements ContainerDerivativeInterface {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs a TestContainerDerivativeDiscovery object.
|
||||||
|
*
|
||||||
|
* @var \Symfony\Component\EventDispatcher\EventDispatcherInterface $example_service
|
||||||
|
* Some service.
|
||||||
|
*/
|
||||||
|
public function __construct(EventDispatcherInterface $example_service) {
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public static function create(ContainerInterface $container, $base_plugin_id) {
|
||||||
|
return new static($container->get('example_service'));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,36 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @file
|
||||||
|
* Contains \Drupal\Tests\Core\Plugin\Discovery\TestDiscovery.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Drupal\Tests\Core\Plugin\Discovery;
|
||||||
|
|
||||||
|
use Drupal\Component\Plugin\Derivative\DerivativeInterface;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Defines test derivative discovery.
|
||||||
|
*/
|
||||||
|
class TestDerivativeDiscovery implements DerivativeInterface {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function getDerivativeDefinition($derivative_id, array $base_plugin_definition) {
|
||||||
|
$definitions = $this->getDerivativeDefinitions($base_plugin_definition);
|
||||||
|
return $definitions[$derivative_id];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function getDerivativeDefinitions(array $base_plugin_definition) {
|
||||||
|
$plugins = array();
|
||||||
|
for ($i = 0; $i < 2; $i++) {
|
||||||
|
$plugins['test_discovery_' . $i] = $base_plugin_definition;
|
||||||
|
}
|
||||||
|
return $plugins;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in New Issue