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;
|
||||
|
||||
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\PluginManagerInterface;
|
||||
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') {
|
||||
$this->subdir = $subdir;
|
||||
$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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
||||
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.
|
||||
*
|
||||
* @see \Drupal\views\Plugin\block\block\ViewsBlock
|
||||
*/
|
||||
class ViewsBlock implements DerivativeInterface {
|
||||
class ViewsBlock implements ContainerDerivativeInterface {
|
||||
|
||||
/**
|
||||
* List of derivative definitions.
|
||||
|
@ -23,6 +25,43 @@ class ViewsBlock implements DerivativeInterface {
|
|||
*/
|
||||
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().
|
||||
*/
|
||||
|
@ -39,7 +78,7 @@ class ViewsBlock implements DerivativeInterface {
|
|||
*/
|
||||
public function getDerivativeDefinitions(array $base_plugin_definition) {
|
||||
// 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.
|
||||
if (!$view->status()) {
|
||||
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