diff --git a/core/lib/Drupal/Component/Plugin/Context/ContextInterface.php b/core/lib/Drupal/Component/Plugin/Context/ContextInterface.php index 512605a..c5cd743 100644 --- a/core/lib/Drupal/Component/Plugin/Context/ContextInterface.php +++ b/core/lib/Drupal/Component/Plugin/Context/ContextInterface.php @@ -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 @@ * 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,7 +26,7 @@ public function setContextValue($value); * 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(); diff --git a/core/lib/Drupal/Component/Plugin/ContextAwarePluginBase.php b/core/lib/Drupal/Component/Plugin/ContextAwarePluginBase.php index c6ffc3d..2b97103 100644 --- a/core/lib/Drupal/Component/Plugin/ContextAwarePluginBase.php +++ b/core/lib/Drupal/Component/Plugin/ContextAwarePluginBase.php @@ -28,18 +28,18 @@ */ 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]; } /** @@ -47,19 +47,15 @@ public function getContextDefinition($key) { */ 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; } @@ -67,25 +63,24 @@ public function getContexts() { /** * 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() { - $definitions = (array) $this->getContextDefinitions(); $values = array(); - foreach ($definitions as $key => $definition) { - $values[$key] = isset($this->context[$key]) ? $this->context[$key]->getContextValue() : NULL; + foreach ($this->getContextDefinitions() as $name => $definition) { + $values[$name] = isset($this->context[$name]) ? $this->context[$name]->getContextValue() : NULL; } return $values; } @@ -93,20 +88,20 @@ public function getContextValues() { /** * 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[$key]->validate(); + $violations = $this->context[$name]->validate(); if (count($violations) > 0) { throw new PluginException("The provided context value does not pass validation."); } @@ -121,14 +116,12 @@ public function validate() { // @todo: Implement symfony validator API to let the validator traverse // and set property paths accordingly. - if ($definitions = $this->getContextDefinitions()) { - foreach ($definitions as $key => $definition) { - // Validate any set values. - if (isset($this->context[$key])) { - $violations->addAll($this->context[$key]->validate()); - } - // @todo: If no value is set, make sure any mapping is validated. + 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; } diff --git a/core/lib/Drupal/Component/Plugin/ContextAwarePluginInterface.php b/core/lib/Drupal/Component/Plugin/ContextAwarePluginInterface.php index 086a25f..a90f787 100644 --- a/core/lib/Drupal/Component/Plugin/ContextAwarePluginInterface.php +++ b/core/lib/Drupal/Component/Plugin/ContextAwarePluginInterface.php @@ -8,34 +8,36 @@ 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. * * @throws \Drupal\Component\Plugin\Exception\PluginException - * If the requested definition is not set. + * 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. @@ -51,9 +53,8 @@ public function getContexts(); /** * 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. @@ -61,13 +62,13 @@ public function getContexts(); * @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 - * An array of set context values, keyed by context key. If a context is + * An array of set context values, keyed by context name. If a context is * unset its value is returned as NULL. */ public function getContextValues(); @@ -75,9 +76,8 @@ 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. @@ -85,15 +85,15 @@ public function getContextValues(); * @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 @@ -102,7 +102,7 @@ public function getContextValue($key); * @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. diff --git a/core/lib/Drupal/Core/Condition/ConditionInterface.php b/core/lib/Drupal/Core/Condition/ConditionInterface.php index 82c220a..00538ba 100644 --- a/core/lib/Drupal/Core/Condition/ConditionInterface.php +++ b/core/lib/Drupal/Core/Condition/ConditionInterface.php @@ -11,11 +11,13 @@ /** * An interface for condition plugins. + * + * @see \Drupal\Core\Executable\ExecutableInterface */ interface ConditionInterface extends ExecutableInterface { /** - * Determines whether condition result will be negaeted. + * Determines whether condition result will be negated. * * @return boolean * Whether the condition result will be negated. @@ -23,9 +25,10 @@ public function isNegated(); /** - * Evaluate the condition and return TRUE or FALSE accordingly + * Evaluates the condition and returns TRUE or FALSE accordingly. * * @return bool + * TRUE if the condition has been met, FALSE otherwise. */ public function evaluate(); diff --git a/core/lib/Drupal/Core/Condition/ConditionManager.php b/core/lib/Drupal/Core/Condition/ConditionManager.php index 847a8e7..c7cdb60 100644 --- a/core/lib/Drupal/Core/Condition/ConditionManager.php +++ b/core/lib/Drupal/Core/Condition/ConditionManager.php @@ -15,7 +15,6 @@ use Drupal\Core\Plugin\Discovery\AlterDecorator; use Drupal\Core\Plugin\Discovery\AnnotatedClassDiscovery; use Drupal\Core\Plugin\Discovery\CacheDecorator; -use Drupal\Core\Processor\ProcessorManager; /** * A plugin manager for condition plugins. diff --git a/core/lib/Drupal/Core/Executable/ExecutableInterface.php b/core/lib/Drupal/Core/Executable/ExecutableInterface.php index efb9b86..f6f5fed 100644 --- a/core/lib/Drupal/Core/Executable/ExecutableInterface.php +++ b/core/lib/Drupal/Core/Executable/ExecutableInterface.php @@ -7,17 +7,27 @@ namespace Drupal\Core\Executable; -use Drupal\Component\Plugin\PluginInspectionInterface; -use Drupal\Core\Processor\ProcessorManager; +use Drupal\Component\Plugin\ContextAwarePluginInterface; use Drupal\Core\Form\FormInterface; /** - * An interface for executable and processable plugins. + * 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 PluginInspectionInterface, FormInterface { +interface ExecutableInterface extends ContextAwarePluginInterface, FormInterface { /** - * Executes the action. + * Executes the plugin. */ public function execute(); @@ -27,7 +37,7 @@ public function execute(); public function summary(); /** - * Sets the manager class for use in certain proxy methods. + * Sets the executable manager class. * * @param \Drupal\Core\Condition\ConditionManager $executableManager * The executable manager. diff --git a/core/lib/Drupal/Core/Executable/ExecutablePluginBase.php b/core/lib/Drupal/Core/Executable/ExecutablePluginBase.php index 0920cb7..509b221 100644 --- a/core/lib/Drupal/Core/Executable/ExecutablePluginBase.php +++ b/core/lib/Drupal/Core/Executable/ExecutablePluginBase.php @@ -8,14 +8,13 @@ namespace Drupal\Core\Executable; use Drupal\Core\Plugin\ContextAwarePluginBase; -use Drupal\Core\Validation\DrupalTranslator; use Symfony\Component\Validator\Validation; use Drupal\Component\Plugin\Exception\PluginException; use Drupal\Component\Plugin\Discovery\DiscoveryInterface; use Drupal\Core\Plugin\Context\Context; /** - * Provides the basic architecture for executable and processable plugins. + * Provides the basic architecture for executable plugins. */ abstract class ExecutablePluginBase extends ContextAwarePluginBase implements ExecutableInterface { @@ -31,6 +30,12 @@ * * Overrides the construction of executable 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(); @@ -54,6 +59,15 @@ public function setExecutableManager(ExecutableManagerInterface $executableManag 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'])) { @@ -62,58 +76,63 @@ public function getConfigDefinitions() { 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 NULL; + return FALSE; } /** * Gets all configuration values. * + * @todo: This needs to go into an interface. + * * @see \Drupal\Component\Plugin\PluginBase::$configuration * * @return array + * The array of all configuration values, keyed by configuration option + * name. */ public function getConfig() { return $this->configuration; } /** - * Sets a particular value in the block settings. + * Sets the value of a particular configuration option. * - * @param string $key - * The key of PluginBase::$configuration to set. + * @param string $name + * The name of the configuration option to set. * @param mixed $value - * The value to set for the provided key. + * 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. * - * @see \Drupal\Component\Plugin\PluginBase::$configuration + * @return \Drupal\Core\Executable\ExecutablePluginBase. + * The executable object for chaining. */ public function setConfig($key, $value) { - $definition = $this->getConfigDefinition($key); - if (!is_null($definition)) { + if ($definition = $this->getConfigDefinition($key)) { $typed_data = typed_data()->create($definition, $value); - $validator = Validation::createValidatorBuilder() - ->setTranslator(new DrupalTranslator()) - ->getValidator(); - if ($validator->validateValue($typed_data, $typed_data->getConstraints())->count() > 0) { + + if ($typed_data->validate()->count() > 0) { throw new PluginException("The provided configuration value does not pass validation."); } } $this->configuration[$key] = $value; return $this; } - - /** - * Implements \Drupal\Core\Executable\ExecutableInterface::execute(). - */ - abstract public function execute(); - } diff --git a/core/lib/Drupal/Core/Plugin/ContextAwarePluginBase.php b/core/lib/Drupal/Core/Plugin/ContextAwarePluginBase.php index e4daeb1..a67a3c8 100644 --- a/core/lib/Drupal/Core/Plugin/ContextAwarePluginBase.php +++ b/core/lib/Drupal/Core/Plugin/ContextAwarePluginBase.php @@ -23,13 +23,14 @@ /** * 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[$key]->validate()->count() > 0) { + if ($this->context[$name]->validate()->count() > 0) { throw new PluginException("The provided context value does not pass validation."); } return $this; diff --git a/core/modules/node/lib/Drupal/node/Plugin/Core/Condition/NodeType.php b/core/modules/node/lib/Drupal/node/Plugin/Core/Condition/NodeType.php index e7deca2..f6d0b22 100644 --- a/core/modules/node/lib/Drupal/node/Plugin/Core/Condition/NodeType.php +++ b/core/modules/node/lib/Drupal/node/Plugin/Core/Condition/NodeType.php @@ -28,7 +28,6 @@ * } * ) */ - class NodeType extends ConditionPluginBase { /** @@ -50,7 +49,7 @@ public function buildForm(array $form, array &$form_state) { } /** - * Implements \Drupal\condition\ConditionInterface::validate(). + * Implements \Drupal\Core\Form\FormInterface::validateForm(). */ public function validateForm(array &$form, array &$form_state) { foreach ($form_state['values']['bundles'] as $bundle) { @@ -61,7 +60,7 @@ public function validateForm(array &$form, array &$form_state) { } /** - * Implements \Drupal\condition\ConditionInterface::submit(). + * Implements \Drupal\Core\Form\FormInterface::submitForm(). */ public function submitForm(array &$form, array &$form_state) { $this->configuration['bundles'] = $form_state['values']['bundles']; @@ -69,7 +68,7 @@ public function submitForm(array &$form, array &$form_state) { } /** - * Implements \Drupal\condition\ConditionInterface::summary(). + * Implements \Drupal\Core\Executable\ExecutableInterface::summary(). */ public function summary() { if (count($this->configuration['bundles']) > 1) { diff --git a/core/modules/system/lib/Drupal/system/Tests/Condition/ConditionFormTest.php b/core/modules/system/lib/Drupal/system/Tests/Condition/ConditionFormTest.php index f28b3c4..b76aac1 100644 --- a/core/modules/system/lib/Drupal/system/Tests/Condition/ConditionFormTest.php +++ b/core/modules/system/lib/Drupal/system/Tests/Condition/ConditionFormTest.php @@ -9,6 +9,13 @@ 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'); @@ -22,7 +29,7 @@ public static function getInfo() { } /** - * Submit the system_config_form ensure the configuration has expected values. + * Submit the condition_node_type_test_form to test condition forms. */ function testConfigForm() { $this->drupalGet('condition_test'); diff --git a/core/modules/system/tests/modules/condition_test/condition_test.module b/core/modules/system/tests/modules/condition_test/condition_test.module index 76fccd8..1310b21 100644 --- a/core/modules/system/tests/modules/condition_test/condition_test.module +++ b/core/modules/system/tests/modules/condition_test/condition_test.module @@ -1,5 +1,8 @@ array( diff --git a/core/modules/system/tests/modules/condition_test/lib/Drupal/condition_test/FormController.php b/core/modules/system/tests/modules/condition_test/lib/Drupal/condition_test/FormController.php index 2d63e19..cd47c89 100644 --- a/core/modules/system/tests/modules/condition_test/lib/Drupal/condition_test/FormController.php +++ b/core/modules/system/tests/modules/condition_test/lib/Drupal/condition_test/FormController.php @@ -15,18 +15,32 @@ */ 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( @@ -36,15 +50,20 @@ public function buildForm(array $form, array &$form_state) { 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('
' . var_export($this->condition->getConfig(), TRUE) . '
'); drupal_set_message(t('The bundles are @bundles', array('@bundles' => $bundles))); } }