Commit fa4ec00f authored by alexpott's avatar alexpott

Issue #2600926 by benjy, mikeryan, phenaproxima, hussainweb, alvar0hurtad0:...

Issue #2600926 by benjy, mikeryan, phenaproxima, hussainweb, alvar0hurtad0: Allow annotations to inherit across namespaces
parent d466fb2c
...@@ -46,6 +46,13 @@ class AnnotatedClassDiscovery implements DiscoveryInterface { ...@@ -46,6 +46,13 @@ class AnnotatedClassDiscovery implements DiscoveryInterface {
*/ */
protected $annotationReader; protected $annotationReader;
/**
* Additional namespaces to be scanned for annotation classes.
*
* @var string[]
*/
protected $annotationNamespaces = [];
/** /**
* Constructs a new instance. * Constructs a new instance.
* *
...@@ -55,10 +62,13 @@ class AnnotatedClassDiscovery implements DiscoveryInterface { ...@@ -55,10 +62,13 @@ class AnnotatedClassDiscovery implements DiscoveryInterface {
* @param string $plugin_definition_annotation_name * @param string $plugin_definition_annotation_name
* (optional) The name of the annotation that contains the plugin definition. * (optional) The name of the annotation that contains the plugin definition.
* Defaults to 'Drupal\Component\Annotation\Plugin'. * Defaults to 'Drupal\Component\Annotation\Plugin'.
* @param string[] $annotation_namespaces
* (optional) Additional namespaces to be scanned for annotation classes.
*/ */
function __construct($plugin_namespaces = array(), $plugin_definition_annotation_name = 'Drupal\Component\Annotation\Plugin') { function __construct($plugin_namespaces = array(), $plugin_definition_annotation_name = 'Drupal\Component\Annotation\Plugin', array $annotation_namespaces = []) {
$this->pluginNamespaces = $plugin_namespaces; $this->pluginNamespaces = $plugin_namespaces;
$this->pluginDefinitionAnnotationName = $plugin_definition_annotation_name; $this->pluginDefinitionAnnotationName = $plugin_definition_annotation_name;
$this->annotationNamespaces = $annotation_namespaces;
} }
/** /**
...@@ -74,6 +84,11 @@ protected function getAnnotationReader() { ...@@ -74,6 +84,11 @@ protected function getAnnotationReader() {
// Add the namespaces from the main plugin annotation, like @EntityType. // Add the namespaces from the main plugin annotation, like @EntityType.
$namespace = substr($this->pluginDefinitionAnnotationName, 0, strrpos($this->pluginDefinitionAnnotationName, '\\')); $namespace = substr($this->pluginDefinitionAnnotationName, 0, strrpos($this->pluginDefinitionAnnotationName, '\\'));
$this->annotationReader->addNamespace($namespace); $this->annotationReader->addNamespace($namespace);
// Register additional namespaces to be scanned for annotations.
foreach ($this->annotationNamespaces as $namespace) {
$this->annotationReader->addNamespace($namespace);
}
} }
return $this->annotationReader; return $this->annotationReader;
} }
......
...@@ -42,7 +42,7 @@ class DefaultPluginManager extends PluginManagerBase implements PluginManagerInt ...@@ -42,7 +42,7 @@ class DefaultPluginManager extends PluginManagerBase implements PluginManagerInt
* *
* @var array * @var array
*/ */
protected $cacheTags = array(); protected $cacheTags = [];
/** /**
* Name of the alter hook if one should be invoked. * Name of the alter hook if one should be invoked.
...@@ -73,7 +73,7 @@ class DefaultPluginManager extends PluginManagerBase implements PluginManagerInt ...@@ -73,7 +73,7 @@ class DefaultPluginManager extends PluginManagerBase implements PluginManagerInt
* *
* @var array * @var array
*/ */
protected $defaults = array(); protected $defaults = [];
/** /**
* The name of the annotation that contains the plugin definition. * The name of the annotation that contains the plugin definition.
...@@ -97,6 +97,14 @@ class DefaultPluginManager extends PluginManagerBase implements PluginManagerInt ...@@ -97,6 +97,14 @@ class DefaultPluginManager extends PluginManagerBase implements PluginManagerInt
*/ */
protected $namespaces; protected $namespaces;
/**
* Additional namespaces the annotation discovery mechanism should scan for
* annotation definitions.
*
* @var string[]
*/
protected $additionalAnnotationNamespaces = [];
/** /**
* Creates the discovery object. * Creates the discovery object.
* *
...@@ -112,13 +120,16 @@ class DefaultPluginManager extends PluginManagerBase implements PluginManagerInt ...@@ -112,13 +120,16 @@ class DefaultPluginManager extends PluginManagerBase implements PluginManagerInt
* @param string $plugin_definition_annotation_name * @param string $plugin_definition_annotation_name
* (optional) The name of the annotation that contains the plugin definition. * (optional) The name of the annotation that contains the plugin definition.
* Defaults to 'Drupal\Component\Annotation\Plugin'. * Defaults to 'Drupal\Component\Annotation\Plugin'.
* @param string[] $additional_annotation_namespaces
* (optional) Additional namespaces to scan for annotation definitions.
*/ */
public function __construct($subdir, \Traversable $namespaces, ModuleHandlerInterface $module_handler, $plugin_interface = NULL, $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', array $additional_annotation_namespaces = []) {
$this->subdir = $subdir; $this->subdir = $subdir;
$this->namespaces = $namespaces; $this->namespaces = $namespaces;
$this->pluginDefinitionAnnotationName = $plugin_definition_annotation_name; $this->pluginDefinitionAnnotationName = $plugin_definition_annotation_name;
$this->pluginInterface = $plugin_interface; $this->pluginInterface = $plugin_interface;
$this->moduleHandler = $module_handler; $this->moduleHandler = $module_handler;
$this->additionalAnnotationNamespaces = $additional_annotation_namespaces;
} }
/** /**
...@@ -242,7 +253,7 @@ public function processDefinition(&$definition, $plugin_id) { ...@@ -242,7 +253,7 @@ public function processDefinition(&$definition, $plugin_id) {
*/ */
protected function getDiscovery() { protected function getDiscovery() {
if (!$this->discovery) { if (!$this->discovery) {
$discovery = new AnnotatedClassDiscovery($this->subdir, $this->namespaces, $this->pluginDefinitionAnnotationName); $discovery = new AnnotatedClassDiscovery($this->subdir, $this->namespaces, $this->pluginDefinitionAnnotationName, $this->additionalAnnotationNamespaces);
$this->discovery = new ContainerDerivativeDiscoveryDecorator($discovery); $this->discovery = new ContainerDerivativeDiscoveryDecorator($discovery);
} }
return $this->discovery; return $this->discovery;
......
...@@ -52,8 +52,10 @@ class AnnotatedClassDiscovery extends ComponentAnnotatedClassDiscovery { ...@@ -52,8 +52,10 @@ class AnnotatedClassDiscovery extends ComponentAnnotatedClassDiscovery {
* @param string $plugin_definition_annotation_name * @param string $plugin_definition_annotation_name
* (optional) The name of the annotation that contains the plugin definition. * (optional) The name of the annotation that contains the plugin definition.
* Defaults to 'Drupal\Component\Annotation\Plugin'. * Defaults to 'Drupal\Component\Annotation\Plugin'.
* @param string[] $annotation_namespaces
* (optional) Additional namespaces to scan for annotation definitions.
*/ */
function __construct($subdir, \Traversable $root_namespaces, $plugin_definition_annotation_name = 'Drupal\Component\Annotation\Plugin') { function __construct($subdir, \Traversable $root_namespaces, $plugin_definition_annotation_name = 'Drupal\Component\Annotation\Plugin', array $annotation_namespaces = []) {
if ($subdir) { if ($subdir) {
// Prepend a directory separator to $subdir, // Prepend a directory separator to $subdir,
// if it does not already have one. // if it does not already have one.
...@@ -65,7 +67,7 @@ function __construct($subdir, \Traversable $root_namespaces, $plugin_definition_ ...@@ -65,7 +67,7 @@ function __construct($subdir, \Traversable $root_namespaces, $plugin_definition_
} }
$this->rootNamespacesIterator = $root_namespaces; $this->rootNamespacesIterator = $root_namespaces;
$plugin_namespaces = array(); $plugin_namespaces = array();
parent::__construct($plugin_namespaces, $plugin_definition_annotation_name); parent::__construct($plugin_namespaces, $plugin_definition_annotation_name, $annotation_namespaces);
} }
/** /**
......
...@@ -57,12 +57,21 @@ protected function setUp() { ...@@ -57,12 +57,21 @@ protected function setUp() {
'class' => 'Drupal\plugin_test\Plugin\plugin_test\fruit\Orange', 'class' => 'Drupal\plugin_test\Plugin\plugin_test\fruit\Orange',
'provider' => 'plugin_test', 'provider' => 'plugin_test',
), ),
'big_apple' => array(
'id' => 'big_apple',
'label' => 'Big Apple',
'color' => 'green',
'class' => 'Drupal\plugin_test_extended\Plugin\plugin_test\fruit\BigApple',
'provider' => 'plugin_test_extended',
),
); );
$base_directory = \Drupal::root() . '/core/modules/system/tests/modules/plugin_test/src'; $base_directory = \Drupal::root() . '/core/modules/system/tests/modules/plugin_test/src';
$namespaces = new \ArrayObject(array('Drupal\plugin_test' => $base_directory)); $base_directory2 = \Drupal::root() . '/core/modules/system/tests/modules/plugin_test_extended/src';
$namespaces = new \ArrayObject(array('Drupal\plugin_test' => $base_directory, 'Drupal\plugin_test_extended' => $base_directory2));
$this->discovery = new AnnotatedClassDiscovery('Plugin/plugin_test/fruit', $namespaces); $annotation_namespaces = ['Drupal\plugin_test\Plugin\Annotation', 'Drupal\plugin_test_extended\Plugin\Annotation'];
$this->discovery = new AnnotatedClassDiscovery('Plugin/plugin_test/fruit', $namespaces, 'Drupal\Component\Annotation\Plugin', $annotation_namespaces);
$this->emptyDiscovery = new AnnotatedClassDiscovery('Plugin/non_existing_module/non_existing_plugin_type', $namespaces); $this->emptyDiscovery = new AnnotatedClassDiscovery('Plugin/non_existing_module/non_existing_plugin_type', $namespaces);
} }
......
name: 'Plugin Test Extended'
type: module
description: 'Test annotations can extend other annotations in a different namespace.'
package: Testing
version: VERSION
core: 8.x
<?php
/**
* @file
* Contains \Drupal\plugin_test_extended\Plugin\Annotation\PluginExampleExtended
*/
namespace Drupal\plugin_test_extended\Plugin\Annotation;
use Drupal\Component\Annotation\Plugin;
/**
* Defines a test annotation that extends an annotation in another namespace.
*
* @Annotation
*/
class PluginExtended extends Plugin {
}
<?php
/**
* @file
* Contains \Drupal\plugin_test_extended\Plugin\plugin_test\fruit\BigApple
*/
namespace Drupal\plugin_test_extended\Plugin\plugin_test\fruit;
/**
* @PluginExtended(
* id = "big_apple",
* label = "Big Apple",
* color = "green"
* )
*/
class BigApple {
}
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