Issue #1743686 by EclipseGc, fago, amateescu, damiankloip: Added Condition Plugin System.
parent
b0e08e4280
commit
89686bf45c
|
@ -8,6 +8,8 @@
|
|||
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.
|
||||
|
@ -39,7 +41,6 @@ class Context implements ContextInterface {
|
|||
* Implements \Drupal\Component\Plugin\Context\ContextInterface::setContextValue().
|
||||
*/
|
||||
public function setContextValue($value) {
|
||||
$value = $this->validate($value);
|
||||
$this->contextValue = $value;
|
||||
}
|
||||
|
||||
|
@ -65,22 +66,22 @@ class Context implements ContextInterface {
|
|||
}
|
||||
|
||||
/**
|
||||
* Implements \Drupal\Component\Plugin\Context\ContextInterface::validate().
|
||||
*
|
||||
* The default validation method only supports instance of checks between the
|
||||
* contextDefintion and the contextValue. Other formats of context
|
||||
* definitions can be supported through a subclass.
|
||||
* Implements \Drupal\Component\Plugin\Context\ContextInterface::getConstraints().
|
||||
*/
|
||||
public function validate($value) {
|
||||
// Check to make sure we have a class name, and that the passed context is
|
||||
// an instance of that class name.
|
||||
if (!empty($this->contextDefinition['class'])) {
|
||||
if ($value instanceof $this->contextDefinition['class']) {
|
||||
return $value;
|
||||
}
|
||||
throw new ContextException("The context passed was not an instance of {$this->contextDefinition['class']}.");
|
||||
public function getConstraints() {
|
||||
if (empty($this->contextDefinition['class'])) {
|
||||
throw new ContextException("An error was encountered while trying to validate the context.");
|
||||
}
|
||||
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());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -7,8 +7,6 @@
|
|||
|
||||
namespace Drupal\Component\Plugin\Context;
|
||||
|
||||
use Drupal\Component\Plugin\Exception\ContextException;
|
||||
|
||||
/**
|
||||
* A generic context interface for wrapping data a plugin needs to operate.
|
||||
*/
|
||||
|
@ -18,8 +16,9 @@ interface ContextInterface {
|
|||
* Sets the context value.
|
||||
*
|
||||
* @param mixed $value
|
||||
* The value of this context, generally an object based upon the class
|
||||
* matching the definition passed to setContextDefinition().
|
||||
* The value of this context, matching the context definition.
|
||||
*
|
||||
* @see \Drupal\Component\Plugin\Context\ContextInterface::setContextDefinition().
|
||||
*/
|
||||
public function setContextValue($value);
|
||||
|
||||
|
@ -27,42 +26,45 @@ interface ContextInterface {
|
|||
* Gets the context value.
|
||||
*
|
||||
* @return mixed
|
||||
* The currently set context value within this class.
|
||||
* 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 mixed $contextDefinition
|
||||
* @param array $contextDefinition
|
||||
* A defining characteristic representation of the context against which
|
||||
* that context can be validated. This is typically a class name, but could
|
||||
* be extended to support other validation notation.
|
||||
* that context can be validated. This is typically an array having a
|
||||
* class name set under the 'class' key, but it could be extended to support
|
||||
* other notations.
|
||||
*/
|
||||
public function setContextDefinition(array $contextDefinition);
|
||||
|
||||
/**
|
||||
* Gets the provided definition that the context must conform to.
|
||||
*
|
||||
* @return mixed
|
||||
* @return array
|
||||
* The defining characteristic representation of the context.
|
||||
*/
|
||||
public function getContextDefinition();
|
||||
|
||||
/**
|
||||
* Validate the provided context value against the provided definition.
|
||||
* Gets a list of validation constraints.
|
||||
*
|
||||
* @param mixed $value
|
||||
* The context value that should be validated against the context
|
||||
* definition.
|
||||
*
|
||||
* @return mixed
|
||||
* Returns the context value passed to it. If it fails validation, an
|
||||
* exception will be thrown.
|
||||
*
|
||||
* @throws \Drupal\Component\Plugin\Exception\ContextException
|
||||
* If validation fails.
|
||||
* @return array
|
||||
* Array of constraints, each being an instance of
|
||||
* \Symfony\Component\Validator\Constraint.
|
||||
*/
|
||||
public function validate($value);
|
||||
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();
|
||||
|
||||
}
|
||||
|
|
|
@ -9,6 +9,8 @@ namespace Drupal\Component\Plugin;
|
|||
|
||||
use Drupal\Component\Plugin\Exception\PluginException;
|
||||
use Drupal\Component\Plugin\Context\Context;
|
||||
use Symfony\Component\Validator\ConstraintViolationList;
|
||||
use Drupal\Component\Plugin\Discovery\DiscoveryInterface;
|
||||
|
||||
/**
|
||||
* Base class for plugins that are context aware.
|
||||
|
@ -22,23 +24,49 @@ abstract class ContextAwarePluginBase extends PluginBase implements ContextAware
|
|||
*/
|
||||
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.
|
||||
*/
|
||||
public function __construct(array $configuration, $plugin_id, DiscoveryInterface $discovery) {
|
||||
$context = array();
|
||||
if (isset($configuration['context'])) {
|
||||
$context = $configuration['context'];
|
||||
unset($configuration['context']);
|
||||
}
|
||||
parent::__construct($configuration, $plugin_id, $discovery);
|
||||
foreach ($context as $key => $value) {
|
||||
$context_definition = $this->getContextDefinition($key);
|
||||
$this->context[$key] = new Context($context_definition);
|
||||
$this->context[$key]->setContextValue($value);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements \Drupal\Component\Plugin\ContextAwarePluginInterface::getContextDefinitions().
|
||||
*/
|
||||
public function getContextDefinitions() {
|
||||
$definition = $this->getDefinition();
|
||||
return !empty($definition['context']) ? $definition['context'] : NULL;
|
||||
return !empty($definition['context']) ? $definition['context'] : array();
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements \Drupal\Component\Plugin\ContextAwarePluginInterface::getContextDefinition().
|
||||
*/
|
||||
public function getContextDefinition($key) {
|
||||
public function getContextDefinition($name) {
|
||||
$definition = $this->getDefinition();
|
||||
if (empty($definition['context'][$key])) {
|
||||
throw new PluginException("The $key context is not a valid context.");
|
||||
if (empty($definition['context'][$name])) {
|
||||
throw new PluginException("The $name context is not a valid context.");
|
||||
}
|
||||
return $definition['context'][$key];
|
||||
return $definition['context'][$name];
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -46,19 +74,15 @@ abstract class ContextAwarePluginBase extends PluginBase implements ContextAware
|
|||
*/
|
||||
public function getContexts() {
|
||||
$definitions = $this->getContextDefinitions();
|
||||
// If there are no contexts defined by the plugin, return an empty array.
|
||||
if (empty($definitions)) {
|
||||
return array();
|
||||
}
|
||||
if (empty($this->context)) {
|
||||
if ($definitions && empty($this->context)) {
|
||||
throw new PluginException("There are no set contexts.");
|
||||
}
|
||||
$contexts = array();
|
||||
foreach (array_keys($definitions) as $key) {
|
||||
if (empty($this->context[$key])) {
|
||||
throw new PluginException("The $key context is not yet set.");
|
||||
foreach (array_keys($definitions) as $name) {
|
||||
if (empty($this->context[$name])) {
|
||||
throw new PluginException("The $name context is not yet set.");
|
||||
}
|
||||
$contexts[$key] = $this->context[$key];
|
||||
$contexts[$name] = $this->context[$name];
|
||||
}
|
||||
return $contexts;
|
||||
}
|
||||
|
@ -66,44 +90,67 @@ abstract class ContextAwarePluginBase extends PluginBase implements ContextAware
|
|||
/**
|
||||
* Implements \Drupal\Component\Plugin\ContextAwarePluginInterface::getContext().
|
||||
*/
|
||||
public function getContext($key) {
|
||||
public function getContext($name) {
|
||||
// Check for a valid context definition.
|
||||
$this->getContextDefinition($key);
|
||||
$this->getContextDefinition($name);
|
||||
// Check for a valid context value.
|
||||
if (empty($this->context[$key])) {
|
||||
throw new PluginException("The $key context is not yet set.");
|
||||
if (!isset($this->context[$name])) {
|
||||
throw new PluginException("The $name context is not yet set.");
|
||||
}
|
||||
|
||||
return $this->context[$key];
|
||||
return $this->context[$name];
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements \Drupal\Component\Plugin\ContextAwarePluginInterface::getContextValues().
|
||||
*/
|
||||
public function getContextValues() {
|
||||
$contexts = array();
|
||||
foreach ($this->getContexts() as $key => $context) {
|
||||
$contexts[$key] = $context->getContextValue();
|
||||
$values = array();
|
||||
foreach ($this->getContextDefinitions() as $name => $definition) {
|
||||
$values[$name] = isset($this->context[$name]) ? $this->context[$name]->getContextValue() : NULL;
|
||||
}
|
||||
return $contexts;
|
||||
return $values;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements \Drupal\Component\Plugin\ContextAwarePluginInterface::getContextValue().
|
||||
*/
|
||||
public function getContextValue($key) {
|
||||
return $this->getContext($key)->getContextValue();
|
||||
public function getContextValue($name) {
|
||||
return $this->getContext($name)->getContextValue();
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements \Drupal\Component\Plugin\ContextAwarePluginInterface::setContextValue().
|
||||
*/
|
||||
public function setContextValue($key, $value) {
|
||||
$context_definition = $this->getContextDefinition($key);
|
||||
$this->context[$key] = new Context($context_definition);
|
||||
$this->context[$key]->setContextValue($value);
|
||||
public function setContextValue($name, $value) {
|
||||
$context_definition = $this->getContextDefinition($name);
|
||||
$this->context[$name] = new Context($context_definition);
|
||||
$this->context[$name]->setContextValue($value);
|
||||
|
||||
// Verify the provided value validates.
|
||||
$violations = $this->context[$name]->validate();
|
||||
if (count($violations) > 0) {
|
||||
throw new PluginException("The provided context value does not pass validation.");
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements \Drupal\Component\Plugin\ContextAwarePluginInterface::valdidateContexts().
|
||||
*/
|
||||
public function validateContexts() {
|
||||
$violations = new ConstraintViolationList();
|
||||
// @todo: Implement symfony validator API to let the validator traverse
|
||||
// and set property paths accordingly.
|
||||
|
||||
foreach ($this->getContextDefinitions() as $name => $definition) {
|
||||
// Validate any set values.
|
||||
if (isset($this->context[$name])) {
|
||||
$violations->addAll($this->context[$name]->validate());
|
||||
}
|
||||
// @todo: If no value is set, make sure any mapping is validated.
|
||||
}
|
||||
return $violations;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -8,35 +8,43 @@
|
|||
namespace Drupal\Component\Plugin;
|
||||
|
||||
use Drupal\Component\Plugin\Exception\PluginException;
|
||||
use Drupal\Component\Plugin\Context\Context;
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
interface ContextAwarePluginInterface extends PluginInspectionInterface {
|
||||
|
||||
/**
|
||||
* Gets the context definitions of the plugin.
|
||||
*
|
||||
* @return array|null
|
||||
* The context definitions if set, otherwise NULL.
|
||||
* @return array
|
||||
* The array of context definitions, keyed by context name.
|
||||
*/
|
||||
public function getContextDefinitions();
|
||||
|
||||
/**
|
||||
* Gets the a specific context definition of the plugin.
|
||||
* Gets a specific context definition of the plugin.
|
||||
*
|
||||
* @param string $key
|
||||
* @param string $name
|
||||
* The name of the context in the plugin definition.
|
||||
*
|
||||
* @return mixed
|
||||
* @throws \Drupal\Component\Plugin\Exception\PluginException
|
||||
* If the requested context is not defined.
|
||||
*
|
||||
* @return array
|
||||
* The definition against which the context value must validate.
|
||||
*/
|
||||
public function getContextDefinition($key);
|
||||
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.
|
||||
*/
|
||||
|
@ -45,47 +53,64 @@ interface ContextAwarePluginInterface extends PluginInspectionInterface {
|
|||
/**
|
||||
* Gets a defined context.
|
||||
*
|
||||
* @param string $key
|
||||
* The name of the context in the plugin configuration. This string is
|
||||
* usually identical to the representative string in the plugin definition.
|
||||
* @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($key);
|
||||
public function getContext($name);
|
||||
|
||||
/**
|
||||
* Gets the values for all defined contexts.
|
||||
*
|
||||
* @return array
|
||||
* The set context object values.
|
||||
* 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 $key
|
||||
* The name of the context in the plugin configuration. This string is
|
||||
* usually identical to the representative string in the plugin definition.
|
||||
* @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($key);
|
||||
public function getContextValue($name);
|
||||
|
||||
/**
|
||||
* Sets the value for a defined context.
|
||||
*
|
||||
* @param string $key
|
||||
* @param string $name
|
||||
* The name of the context in the plugin definition.
|
||||
* @param mixed $value
|
||||
* The variable to set the context to. This should validate against the
|
||||
* 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($key, $value);
|
||||
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();
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,35 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Contains \Drupal\Core\Condition\ConditionInterface.
|
||||
*/
|
||||
|
||||
namespace Drupal\Core\Condition;
|
||||
|
||||
use Drupal\Core\Executable\ExecutableInterface;
|
||||
|
||||
/**
|
||||
* An interface for condition plugins.
|
||||
*
|
||||
* @see \Drupal\Core\Executable\ExecutableInterface
|
||||
*/
|
||||
interface ConditionInterface extends ExecutableInterface {
|
||||
|
||||
/**
|
||||
* Determines whether condition result will be negated.
|
||||
*
|
||||
* @return boolean
|
||||
* Whether the condition result will be negated.
|
||||
*/
|
||||
public function isNegated();
|
||||
|
||||
/**
|
||||
* Evaluates the condition and returns TRUE or FALSE accordingly.
|
||||
*
|
||||
* @return bool
|
||||
* TRUE if the condition has been met, FALSE otherwise.
|
||||
*/
|
||||
public function evaluate();
|
||||
|
||||
}
|
|
@ -0,0 +1,52 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Contains \Drupal\Core\Condition\ConditionManager.
|
||||
*/
|
||||
|
||||
namespace Drupal\Core\Condition;
|
||||
|
||||
use Drupal\Component\Plugin\PluginManagerBase;
|
||||
use Drupal\Core\Executable\ExecutableManagerInterface;
|
||||
use Drupal\Core\Executable\ExecutableInterface;
|
||||
use Drupal\Component\Plugin\Factory\DefaultFactory;
|
||||
use Drupal\Component\Plugin\Discovery\DerivativeDiscoveryDecorator;
|
||||
use Drupal\Core\Plugin\Discovery\AlterDecorator;
|
||||
use Drupal\Core\Plugin\Discovery\AnnotatedClassDiscovery;
|
||||
use Drupal\Core\Plugin\Discovery\CacheDecorator;
|
||||
|
||||
/**
|
||||
* A plugin manager for condition plugins.
|
||||
*/
|
||||
class ConditionManager extends PluginManagerBase implements ExecutableManagerInterface {
|
||||
|
||||
/**
|
||||
* Constructs aa ConditionManager object.
|
||||
*/
|
||||
public function __construct() {
|
||||
$this->discovery = new AnnotatedClassDiscovery('Core', 'Condition');
|
||||
$this->discovery = new DerivativeDiscoveryDecorator($this->discovery);
|
||||
$this->discovery = new AlterDecorator($this->discovery, 'condition_info');
|
||||
$this->discovery = new CacheDecorator($this->discovery, 'condition:' . language(LANGUAGE_TYPE_INTERFACE)->langcode);
|
||||
|
||||
$this->factory = new DefaultFactory($this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Override of Drupal\Component\Plugin\PluginManagerBase::createInstance().
|
||||
*/
|
||||
public function createInstance($plugin_id, array $configuration = array()) {
|
||||
$plugin = $this->factory->createInstance($plugin_id, $configuration);
|
||||
return $plugin->setExecutableManager($this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements Drupal\Core\Executable\ExecutableManagerInterface::execute().
|
||||
*/
|
||||
public function execute(ExecutableInterface $condition) {
|
||||
$result = $condition->evaluate();
|
||||
return $condition->isNegated() ? !$result : $result;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,63 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Contains \Drupal\Core\Condition\ConditionPluginBase.
|
||||
*/
|
||||
|
||||
namespace Drupal\Core\Condition;
|
||||
|
||||
use Drupal\Core\Executable\ExecutablePluginBase;
|
||||
|
||||
/**
|
||||
* Provides a basis for fulfilling contexts for condition plugins.
|
||||
*/
|
||||
abstract class ConditionPluginBase extends ExecutablePluginBase implements ConditionInterface {
|
||||
|
||||
/**
|
||||
* Implements \Drupal\Core\Form\FormInterface::getFormID().
|
||||
*/
|
||||
public function getFormID() {
|
||||
$definition = $this->getDefinition();
|
||||
return implode('_', array($definition['module'], $definition['id'], 'condition'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements \Drupal\condition\Plugin\ConditionInterface::isNegated().
|
||||
*/
|
||||
public function isNegated() {
|
||||
return !empty($this->configuration['negate']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements \Drupal\Core\Form\FormInterface::buildForm().
|
||||
*/
|
||||
public function buildForm(array $form, array &$form_state) {
|
||||
$form['negate'] = array(
|
||||
'#type' => 'checkbox',
|
||||
'#title' => t('Negate the condition.'),
|
||||
'#default_value' => isset($this->configuration['negate']) ? $this->configuration['negate'] : FALSE,
|
||||
);
|
||||
return $form;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements \Drupal\Core\Form\FormInterface::validateForm().
|
||||
*/
|
||||
public function validateForm(array &$form, array &$form_state) {}
|
||||
|
||||
/**
|
||||
* Implements \Drupal\Core\Form\FormInterface::submitForm().
|
||||
*/
|
||||
public function submitForm(array &$form, array &$form_state) {
|
||||
$this->configuration['negate'] = $form_state['values']['negate'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements \Drupal\Core\Executable\ExecutablePluginBase::execute().
|
||||
*/
|
||||
public function execute() {
|
||||
return $this->executableManager->execute($this);
|
||||
}
|
||||
|
||||
}
|
|
@ -276,6 +276,8 @@ class CoreBundle extends Bundle {
|
|||
$container->register('flood', 'Drupal\Core\Flood\DatabaseBackend')
|
||||
->addArgument(new Reference('database'));
|
||||
|
||||
$container->register('plugin.manager.condition', 'Drupal\Core\Condition\ConditionManager');
|
||||
|
||||
$container->addCompilerPass(new RegisterMatchersPass());
|
||||
$container->addCompilerPass(new RegisterRouteFiltersPass());
|
||||
// Add a compiler pass for registering event subscribers.
|
||||
|
|
|
@ -0,0 +1,16 @@
|
|||
<?php
|
||||
/**
|
||||
* @file
|
||||
* Definition of \Drupal\Core\Executable\ExecutableException.
|
||||
*/
|
||||
|
||||
namespace Drupal\Core\Executable;
|
||||
|
||||
use Exception;
|
||||
use Drupal\Component\Plugin\Exception\ExceptionInterface;
|
||||
|
||||
/**
|
||||
* Generic executable plugin exception class.
|
||||
*/
|
||||
class ExecutableException extends Exception implements ExceptionInterface {
|
||||
}
|
|
@ -0,0 +1,47 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Contains \Drupal\Core\Executable\ExecutableInterface.
|
||||
*/
|
||||
|
||||
namespace Drupal\Core\Executable;
|
||||
|
||||
use Drupal\Component\Plugin\ContextAwarePluginInterface;
|
||||
use Drupal\Core\Form\FormInterface;
|
||||
|
||||
/**
|
||||
* An interface for executable plugins.
|
||||
*
|
||||
* Executable plugins are context-aware and configurable. They support the
|
||||
* following keys in their plugin definitions:
|
||||
* - context: An array of context definitions, keyed by context name. Each
|
||||
* context definition is a typed data definition describing the context. Check
|
||||
* the typed data definition docs for details.
|
||||
* - configuration: An array of configuration option definitions, keyed by
|
||||
* option name. Each option definition is a typed data definition describing
|
||||
* the configuration option. Check the typed data definition docs for details.
|
||||
*
|
||||
* @see \Drupal\Core\TypedData\TypedDataManager::create()
|
||||
*/
|
||||
interface ExecutableInterface extends ContextAwarePluginInterface, FormInterface {
|
||||
|
||||
/**
|
||||
* Executes the plugin.
|
||||
*/
|
||||
public function execute();
|
||||
|
||||
/**
|
||||
* Provides a human readable summary of the executable's configuration.
|
||||
*/
|
||||
public function summary();
|
||||
|
||||
/**
|
||||
* Sets the executable manager class.
|
||||
*
|
||||
* @param \Drupal\Core\Condition\ConditionManager $executableManager
|
||||
* The executable manager.
|
||||
*/
|
||||
public function setExecutableManager(ExecutableManagerInterface $executableManager);
|
||||
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Contains \Drupal\Core\Executable\ExecutableManagerInterface.
|
||||
*/
|
||||
|
||||
namespace Drupal\Core\Executable;
|
||||
|
||||
use Drupal\Component\Plugin\PluginManagerInterface;
|
||||
|
||||
/**
|
||||
* An interface for managers of executable plugins.
|
||||
*/
|
||||
interface ExecutableManagerInterface extends PluginManagerInterface {
|
||||
|
||||
/**
|
||||
* Executes an executable plugin.
|
||||
*
|
||||
* @param \Drupal\Core\Executable\ExecutableInterface $plugin
|
||||
* An executable plugin instance managed by the implementing manager.
|
||||
*
|
||||
* @throws \Drupal\Core\Executable\ExecutableException
|
||||
* If the plugin could not be executed.
|
||||
*
|
||||
* @return mixed
|
||||
* The returned data varies by plugin implementation, e.g. conditions return
|
||||
* the the boolean evaluation result.
|
||||
*/
|
||||
public function execute(ExecutableInterface $plugin);
|
||||
|
||||
}
|
|
@ -0,0 +1,108 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Contains \Drupal\Core\Executable\ExecutablePluginBase.
|
||||
*/
|
||||
|
||||
namespace Drupal\Core\Executable;
|
||||
|
||||
use Drupal\Core\Plugin\ContextAwarePluginBase;
|
||||
use Symfony\Component\Validator\Validation;
|
||||
use Drupal\Component\Plugin\Exception\PluginException;
|
||||
|
||||
/**
|
||||
* Provides the basic architecture for executable plugins.
|
||||
*/
|
||||
abstract class ExecutablePluginBase extends ContextAwarePluginBase implements ExecutableInterface {
|
||||
|
||||
/**
|
||||
* The condition manager to proxy execute calls through.
|
||||
*
|
||||
* @var \Drupal\Component\Plugin\PluginManagerInterface
|
||||
*/
|
||||
protected $executableManager;
|
||||
|
||||
/**
|
||||
* Implements \Drupal\Core\Executable\ExecutableInterace::setExecutableManager().
|
||||
*/
|
||||
public function setExecutableManager(ExecutableManagerInterface $executableManager) {
|
||||
$this->executableManager = $executableManager;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets an array of definitions of available configuration options.
|
||||
*
|
||||
* @todo: This needs to go into an interface.
|
||||
*
|
||||
* @return array
|
||||
* An array of typed data definitions describing available configuration
|
||||
* options, keyed by option name.
|
||||
*/
|
||||
public function getConfigDefinitions() {
|
||||
$definition = $this->getDefinition();
|
||||
if (!empty($definition['configuration'])) {
|
||||
return $definition['configuration'];
|
||||
}
|
||||
return array();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the definition of a configuration option.
|
||||
*
|
||||
* @todo: This needs to go into an interface.
|
||||
*
|
||||
* @return array
|
||||
* The typed data definition describing the configuration option, or FALSE
|
||||
* if the option does not exist.
|
||||
*/
|
||||
public function getConfigDefinition($key) {
|
||||
$definition = $this->getDefinition();
|
||||
if (!empty($definition['configuration'][$key])) {
|
||||
return $definition['configuration'][$key];
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets all configuration values.
|
||||
*
|
||||
* @todo: This needs to go into an interface.
|
||||
*
|
||||
* @return array
|
||||
* The array of all configuration values, keyed by configuration option
|
||||
* name.
|
||||
*/
|
||||
public function getConfig() {
|
||||
return $this->configuration;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of a particular configuration option.
|
||||
*
|
||||
* @param string $name
|
||||
* The name of the configuration option to set.
|
||||
* @param mixed $value
|
||||
* The value to set.
|
||||
*
|
||||
* @todo This doesn't belong here. Move this into a new base class in
|
||||
* http://drupal.org/node/1764380.
|
||||
* @todo This does not set a value in config(), so the name is confusing.
|
||||
*
|
||||
* @return \Drupal\Core\Executable\ExecutablePluginBase.
|
||||
* The executable object for chaining.
|
||||
*/
|
||||
public function setConfig($key, $value) {
|
||||
if ($definition = $this->getConfigDefinition($key)) {
|
||||
$typed_data = typed_data()->create($definition, $value);
|
||||
|
||||
if ($typed_data->validate()->count() > 0) {
|
||||
throw new PluginException("The provided configuration value does not pass validation.");
|
||||
}
|
||||
}
|
||||
$this->configuration[$key] = $value;
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
|
|
@ -8,9 +8,11 @@
|
|||
namespace Drupal\Core\Plugin\Context;
|
||||
|
||||
use Drupal\Component\Plugin\Context\Context as ComponentContext;
|
||||
use Drupal\Component\Plugin\Exception\ContextException;
|
||||
use Drupal\Core\TypedData\TypedDataManager;
|
||||
use Drupal\Core\TypedData\ComplexDataInterface;
|
||||
use Drupal\Core\TypedData\ListInterface;
|
||||
use Drupal\Core\TypedData\TypedDataInterface;
|
||||
use Drupal\Core\Validation\DrupalTranslator;
|
||||
use Symfony\Component\Validator\Validation;
|
||||
|
||||
/**
|
||||
* A Drupal specific context wrapper class.
|
||||
|
@ -26,17 +28,31 @@ class Context extends ComponentContext {
|
|||
*/
|
||||
public function getContextValue() {
|
||||
$typed_value = parent::getContextValue();
|
||||
// If the data is of a primitive type, directly return the plain value.
|
||||
// That way, e.g. a string will be return as plain PHP string.
|
||||
if ($typed_value instanceof \Drupal\Core\TypedData\TypedDataInterface) {
|
||||
$type_definition = typed_data()->getDefinition($typed_value->getType());
|
||||
if (!empty($type_definition['primitive type'])) {
|
||||
return $typed_value->getValue();
|
||||
}
|
||||
// If the typed data is complex, pass it on as typed data. Else pass on its
|
||||
// plain value, such that e.g. a string will be directly returned as PHP
|
||||
// string.
|
||||
$is_complex = $typed_value instanceof ComplexDataInterface;
|
||||
if (!$is_complex && $typed_value instanceof ListInterface) {
|
||||
$is_complex = $typed_value[0] instanceof ComplexDataInterface;
|
||||
}
|
||||
// @todo We won't need the getType == entity check once #1868004 lands.
|
||||
if ($typed_value instanceof TypedDataInterface && (!$is_complex || $typed_value->getType() == 'entity')) {
|
||||
return $typed_value->getValue();
|
||||
}
|
||||
return $typed_value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements \Drupal\Component\Plugin\Context\ContextInterface::setContextValue().
|
||||
*/
|
||||
public function setContextValue($value) {
|
||||
// Make sure the value set is a typed data object.
|
||||
if (!empty($this->contextDefinition['type']) && !$value instanceof TypedDataInterface) {
|
||||
$value = typed_data()->create($this->contextDefinition, $value);
|
||||
}
|
||||
parent::setContextValue($value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the context value as typed data object.
|
||||
*
|
||||
|
@ -54,21 +70,31 @@ class Context extends ComponentContext {
|
|||
}
|
||||
|
||||
/**
|
||||
* Override for \Drupal\Component\Plugin\Context\Context::validate().
|
||||
* Implements \Drupal\Component\Plugin\Context\ContextInterface::getConstraints().
|
||||
*/
|
||||
public function validate($value) {
|
||||
public function getConstraints() {
|
||||
if (!empty($this->contextDefinition['type'])) {
|
||||
$typed_data_manager = new TypedDataManager();
|
||||
$typed_data = $typed_data_manager->create($this->contextDefinition, $value);
|
||||
// If we do have a typed data definition, validate it and return the
|
||||
// typed data instance instead.
|
||||
$violations = $typed_data->validate();
|
||||
if (count($violations) == 0) {
|
||||
return $typed_data;
|
||||
}
|
||||
throw new ContextException("The context passed could not be validated through typed data.");
|
||||
// If we do have typed data, leverage it for getting constraints.
|
||||
return $this->getTypedContext()->getConstraints();
|
||||
}
|
||||
return parent::validate($value);
|
||||
return parent::getConstraints();
|
||||
}
|
||||
|
||||
/**
|
||||
* Overrides \Drupal\Component\Plugin\Context\Context::getConstraints().
|
||||
*/
|
||||
public function validate() {
|
||||
$validator = Validation::createValidatorBuilder()
|
||||
->setTranslator(new DrupalTranslator())
|
||||
->getValidator();
|
||||
|
||||
// @todo We won't need to special case "entity" here once #1868004 lands.
|
||||
if (!empty($this->contextDefinition['type']) && $this->contextDefinition['type'] == 'entity') {
|
||||
$value = $this->getTypedContext();
|
||||
}
|
||||
else {
|
||||
$value = $this->getContextValue();
|
||||
}
|
||||
return $validator->validateValue($value, $this->getConstraints());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,7 +8,9 @@
|
|||
namespace Drupal\Core\Plugin;
|
||||
|
||||
use Drupal\Component\Plugin\ContextAwarePluginBase as PluginBase;
|
||||
use Drupal\Component\Plugin\Exception\PluginException;
|
||||
use Drupal\Core\Plugin\Context\Context;
|
||||
use Drupal\Component\Plugin\Discovery\DiscoveryInterface;
|
||||
|
||||
/**
|
||||
* Drupal specific class for plugins that use context.
|
||||
|
@ -19,14 +21,36 @@ use Drupal\Core\Plugin\Context\Context;
|
|||
*/
|
||||
abstract class ContextAwarePluginBase extends PluginBase {
|
||||
|
||||
/**
|
||||
* Override of \Drupal\Component\Plugin\ContextAwarePluginBase::__construct().
|
||||
*/
|
||||
public function __construct(array $configuration, $plugin_id, DiscoveryInterface $discovery) {
|
||||
$context = array();
|
||||
if (isset($configuration['context'])) {
|
||||
$context = $configuration['context'];
|
||||
unset($configuration['context']);
|
||||
}
|
||||
parent::__construct($configuration, $plugin_id, $discovery);
|
||||
foreach ($context as $key => $value) {
|
||||
$context_definition = $this->getContextDefinition($key);
|
||||
$this->context[$key] = new Context($context_definition);
|
||||
$this->context[$key]->setContextValue($value);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Override of \Drupal\Component\Plugin\ContextAwarePluginBase::setContextValue().
|
||||
*/
|
||||
public function setContextValue($key, $value) {
|
||||
$context_definition = $this->getContextDefinition($key);
|
||||
$this->context[$key] = new Context($context_definition);
|
||||
$this->context[$key]->setContextValue($value);
|
||||
public function setContextValue($name, $value) {
|
||||
$context_definition = $this->getContextDefinition($name);
|
||||
// Use the Drupal specific context class.
|
||||
$this->context[$name] = new Context($context_definition);
|
||||
$this->context[$name]->setContextValue($value);
|
||||
|
||||
// Verify the provided value validates.
|
||||
if ($this->context[$name]->validate()->count() > 0) {
|
||||
throw new PluginException("The provided context value does not pass validation.");
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
|
|
@ -22,7 +22,7 @@ class EntityTypeConstraintValidator extends ConstraintValidator {
|
|||
$entity = isset($typed_data) ? $typed_data->getValue() : FALSE;
|
||||
|
||||
if (!empty($entity) && $entity->entityType() != $constraint->type) {
|
||||
$this->context->addViolation($constraint->message, array('%type', $constraint->type));
|
||||
$this->context->addViolation($constraint->message, array('%type' => $constraint->type));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,92 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Contains \Drupal\node\Plugin\Core\Condition\NodeType.
|
||||
*/
|
||||
|
||||
namespace Drupal\node\Plugin\Core\Condition;
|
||||
|
||||
use Drupal\Core\Condition\ConditionPluginBase;
|
||||
use Drupal\Core\Annotation\Plugin;
|
||||
use Drupal\Core\Annotation\Translation;
|
||||
|
||||
/**
|
||||
* Provides a 'Node Type' condition.
|
||||
*
|
||||
* @Plugin(
|
||||
* id = "node_type",
|
||||
* label = @Translation("Node Bundle"),
|
||||
* module = "node",
|
||||
* context = {
|
||||
* "node" = {
|
||||
* "type" = "entity",
|
||||
* "constraints" = {
|
||||
* "EntityType" = "node"
|
||||
* }
|
||||
* }
|
||||
* }
|
||||
* )
|
||||
*/
|
||||
class NodeType extends ConditionPluginBase {
|
||||
|
||||
/**
|
||||
* Implements \Drupal\Core\Form\FormInterface::buildForm().
|
||||
*/
|
||||
public function buildForm(array $form, array &$form_state) {
|
||||
$form = parent::buildForm($form, $form_state);
|
||||
$options = array();
|
||||
foreach (node_type_get_types() as $type) {
|
||||
$options[$type->type] = $type->name;
|
||||
}
|
||||
$form['bundles'] = array(
|
||||
'#type' => 'checkboxes',
|
||||
'#options' => $options,
|
||||
'#required' => TRUE,
|
||||
'#default_value' => isset($this->configuration['bundles']) ? $this->configuration['bundles'] : array(),
|
||||
);
|
||||
return $form;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements \Drupal\Core\Form\FormInterface::validateForm().
|
||||
*/
|
||||
public function validateForm(array &$form, array &$form_state) {
|
||||
foreach ($form_state['values']['bundles'] as $bundle) {
|
||||
if (!in_array($bundle, array_keys(node_type_get_types()))) {
|
||||
form_set_error('bundles', t('You have chosen an invalid node bundle, please check your selection and try again.'));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements \Drupal\Core\Form\FormInterface::submitForm().
|
||||
*/
|
||||
public function submitForm(array &$form, array &$form_state) {
|
||||
$this->configuration['bundles'] = $form_state['values']['bundles'];
|
||||
parent::submitForm($form, $form_state);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements \Drupal\Core\Executable\ExecutableInterface::summary().
|
||||
*/
|
||||
public function summary() {
|
||||
if (count($this->configuration['bundles']) > 1) {
|
||||
$bundles = $this->configuration['bundles'];
|
||||
$last = array_pop($bundles);
|
||||
$bundles = implode(', ', $bundles);
|
||||
return t('The node bundle is @bundles or @last', array('@bundles' => $bundles, '@last' => $last));
|
||||
}
|
||||
$bundle = $this->configuration['bundles'][0];
|
||||
return t('The node bundle is @bundle', array('@bundle' => $bundle));
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements \Drupal\condition\ConditionInterface::evaluate().
|
||||
*/
|
||||
public function evaluate() {
|
||||
$node = $this->getContextValue('node');
|
||||
return in_array($node->type, $this->configuration['bundles']);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,88 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Contains \Drupal\condition\Tests\Condition\NodeConditionTest.
|
||||
*/
|
||||
|
||||
namespace Drupal\node\Tests\Condition;
|
||||
|
||||
use Drupal\simpletest\DrupalUnitTestBase;
|
||||
use Drupal\Core\Condition\ConditionManager;
|
||||
|
||||
/**
|
||||
* Tests the node conditions.
|
||||
*/
|
||||
class NodeConditionTest extends DrupalUnitTestBase {
|
||||
|
||||
public static $modules = array('system', 'node', 'field');
|
||||
|
||||
public static function getInfo() {
|
||||
return array(
|
||||
'name' => 'Node Condition Plugins',
|
||||
'description' => 'Tests that conditions, provided by the node module, are working properly.',
|
||||
'group' => 'Condition API',
|
||||
);
|
||||
}
|
||||
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
$this->installSchema('node', 'node_type');
|
||||
$this->installSchema('node', 'node');
|
||||
$this->installSchema('node', 'node_revision');
|
||||
$this->installSchema('field', 'field_config');
|
||||
$this->installSchema('field', 'field_config_instance');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests conditions.
|
||||
*/
|
||||
function testConditions() {
|
||||
$manager = new ConditionManager();
|
||||
|
||||
// Get some nodes of various types to check against.
|
||||
$page = entity_create('node', array('type' => 'page', 'title' => $this->randomName()));
|
||||
$page->save();
|
||||
$article = entity_create('node', array('type' => 'article', 'title' => $this->randomName()));
|
||||
$article->save();
|
||||
$test = entity_create('node', array('type' => 'test', 'title' => $this->randomName()));
|
||||
$test->save();
|
||||
|
||||
// Grab the node type condition and configure it to check against node type
|
||||
// of 'article' and set the context to the page type node.
|
||||
$condition = $manager->createInstance('node_type')
|
||||
->setConfig('bundles', array('article'))
|
||||
->setContextValue('node', $page);
|
||||
$this->assertFalse($condition->execute(), 'Page type nodes fail node type checks for articles.');
|
||||
// Check for the proper summary.
|
||||
$this->assertEqual('The node bundle is article', $condition->summary());
|
||||
|
||||
// Set the node type check to page.
|
||||
$condition->setConfig('bundles', array('page'));
|
||||
$this->assertTrue($condition->execute(), 'Page type nodes pass node type checks for pages');
|
||||
// Check for the proper summary.
|
||||
$this->assertEqual('The node bundle is page', $condition->summary());
|
||||
|
||||
// Set the node type check to page or article.
|
||||
$condition->setConfig('bundles', array('page', 'article'));
|
||||
$this->assertTrue($condition->execute(), 'Page type nodes pass node type checks for pages or articles');
|
||||
// Check for the proper summary.
|
||||
$this->assertEqual('The node bundle is page or article', $condition->summary());
|
||||
|
||||
// Set the context to the article node.
|
||||
$condition->setContextValue('node', $article);
|
||||
$this->assertTrue($condition->execute(), 'Article type nodes pass node type checks for pages or articles');
|
||||
|
||||
// Set the context to the test node.
|
||||
$condition->setContextValue('node', $test);
|
||||
$this->assertFalse($condition->execute(), 'Test type nodes pass node type checks for pages or articles');
|
||||
|
||||
// Check a greater than 2 bundles summary scenario.
|
||||
$condition->setConfig('bundles', array('page', 'article', 'test'));
|
||||
$this->assertEqual('The node bundle is page, article or test', $condition->summary());
|
||||
|
||||
// Test Constructor injection.
|
||||
$condition = $manager->createInstance('node_type', array('bundles' => array('article'), 'context' => array('node' => $article)));
|
||||
$this->assertTrue($condition->execute(), 'Constructor injection of context and configuration working as anticipated.');
|
||||
}
|
||||
}
|
|
@ -0,0 +1,45 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Contains \Drupal\system\Tests\Condition\ConditionFormTest.
|
||||
*/
|
||||
|
||||
namespace Drupal\system\Tests\Condition;
|
||||
|
||||
use Drupal\simpletest\WebTestBase;
|
||||
|
||||
/**
|
||||
* Tests condition forms, configuration and execution.
|
||||
*
|
||||
* Checks condition forms and submission and gives a very cursory check to make
|
||||
* sure the configuration that was submitted actually causes the condition to
|
||||
* validate correctly.
|
||||
*/
|
||||
class ConditionFormTest extends WebTestBase {
|
||||
|
||||
public static $modules = array('node', 'condition_test');
|
||||
|
||||
public static function getInfo() {
|
||||
return array(
|
||||
'name' => 'Condition Form Tests',
|
||||
'description' => 'Tests that condtion plugins basic form handling is working.',
|
||||
'group' => 'Condition API',
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Submit the condition_node_type_test_form to test condition forms.
|
||||
*/
|
||||
function testConfigForm() {
|
||||
$article = entity_create('node', array('type' => 'article', 'title' => $this->randomName()));
|
||||
$article->save();
|
||||
$this->drupalGet('condition_test');
|
||||
$this->assertField('bundles[article]', 'There is an article bundle selector.');
|
||||
$this->assertField('bundles[page]', 'There is a page bundle selector.');
|
||||
$this->drupalPost(NULL, array('bundles[page]' => 'page', 'bundles[article]' => 'article'), t('Submit'));
|
||||
$this->assertText('The bundles are article and page', 'The form component appropriately saved the bundles.');
|
||||
$this->assertText('Executed successfully.', 'The form configured condition executed properly.');
|
||||
}
|
||||
|
||||
}
|
|
@ -93,8 +93,8 @@ class ContextPluginTest extends DrupalUnitTestBase {
|
|||
$plugin->setContextValue('user', $node);
|
||||
$this->fail('The node context should fail validation for a user context.');
|
||||
}
|
||||
catch (ContextException $e) {
|
||||
$this->assertEqual($e->getMessage(), 'The context passed was not an instance of Drupal\user\Plugin\Core\Entity\User.');
|
||||
catch (PluginException $e) {
|
||||
$this->assertEqual($e->getMessage(), 'The provided context value does not pass validation.');
|
||||
}
|
||||
|
||||
// Set an appropriate context value appropriately and check to make sure
|
||||
|
@ -157,13 +157,8 @@ class ContextPluginTest extends DrupalUnitTestBase {
|
|||
}
|
||||
|
||||
// With no contexts set, try to get the context values.
|
||||
try {
|
||||
$complex_plugin->getContextValues();
|
||||
$this->fail('There should not be any contexts set yet.');
|
||||
}
|
||||
catch (PluginException $e) {
|
||||
$this->assertEqual($e->getMessage(), 'There are no set contexts.');
|
||||
}
|
||||
$values = $complex_plugin->getContextValues();
|
||||
$this->assertIdentical(array_filter($values), array(), 'There are no set contexts.');
|
||||
|
||||
// Set the user context value.
|
||||
$complex_plugin->setContextValue('user', $user);
|
||||
|
@ -178,13 +173,9 @@ class ContextPluginTest extends DrupalUnitTestBase {
|
|||
}
|
||||
|
||||
// With only the user context set, try to get the context values.
|
||||
try {
|
||||
$complex_plugin->getContextValues();
|
||||
$this->fail('The node context should not yet be set.');
|
||||
}
|
||||
catch (PluginException $e) {
|
||||
$this->assertEqual($e->getMessage(), 'The node context is not yet set.');
|
||||
}
|
||||
$values = $complex_plugin->getContextValues();
|
||||
$this->assertNull($values['node'], 'The node context is not yet set.');
|
||||
$this->assertNotNull($values['user'], 'The user context is set');
|
||||
|
||||
$complex_plugin->setContextValue('node', $node);
|
||||
$context_wrappers = $complex_plugin->getContexts();
|
||||
|
|
|
@ -0,0 +1,6 @@
|
|||
name = "Condition Test Support"
|
||||
description = "Test general form component for condition plugins."
|
||||
package = Testing
|
||||
version = VERSION
|
||||
core = 8.x
|
||||
hidden = TRUE
|
|
@ -0,0 +1,21 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* Implements hook_node_info().
|
||||
*/
|
||||
function condition_test_node_info() {
|
||||
return array(
|
||||
'article' => array(
|
||||
'name' => t('Article'),
|
||||
'base' => 'article',
|
||||
'description' => t('An article content type'),
|
||||
'title_label' => t('Subject'),
|
||||
),
|
||||
'page' => array(
|
||||
'name' => t('Page'),
|
||||
'base' => 'page',
|
||||
'description' => t('A page content type'),
|
||||
'title_label' => t('Subject'),
|
||||
),
|
||||
);
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
condition_test_1:
|
||||
pattern: '/condition_test'
|
||||
defaults:
|
||||
_controller: '\Drupal\condition_test\FormController::getForm'
|
||||
requirements:
|
||||
_access: 'TRUE'
|
|
@ -0,0 +1,74 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Contains \Drupal\condition_test\FormController.
|
||||
*/
|
||||
|
||||
namespace Drupal\condition_test;
|
||||
|
||||
use Drupal\Core\Form\FormInterface;
|
||||
use Drupal\Core\Condition\ConditionManager;
|
||||
|
||||
/**
|
||||
* Routing controller class for condition_test testing of condition forms.
|
||||
*/
|
||||
class FormController implements FormInterface {
|
||||
|
||||
/**
|
||||
* The condition plugin we will be working with.
|
||||
*
|
||||
* @var \Drupal\Core\Condition\ConditionInterface
|
||||
*/
|
||||
protected $condition;
|
||||
|
||||
/**
|
||||
* Implements \Drupal\Core\Form\FormInterface::getFormID().
|
||||
*/
|
||||
public function getFormID() {
|
||||
return 'condition_node_type_test_form';
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides a simple method the router can fire in order to invoke this form.
|
||||
*/
|
||||
public function getForm() {
|
||||
$manager = new ConditionManager();
|
||||
$this->condition = $manager->createInstance('node_type');
|
||||
return drupal_get_form($this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements \Drupal\Core\Form\FormInterface::buildForm().
|
||||
*/
|
||||
public function buildForm(array $form, array &$form_state) {
|
||||
$form = $this->condition->buildForm($form, $form_state);
|
||||
$form['actions']['submit'] = array(
|
||||
'#type' => 'submit',
|
||||
'#value' => t('Submit'),
|
||||
);
|
||||
return $form;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements \Drupal\Core\Form\FormInterface::validateForm().
|
||||
*/
|
||||
public function validateForm(array &$form, array &$form_state) {
|
||||
$this->condition->validateForm($form, $form_state);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements \Drupal\Core\Form\FormInterface::submitForm().
|
||||
*/
|
||||
public function submitForm(array &$form, array &$form_state) {
|
||||
$this->condition->submitForm($form, $form_state);
|
||||
$config = $this->condition->getConfig();
|
||||
$bundles = implode(' and ', $config['bundles']);
|
||||
drupal_set_message(t('The bundles are @bundles', array('@bundles' => $bundles)));
|
||||
$article = node_load(1);
|
||||
$this->condition->setContextValue('node', $article);
|
||||
if ($this->condition->execute()) {
|
||||
drupal_set_message(t('Executed successfully.'));
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue