Drupal 8.0.0 beta 12. More info: https://www.drupal.org/node/2514176
This commit is contained in:
commit
9921556621
13277 changed files with 1459781 additions and 0 deletions
|
@ -0,0 +1,51 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Contains \Drupal\Component\Plugin\CategorizingPluginManagerInterface.
|
||||
*/
|
||||
|
||||
namespace Drupal\Component\Plugin;
|
||||
|
||||
/**
|
||||
* Defines an interface for plugin managers that categorize plugin definitions.
|
||||
*/
|
||||
interface CategorizingPluginManagerInterface extends PluginManagerInterface {
|
||||
|
||||
/**
|
||||
* Gets the names of all categories.
|
||||
*
|
||||
* @return string[]
|
||||
* An array of translated categories, sorted alphabetically.
|
||||
*/
|
||||
public function getCategories();
|
||||
|
||||
/**
|
||||
* Gets sorted plugin definitions.
|
||||
*
|
||||
* @param array[]|null $definitions
|
||||
* (optional) The plugin definitions to sort. If omitted, all plugin
|
||||
* definitions are used.
|
||||
*
|
||||
* @return array[]
|
||||
* An array of plugin definitions, sorted by category and label.
|
||||
*/
|
||||
public function getSortedDefinitions(array $definitions = NULL);
|
||||
|
||||
/**
|
||||
* Gets sorted plugin definitions grouped by category.
|
||||
*
|
||||
* In addition to grouping, both categories and its entries are sorted,
|
||||
* whereas plugin definitions are sorted by label.
|
||||
*
|
||||
* @param array[]|null $definitions
|
||||
* (optional) The plugin definitions to group. If omitted, all plugin
|
||||
* definitions are used.
|
||||
*
|
||||
* @return array[]
|
||||
* Keys are category names, and values are arrays of which the keys are
|
||||
* plugin IDs and the values are plugin definitions.
|
||||
*/
|
||||
public function getGroupedDefinitions(array $definitions = NULL);
|
||||
|
||||
}
|
|
@ -0,0 +1,41 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Contains \Drupal\Component\Plugin\ConfigurablePluginInterface.
|
||||
*/
|
||||
|
||||
namespace Drupal\Component\Plugin;
|
||||
|
||||
/**
|
||||
* Provides an interface for a configurable plugin.
|
||||
*
|
||||
* @ingroup plugin_api
|
||||
*/
|
||||
interface ConfigurablePluginInterface extends DependentPluginInterface {
|
||||
|
||||
/**
|
||||
* Gets this plugin's configuration.
|
||||
*
|
||||
* @return array
|
||||
* An array of this plugin's configuration.
|
||||
*/
|
||||
public function getConfiguration();
|
||||
|
||||
/**
|
||||
* Sets the configuration for this plugin instance.
|
||||
*
|
||||
* @param array $configuration
|
||||
* An associative array containing the plugin's configuration.
|
||||
*/
|
||||
public function setConfiguration(array $configuration);
|
||||
|
||||
/**
|
||||
* Gets default configuration for this plugin.
|
||||
*
|
||||
* @return array
|
||||
* An associative array with the default configuration.
|
||||
*/
|
||||
public function defaultConfiguration();
|
||||
|
||||
}
|
103
core/lib/Drupal/Component/Plugin/Context/Context.php
Normal file
103
core/lib/Drupal/Component/Plugin/Context/Context.php
Normal file
|
@ -0,0 +1,103 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Contains \Drupal\Component\Plugin\Context\Context.
|
||||
*/
|
||||
|
||||
namespace Drupal\Component\Plugin\Context;
|
||||
|
||||
use Drupal\Component\Plugin\Exception\ContextException;
|
||||
use Symfony\Component\Validator\Constraints\Type;
|
||||
use Symfony\Component\Validator\Validation;
|
||||
|
||||
/**
|
||||
* A generic context class for wrapping data a plugin needs to operate.
|
||||
*/
|
||||
class Context implements ContextInterface {
|
||||
|
||||
/**
|
||||
* The value of the context.
|
||||
*
|
||||
* @var mixed
|
||||
*/
|
||||
protected $contextValue;
|
||||
|
||||
/**
|
||||
* The definition to which a context must conform.
|
||||
*
|
||||
* @var \Drupal\Component\Plugin\Context\ContextDefinitionInterface
|
||||
*/
|
||||
protected $contextDefinition;
|
||||
|
||||
/**
|
||||
* Sets the contextDefinition for us without needing to call the setter.
|
||||
*
|
||||
* @param \Drupal\Component\Plugin\Context\ContextDefinitionInterface $context_definition
|
||||
* The context definition.
|
||||
*/
|
||||
public function __construct(ContextDefinitionInterface $context_definition) {
|
||||
$this->contextDefinition = $context_definition;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements \Drupal\Component\Plugin\Context\ContextInterface::setContextValue().
|
||||
*/
|
||||
public function setContextValue($value) {
|
||||
$this->contextValue = $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements \Drupal\Component\Plugin\Context\ContextInterface::getContextValue().
|
||||
*/
|
||||
public function getContextValue() {
|
||||
// Support optional contexts.
|
||||
if (!isset($this->contextValue)) {
|
||||
$definition = $this->getContextDefinition();
|
||||
$default_value = $definition->getDefaultValue();
|
||||
|
||||
if (!isset($default_value) && $definition->isRequired()) {
|
||||
$type = $definition->getDataType();
|
||||
throw new ContextException(sprintf("The %s context is required and not present.", $type));
|
||||
}
|
||||
// Keep the default value here so that subsequent calls don't have to look
|
||||
// it up again.
|
||||
$this->contextValue = $default_value;
|
||||
}
|
||||
return $this->contextValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function setContextDefinition(ContextDefinitionInterface $context_definition) {
|
||||
$this->contextDefinition = $context_definition;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements \Drupal\Component\Plugin\Context\ContextInterface::getContextDefinition().
|
||||
*/
|
||||
public function getContextDefinition() {
|
||||
return $this->contextDefinition;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements \Drupal\Component\Plugin\Context\ContextInterface::getConstraints().
|
||||
*/
|
||||
public function getConstraints() {
|
||||
if (empty($this->contextDefinition['class'])) {
|
||||
throw new ContextException("An error was encountered while trying to validate the context.");
|
||||
}
|
||||
return array(new Type($this->contextDefinition['class']));
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements \Drupal\Component\Plugin\Context\ContextInterface::validate().
|
||||
*/
|
||||
public function validate() {
|
||||
$validator = Validation::createValidatorBuilder()
|
||||
->getValidator();
|
||||
return $validator->validateValue($this->getContextValue(), $this->getConstraints());
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,179 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Contains \Drupal\Component\Plugin\Context\ContextDefinitionInterface.
|
||||
*/
|
||||
|
||||
namespace Drupal\Component\Plugin\Context;
|
||||
|
||||
/**
|
||||
* Interface for context definitions.
|
||||
*
|
||||
* @todo WARNING: This interface is going to receive some additions as part of
|
||||
* https://www.drupal.org/node/2346999.
|
||||
*/
|
||||
interface ContextDefinitionInterface {
|
||||
|
||||
/**
|
||||
* Gets a human readable label.
|
||||
*
|
||||
* @return string
|
||||
* The label.
|
||||
*/
|
||||
public function getLabel();
|
||||
|
||||
/**
|
||||
* Sets the human readable label.
|
||||
*
|
||||
* @param string $label
|
||||
* The label to set.
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setLabel($label);
|
||||
|
||||
/**
|
||||
* Gets a human readable description.
|
||||
*
|
||||
* @return string|null
|
||||
* The description, or NULL if no description is available.
|
||||
*/
|
||||
public function getDescription();
|
||||
|
||||
/**
|
||||
* Sets the human readable description.
|
||||
*
|
||||
* @param string|null $description
|
||||
* The description to set.
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setDescription($description);
|
||||
|
||||
/**
|
||||
* Gets the data type needed by the context.
|
||||
*
|
||||
* If the context is multiple-valued, this represents the type of each value.
|
||||
*
|
||||
* @return string
|
||||
* The data type.
|
||||
*/
|
||||
public function getDataType();
|
||||
|
||||
/**
|
||||
* Sets the data type needed by the context.
|
||||
*
|
||||
* @param string $data_type
|
||||
* The data type to set.
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setDataType($data_type);
|
||||
|
||||
/**
|
||||
* Determines whether the data is multi-valued, i.e. a list of data items.
|
||||
*
|
||||
* @return bool
|
||||
* Whether the data is multi-valued; i.e. a list of data items.
|
||||
*/
|
||||
public function isMultiple();
|
||||
|
||||
/**
|
||||
* Sets whether the data is multi-valued.
|
||||
*
|
||||
* @param bool $multiple
|
||||
* (optional) Whether the data is multi-valued. Defaults to TRUE.
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setMultiple($multiple = TRUE);
|
||||
|
||||
/**
|
||||
* Determines whether the context is required.
|
||||
*
|
||||
* For required data a non-NULL value is mandatory.
|
||||
*
|
||||
* @return bool
|
||||
* Whether a data value is required.
|
||||
*/
|
||||
public function isRequired();
|
||||
|
||||
/**
|
||||
* Sets whether the data is required.
|
||||
*
|
||||
* @param bool $required
|
||||
* (optional) Whether the data is multi-valued. Defaults to TRUE.
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setRequired($required = TRUE);
|
||||
|
||||
/**
|
||||
* Gets the default value for this context definition.
|
||||
*
|
||||
* @return mixed
|
||||
* The default value or NULL if no default value is set.
|
||||
*/
|
||||
public function getDefaultValue();
|
||||
|
||||
/**
|
||||
* Sets the default data value.
|
||||
*
|
||||
* @param mixed $default_value
|
||||
* The default value to be set or NULL to remove any default value.
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setDefaultValue($default_value);
|
||||
|
||||
/**
|
||||
* Gets an array of validation constraints.
|
||||
*
|
||||
* @return array
|
||||
* An array of validation constraint definitions, keyed by constraint name.
|
||||
* Each constraint definition can be used for instantiating
|
||||
* \Symfony\Component\Validator\Constraint objects.
|
||||
*/
|
||||
public function getConstraints();
|
||||
|
||||
/**
|
||||
* Sets the array of validation constraints.
|
||||
*
|
||||
* NOTE: This will override any previously set constraints. In most cases
|
||||
* ContextDefinitionInterface::addConstraint() should be used instead.
|
||||
*
|
||||
* @param array $constraints
|
||||
* The array of constraints.
|
||||
*
|
||||
* @return $this
|
||||
*
|
||||
* @see self::addConstraint()
|
||||
*/
|
||||
public function setConstraints(array $constraints);
|
||||
|
||||
/**
|
||||
* Adds a validation constraint.
|
||||
*
|
||||
* @param string $constraint_name
|
||||
* The name of the constraint to add, i.e. its plugin id.
|
||||
* @param array|null $options
|
||||
* The constraint options as required by the constraint plugin, or NULL.
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function addConstraint($constraint_name, $options = NULL);
|
||||
|
||||
/**
|
||||
* Gets a validation constraint.
|
||||
*
|
||||
* @param string $constraint_name
|
||||
* The name of the constraint, i.e. its plugin id.
|
||||
*
|
||||
* @return array
|
||||
* A validation constraint definition which can be used for instantiating a
|
||||
* \Symfony\Component\Validator\Constraint object.
|
||||
*/
|
||||
public function getConstraint($constraint_name);
|
||||
|
||||
}
|
|
@ -0,0 +1,68 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Contains \Drupal\Component\Plugin\Context\ContextInterface.
|
||||
*/
|
||||
|
||||
namespace Drupal\Component\Plugin\Context;
|
||||
|
||||
/**
|
||||
* A generic context interface for wrapping data a plugin needs to operate.
|
||||
*/
|
||||
interface ContextInterface {
|
||||
|
||||
/**
|
||||
* Sets the context value.
|
||||
*
|
||||
* @param mixed $value
|
||||
* The value of this context, matching the context definition.
|
||||
*
|
||||
* @see \Drupal\Component\Plugin\Context\ContextInterface::setContextDefinition().
|
||||
*/
|
||||
public function setContextValue($value);
|
||||
|
||||
/**
|
||||
* Gets the context value.
|
||||
*
|
||||
* @return mixed
|
||||
* The currently set context value, or NULL if it is not set.
|
||||
*/
|
||||
public function getContextValue();
|
||||
|
||||
/**
|
||||
* Sets the definition that the context must conform to.
|
||||
*
|
||||
* @param \Drupal\Component\Plugin\Context\ContextDefinitionInterface $context_definition
|
||||
* A defining characteristic representation of the context against which
|
||||
* that context can be validated.
|
||||
*/
|
||||
public function setContextDefinition(ContextDefinitionInterface $context_definition);
|
||||
|
||||
/**
|
||||
* Gets the provided definition that the context must conform to.
|
||||
*
|
||||
* @return \Drupal\Component\Plugin\Context\ContextDefinitionInterface
|
||||
* The defining characteristic representation of the context.
|
||||
*/
|
||||
public function getContextDefinition();
|
||||
|
||||
/**
|
||||
* Gets a list of validation constraints.
|
||||
*
|
||||
* @return array
|
||||
* Array of constraints, each being an instance of
|
||||
* \Symfony\Component\Validator\Constraint.
|
||||
*/
|
||||
public function getConstraints();
|
||||
|
||||
/**
|
||||
* Validates the set context value.
|
||||
*
|
||||
* @return \Symfony\Component\Validator\ConstraintViolationListInterface
|
||||
* A list of constraint violations. If the list is empty, validation
|
||||
* succeeded.
|
||||
*/
|
||||
public function validate();
|
||||
|
||||
}
|
145
core/lib/Drupal/Component/Plugin/ContextAwarePluginBase.php
Normal file
145
core/lib/Drupal/Component/Plugin/ContextAwarePluginBase.php
Normal file
|
@ -0,0 +1,145 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Contains \Drupal\Component\Plugin\ContextAwarePluginBase.
|
||||
*/
|
||||
|
||||
namespace Drupal\Component\Plugin;
|
||||
|
||||
use Drupal\Component\Plugin\Context\ContextInterface;
|
||||
use Drupal\Component\Plugin\Exception\ContextException;
|
||||
use Drupal\Component\Plugin\Context\Context;
|
||||
use Symfony\Component\Validator\ConstraintViolationList;
|
||||
|
||||
/**
|
||||
* Base class for plugins that are context aware.
|
||||
*/
|
||||
abstract class ContextAwarePluginBase extends PluginBase implements ContextAwarePluginInterface {
|
||||
|
||||
/**
|
||||
* The data objects representing the context of this plugin.
|
||||
*
|
||||
* @var \Drupal\Component\Plugin\Context\ContextInterface[]
|
||||
*/
|
||||
protected $context;
|
||||
|
||||
/**
|
||||
* Overrides \Drupal\Component\Plugin\PluginBase::__construct().
|
||||
*
|
||||
* Overrides the construction of context aware plugins to allow for
|
||||
* unvalidated constructor based injection of contexts.
|
||||
*
|
||||
* @param array $configuration
|
||||
* The plugin configuration, i.e. an array with configuration values keyed
|
||||
* by configuration option name. The special key 'context' may be used to
|
||||
* initialize the defined contexts by setting it to an array of context
|
||||
* values keyed by context names.
|
||||
* @param string $plugin_id
|
||||
* The plugin_id for the plugin instance.
|
||||
* @param mixed $plugin_definition
|
||||
* The plugin implementation definition.
|
||||
*/
|
||||
public function __construct(array $configuration, $plugin_id, $plugin_definition) {
|
||||
$context = array();
|
||||
if (isset($configuration['context'])) {
|
||||
$context = $configuration['context'];
|
||||
unset($configuration['context']);
|
||||
}
|
||||
parent::__construct($configuration, $plugin_id, $plugin_definition);
|
||||
foreach ($context as $key => $value) {
|
||||
$context_definition = $this->getContextDefinition($key);
|
||||
$this->context[$key] = new Context($context_definition);
|
||||
$this->context[$key]->setContextValue($value);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getContextDefinitions() {
|
||||
$definition = $this->getPluginDefinition();
|
||||
return !empty($definition['context']) ? $definition['context'] : array();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getContextDefinition($name) {
|
||||
$definition = $this->getPluginDefinition();
|
||||
if (empty($definition['context'][$name])) {
|
||||
throw new ContextException(sprintf("The %s context is not a valid context.", $name));
|
||||
}
|
||||
return $definition['context'][$name];
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getContexts() {
|
||||
// Make sure all context objects are initialized.
|
||||
foreach ($this->getContextDefinitions() as $name => $definition) {
|
||||
$this->getContext($name);
|
||||
}
|
||||
return $this->context;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getContext($name) {
|
||||
// Check for a valid context value.
|
||||
if (!isset($this->context[$name])) {
|
||||
$this->context[$name] = new Context($this->getContextDefinition($name));
|
||||
}
|
||||
return $this->context[$name];
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function setContext($name, ContextInterface $context) {
|
||||
$this->context[$name] = $context;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getContextValues() {
|
||||
$values = array();
|
||||
foreach ($this->getContextDefinitions() as $name => $definition) {
|
||||
$values[$name] = isset($this->context[$name]) ? $this->context[$name]->getContextValue() : NULL;
|
||||
}
|
||||
return $values;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getContextValue($name) {
|
||||
return $this->getContext($name)->getContextValue();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function setContextValue($name, $value) {
|
||||
$this->getContext($name)->setContextValue($value);
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function validateContexts() {
|
||||
$violations = new ConstraintViolationList();
|
||||
// @todo: Implement symfony validator API to let the validator traverse
|
||||
// and set property paths accordingly.
|
||||
|
||||
foreach ($this->getContexts() as $context) {
|
||||
$violations->addAll($context->validate());
|
||||
}
|
||||
return $violations;
|
||||
}
|
||||
|
||||
}
|
152
core/lib/Drupal/Component/Plugin/ContextAwarePluginInterface.php
Normal file
152
core/lib/Drupal/Component/Plugin/ContextAwarePluginInterface.php
Normal file
|
@ -0,0 +1,152 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Contains \Drupal\Component\Plugin\ContextAwarePluginInterface.
|
||||
*/
|
||||
|
||||
namespace Drupal\Component\Plugin;
|
||||
|
||||
use \Drupal\Component\Plugin\Context\ContextInterface;
|
||||
|
||||
/**
|
||||
* Interface for defining context aware plugins.
|
||||
*
|
||||
* Context aware plugins can specify an array of context definitions keyed by
|
||||
* context name at the plugin definition under the "context" key.
|
||||
*
|
||||
* @ingroup plugin_api
|
||||
*/
|
||||
interface ContextAwarePluginInterface extends PluginInspectionInterface {
|
||||
|
||||
/**
|
||||
* Gets the context definitions of the plugin.
|
||||
*
|
||||
* @return \Drupal\Component\Plugin\Context\ContextDefinitionInterface[]
|
||||
* The array of context definitions, keyed by context name.
|
||||
*/
|
||||
public function getContextDefinitions();
|
||||
|
||||
/**
|
||||
* Gets a specific context definition of the plugin.
|
||||
*
|
||||
* @param string $name
|
||||
* The name of the context in the plugin definition.
|
||||
*
|
||||
* @throws \Drupal\Component\Plugin\Exception\PluginException
|
||||
* If the requested context is not defined.
|
||||
*
|
||||
* @return \Drupal\Component\Plugin\Context\ContextDefinitionInterface.
|
||||
* The definition against which the context value must validate.
|
||||
*/
|
||||
public function getContextDefinition($name);
|
||||
|
||||
/**
|
||||
* Gets the defined contexts.
|
||||
*
|
||||
* @throws \Drupal\Component\Plugin\Exception\PluginException
|
||||
* If contexts are defined but not set.
|
||||
*
|
||||
* @return array
|
||||
* The set context objects.
|
||||
*/
|
||||
public function getContexts();
|
||||
|
||||
/**
|
||||
* Gets a defined context.
|
||||
*
|
||||
* @param string $name
|
||||
* The name of the context in the plugin definition.
|
||||
*
|
||||
* @throws \Drupal\Component\Plugin\Exception\PluginException
|
||||
* If the requested context is not set.
|
||||
*
|
||||
* @return \Drupal\Component\Plugin\Context\ContextInterface
|
||||
* The context object.
|
||||
*/
|
||||
public function getContext($name);
|
||||
|
||||
/**
|
||||
* Gets the values for all defined contexts.
|
||||
*
|
||||
* @return array
|
||||
* An array of set context values, keyed by context name. If a context is
|
||||
* unset its value is returned as NULL.
|
||||
*/
|
||||
public function getContextValues();
|
||||
|
||||
/**
|
||||
* Gets the value for a defined context.
|
||||
*
|
||||
* @param string $name
|
||||
* The name of the context in the plugin configuration.
|
||||
*
|
||||
* @throws \Drupal\Component\Plugin\Exception\PluginException
|
||||
* If the requested context is not set.
|
||||
*
|
||||
* @return mixed
|
||||
* The currently set context value.
|
||||
*/
|
||||
public function getContextValue($name);
|
||||
|
||||
/**
|
||||
* Set a context on this plugin.
|
||||
*
|
||||
* @param string $name
|
||||
* The name of the context in the plugin configuration.
|
||||
* @param \Drupal\Component\Plugin\Context\ContextInterface $context
|
||||
* The context object to set.
|
||||
*/
|
||||
public function setContext($name, ContextInterface $context);
|
||||
|
||||
/**
|
||||
* Sets the value for a defined context.
|
||||
*
|
||||
* @param string $name
|
||||
* The name of the context in the plugin definition.
|
||||
* @param mixed $value
|
||||
* The value to set the context to. The value has to validate against the
|
||||
* provided context definition.
|
||||
*
|
||||
* @throws \Drupal\Component\Plugin\Exception\PluginException
|
||||
* If the value does not pass validation.
|
||||
*
|
||||
* @return \Drupal\Component\Plugin\ContextAwarePluginInterface.
|
||||
* A context aware plugin object for chaining.
|
||||
*/
|
||||
public function setContextValue($name, $value);
|
||||
|
||||
/**
|
||||
* Validates the set values for the defined contexts.
|
||||
*
|
||||
* @return \Symfony\Component\Validator\ConstraintViolationListInterface
|
||||
* A list of constraint violations. If the list is empty, validation
|
||||
* succeeded.
|
||||
*/
|
||||
public function validateContexts();
|
||||
|
||||
/**
|
||||
* Gets a mapping of the expected assignment names to their context names.
|
||||
*
|
||||
* @return array
|
||||
* A mapping of the expected assignment names to their context names. For
|
||||
* example, if one of the $contexts is named 'user.current_user', but the
|
||||
* plugin expects a context named 'user', then this map would contain
|
||||
* 'user' => 'user.current_user'.
|
||||
*/
|
||||
public function getContextMapping();
|
||||
|
||||
/**
|
||||
* Sets a mapping of the expected assignment names to their context names.
|
||||
*
|
||||
* @param array $context_mapping
|
||||
* A mapping of the expected assignment names to their context names. For
|
||||
* example, if one of the $contexts is named 'user.current_user', but the
|
||||
* plugin expects a context named 'user', then this map would contain
|
||||
* 'user' => 'user.current_user'.
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setContextMapping(array $context_mapping);
|
||||
|
||||
}
|
|
@ -0,0 +1,42 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Contains \Drupal\Component\Plugin\DependentPluginInterface.
|
||||
*/
|
||||
|
||||
namespace Drupal\Component\Plugin;
|
||||
|
||||
/**
|
||||
* Provides an interface for a plugin that has dependencies.
|
||||
*
|
||||
* @ingroup plugin_api
|
||||
*/
|
||||
interface DependentPluginInterface {
|
||||
|
||||
/**
|
||||
* Calculates dependencies for the configured plugin.
|
||||
*
|
||||
* Dependencies are saved in the plugin's configuration entity and are used to
|
||||
* determine configuration synchronization order. For example, if the plugin
|
||||
* integrates with specific user roles, this method should return an array of
|
||||
* dependencies listing the specified roles.
|
||||
*
|
||||
* @return array
|
||||
* An array of dependencies grouped by type (config, content, module,
|
||||
* theme). For example:
|
||||
* @code
|
||||
* array(
|
||||
* 'config' => array('user.role.anonymous', 'user.role.authenticated'),
|
||||
* 'content' => array('node:article:f0a189e6-55fb-47fb-8005-5bef81c44d6d'),
|
||||
* 'module' => array('node', 'user'),
|
||||
* 'theme' => array('seven'),
|
||||
* );
|
||||
* @endcode
|
||||
*
|
||||
* @see \Drupal\Core\Config\Entity\ConfigDependencyManager
|
||||
* @see \Drupal\Core\Entity\EntityInterface::getConfigDependencyName()
|
||||
*/
|
||||
public function calculateDependencies();
|
||||
|
||||
}
|
39
core/lib/Drupal/Component/Plugin/Derivative/DeriverBase.php
Normal file
39
core/lib/Drupal/Component/Plugin/Derivative/DeriverBase.php
Normal file
|
@ -0,0 +1,39 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Contains \Drupal\Component\Plugin\Derivative\DeriverBase.
|
||||
*/
|
||||
|
||||
namespace Drupal\Component\Plugin\Derivative;
|
||||
|
||||
/**
|
||||
* Provides a basic deriver.
|
||||
*/
|
||||
abstract class DeriverBase implements DeriverInterface {
|
||||
|
||||
/**
|
||||
* List of derivative definitions.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $derivatives = array();
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getDerivativeDefinition($derivative_id, $base_plugin_definition) {
|
||||
if (!empty($this->derivatives) && !empty($this->derivatives[$derivative_id])) {
|
||||
return $this->derivatives[$derivative_id];
|
||||
}
|
||||
$this->getDerivativeDefinitions($base_plugin_definition);
|
||||
return $this->derivatives[$derivative_id];
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getDerivativeDefinitions($base_plugin_definition) {
|
||||
return $this->derivatives;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,47 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Contains \Drupal\Component\Plugin\Derivative\DeriverInterface.
|
||||
*/
|
||||
|
||||
namespace Drupal\Component\Plugin\Derivative;
|
||||
|
||||
/**
|
||||
* Provides additional plugin definitions based on an existing definition.
|
||||
*
|
||||
* @ingroup plugin_api
|
||||
*/
|
||||
interface DeriverInterface {
|
||||
|
||||
/**
|
||||
* Gets the definition of a derivative plugin.
|
||||
*
|
||||
* @param string $derivative_id
|
||||
* The derivative id. The id must uniquely identify the derivative within a
|
||||
* given base plugin, but derivative ids can be reused across base plugins.
|
||||
* @param mixed $base_plugin_definition
|
||||
* The definition of the base plugin from which the derivative plugin
|
||||
* is derived. It is maybe an entire object or just some array, depending
|
||||
* on the discovery mechanism.
|
||||
*
|
||||
* @return array
|
||||
* The full definition array of the derivative plugin, typically a merge of
|
||||
* $base_plugin_definition with extra derivative-specific information. NULL
|
||||
* if the derivative doesn't exist.
|
||||
*/
|
||||
public function getDerivativeDefinition($derivative_id, $base_plugin_definition);
|
||||
|
||||
/**
|
||||
* Gets the definition of all derivatives of a base plugin.
|
||||
*
|
||||
* @param array $base_plugin_definition
|
||||
* The definition array of the base plugin.
|
||||
* @return array
|
||||
* An array of full derivative definitions keyed on derivative id.
|
||||
*
|
||||
* @see getDerivativeDefinition()
|
||||
*/
|
||||
public function getDerivativeDefinitions($base_plugin_definition);
|
||||
|
||||
}
|
|
@ -0,0 +1,31 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Contains \Drupal\Component\Plugin\DerivativeInspectionInterface.
|
||||
*/
|
||||
|
||||
namespace Drupal\Component\Plugin;
|
||||
|
||||
/**
|
||||
* Provides a plugin interface for providing derivative metadata inspection.
|
||||
*/
|
||||
interface DerivativeInspectionInterface {
|
||||
|
||||
/**
|
||||
* Gets the base_plugin_id of the plugin instance.
|
||||
*
|
||||
* @return string
|
||||
* The base_plugin_id of the plugin instance.
|
||||
*/
|
||||
public function getBaseId();
|
||||
|
||||
/**
|
||||
* Gets the derivative_id of the plugin instance.
|
||||
*
|
||||
* @return string|null
|
||||
* The derivative_id of the plugin instance NULL otherwise.
|
||||
*/
|
||||
public function getDerivativeId();
|
||||
|
||||
}
|
|
@ -0,0 +1,37 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Contains \Drupal\Component\Plugin\Discovery\CachedDiscoveryInterface.
|
||||
*/
|
||||
|
||||
namespace Drupal\Component\Plugin\Discovery;
|
||||
|
||||
/**
|
||||
* Interface for discovery components holding a cache of plugin definitions.
|
||||
*/
|
||||
interface CachedDiscoveryInterface extends DiscoveryInterface {
|
||||
|
||||
/**
|
||||
* Clears static and persistent plugin definition caches.
|
||||
*
|
||||
* Don't resort to calling \Drupal::cache()->delete() and friends to make
|
||||
* Drupal detect new or updated plugin definitions. Always use this method on
|
||||
* the appropriate plugin type's plugin manager!
|
||||
*/
|
||||
public function clearCachedDefinitions();
|
||||
|
||||
/**
|
||||
* Disable the use of caches.
|
||||
*
|
||||
* Can be used to ensure that uncached plugin definitions are returned,
|
||||
* without invalidating all cached information.
|
||||
*
|
||||
* This will also remove all local/static caches.
|
||||
*
|
||||
* @param bool $use_caches
|
||||
* FALSE to not use any caches.
|
||||
*/
|
||||
public function useCaches($use_caches = FALSE);
|
||||
|
||||
}
|
|
@ -0,0 +1,248 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Contains \Drupal\Component\Plugin\Discovery\DerivativeDiscoveryDecorator.
|
||||
*/
|
||||
|
||||
namespace Drupal\Component\Plugin\Discovery;
|
||||
|
||||
use Drupal\Component\Plugin\Exception\InvalidDeriverException;
|
||||
|
||||
/**
|
||||
* Base class providing the tools for a plugin discovery to be derivative aware.
|
||||
*
|
||||
* Provides a decorator that allows the use of plugin derivatives for normal
|
||||
* implementations DiscoveryInterface.
|
||||
*/
|
||||
class DerivativeDiscoveryDecorator implements DiscoveryInterface {
|
||||
|
||||
use DiscoveryTrait;
|
||||
|
||||
/**
|
||||
* Plugin derivers.
|
||||
*
|
||||
* @var \Drupal\Component\Plugin\Derivative\DeriverInterface[]
|
||||
* Keys are base plugin IDs.
|
||||
*/
|
||||
protected $derivers = array();
|
||||
|
||||
/**
|
||||
* The decorated plugin discovery.
|
||||
*
|
||||
* @var \Drupal\Component\Plugin\Discovery\DiscoveryInterface
|
||||
*/
|
||||
protected $decorated;
|
||||
|
||||
/**
|
||||
* Creates a new instance.
|
||||
*
|
||||
* @param \Drupal\Component\Plugin\Discovery\DiscoveryInterface $decorated
|
||||
* The parent object implementing DiscoveryInterface that is being
|
||||
* decorated.
|
||||
*/
|
||||
public function __construct(DiscoveryInterface $decorated) {
|
||||
$this->decorated = $decorated;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @throws \Drupal\Component\Plugin\Exception\InvalidDeriverException
|
||||
* Thrown if the 'deriver' class specified in the plugin definition
|
||||
* does not implement \Drupal\Component\Plugin\Derivative\DeriverInterface.
|
||||
*/
|
||||
public function getDefinition($plugin_id, $exception_on_invalid = TRUE) {
|
||||
// This check is only for derivative plugins that have explicitly provided
|
||||
// an ID. This is not common, and can be expected to fail. Therefore, opt
|
||||
// out of the thrown exception, which will be handled when checking the
|
||||
// $base_plugin_id.
|
||||
$plugin_definition = $this->decorated->getDefinition($plugin_id, FALSE);
|
||||
|
||||
list($base_plugin_id, $derivative_id) = $this->decodePluginId($plugin_id);
|
||||
$base_plugin_definition = $this->decorated->getDefinition($base_plugin_id, $exception_on_invalid);
|
||||
if ($base_plugin_definition) {
|
||||
$deriver = $this->getDeriver($base_plugin_id, $base_plugin_definition);
|
||||
if ($deriver) {
|
||||
$derivative_plugin_definition = $deriver->getDerivativeDefinition($derivative_id, $base_plugin_definition);
|
||||
// If a plugin defined itself as a derivative, merge in possible
|
||||
// defaults from the derivative.
|
||||
if ($derivative_id && isset($plugin_definition)) {
|
||||
$plugin_definition = $this->mergeDerivativeDefinition($plugin_definition, $derivative_plugin_definition);
|
||||
}
|
||||
else {
|
||||
$plugin_definition = $derivative_plugin_definition;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $plugin_definition;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @throws \Drupal\Component\Plugin\Exception\InvalidDeriverException
|
||||
* Thrown if the 'deriver' class specified in the plugin definition
|
||||
* does not implement \Drupal\Component\Plugin\Derivative\DeriverInterface.
|
||||
*/
|
||||
public function getDefinitions() {
|
||||
$plugin_definitions = $this->decorated->getDefinitions();
|
||||
return $this->getDerivatives($plugin_definitions);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds derivatives to a list of plugin definitions.
|
||||
*
|
||||
* This should be called by the class extending this in
|
||||
* DiscoveryInterface::getDefinitions().
|
||||
*/
|
||||
protected function getDerivatives(array $base_plugin_definitions) {
|
||||
$plugin_definitions = array();
|
||||
foreach ($base_plugin_definitions as $base_plugin_id => $plugin_definition) {
|
||||
$deriver = $this->getDeriver($base_plugin_id, $plugin_definition);
|
||||
if ($deriver) {
|
||||
$derivative_definitions = $deriver->getDerivativeDefinitions($plugin_definition);
|
||||
foreach ($derivative_definitions as $derivative_id => $derivative_definition) {
|
||||
$plugin_id = $this->encodePluginId($base_plugin_id, $derivative_id);
|
||||
// Use this definition as defaults if a plugin already defined
|
||||
// itself as this derivative.
|
||||
if ($derivative_id && isset($base_plugin_definitions[$plugin_id])) {
|
||||
$derivative_definition = $this->mergeDerivativeDefinition($base_plugin_definitions[$plugin_id], $derivative_definition);
|
||||
}
|
||||
$plugin_definitions[$plugin_id] = $derivative_definition;
|
||||
}
|
||||
}
|
||||
// If a plugin already defined itself as a derivative it might already
|
||||
// be merged into the definitions.
|
||||
elseif (!isset($plugin_definitions[$base_plugin_id])) {
|
||||
$plugin_definitions[$base_plugin_id] = $plugin_definition;
|
||||
}
|
||||
}
|
||||
|
||||
return $plugin_definitions;
|
||||
}
|
||||
|
||||
/**
|
||||
* Decodes derivative id and plugin id from a string.
|
||||
*
|
||||
* @param string $plugin_id
|
||||
* Plugin identifier that may point to a derivative plugin.
|
||||
*
|
||||
* @return array
|
||||
* An array with the base plugin id as the first index and the derivative id
|
||||
* as the second. If there is no derivative id it will be null.
|
||||
*/
|
||||
protected function decodePluginId($plugin_id) {
|
||||
// Try and split the passed plugin definition into a plugin and a
|
||||
// derivative id. We don't need to check for !== FALSE because a leading
|
||||
// colon would break the derivative system and doesn't makes sense.
|
||||
if (strpos($plugin_id, ':')) {
|
||||
return explode(':', $plugin_id, 2);
|
||||
}
|
||||
|
||||
return array($plugin_id, NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* Encodes plugin and derivative id's into a string.
|
||||
*
|
||||
* @param string $base_plugin_id
|
||||
* The base plugin identifier.
|
||||
* @param string $derivative_id
|
||||
* The derivative identifier.
|
||||
*
|
||||
* @return string
|
||||
* A uniquely encoded combination of the $base_plugin_id and $derivative_id.
|
||||
*/
|
||||
protected function encodePluginId($base_plugin_id, $derivative_id) {
|
||||
if ($derivative_id) {
|
||||
return "$base_plugin_id:$derivative_id";
|
||||
}
|
||||
|
||||
// By returning the unmerged plugin_id, we are able to support derivative
|
||||
// plugins that support fetching the base definitions.
|
||||
return $base_plugin_id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a deriver for a base plugin.
|
||||
*
|
||||
* @param string $base_plugin_id
|
||||
* The base plugin id of the plugin.
|
||||
* @param mixed $base_definition
|
||||
* The base plugin definition to build derivatives.
|
||||
*
|
||||
* @return \Drupal\Component\Plugin\Derivative\DeriverInterface|null
|
||||
* A DerivativeInterface or NULL if none exists for the plugin.
|
||||
*
|
||||
* @throws \Drupal\Component\Plugin\Exception\InvalidDeriverException
|
||||
* Thrown if the 'deriver' class specified in the plugin definition
|
||||
* does not implement \Drupal\Component\Plugin\Derivative\DeriverInterface.
|
||||
*/
|
||||
protected function getDeriver($base_plugin_id, $base_definition) {
|
||||
if (!isset($this->derivers[$base_plugin_id])) {
|
||||
$this->derivers[$base_plugin_id] = FALSE;
|
||||
$class = $this->getDeriverClass($base_definition);
|
||||
if ($class) {
|
||||
$this->derivers[$base_plugin_id] = new $class($base_plugin_id);
|
||||
}
|
||||
}
|
||||
return $this->derivers[$base_plugin_id] ?: NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the deriver class name from the base plugin definition.
|
||||
*
|
||||
* @param array $base_definition
|
||||
* The base plugin definition to build derivatives.
|
||||
*
|
||||
* @return string|null
|
||||
* The name of a class implementing
|
||||
* \Drupal\Component\Plugin\Derivative\DeriverInterface.
|
||||
*
|
||||
* @throws \Drupal\Component\Plugin\Exception\InvalidDeriverException
|
||||
* Thrown if the 'deriver' class specified in the plugin definition
|
||||
* does not implement
|
||||
* \Drupal\Component\Plugin\Derivative\DerivativeInterface.
|
||||
*/
|
||||
protected function getDeriverClass($base_definition) {
|
||||
$class = NULL;
|
||||
if ((is_array($base_definition) || ($base_definition = (array) $base_definition)) && (isset($base_definition['deriver']) && $class = $base_definition['deriver'])) {
|
||||
if (!class_exists($class)) {
|
||||
throw new InvalidDeriverException(sprintf('Plugin (%s) deriver "%s" does not exist.', $base_definition['id'], $class));
|
||||
}
|
||||
if (!is_subclass_of($class, '\Drupal\Component\Plugin\Derivative\DeriverInterface')) {
|
||||
throw new InvalidDeriverException(sprintf('Plugin (%s) deriver "%s" must implement \Drupal\Component\Plugin\Derivative\DeriverInterface.', $base_definition['id'], $class));
|
||||
}
|
||||
}
|
||||
return $class;
|
||||
}
|
||||
|
||||
/**
|
||||
* Merges a base and derivative definition, taking into account empty values.
|
||||
*
|
||||
* @param array $base_plugin_definition
|
||||
* The base plugin definition.
|
||||
* @param array $derivative_definition
|
||||
* The derivative plugin definition.
|
||||
*
|
||||
* @return array
|
||||
* The merged definition.
|
||||
*/
|
||||
protected function mergeDerivativeDefinition($base_plugin_definition, $derivative_definition) {
|
||||
// Use this definition as defaults if a plugin already defined itself as
|
||||
// this derivative, but filter out empty values first.
|
||||
$filtered_base = array_filter($base_plugin_definition);
|
||||
$derivative_definition = $filtered_base + ($derivative_definition ?: array());
|
||||
// Add back any empty keys that the derivative didn't have.
|
||||
return $derivative_definition + $base_plugin_definition;
|
||||
}
|
||||
|
||||
/**
|
||||
* Passes through all unknown calls onto the decorated object.
|
||||
*/
|
||||
public function __call($method, $args) {
|
||||
return call_user_func_array(array($this->decorated, $method), $args);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,33 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Contains \Drupal\Component\Plugin\Discovery\DiscoveryCachedTrait.
|
||||
*/
|
||||
|
||||
namespace Drupal\Component\Plugin\Discovery;
|
||||
|
||||
trait DiscoveryCachedTrait {
|
||||
|
||||
use DiscoveryTrait;
|
||||
|
||||
/**
|
||||
* Cached definitions array.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $definitions;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getDefinition($plugin_id, $exception_on_invalid = TRUE) {
|
||||
// Fetch definitions if they're not loaded yet.
|
||||
if (!isset($this->definitions)) {
|
||||
$this->getDefinitions();
|
||||
}
|
||||
|
||||
return $this->doGetDefinition($this->definitions, $plugin_id, $exception_on_invalid);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,55 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Contains \Drupal\Component\Plugin\Discovery\DiscoveryInterface.
|
||||
*/
|
||||
|
||||
namespace Drupal\Component\Plugin\Discovery;
|
||||
|
||||
/**
|
||||
* An interface defining the minimum requirements of building a plugin
|
||||
* discovery component.
|
||||
*
|
||||
* @ingroup plugin_api
|
||||
*/
|
||||
interface DiscoveryInterface {
|
||||
|
||||
/**
|
||||
* Gets a specific plugin definition.
|
||||
*
|
||||
* @param string $plugin_id
|
||||
* A plugin id.
|
||||
* @param bool $exception_on_invalid
|
||||
* (optional) If TRUE, an invalid plugin ID will throw an exception.
|
||||
*
|
||||
* @return mixed
|
||||
* A plugin definition, or NULL if the plugin ID is invalid and
|
||||
* $exception_on_invalid is FALSE.
|
||||
*
|
||||
* @throws \Drupal\Component\Plugin\Exception\PluginNotFoundException
|
||||
* Thrown if $plugin_id is invalid and $exception_on_invalid is TRUE.
|
||||
*/
|
||||
public function getDefinition($plugin_id, $exception_on_invalid = TRUE);
|
||||
|
||||
/**
|
||||
* Gets the definition of all plugins for this type.
|
||||
*
|
||||
* @return mixed[]
|
||||
* An array of plugin definitions (empty array if no definitions were
|
||||
* found). Keys are plugin IDs.
|
||||
*/
|
||||
public function getDefinitions();
|
||||
|
||||
/**
|
||||
* Indicates if a specific plugin definition exists.
|
||||
*
|
||||
* @param string $plugin_id
|
||||
* A plugin ID.
|
||||
*
|
||||
* @return bool
|
||||
* TRUE if the definition exists, FALSE otherwise.
|
||||
*/
|
||||
public function hasDefinition($plugin_id);
|
||||
|
||||
}
|
|
@ -0,0 +1,67 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Contains \Drupal\Component\Plugin\Discovery\DiscoveryTrait.
|
||||
*/
|
||||
|
||||
namespace Drupal\Component\Plugin\Discovery;
|
||||
|
||||
use Drupal\Component\Plugin\Exception\PluginNotFoundException;
|
||||
|
||||
/**
|
||||
* @see Drupal\Component\Plugin\Discovery\DiscoveryInterface
|
||||
*/
|
||||
trait DiscoveryTrait {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
abstract public function getDefinitions();
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getDefinition($plugin_id, $exception_on_invalid = TRUE) {
|
||||
$definitions = $this->getDefinitions();
|
||||
return $this->doGetDefinition($definitions, $plugin_id, $exception_on_invalid);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a specific plugin definition.
|
||||
*
|
||||
* @param array $definitions
|
||||
* An array of the available plugin definitions.
|
||||
* @param string $plugin_id
|
||||
* A plugin id.
|
||||
* @param bool $exception_on_invalid
|
||||
* (optional) If TRUE, an invalid plugin ID will throw an exception.
|
||||
* Defaults to FALSE.
|
||||
*
|
||||
* @return array|null
|
||||
* A plugin definition, or NULL if the plugin ID is invalid and
|
||||
* $exception_on_invalid is TRUE.
|
||||
*
|
||||
* @throws \Drupal\Component\Plugin\Exception\PluginNotFoundException
|
||||
* Thrown if $plugin_id is invalid and $exception_on_invalid is TRUE.
|
||||
*/
|
||||
protected function doGetDefinition(array $definitions, $plugin_id, $exception_on_invalid) {
|
||||
// Avoid using a ternary that would create a copy of the array.
|
||||
if (isset($definitions[$plugin_id])) {
|
||||
return $definitions[$plugin_id];
|
||||
}
|
||||
elseif (!$exception_on_invalid) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
throw new PluginNotFoundException($plugin_id, sprintf('The "%s" plugin does not exist.', $plugin_id));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function hasDefinition($plugin_id) {
|
||||
return (bool) $this->getDefinition($plugin_id, FALSE);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,41 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Contains \Drupal\Component\Plugin\Discovery\StaticDiscovery.
|
||||
*/
|
||||
|
||||
namespace Drupal\Component\Plugin\Discovery;
|
||||
|
||||
/**
|
||||
* A discovery mechanism that allows plugin definitions to be manually
|
||||
* registered rather than actively discovered.
|
||||
*/
|
||||
class StaticDiscovery implements DiscoveryInterface {
|
||||
|
||||
use DiscoveryCachedTrait;
|
||||
|
||||
/**
|
||||
* Implements Drupal\Component\Plugin\Discovery\DiscoveryInterface::getDefinitions().
|
||||
*/
|
||||
public function getDefinitions() {
|
||||
if (!$this->definitions) {
|
||||
$this->definitions = array();
|
||||
}
|
||||
return $this->definitions;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a plugin definition.
|
||||
*/
|
||||
public function setDefinition($plugin, $definition) {
|
||||
$this->definitions[$plugin] = $definition;
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes a plugin definition.
|
||||
*/
|
||||
public function deleteDefinition($plugin) {
|
||||
unset($this->definitions[$plugin]);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,71 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Contains \Drupal\Component\Plugin\Discovery\StaticDiscoveryDecorator.
|
||||
*/
|
||||
|
||||
namespace Drupal\Component\Plugin\Discovery;
|
||||
|
||||
/**
|
||||
* A decorator that allows manual registration of undiscoverable definitions.
|
||||
*/
|
||||
class StaticDiscoveryDecorator extends StaticDiscovery {
|
||||
|
||||
/**
|
||||
* The Discovery object being decorated.
|
||||
*
|
||||
* @var \Drupal\Component\Plugin\Discovery\DiscoveryInterface
|
||||
*/
|
||||
protected $decorated;
|
||||
|
||||
/**
|
||||
* A callback or closure used for registering additional definitions.
|
||||
*
|
||||
* @var \Callable
|
||||
*/
|
||||
protected $registerDefinitions;
|
||||
|
||||
/**
|
||||
* Constructs a \Drupal\Component\Plugin\Discovery\StaticDiscoveryDecorator object.
|
||||
*
|
||||
* @param \Drupal\Component\Plugin\Discovery\DiscoveryInterface $decorated
|
||||
* The discovery object that is being decorated.
|
||||
* @param \Callable $registerDefinitions
|
||||
* (optional) A callback or closure used for registering additional
|
||||
* definitions.
|
||||
*/
|
||||
public function __construct(DiscoveryInterface $decorated, $registerDefinitions = NULL) {
|
||||
$this->decorated = $decorated;
|
||||
$this->registerDefinitions = $registerDefinitions;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getDefinition($base_plugin_id, $exception_on_invalid = TRUE) {
|
||||
if (isset($this->registerDefinitions)) {
|
||||
call_user_func($this->registerDefinitions);
|
||||
}
|
||||
$this->definitions += $this->decorated->getDefinitions();
|
||||
return parent::getDefinition($base_plugin_id, $exception_on_invalid);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements Drupal\Component\Plugin\Discovery\DiscoveryInterface::getDefinitions().
|
||||
*/
|
||||
public function getDefinitions() {
|
||||
if (isset($this->registerDefinitions)) {
|
||||
call_user_func($this->registerDefinitions);
|
||||
}
|
||||
$this->definitions += $this->decorated->getDefinitions();
|
||||
return parent::getDefinitions();
|
||||
}
|
||||
|
||||
/**
|
||||
* Passes through all unknown calls onto the decorated object
|
||||
*/
|
||||
public function __call($method, $args) {
|
||||
return call_user_func_array(array($this->decorated, $method), $args);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Contains \Drupal\Component\Plugin\Exception\ContextException.
|
||||
*/
|
||||
|
||||
namespace Drupal\Component\Plugin\Exception;
|
||||
|
||||
/**
|
||||
* An exception class to be thrown for context plugin exceptions.
|
||||
*/
|
||||
class ContextException extends \Exception implements ExceptionInterface { }
|
|
@ -0,0 +1,12 @@
|
|||
<?php
|
||||
/**
|
||||
* @file
|
||||
* Contains \Drupal\Component\Plugin\Exception\ExceptionInterface.
|
||||
*/
|
||||
|
||||
namespace Drupal\Component\Plugin\Exception;
|
||||
|
||||
/**
|
||||
* Exception interface for all exceptions thrown by the Plugin component.
|
||||
*/
|
||||
interface ExceptionInterface { }
|
|
@ -0,0 +1,17 @@
|
|||
<?php
|
||||
/**
|
||||
* @file
|
||||
* Contains \Drupal\Component\Plugin\Exception\InvalidDecoratedMethod.
|
||||
*/
|
||||
|
||||
namespace Drupal\Component\Plugin\Exception;
|
||||
|
||||
use Drupal\Component\Plugin\Exception\ExceptionInterface;
|
||||
use \BadMethodCallException;
|
||||
|
||||
/**
|
||||
* Exception thrown when a decorator's _call() method is triggered, but the
|
||||
* decorated object does not contain the requested method.
|
||||
*
|
||||
*/
|
||||
class InvalidDecoratedMethod extends BadMethodCallException implements ExceptionInterface { }
|
|
@ -0,0 +1,12 @@
|
|||
<?php
|
||||
/**
|
||||
* @file
|
||||
* Contains \Drupal\Component\Plugin\Exception\InvalidDeriverException.
|
||||
*/
|
||||
|
||||
namespace Drupal\Component\Plugin\Exception;
|
||||
|
||||
/**
|
||||
* Exception to be thrown if a plugin tries to use an invalid deriver.
|
||||
*/
|
||||
class InvalidDeriverException extends PluginException { }
|
|
@ -0,0 +1,45 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Contains \Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException.
|
||||
*/
|
||||
|
||||
namespace Drupal\Component\Plugin\Exception;
|
||||
|
||||
/**
|
||||
* Defines a class for invalid plugin definition exceptions.
|
||||
*/
|
||||
class InvalidPluginDefinitionException extends PluginException {
|
||||
|
||||
/**
|
||||
* The plugin ID of the mapper.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $pluginId;
|
||||
|
||||
/**
|
||||
* Constructs a InvalidPluginDefinitionException.
|
||||
*
|
||||
* @param string $plugin_id
|
||||
* The plugin ID of the mapper.
|
||||
*
|
||||
* @see \Exception for the remaining parameters.
|
||||
*/
|
||||
public function __construct($plugin_id, $message = '', $code = 0, \Exception $previous = NULL) {
|
||||
$this->pluginId = $plugin_id;
|
||||
parent::__construct($message, $code, $previous);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the plugin ID of the mapper that raised the exception.
|
||||
*
|
||||
* @return string
|
||||
* The plugin ID.
|
||||
*/
|
||||
public function getPluginId() {
|
||||
return $this->pluginId;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
<?php
|
||||
/**
|
||||
* @file
|
||||
* Contains \Drupal\Component\Plugin\Exception\MapperExceptionInterface.
|
||||
*
|
||||
* Base exception interface for grouping mapper exceptions.
|
||||
*/
|
||||
|
||||
namespace Drupal\Component\Plugin\Exception;
|
||||
|
||||
/**
|
||||
* Extended interface for exceptions thrown specifically by the Mapper subsystem
|
||||
* within the Plugin component.
|
||||
*/
|
||||
interface MapperExceptionInterface extends ExceptionInterface { }
|
|
@ -0,0 +1,13 @@
|
|||
<?php
|
||||
/**
|
||||
* @file
|
||||
* Contains \Drupal\Component\Plugin\Exception\PluginException.
|
||||
*/
|
||||
|
||||
namespace Drupal\Component\Plugin\Exception;
|
||||
|
||||
/**
|
||||
* Generic Plugin exception class to be thrown when no more specific class
|
||||
* is applicable.
|
||||
*/
|
||||
class PluginException extends \Exception implements ExceptionInterface { }
|
|
@ -0,0 +1,30 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Contains \Drupal\Component\Plugin\Exception\PluginNotFoundException.
|
||||
*/
|
||||
|
||||
namespace Drupal\Component\Plugin\Exception;
|
||||
|
||||
/**
|
||||
* Plugin exception class to be thrown when a plugin ID could not be found.
|
||||
*/
|
||||
class PluginNotFoundException extends PluginException {
|
||||
|
||||
/**
|
||||
* Construct an PluginNotFoundException exception.
|
||||
*
|
||||
* @param string $plugin_id
|
||||
* The plugin ID that was not found.
|
||||
*
|
||||
* @see \Exception for remaining parameters.
|
||||
*/
|
||||
public function __construct($plugin_id, $message = '', $code = 0, \Exception $previous = NULL) {
|
||||
if (empty($message)) {
|
||||
$message = sprintf("Plugin ID '%s' was not found.", $plugin_id);
|
||||
}
|
||||
parent::__construct($message, $code, $previous);
|
||||
}
|
||||
|
||||
}
|
96
core/lib/Drupal/Component/Plugin/Factory/DefaultFactory.php
Normal file
96
core/lib/Drupal/Component/Plugin/Factory/DefaultFactory.php
Normal file
|
@ -0,0 +1,96 @@
|
|||
<?php
|
||||
/**
|
||||
* @file
|
||||
* Contains \Drupal\Component\Plugin\Factory\DefaultFactory.
|
||||
*/
|
||||
|
||||
namespace Drupal\Component\Plugin\Factory;
|
||||
|
||||
use Drupal\Component\Plugin\Discovery\DiscoveryInterface;
|
||||
use Drupal\Component\Plugin\Exception\PluginException;
|
||||
|
||||
/**
|
||||
* Default plugin factory.
|
||||
*
|
||||
* Instantiates plugin instances by passing the full configuration array as a
|
||||
* single constructor argument. Plugin types wanting to support plugin classes
|
||||
* with more flexible constructor signatures can do so by using an alternate
|
||||
* factory such as Drupal\Component\Plugin\Factory\ReflectionFactory.
|
||||
*/
|
||||
class DefaultFactory implements FactoryInterface {
|
||||
|
||||
/**
|
||||
* The object that retrieves the definitions of the plugins that this factory instantiates.
|
||||
*
|
||||
* The plugin definition includes the plugin class and possibly other
|
||||
* information necessary for proper instantiation.
|
||||
*
|
||||
* @var \Drupal\Component\Plugin\Discovery\DiscoveryInterface
|
||||
*/
|
||||
protected $discovery;
|
||||
|
||||
/**
|
||||
* Defines an interface each plugin should implement.
|
||||
*
|
||||
* @var string|null
|
||||
*/
|
||||
protected $interface;
|
||||
|
||||
/**
|
||||
* Constructs a Drupal\Component\Plugin\Factory\DefaultFactory object.
|
||||
*
|
||||
* @param \Drupal\Component\Plugin\Discovery\DiscoveryInterface $discovery
|
||||
* The plugin discovery.
|
||||
* @param string|null $plugin_interface
|
||||
* (optional) The interface each plugin should implement.
|
||||
*/
|
||||
public function __construct(DiscoveryInterface $discovery, $plugin_interface = NULL) {
|
||||
$this->discovery = $discovery;
|
||||
$this->interface = $plugin_interface;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements Drupal\Component\Plugin\Factory\FactoryInterface::createInstance().
|
||||
*/
|
||||
public function createInstance($plugin_id, array $configuration = array()) {
|
||||
$plugin_definition = $this->discovery->getDefinition($plugin_id);
|
||||
$plugin_class = static::getPluginClass($plugin_id, $plugin_definition, $this->interface);
|
||||
return new $plugin_class($configuration, $plugin_id, $plugin_definition);
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds the class relevant for a given plugin.
|
||||
*
|
||||
* @param string $plugin_id
|
||||
* The id of a plugin.
|
||||
* @param mixed $plugin_definition
|
||||
* The plugin definition associated with the plugin ID.
|
||||
* @param string $required_interface
|
||||
* (optional) THe required plugin interface.
|
||||
*
|
||||
* @return string
|
||||
* The appropriate class name.
|
||||
*
|
||||
* @throws \Drupal\Component\Plugin\Exception\PluginException
|
||||
* Thrown when there is no class specified, the class doesn't exist, or
|
||||
* the class does not implement the specified required interface.
|
||||
*
|
||||
*/
|
||||
public static function getPluginClass($plugin_id, $plugin_definition = NULL, $required_interface = NULL) {
|
||||
if (empty($plugin_definition['class'])) {
|
||||
throw new PluginException(sprintf('The plugin (%s) did not specify an instance class.', $plugin_id));
|
||||
}
|
||||
|
||||
$class = $plugin_definition['class'];
|
||||
|
||||
if (!class_exists($class)) {
|
||||
throw new PluginException(sprintf('Plugin (%s) instance class "%s" does not exist.', $plugin_id, $class));
|
||||
}
|
||||
|
||||
if ($required_interface && !is_subclass_of($plugin_definition['class'], $required_interface)) {
|
||||
throw new PluginException(sprintf('Plugin "%s" (%s) must implement interface %s.', $plugin_id, $plugin_definition['class'], $required_interface));
|
||||
}
|
||||
|
||||
return $class;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
<?php
|
||||
/**
|
||||
* @file
|
||||
* Contains \Drupal\Component\Plugin\Factory\FactoryInterface.
|
||||
*/
|
||||
|
||||
namespace Drupal\Component\Plugin\Factory;
|
||||
|
||||
/**
|
||||
* Factory interface implemented by all plugin factories.
|
||||
*/
|
||||
interface FactoryInterface {
|
||||
|
||||
/**
|
||||
* Creates a pre-configured instance of a plugin.
|
||||
*
|
||||
* @param string $plugin_id
|
||||
* The ID of the plugin being instantiated.
|
||||
* @param array $configuration
|
||||
* An array of configuration relevant to the plugin instance.
|
||||
*
|
||||
* @return object
|
||||
* A fully configured plugin instance.
|
||||
*
|
||||
* @throws \Drupal\Component\Plugin\Exception\PluginException
|
||||
* If the instance cannot be created, such as if the ID is invalid.
|
||||
*/
|
||||
public function createInstance($plugin_id, array $configuration = array());
|
||||
|
||||
}
|
|
@ -0,0 +1,83 @@
|
|||
<?php
|
||||
/**
|
||||
* @file
|
||||
* Contains \Drupal\Component\Plugin\Factory\ReflectionFactory.
|
||||
*/
|
||||
|
||||
namespace Drupal\Component\Plugin\Factory;
|
||||
|
||||
/**
|
||||
* A plugin factory that maps instance configuration to constructor arguments.
|
||||
*
|
||||
* Provides logic for any basic plugin type that needs to provide individual
|
||||
* plugins based upon some basic logic.
|
||||
*/
|
||||
class ReflectionFactory extends DefaultFactory {
|
||||
|
||||
/**
|
||||
* Implements Drupal\Component\Plugin\Factory\FactoryInterface::createInstance().
|
||||
*/
|
||||
public function createInstance($plugin_id, array $configuration = array()) {
|
||||
$plugin_definition = $this->discovery->getDefinition($plugin_id);
|
||||
$plugin_class = static::getPluginClass($plugin_id, $plugin_definition, $this->interface);
|
||||
|
||||
// Lets figure out of there's a constructor for this class and pull
|
||||
// arguments from the $options array if so to populate it.
|
||||
$reflector = new \ReflectionClass($plugin_class);
|
||||
if ($reflector->hasMethod('__construct')) {
|
||||
$arguments = $this->getInstanceArguments($reflector, $plugin_id, $plugin_definition, $configuration);
|
||||
$instance = $reflector->newInstanceArgs($arguments);
|
||||
}
|
||||
else {
|
||||
$instance = new $plugin_class();
|
||||
}
|
||||
|
||||
return $instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Inspects the plugin class and build a list of arguments for the constructor.
|
||||
*
|
||||
* This is provided as a helper method so factories extending this class can
|
||||
* replace this and insert their own reflection logic.
|
||||
*
|
||||
* @param \ReflectionClass $reflector
|
||||
* The reflector object being used to inspect the plugin class.
|
||||
* @param string $plugin_id
|
||||
* The identifier of the plugin implementation.
|
||||
* @param mixed $plugin_definition
|
||||
* The definition associated to the plugin_id.
|
||||
* @param array $configuration
|
||||
* An array of configuration that may be passed to the instance.
|
||||
*
|
||||
* @return array
|
||||
* An array of arguments to be passed to the constructor.
|
||||
*/
|
||||
protected function getInstanceArguments(\ReflectionClass $reflector, $plugin_id, $plugin_definition, array $configuration) {
|
||||
|
||||
$arguments = array();
|
||||
foreach ($reflector->getMethod('__construct')->getParameters() as $param) {
|
||||
$param_name = $param->getName();
|
||||
|
||||
if ($param_name == 'plugin_id') {
|
||||
$arguments[] = $plugin_id;
|
||||
}
|
||||
elseif ($param_name == 'plugin_definition') {
|
||||
$arguments[] = $plugin_definition;
|
||||
}
|
||||
elseif ($param_name == 'configuration') {
|
||||
$arguments[] = $configuration;
|
||||
}
|
||||
elseif (isset($configuration[$param_name]) || array_key_exists($param_name, $configuration)) {
|
||||
$arguments[] = $configuration[$param_name];
|
||||
}
|
||||
elseif ($param->isDefaultValueAvailable()) {
|
||||
$arguments[] = $param->getDefaultValue();
|
||||
}
|
||||
else {
|
||||
$arguments[] = NULL;
|
||||
}
|
||||
}
|
||||
return $arguments;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Contains \Drupal\Component\Plugin\FallbackPluginManagerInterface.
|
||||
*/
|
||||
|
||||
namespace Drupal\Component\Plugin;
|
||||
|
||||
/**
|
||||
* An interface implemented by plugin managers with fallback plugin behaviors.
|
||||
*/
|
||||
interface FallbackPluginManagerInterface {
|
||||
|
||||
/**
|
||||
* Gets a fallback id for a missing plugin.
|
||||
*
|
||||
* @param string $plugin_id
|
||||
* The ID of the missing requested plugin.
|
||||
* @param array $configuration
|
||||
* An array of configuration relevant to the plugin instance.
|
||||
*
|
||||
* @return string
|
||||
* The id of an existing plugin to use when the plugin does not exist.
|
||||
*/
|
||||
public function getFallbackPluginId($plugin_id, array $configuration = array());
|
||||
|
||||
}
|
165
core/lib/Drupal/Component/Plugin/LazyPluginCollection.php
Normal file
165
core/lib/Drupal/Component/Plugin/LazyPluginCollection.php
Normal file
|
@ -0,0 +1,165 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Contains \Drupal\Component\Plugin\LazyPluginCollection.
|
||||
*/
|
||||
|
||||
namespace Drupal\Component\Plugin;
|
||||
|
||||
/**
|
||||
* Defines an object which stores multiple plugin instances to lazy load them.
|
||||
*
|
||||
* @ingroup plugin_api
|
||||
*/
|
||||
abstract class LazyPluginCollection implements \IteratorAggregate, \Countable {
|
||||
|
||||
/**
|
||||
* Stores all instantiated plugins.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $pluginInstances = array();
|
||||
|
||||
/**
|
||||
* Stores the IDs of all potential plugin instances.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $instanceIDs = array();
|
||||
|
||||
/**
|
||||
* Initializes and stores a plugin.
|
||||
*
|
||||
* @param string $instance_id
|
||||
* The ID of the plugin instance to initialize.
|
||||
*/
|
||||
abstract protected function initializePlugin($instance_id);
|
||||
|
||||
/**
|
||||
* Gets the current configuration of all plugins in this collection.
|
||||
*
|
||||
* @return array
|
||||
* An array of up-to-date plugin configuration.
|
||||
*/
|
||||
abstract public function getConfiguration();
|
||||
|
||||
/**
|
||||
* Sets the configuration for all plugins in this collection.
|
||||
*
|
||||
* @param array $configuration
|
||||
* An array of up-to-date plugin configuration.
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
abstract public function setConfiguration($configuration);
|
||||
|
||||
/**
|
||||
* Clears all instantiated plugins.
|
||||
*/
|
||||
public function clear() {
|
||||
$this->pluginInstances = array();
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines if a plugin instance exists.
|
||||
*
|
||||
* @param string $instance_id
|
||||
* The ID of the plugin instance to check.
|
||||
*
|
||||
* @return bool
|
||||
* TRUE if the plugin instance exists, FALSE otherwise.
|
||||
*/
|
||||
public function has($instance_id) {
|
||||
return isset($this->pluginInstances[$instance_id]) || isset($this->instanceIDs[$instance_id]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a plugin instance, initializing it if necessary.
|
||||
*
|
||||
* @param string $instance_id
|
||||
* The ID of the plugin instance being retrieved.
|
||||
*/
|
||||
public function &get($instance_id) {
|
||||
if (!isset($this->pluginInstances[$instance_id])) {
|
||||
$this->initializePlugin($instance_id);
|
||||
}
|
||||
return $this->pluginInstances[$instance_id];
|
||||
}
|
||||
|
||||
/**
|
||||
* Stores an initialized plugin.
|
||||
*
|
||||
* @param string $instance_id
|
||||
* The ID of the plugin instance being stored.
|
||||
* @param mixed $value
|
||||
* An instantiated plugin.
|
||||
*/
|
||||
public function set($instance_id, $value) {
|
||||
$this->pluginInstances[$instance_id] = $value;
|
||||
$this->addInstanceId($instance_id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes an initialized plugin.
|
||||
*
|
||||
* The plugin can still be used; it will be reinitialized.
|
||||
*
|
||||
* @param string $instance_id
|
||||
* The ID of the plugin instance to remove.
|
||||
*/
|
||||
public function remove($instance_id) {
|
||||
unset($this->pluginInstances[$instance_id]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds an instance ID to the available instance IDs.
|
||||
*
|
||||
* @param string $id
|
||||
* The ID of the plugin instance to add.
|
||||
* @param array|null $configuration
|
||||
* (optional) The configuration used by this instance. Defaults to NULL.
|
||||
*/
|
||||
public function addInstanceId($id, $configuration = NULL) {
|
||||
if (!isset($this->instanceIDs[$id])) {
|
||||
$this->instanceIDs[$id] = $id;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets all instance IDs.
|
||||
*
|
||||
* @return array
|
||||
* An array of all available instance IDs.
|
||||
*/
|
||||
public function getInstanceIds() {
|
||||
return $this->instanceIDs;
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes an instance ID.
|
||||
*
|
||||
* @param string $instance_id
|
||||
* The ID of the plugin instance to remove.
|
||||
*/
|
||||
public function removeInstanceId($instance_id) {
|
||||
unset($this->instanceIDs[$instance_id]);
|
||||
$this->remove($instance_id);
|
||||
}
|
||||
|
||||
public function getIterator() {
|
||||
$instances = [];
|
||||
foreach ($this->getInstanceIds() as $instance_id) {
|
||||
$instances[$instance_id] = $this->get($instance_id);
|
||||
}
|
||||
return new \ArrayIterator($instances);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function count() {
|
||||
return count($this->instanceIDs);
|
||||
}
|
||||
|
||||
}
|
34
core/lib/Drupal/Component/Plugin/Mapper/MapperInterface.php
Normal file
34
core/lib/Drupal/Component/Plugin/Mapper/MapperInterface.php
Normal file
|
@ -0,0 +1,34 @@
|
|||
<?php
|
||||
/**
|
||||
* @file
|
||||
* Contains \Drupal\Component\Plugin\Mapper\MapperInterface.
|
||||
*/
|
||||
|
||||
namespace Drupal\Component\Plugin\Mapper;
|
||||
|
||||
/**
|
||||
* Plugin mapper interface.
|
||||
*
|
||||
* Plugin mappers are responsible for mapping a plugin request to its
|
||||
* implementation. For example, it might map a cache bin to a memcache bin.
|
||||
*
|
||||
* Mapper objects incorporate the best practices of retrieving configurations,
|
||||
* type information, and factory instantiation.
|
||||
*/
|
||||
interface MapperInterface {
|
||||
|
||||
/**
|
||||
* Gets a preconfigured instance of a plugin.
|
||||
*
|
||||
* @param array $options
|
||||
* An array of options that can be used to determine a suitable plugin to
|
||||
* instantiate and how to configure it.
|
||||
*
|
||||
* @return object|false
|
||||
* A fully configured plugin instance. The interface of the plugin instance
|
||||
* will depends on the plugin type. If no instance can be retrieved, FALSE
|
||||
* will be returned.
|
||||
*/
|
||||
public function getInstance(array $options);
|
||||
|
||||
}
|
99
core/lib/Drupal/Component/Plugin/PluginBase.php
Normal file
99
core/lib/Drupal/Component/Plugin/PluginBase.php
Normal file
|
@ -0,0 +1,99 @@
|
|||
<?php
|
||||
/**
|
||||
* @file
|
||||
* Contains \Drupal\Component\Plugin\PluginBase.
|
||||
*/
|
||||
|
||||
namespace Drupal\Component\Plugin;
|
||||
|
||||
/**
|
||||
* Base class for plugins wishing to support metadata inspection.
|
||||
*/
|
||||
abstract class PluginBase implements PluginInspectionInterface, DerivativeInspectionInterface {
|
||||
|
||||
/**
|
||||
* A string which is used to separate base plugin IDs from the derivative ID.
|
||||
*/
|
||||
const DERIVATIVE_SEPARATOR = ':';
|
||||
|
||||
/**
|
||||
* The plugin_id.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $pluginId;
|
||||
|
||||
/**
|
||||
* The plugin implementation definition.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $pluginDefinition;
|
||||
|
||||
/**
|
||||
* Configuration information passed into the plugin.
|
||||
*
|
||||
* When using an interface like
|
||||
* \Drupal\Component\Plugin\ConfigurablePluginInterface, this is where the
|
||||
* configuration should be stored.
|
||||
*
|
||||
* Plugin configuration is optional, so plugin implementations must provide
|
||||
* their own setters and getters.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $configuration;
|
||||
|
||||
/**
|
||||
* Constructs a Drupal\Component\Plugin\PluginBase object.
|
||||
*
|
||||
* @param array $configuration
|
||||
* A configuration array containing information about the plugin instance.
|
||||
* @param string $plugin_id
|
||||
* The plugin_id for the plugin instance.
|
||||
* @param mixed $plugin_definition
|
||||
* The plugin implementation definition.
|
||||
*/
|
||||
public function __construct(array $configuration, $plugin_id, $plugin_definition) {
|
||||
$this->configuration = $configuration;
|
||||
$this->pluginId = $plugin_id;
|
||||
$this->pluginDefinition = $plugin_definition;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getPluginId() {
|
||||
return $this->pluginId;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getBaseId() {
|
||||
$plugin_id = $this->getPluginId();
|
||||
if (strpos($plugin_id, static::DERIVATIVE_SEPARATOR)) {
|
||||
list($plugin_id) = explode(static::DERIVATIVE_SEPARATOR, $plugin_id, 2);
|
||||
}
|
||||
return $plugin_id;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getDerivativeId() {
|
||||
$plugin_id = $this->getPluginId();
|
||||
$derivative_id = NULL;
|
||||
if (strpos($plugin_id, static::DERIVATIVE_SEPARATOR)) {
|
||||
list(, $derivative_id) = explode(static::DERIVATIVE_SEPARATOR, $plugin_id, 2);
|
||||
}
|
||||
return $derivative_id;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getPluginDefinition() {
|
||||
return $this->pluginDefinition;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,36 @@
|
|||
<?php
|
||||
/**
|
||||
* @file
|
||||
* Contains \Drupal\Component\Plugin\PluginInspectionInterface.
|
||||
*/
|
||||
|
||||
namespace Drupal\Component\Plugin;
|
||||
|
||||
/**
|
||||
* Plugin interface for providing some metadata inspection.
|
||||
*
|
||||
* This interface provides some simple tools for code receiving a plugin to
|
||||
* interact with the plugin system.
|
||||
*
|
||||
* @ingroup plugin_api
|
||||
*/
|
||||
interface PluginInspectionInterface {
|
||||
|
||||
/**
|
||||
* Gets the plugin_id of the plugin instance.
|
||||
*
|
||||
* @return string
|
||||
* The plugin_id of the plugin instance.
|
||||
*/
|
||||
public function getPluginId();
|
||||
|
||||
/**
|
||||
* Gets the definition of the plugin implementation.
|
||||
*
|
||||
* @return array
|
||||
* The plugin definition, as returned by the discovery object used by the
|
||||
* plugin manager.
|
||||
*/
|
||||
public function getPluginDefinition();
|
||||
|
||||
}
|
100
core/lib/Drupal/Component/Plugin/PluginManagerBase.php
Normal file
100
core/lib/Drupal/Component/Plugin/PluginManagerBase.php
Normal file
|
@ -0,0 +1,100 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Contains \Drupal\Component\Plugin\PluginManagerBase.
|
||||
*/
|
||||
|
||||
namespace Drupal\Component\Plugin;
|
||||
|
||||
use Drupal\Component\Plugin\Discovery\DiscoveryTrait;
|
||||
use Drupal\Component\Plugin\Exception\PluginNotFoundException;
|
||||
|
||||
/**
|
||||
* Base class for plugin managers.
|
||||
*/
|
||||
abstract class PluginManagerBase implements PluginManagerInterface {
|
||||
|
||||
use DiscoveryTrait;
|
||||
|
||||
/**
|
||||
* The object that discovers plugins managed by this manager.
|
||||
*
|
||||
* @var \Drupal\Component\Plugin\Discovery\DiscoveryInterface
|
||||
*/
|
||||
protected $discovery;
|
||||
|
||||
/**
|
||||
* The object that instantiates plugins managed by this manager.
|
||||
*
|
||||
* @var \Drupal\Component\Plugin\Factory\FactoryInterface
|
||||
*/
|
||||
protected $factory;
|
||||
|
||||
/**
|
||||
* The object that returns the preconfigured plugin instance appropriate for a particular runtime condition.
|
||||
*
|
||||
* @var \Drupal\Component\Plugin\Mapper\MapperInterface
|
||||
*/
|
||||
protected $mapper;
|
||||
|
||||
/**
|
||||
* Gets the plugin discovery.
|
||||
*
|
||||
* @return \Drupal\Component\Plugin\Discovery\DiscoveryInterface
|
||||
*/
|
||||
protected function getDiscovery() {
|
||||
return $this->discovery;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the plugin factory.
|
||||
*
|
||||
* @return \Drupal\Component\Plugin\Factory\FactoryInterface
|
||||
*/
|
||||
protected function getFactory() {
|
||||
return $this->factory;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getDefinition($plugin_id, $exception_on_invalid = TRUE) {
|
||||
return $this->getDiscovery()->getDefinition($plugin_id, $exception_on_invalid);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getDefinitions() {
|
||||
return $this->getDiscovery()->getDefinitions();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function createInstance($plugin_id, array $configuration = array()) {
|
||||
// If this PluginManager has fallback capabilities catch
|
||||
// PluginNotFoundExceptions.
|
||||
if ($this instanceof FallbackPluginManagerInterface) {
|
||||
try {
|
||||
return $this->getFactory()->createInstance($plugin_id, $configuration);
|
||||
}
|
||||
catch (PluginNotFoundException $e) {
|
||||
$fallback_id = $this->getFallbackPluginId($plugin_id, $configuration);
|
||||
return $this->getFactory()->createInstance($fallback_id, $configuration);
|
||||
}
|
||||
}
|
||||
else {
|
||||
return $this->getFactory()->createInstance($plugin_id, $configuration);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getInstance(array $options) {
|
||||
return $this->mapper->getInstance($options);
|
||||
}
|
||||
|
||||
}
|
33
core/lib/Drupal/Component/Plugin/PluginManagerInterface.php
Normal file
33
core/lib/Drupal/Component/Plugin/PluginManagerInterface.php
Normal file
|
@ -0,0 +1,33 @@
|
|||
<?php
|
||||
/**
|
||||
* @file
|
||||
* Contains \Drupal\Component\Plugin\PluginManagerInterface.
|
||||
*/
|
||||
|
||||
namespace Drupal\Component\Plugin;
|
||||
|
||||
use Drupal\Component\Plugin\Discovery\DiscoveryInterface;
|
||||
use Drupal\Component\Plugin\Factory\FactoryInterface;
|
||||
use Drupal\Component\Plugin\Mapper\MapperInterface;
|
||||
|
||||
/**
|
||||
* Interface implemented by plugin managers.
|
||||
*
|
||||
* There are no explicit methods on the manager interface. Instead plugin
|
||||
* managers broker the interactions of the different plugin components, and
|
||||
* therefore, must implement each component interface, which is enforced by
|
||||
* this interface extending all of the component ones.
|
||||
*
|
||||
* While a plugin manager may directly implement these interface methods with
|
||||
* custom logic, it is expected to be more common for plugin managers to proxy
|
||||
* the method invocations to the respective components, and directly implement
|
||||
* only the additional functionality needed by the specific pluggable system.
|
||||
* To follow this pattern, plugin managers can extend from the PluginManagerBase
|
||||
* class, which contains the proxying logic.
|
||||
*
|
||||
* @see \Drupal\Component\Plugin\PluginManagerBase
|
||||
*
|
||||
* @ingroup plugin_api
|
||||
*/
|
||||
interface PluginManagerInterface extends DiscoveryInterface, FactoryInterface, MapperInterface {
|
||||
}
|
18
core/lib/Drupal/Component/Plugin/composer.json
Normal file
18
core/lib/Drupal/Component/Plugin/composer.json
Normal file
|
@ -0,0 +1,18 @@
|
|||
{
|
||||
"name": "drupal/core-plugin",
|
||||
"description": "Base building block for a scalable and extensible plug-in system for PHP components and application framework extensions.",
|
||||
"keywords": ["drupal", "plugin", "plugins"],
|
||||
"homepage": "https://www.drupal.org/project/drupal",
|
||||
"license": "GPL-2.0+",
|
||||
"require": {
|
||||
"php": ">=5.4.2"
|
||||
},
|
||||
"autoload": {
|
||||
"psr-0": {
|
||||
"Drupal\\Component\\Plugin\\": ""
|
||||
}
|
||||
},
|
||||
"suggest": {
|
||||
"symfony/validator": "Leveraged in the use of context aware plugins."
|
||||
}
|
||||
}
|
Reference in a new issue