diff --git a/core/lib/Drupal/Core/CoreBundle.php b/core/lib/Drupal/Core/CoreBundle.php index 16faeef..5b94b75 100644 --- a/core/lib/Drupal/Core/CoreBundle.php +++ b/core/lib/Drupal/Core/CoreBundle.php @@ -278,6 +278,8 @@ public function build(ContainerBuilder $container) { $container->register('flood', 'Drupal\Core\Flood\DatabaseBackend') ->addArgument(new Reference('database')); + $container->register('plugin.manager.processor', 'Drupal\Core\Processor\ProcessorManager'); + $container->addCompilerPass(new RegisterMatchersPass()); $container->addCompilerPass(new RegisterRouteFiltersPass()); // Add a compiler pass for registering event subscribers. diff --git a/core/lib/Drupal/Core/Executable/ExecutableException.php b/core/lib/Drupal/Core/Executable/ExecutableException.php new file mode 100644 index 0000000..1f105c4 --- /dev/null +++ b/core/lib/Drupal/Core/Executable/ExecutableException.php @@ -0,0 +1,16 @@ +processorManager = $processorManager; + return $this; + } + + /** + * Implements \Drupal\Core\Executable\ExecutableInterface::setProcessor(). + */ + public function setProcessor($plugin_id, array $configuration) { + // @todo Do we want to check this before actually assigning? + $this->configuration['processors'][] = $this->processorManager->createInstance($plugin_id, $configuration); + return $this; + } + + /** + * Implements \Drupal\Core\Executable\ExecutableInterface::getProcessor(). + */ + public function getProcessors() { + return $this->configuration['processors']; + } + + /** + * Gets all configuration values. + * + * @see \Drupal\Component\Plugin\PluginBase::$configuration + * + * @return array + */ + public function getConfig() { + return $this->configuration; + } + + /** + * Sets a particular value in the block settings. + * + * @param string $key + * The key of PluginBase::$configuration to set. + * @param mixed $value + * The value to set for the provided key. + * + * @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 + */ + public function setConfig($key, $value) { + $this->configuration[$key] = $value; + return $this; + } + + /** + * Implements \Drupal\Core\Executable\ExecutableInterface::execute(). + */ + abstract public function execute(); + +} + diff --git a/core/lib/Drupal/Core/Plugin/Context/Context.php b/core/lib/Drupal/Core/Plugin/Context/Context.php index bcab7e1..9367401 100644 --- a/core/lib/Drupal/Core/Plugin/Context/Context.php +++ b/core/lib/Drupal/Core/Plugin/Context/Context.php @@ -30,7 +30,8 @@ public function getContextValue() { // 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'])) { + // @todo We won't need the getType == entity check once #1868004 lands. + if (!empty($type_definition['primitive type']) || $typed_value->getType() == 'entity') { return $typed_value->getValue(); } } diff --git a/core/lib/Drupal/Core/Processor/ProcessorInterface.php b/core/lib/Drupal/Core/Processor/ProcessorInterface.php new file mode 100644 index 0000000..a3e15e7 --- /dev/null +++ b/core/lib/Drupal/Core/Processor/ProcessorInterface.php @@ -0,0 +1,15 @@ +discovery = new AnnotatedClassDiscovery('Core', 'Processor'); + $this->discovery = new AlterDecorator($this->discovery, 'processor'); + $this->discovery = new ProcessDecorator($this->discovery, array($this, 'processDefinition')); + $this->discovery = new CacheDecorator($this->discovery, 'processor:' . language(LANGUAGE_TYPE_INTERFACE)->langcode); + + $this->factory = new DefaultFactory($this); + } + +} + diff --git a/core/modules/condition/condition.info b/core/modules/condition/condition.info new file mode 100644 index 0000000..52d7d2a --- /dev/null +++ b/core/modules/condition/condition.info @@ -0,0 +1,6 @@ +name = Conditions +description = Perform evaluations of various information to yield TRUE/FALSE statements. +package = Core +version = VERSION +core = 8.x +configure = admin/config/system/conditions diff --git a/core/modules/condition/condition.module b/core/modules/condition/condition.module new file mode 100644 index 0000000..d6ed5b2 --- /dev/null +++ b/core/modules/condition/condition.module @@ -0,0 +1,20 @@ +get('plugin.manager.condition')->createInstance($plugin_id, $options); +} diff --git a/core/modules/condition/lib/Drupal/condition/ConditionBundle.php b/core/modules/condition/lib/Drupal/condition/ConditionBundle.php new file mode 100644 index 0000000..b41a3db --- /dev/null +++ b/core/modules/condition/lib/Drupal/condition/ConditionBundle.php @@ -0,0 +1,28 @@ +register('plugin.manager.condition', 'Drupal\condition\Plugin\Type\ConditionManager')->addArgument(new Reference('plugin.manager.processor')); + } + +} diff --git a/core/modules/condition/lib/Drupal/condition/Plugin/ConditionInterface.php b/core/modules/condition/lib/Drupal/condition/Plugin/ConditionInterface.php new file mode 100644 index 0000000..1dd7e5f --- /dev/null +++ b/core/modules/condition/lib/Drupal/condition/Plugin/ConditionInterface.php @@ -0,0 +1,74 @@ + 'checkbox', + '#title' => t('Negate the condition.'), + '#default_value' => isset($this->configuration['negate']) ? $this->configuration['negate'] : FALSE, + ); + return $form; + } + + /** + * Implements Drupal\condition\ConditionInterface::submit(). + */ + public function submit($form, &$form_state) { + $this->configuration['negate'] = $form_state['values']['negate']; + } + + /** + * Implements ExecutablePluginBase::execute(). + */ + public function execute() { + if (!empty($this->configuration['negate'])) { + return !$this->evaluate(); + } + return $this->evaluate(); + } + +} diff --git a/core/modules/condition/lib/Drupal/condition/Plugin/Type/ConditionManager.php b/core/modules/condition/lib/Drupal/condition/Plugin/Type/ConditionManager.php new file mode 100644 index 0000000..b0da81f --- /dev/null +++ b/core/modules/condition/lib/Drupal/condition/Plugin/Type/ConditionManager.php @@ -0,0 +1,49 @@ +processorManager = $process_manager; + $this->discovery = new AnnotatedClassDiscovery('Core', 'Condition'); + $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->setProcessorManager($this->processorManager); + } + +} 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 new file mode 100644 index 0000000..828c524 --- /dev/null +++ b/core/modules/node/lib/Drupal/node/Plugin/Core/Condition/NodeType.php @@ -0,0 +1,93 @@ +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\condition\ConditionInterface::validate(). + */ + public function validate($form, &$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\condition\ConditionInterface::submit(). + */ + public function submit($form, &$form_state) { + $this->configuration['bundles'] = $form_state['values']['bundles']; + parent::submit($form, $form_state); + } + + /** + * Implements \Drupal\condition\ConditionInterface::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']); + } + +} diff --git a/core/modules/node/lib/Drupal/node/Tests/Condition/NodeConditionTest.php b/core/modules/node/lib/Drupal/node/Tests/Condition/NodeConditionTest.php new file mode 100644 index 0000000..e6592b7 --- /dev/null +++ b/core/modules/node/lib/Drupal/node/Tests/Condition/NodeConditionTest.php @@ -0,0 +1,86 @@ + '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() { + $processor = new ProcessorManager(); + $manager = new ConditionManager($processor); + + // 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()); + } +}