Skip to content
Snippets Groups Projects
Commit fa4ec00f authored by Alex Pott's avatar Alex Pott
Browse files

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

Issue #2600926 by benjy, mikeryan, phenaproxima, hussainweb, alvar0hurtad0: Allow annotations to inherit across namespaces
parent d466fb2c
No related branches found
No related tags found
2 merge requests!7452Issue #1797438. HTML5 validation is preventing form submit and not fully...,!789Issue #3210310: Adjust Database API to remove deprecated Drupal 9 code in Drupal 10
......@@ -46,6 +46,13 @@ class AnnotatedClassDiscovery implements DiscoveryInterface {
*/
protected $annotationReader;
/**
* Additional namespaces to be scanned for annotation classes.
*
* @var string[]
*/
protected $annotationNamespaces = [];
/**
* Constructs a new instance.
*
......@@ -55,10 +62,13 @@ class AnnotatedClassDiscovery implements DiscoveryInterface {
* @param string $plugin_definition_annotation_name
* (optional) The name of the annotation that contains the plugin definition.
* 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->pluginDefinitionAnnotationName = $plugin_definition_annotation_name;
$this->annotationNamespaces = $annotation_namespaces;
}
/**
......@@ -74,6 +84,11 @@ protected function getAnnotationReader() {
// Add the namespaces from the main plugin annotation, like @EntityType.
$namespace = substr($this->pluginDefinitionAnnotationName, 0, strrpos($this->pluginDefinitionAnnotationName, '\\'));
$this->annotationReader->addNamespace($namespace);
// Register additional namespaces to be scanned for annotations.
foreach ($this->annotationNamespaces as $namespace) {
$this->annotationReader->addNamespace($namespace);
}
}
return $this->annotationReader;
}
......
......@@ -42,7 +42,7 @@ class DefaultPluginManager extends PluginManagerBase implements PluginManagerInt
*
* @var array
*/
protected $cacheTags = array();
protected $cacheTags = [];
/**
* Name of the alter hook if one should be invoked.
......@@ -73,7 +73,7 @@ class DefaultPluginManager extends PluginManagerBase implements PluginManagerInt
*
* @var array
*/
protected $defaults = array();
protected $defaults = [];
/**
* The name of the annotation that contains the plugin definition.
......@@ -97,6 +97,14 @@ class DefaultPluginManager extends PluginManagerBase implements PluginManagerInt
*/
protected $namespaces;
/**
* Additional namespaces the annotation discovery mechanism should scan for
* annotation definitions.
*
* @var string[]
*/
protected $additionalAnnotationNamespaces = [];
/**
* Creates the discovery object.
*
......@@ -112,13 +120,16 @@ class DefaultPluginManager extends PluginManagerBase implements PluginManagerInt
* @param string $plugin_definition_annotation_name
* (optional) The name of the annotation that contains the plugin definition.
* 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->namespaces = $namespaces;
$this->pluginDefinitionAnnotationName = $plugin_definition_annotation_name;
$this->pluginInterface = $plugin_interface;
$this->moduleHandler = $module_handler;
$this->additionalAnnotationNamespaces = $additional_annotation_namespaces;
}
/**
......@@ -242,7 +253,7 @@ public function processDefinition(&$definition, $plugin_id) {
*/
protected function getDiscovery() {
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);
}
return $this->discovery;
......
......@@ -52,8 +52,10 @@ class AnnotatedClassDiscovery extends ComponentAnnotatedClassDiscovery {
* @param string $plugin_definition_annotation_name
* (optional) The name of the annotation that contains the plugin definition.
* 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) {
// Prepend a directory separator to $subdir,
// if it does not already have one.
......@@ -65,7 +67,7 @@ function __construct($subdir, \Traversable $root_namespaces, $plugin_definition_
}
$this->rootNamespacesIterator = $root_namespaces;
$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() {
'class' => 'Drupal\plugin_test\Plugin\plugin_test\fruit\Orange',
'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';
$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);
}
......
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 {
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment