From ddddfd2162732daa7419e9e0bade78142e3a60a7 Mon Sep 17 00:00:00 2001 From: milkovsky Date: Fri, 5 Feb 2016 15:56:07 +0100 Subject: [PATCH 01/30] Added EventHandlerEntityBundle. --- rules.rules.events.yml | 1 + src/EventHandler/EventHandlerBase.php | 107 ++++++++++++++++++ src/EventHandler/EventHandlerEntityBundle.php | 27 +++++ .../GenericEventSubscriber.php | 2 +- 4 files changed, 136 insertions(+), 1 deletion(-) create mode 100644 src/EventHandler/EventHandlerBase.php create mode 100644 src/EventHandler/EventHandlerEntityBundle.php diff --git a/rules.rules.events.yml b/rules.rules.events.yml index d8b8c973..ca5b3c51 100644 --- a/rules.rules.events.yml +++ b/rules.rules.events.yml @@ -21,6 +21,7 @@ kernel.request: rules_entity_presave: label: 'Before saving an entity' deriver: '\Drupal\rules\Plugin\RulesEvent\EntityPresaveDeriver' + class: '\Drupal\rules\EventHandler\EventHandlerEntityBundle' rules_entity_delete: label: 'After deleting an entity' deriver: '\Drupal\rules\Plugin\RulesEvent\EntityDeleteDeriver' diff --git a/src/EventHandler/EventHandlerBase.php b/src/EventHandler/EventHandlerBase.php new file mode 100644 index 00000000..8f611e51 --- /dev/null +++ b/src/EventHandler/EventHandlerBase.php @@ -0,0 +1,107 @@ +defaultConfiguration() as $key => $configuration) { + $this->configuration[$key] = $form_state->hasValue($key) ? $form_state->getValue($key) : $configuration; + } + } + + /** + * @inheritdoc + */ + public function getConfiguration() { + return $this->configuration; + } + + /** + * @inheritdoc + */ + public function setConfiguration(array $configuration) { + $this->configuration = $configuration + $this->defaultConfiguration(); + return $this; + } + + /** + * @inheritdoc + */ + public function defaultConfiguration() { + return array(); + } + + /** + * @inheritdoc + */ + public function getEventNameSuffix() { + return ''; + } + + /** + * @inheritdoc + */ + public function refineContextDefinitions() { + // Nothing to refine by default. + } + + /** + * @inheritdoc + */ + public function calculateDependencies() { + // Nothing to calculate by default. + } + +} diff --git a/src/EventHandler/EventHandlerEntityBundle.php b/src/EventHandler/EventHandlerEntityBundle.php new file mode 100644 index 00000000..7209fba9 --- /dev/null +++ b/src/EventHandler/EventHandlerEntityBundle.php @@ -0,0 +1,27 @@ +getSubject()->bundle(); + } + return $events_suffixes; + } + +} diff --git a/src/EventSubscriber/GenericEventSubscriber.php b/src/EventSubscriber/GenericEventSubscriber.php index 9f591b9c..ce3edd81 100644 --- a/src/EventSubscriber/GenericEventSubscriber.php +++ b/src/EventSubscriber/GenericEventSubscriber.php @@ -95,7 +95,7 @@ public function onRulesEvent(Event $event, $event_name) { if (is_subclass_of($handler_class, RulesConfigurableEventHandlerInterface::class)) { $qualified_event_suffixes = $handler_class::determineQualifiedEvents($event, $event_name, $event_definition); foreach ($qualified_event_suffixes as $qualified_event_suffix) { - $triggered_event[] = "$event_name--$qualified_event_suffix"; + $triggered_events[] = "$event_name--$qualified_event_suffix"; } } From 52317fdfdc6d9989078938d252e5440bb79e4a48 Mon Sep 17 00:00:00 2001 From: milkovsky Date: Fri, 5 Feb 2016 16:23:12 +0100 Subject: [PATCH 02/30] Added EventHandlerEntityBundle to events yml. --- rules.rules.events.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/rules.rules.events.yml b/rules.rules.events.yml index ca5b3c51..35672709 100644 --- a/rules.rules.events.yml +++ b/rules.rules.events.yml @@ -25,15 +25,19 @@ rules_entity_presave: rules_entity_delete: label: 'After deleting an entity' deriver: '\Drupal\rules\Plugin\RulesEvent\EntityDeleteDeriver' + class: '\Drupal\rules\EventHandler\EventHandlerEntityBundle' rules_entity_insert: label: 'After saving a new entity' deriver: '\Drupal\rules\Plugin\RulesEvent\EntityInsertDeriver' + class: '\Drupal\rules\EventHandler\EventHandlerEntityBundle' rules_entity_update: label: 'After updating an entity' deriver: '\Drupal\rules\Plugin\RulesEvent\EntityUpdateDeriver' + class: '\Drupal\rules\EventHandler\EventHandlerEntityBundle' rules_entity_view: label: 'Viewing an entity' deriver: '\Drupal\rules\Plugin\RulesEvent\EntityViewDeriver' + class: '\Drupal\rules\EventHandler\EventHandlerEntityBundle' rules_system_cron: label: 'Cron maintenance tasks are performed' category: 'System' From b60b780a7ee741b8f92236767cd77586e4a2b723 Mon Sep 17 00:00:00 2001 From: milkovsky Date: Fri, 5 Feb 2016 16:24:39 +0100 Subject: [PATCH 03/30] Started writing EventHandlerTest. WIP. --- .../Integration/Engine/EventHandlerTest.php | 60 +++++++++++++++++++ 1 file changed, 60 insertions(+) create mode 100644 tests/src/Integration/Engine/EventHandlerTest.php diff --git a/tests/src/Integration/Engine/EventHandlerTest.php b/tests/src/Integration/Engine/EventHandlerTest.php new file mode 100644 index 00000000..31619460 --- /dev/null +++ b/tests/src/Integration/Engine/EventHandlerTest.php @@ -0,0 +1,60 @@ +rulesExpressionManager->createRule(); + $rule1->addAction('rules_entity_presave:node', ContextConfig::create() + ->map('entity', 'entity') + ); + + $rule2 = $this->rulesExpressionManager->createRule(); + $rule2->addAction('rules_entity_presave:node--page', ContextConfig::create() + ->map('entity', 'entity') + ); + + // @todo: save node page and check if both rules are triggered. + } + + /** + * Tests EventHandlerEntityBundle execution. + */ + public function testEntityBundleHandlerExecution() { + // - Second we must cover execution time: Trigger that event and verify a + // reaction rule for the qualified event is correctly executed. + + #1. mock somehow entity: 'node' with bundle 'page' and field 'body' + #2. create somehow rule with action 'rules_entity_presave:node–page' + #3. node->save(). + #4. check somehow that the rule was triggered + } + +} From 753833d5aa56773d323087c9281d8c0f4d57c144 Mon Sep 17 00:00:00 2001 From: milkovsky Date: Fri, 5 Feb 2016 18:02:46 +0100 Subject: [PATCH 04/30] EventHandlerTest WIP. --- .../Integration/Engine/EventHandlerTest.php | 60 -------- tests/src/Kernel/EventHandlerTest.php | 133 ++++++++++++++++++ 2 files changed, 133 insertions(+), 60 deletions(-) delete mode 100644 tests/src/Integration/Engine/EventHandlerTest.php create mode 100644 tests/src/Kernel/EventHandlerTest.php diff --git a/tests/src/Integration/Engine/EventHandlerTest.php b/tests/src/Integration/Engine/EventHandlerTest.php deleted file mode 100644 index 31619460..00000000 --- a/tests/src/Integration/Engine/EventHandlerTest.php +++ /dev/null @@ -1,60 +0,0 @@ -rulesExpressionManager->createRule(); - $rule1->addAction('rules_entity_presave:node', ContextConfig::create() - ->map('entity', 'entity') - ); - - $rule2 = $this->rulesExpressionManager->createRule(); - $rule2->addAction('rules_entity_presave:node--page', ContextConfig::create() - ->map('entity', 'entity') - ); - - // @todo: save node page and check if both rules are triggered. - } - - /** - * Tests EventHandlerEntityBundle execution. - */ - public function testEntityBundleHandlerExecution() { - // - Second we must cover execution time: Trigger that event and verify a - // reaction rule for the qualified event is correctly executed. - - #1. mock somehow entity: 'node' with bundle 'page' and field 'body' - #2. create somehow rule with action 'rules_entity_presave:node–page' - #3. node->save(). - #4. check somehow that the rule was triggered - } - -} diff --git a/tests/src/Kernel/EventHandlerTest.php b/tests/src/Kernel/EventHandlerTest.php new file mode 100644 index 00000000..5add0e9b --- /dev/null +++ b/tests/src/Kernel/EventHandlerTest.php @@ -0,0 +1,133 @@ +installConfig(['system']); + $this->installConfig(['field']); + $this->installSchema('system', ['sequences']); + $this->installEntitySchema('node'); + + $this->storage = $this->container->get('entity_type.manager')->getStorage('rules_reaction_rule'); + } + + /** + * Tests EventHandlerEntityBundle configuration. + */ + public function testEntityBundleHandlerConfiguration() { + // Create a multi-value integer field for testing. + FieldStorageConfig::create([ + 'field_name' => 'field_integer', + 'type' => 'integer', + 'entity_type' => 'node', + 'cardinality' => FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED, + ])->save(); + FieldConfig::create([ + 'field_name' => 'field_integer', + 'entity_type' => 'node', + 'bundle' => 'page', + ])->save(); + + // Create test node with a bundle and field. + $entity_type_manager = $this->container->get('entity_type.manager'); + $entity_type_manager->getStorage('node_type') + ->create(['type' => 'page']) + ->save(); + + // Create rule with an action 'rules_entity_presave:node–-page'. + $rule = $this->expressionManager->createRule(); + $config_entity = $this->storage->create([ + 'id' => 'test_rule', + 'expression_id' => 'rules_rule', + 'event' => 'rules_entity_presave:node-–page', + 'configuration' => $rule->getConfiguration(), + ]); + $config_entity->save(); + + // @todo Add integrity check that node.field_integer is detected by Rules. + } + + /** + * Tests EventHandlerEntityBundle execution. + */ + public function testEntityBundleHandlerExecution() { + // Create a multi-value integer field for testing. + FieldStorageConfig::create([ + 'field_name' => 'field_integer', + 'type' => 'integer', + 'entity_type' => 'node', + 'cardinality' => FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED, + ])->save(); + FieldConfig::create([ + 'field_name' => 'field_integer', + 'entity_type' => 'node', + 'bundle' => 'page', + ])->save(); + + // Create test node with a bundle and field. + $entity_type_manager = $this->container->get('entity_type.manager'); + $entity_type_manager->getStorage('node_type') + ->create(['type' => 'page']) + ->save(); + $node = $entity_type_manager->getStorage('node') + ->create([ + 'title' => 'test', + 'type' => 'page', + // @todo set node.field_integer.0.value. + ]) + ->save(); + + // Create rule with an action 'rules_entity_presave:node–-page'. + $rule = $this->expressionManager->createRule(); + $rule->addAction('rules_test_log', + ContextConfig::create() + ->map('message', 'node.field_integer.0.value') + ); + $config_entity = $this->storage->create([ + 'id' => 'test_rule', + 'expression_id' => 'rules_rule', + 'event' => 'rules_entity_presave:node-–page', + 'configuration' => $rule->getConfiguration(), + ]); + $config_entity->save(); + + // @todo Dispatch presave. + $dispatcher = $this->container->get('event_dispatcher'); + // $dispatcher->dispatch('entity_presave', $node); + + // @todo Test that the action in the rule logged node value. + // $this->assertRulesLogEntryExists('test_user'); + } + +} From 46f1fbe2687db9873ccbe9f046d31d4ff29fcb46 Mon Sep 17 00:00:00 2001 From: milkovsky Date: Fri, 5 Feb 2016 18:31:42 +0100 Subject: [PATCH 05/30] Improved EventHandlerTest WIP. --- tests/src/Kernel/EventHandlerTest.php | 81 ++++++++++++--------------- 1 file changed, 35 insertions(+), 46 deletions(-) diff --git a/tests/src/Kernel/EventHandlerTest.php b/tests/src/Kernel/EventHandlerTest.php index 5add0e9b..bd694938 100644 --- a/tests/src/Kernel/EventHandlerTest.php +++ b/tests/src/Kernel/EventHandlerTest.php @@ -19,7 +19,10 @@ */ class EventHandlerTest extends RulesDrupalTestBase { - public static $modules = ['rules', 'rules_test', 'system', 'node', 'field']; + /** + * {@inheritdoc} + */ + public static $modules = ['rules', 'rules_test', 'system', 'node', 'field', 'user']; /** * The entity storage for Rules config entities. @@ -28,25 +31,31 @@ class EventHandlerTest extends RulesDrupalTestBase { */ protected $storage; + /** + * A node used for testing. + * + * @var \Drupal\node\NodeInterface + */ + protected $node; + /** * {@inheritdoc} */ public function setUp() { parent::setUp(); - $this->installConfig(['system']); - $this->installConfig(['field']); $this->installSchema('system', ['sequences']); + $this->installEntitySchema('user'); $this->installEntitySchema('node'); + $this->installConfig(['field']); $this->storage = $this->container->get('entity_type.manager')->getStorage('rules_reaction_rule'); - } - /** - * Tests EventHandlerEntityBundle configuration. - */ - public function testEntityBundleHandlerConfiguration() { - // Create a multi-value integer field for testing. + $entity_type_manager = $this->container->get('entity_type.manager'); + $entity_type_manager->getStorage('node_type') + ->create(['type' => 'page']) + ->save(); + FieldStorageConfig::create([ 'field_name' => 'field_integer', 'type' => 'integer', @@ -59,12 +68,17 @@ public function testEntityBundleHandlerConfiguration() { 'bundle' => 'page', ])->save(); - // Create test node with a bundle and field. - $entity_type_manager = $this->container->get('entity_type.manager'); - $entity_type_manager->getStorage('node_type') - ->create(['type' => 'page']) - ->save(); + $this->node = $entity_type_manager->getStorage('node') + ->create([ + 'title' => 'test', + 'type' => 'page', + ]); + } + /** + * Tests EventHandlerEntityBundle configuration. + */ + public function testEntityBundleHandlerConfiguration() { // Create rule with an action 'rules_entity_presave:node–-page'. $rule = $this->expressionManager->createRule(); $config_entity = $this->storage->create([ @@ -82,33 +96,9 @@ public function testEntityBundleHandlerConfiguration() { * Tests EventHandlerEntityBundle execution. */ public function testEntityBundleHandlerExecution() { - // Create a multi-value integer field for testing. - FieldStorageConfig::create([ - 'field_name' => 'field_integer', - 'type' => 'integer', - 'entity_type' => 'node', - 'cardinality' => FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED, - ])->save(); - FieldConfig::create([ - 'field_name' => 'field_integer', - 'entity_type' => 'node', - 'bundle' => 'page', - ])->save(); + $this->node->field_integer->setValue(['0' => 1, '1' => 2]); - // Create test node with a bundle and field. - $entity_type_manager = $this->container->get('entity_type.manager'); - $entity_type_manager->getStorage('node_type') - ->create(['type' => 'page']) - ->save(); - $node = $entity_type_manager->getStorage('node') - ->create([ - 'title' => 'test', - 'type' => 'page', - // @todo set node.field_integer.0.value. - ]) - ->save(); - - // Create rule with an action 'rules_entity_presave:node–-page'. + // Create rule with an action 'rules_entity_presave:node--page'. $rule = $this->expressionManager->createRule(); $rule->addAction('rules_test_log', ContextConfig::create() @@ -117,17 +107,16 @@ public function testEntityBundleHandlerExecution() { $config_entity = $this->storage->create([ 'id' => 'test_rule', 'expression_id' => 'rules_rule', - 'event' => 'rules_entity_presave:node-–page', + 'event' => 'rules_entity_presave:node--page', 'configuration' => $rule->getConfiguration(), ]); $config_entity->save(); - // @todo Dispatch presave. - $dispatcher = $this->container->get('event_dispatcher'); - // $dispatcher->dispatch('entity_presave', $node); + // @todo Better dispatch presave event. + $this->node->save(); - // @todo Test that the action in the rule logged node value. - // $this->assertRulesLogEntryExists('test_user'); + // Test that the action in the rule logged node value. + $this->assertRulesLogEntryExists('1'); } } From 066e4ecbb5701d5776a702b78c2c7fac7f50dc5c Mon Sep 17 00:00:00 2001 From: milkovsky Date: Wed, 10 Feb 2016 15:50:45 +0100 Subject: [PATCH 06/30] PR fixes. --- rules.rules.events.yml | 10 +++++----- ...e.php => ConfigurableEventHandlerBase.php} | 12 +++++------ src/EventHandler/EventHandlerEntityBundle.php | 7 ++++--- tests/src/Kernel/EventHandlerTest.php | 20 ++++++++++--------- 4 files changed, 26 insertions(+), 23 deletions(-) rename src/EventHandler/{EventHandlerBase.php => ConfigurableEventHandlerBase.php} (84%) diff --git a/rules.rules.events.yml b/rules.rules.events.yml index 35672709..ee4081e6 100644 --- a/rules.rules.events.yml +++ b/rules.rules.events.yml @@ -21,23 +21,23 @@ kernel.request: rules_entity_presave: label: 'Before saving an entity' deriver: '\Drupal\rules\Plugin\RulesEvent\EntityPresaveDeriver' - class: '\Drupal\rules\EventHandler\EventHandlerEntityBundle' + class: '\Drupal\rules\EventHandler\ConfigurableEventHandlerEntityBundle' rules_entity_delete: label: 'After deleting an entity' deriver: '\Drupal\rules\Plugin\RulesEvent\EntityDeleteDeriver' - class: '\Drupal\rules\EventHandler\EventHandlerEntityBundle' + class: '\Drupal\rules\EventHandler\ConfigurableEventHandlerEntityBundle' rules_entity_insert: label: 'After saving a new entity' deriver: '\Drupal\rules\Plugin\RulesEvent\EntityInsertDeriver' - class: '\Drupal\rules\EventHandler\EventHandlerEntityBundle' + class: '\Drupal\rules\EventHandler\ConfigurableEventHandlerEntityBundle' rules_entity_update: label: 'After updating an entity' deriver: '\Drupal\rules\Plugin\RulesEvent\EntityUpdateDeriver' - class: '\Drupal\rules\EventHandler\EventHandlerEntityBundle' + class: '\Drupal\rules\EventHandler\ConfigurableEventHandlerEntityBundle' rules_entity_view: label: 'Viewing an entity' deriver: '\Drupal\rules\Plugin\RulesEvent\EntityViewDeriver' - class: '\Drupal\rules\EventHandler\EventHandlerEntityBundle' + class: '\Drupal\rules\EventHandler\ConfigurableEventHandlerEntityBundle' rules_system_cron: label: 'Cron maintenance tasks are performed' category: 'System' diff --git a/src/EventHandler/EventHandlerBase.php b/src/EventHandler/ConfigurableEventHandlerBase.php similarity index 84% rename from src/EventHandler/EventHandlerBase.php rename to src/EventHandler/ConfigurableEventHandlerBase.php index 8f611e51..43abeae5 100644 --- a/src/EventHandler/EventHandlerBase.php +++ b/src/EventHandler/ConfigurableEventHandlerBase.php @@ -2,7 +2,7 @@ /** * @file - * Contains \Drupal\rules\EventHandler\EventHandlerBase. + * Contains \Drupal\rules\EventHandler\ConfigurableEventHandlerBase. */ namespace Drupal\rules\EventHandler; @@ -15,7 +15,7 @@ /** * Base class for event handler. */ -abstract class EventHandlerBase extends RulesDefaultEventHandler implements RulesConfigurableEventHandlerInterface { +abstract class ConfigurableEventHandlerBase extends RulesDefaultEventHandler implements RulesConfigurableEventHandlerInterface { /** * The event configuration. @@ -28,21 +28,21 @@ abstract class EventHandlerBase extends RulesDefaultEventHandler implements Rule * @inheritdoc */ public static function determineQualifiedEvents(Event $event, $event_name, array &$event_definition) { - return array(); + // Nothing to do by default. } /** * @inheritdoc */ public function summary() { - return ''; + // Nothing to do by default. } /** * @inheritdoc */ public function buildConfigurationForm(array $form, FormStateInterface $form_state) { - return $form; + // Nothing to do by default. } /** @@ -87,7 +87,7 @@ public function defaultConfiguration() { * @inheritdoc */ public function getEventNameSuffix() { - return ''; + // Nothing to do by default. } /** diff --git a/src/EventHandler/EventHandlerEntityBundle.php b/src/EventHandler/EventHandlerEntityBundle.php index 7209fba9..61b132d1 100644 --- a/src/EventHandler/EventHandlerEntityBundle.php +++ b/src/EventHandler/EventHandlerEntityBundle.php @@ -2,16 +2,17 @@ /** * @file - * Contains \Drupal\rules\EventHandler\EventHandlerEntityBundle. + * Contains \Drupal\rules\EventHandler\ConfigurableEventHandlerEntityBundle. */ namespace Drupal\rules\EventHandler; + use Symfony\Component\EventDispatcher\Event; /** * Exposes the bundle of an entity as event setting. */ -class EventHandlerEntityBundle extends EventHandlerBase { +class ConfigurableEventHandlerEntityBundle extends ConfigurableEventHandlerBase { /** * @inheritdoc @@ -19,7 +20,7 @@ class EventHandlerEntityBundle extends EventHandlerBase { public static function determineQualifiedEvents(Event $event, $event_name, array &$event_definition) { $events_suffixes = []; if ($event instanceof \Drupal\rules\Event\EntityEvent) { - $events[] = $event->getSubject()->bundle(); + $events_suffixes[] = $event->getSubject()->bundle(); } return $events_suffixes; } diff --git a/tests/src/Kernel/EventHandlerTest.php b/tests/src/Kernel/EventHandlerTest.php index bd694938..53e54625 100644 --- a/tests/src/Kernel/EventHandlerTest.php +++ b/tests/src/Kernel/EventHandlerTest.php @@ -10,7 +10,6 @@ use Drupal\Core\Field\FieldStorageDefinitionInterface; use Drupal\field\Entity\FieldConfig; use Drupal\field\Entity\FieldStorageConfig; -use Drupal\rules\Context\ContextConfig; /** * Tests events with qualified name. @@ -96,14 +95,12 @@ public function testEntityBundleHandlerConfiguration() { * Tests EventHandlerEntityBundle execution. */ public function testEntityBundleHandlerExecution() { - $this->node->field_integer->setValue(['0' => 1, '1' => 2]); + // @todo Add node.field_integer.0.value to rules log message, read result. + //$this->node->field_integer->setValue(['0' => 1, '1' => 2]); - // Create rule with an action 'rules_entity_presave:node--page'. + // Create rule with the 'rules_entity_presave:node--page' event. $rule = $this->expressionManager->createRule(); - $rule->addAction('rules_test_log', - ContextConfig::create() - ->map('message', 'node.field_integer.0.value') - ); + $rule->addAction('rules_test_log'); $config_entity = $this->storage->create([ 'id' => 'test_rule', 'expression_id' => 'rules_rule', @@ -112,11 +109,16 @@ public function testEntityBundleHandlerExecution() { ]); $config_entity->save(); - // @todo Better dispatch presave event. + // Trigger node save. $this->node->save(); + // @todo Should we better dispatch rules_entity_presave:node event instead? + /*$entity_type_id = $this->node->getEntityTypeId(); + $event = new EntityEvent($this->node, [$entity_type_id => $this->node]); + $event_dispatcher = \Drupal::service('event_dispatcher'); + $event_dispatcher->dispatch("rules_entity_presave:$entity_type_id", $event);*/ // Test that the action in the rule logged node value. - $this->assertRulesLogEntryExists('1'); + $this->assertRulesLogEntryExists('action called'); } } From 0f1a9e5ff39abe2be3141360fdbd61aba1822ca6 Mon Sep 17 00:00:00 2001 From: milkovsky Date: Wed, 10 Feb 2016 17:41:30 +0100 Subject: [PATCH 07/30] Dispatch events by base name of a configured event name. --- src/Core/RulesEventManager.php | 18 ++++++++++++++++++ src/Entity/ReactionRuleStorage.php | 2 ++ ...> ConfigurableEventHandlerEntityBundle.php} | 0 3 files changed, 20 insertions(+) rename src/EventHandler/{EventHandlerEntityBundle.php => ConfigurableEventHandlerEntityBundle.php} (100%) diff --git a/src/Core/RulesEventManager.php b/src/Core/RulesEventManager.php index 033f6d28..97ff125f 100644 --- a/src/Core/RulesEventManager.php +++ b/src/Core/RulesEventManager.php @@ -60,4 +60,22 @@ public function processDefinition(&$definition, $plugin_id) { } } + /** + * Returns the base name of a configured event name. + * + * For a configured event name like node_view--article the base event name + * node_view is returned. + * + * @return string + * The event base name. + */ + static public function rulesGetEventBaseName($event_name) { + // Cut off any suffix from a configured event name. + if (strpos($event_name, '--') !== FALSE) { + $parts = explode('--', $event_name, 2); + return $parts[0]; + } + return $event_name; + } + } diff --git a/src/Entity/ReactionRuleStorage.php b/src/Entity/ReactionRuleStorage.php index 1de2c0cf..e69af572 100644 --- a/src/Entity/ReactionRuleStorage.php +++ b/src/Entity/ReactionRuleStorage.php @@ -15,6 +15,7 @@ use Drupal\Core\Config\ConfigFactoryInterface; use Drupal\Component\Uuid\UuidInterface; use Drupal\Core\Language\LanguageManagerInterface; +use Drupal\rules\Core\RulesEventManager; use Symfony\Component\DependencyInjection\ContainerInterface; @@ -84,6 +85,7 @@ protected function getRegisteredEvents() { $events = []; foreach ($this->loadMultiple() as $rules_config) { $event = $rules_config->getEvent(); + $event = RulesEventManager::rulesGetEventBaseName($event); if ($event && !isset($events[$event])) { $events[$event] = $event; } diff --git a/src/EventHandler/EventHandlerEntityBundle.php b/src/EventHandler/ConfigurableEventHandlerEntityBundle.php similarity index 100% rename from src/EventHandler/EventHandlerEntityBundle.php rename to src/EventHandler/ConfigurableEventHandlerEntityBundle.php From ecce5578629d472e36fd60431c95876889ff154b Mon Sep 17 00:00:00 2001 From: milkovsky Date: Wed, 10 Feb 2016 17:56:52 +0100 Subject: [PATCH 08/30] Implemented testEntityBundleHandlerExecution. --- tests/src/Kernel/EventHandlerTest.php | 54 +++++++++++++++++++-------- 1 file changed, 38 insertions(+), 16 deletions(-) diff --git a/tests/src/Kernel/EventHandlerTest.php b/tests/src/Kernel/EventHandlerTest.php index 53e54625..ab3bb19f 100644 --- a/tests/src/Kernel/EventHandlerTest.php +++ b/tests/src/Kernel/EventHandlerTest.php @@ -10,6 +10,8 @@ use Drupal\Core\Field\FieldStorageDefinitionInterface; use Drupal\field\Entity\FieldConfig; use Drupal\field\Entity\FieldStorageConfig; +use Drupal\rules\Context\ContextConfig; +use Drupal\rules\Event\EntityEvent; /** * Tests events with qualified name. @@ -95,30 +97,50 @@ public function testEntityBundleHandlerConfiguration() { * Tests EventHandlerEntityBundle execution. */ public function testEntityBundleHandlerExecution() { - // @todo Add node.field_integer.0.value to rules log message, read result. - //$this->node->field_integer->setValue(['0' => 1, '1' => 2]); - - // Create rule with the 'rules_entity_presave:node--page' event. - $rule = $this->expressionManager->createRule(); - $rule->addAction('rules_test_log'); - $config_entity = $this->storage->create([ - 'id' => 'test_rule', + // Create rule1 with the 'rules_entity_presave:node--page' event. + $rule1 = $this->expressionManager->createRule(); + $rule1->addAction('rules_test_log', + ContextConfig::create() + ->map('message', 'node.field_integer.0.value') + ); + $config_entity1 = $this->storage->create([ + 'id' => 'test_rule1', 'expression_id' => 'rules_rule', 'event' => 'rules_entity_presave:node--page', - 'configuration' => $rule->getConfiguration(), + 'configuration' => $rule1->getConfiguration(), ]); - $config_entity->save(); + $config_entity1->save(); + + // Create rule2 with the 'rules_entity_presave:node' event. + $rule2 = $this->expressionManager->createRule(); + $rule2->addAction('rules_test_log', + ContextConfig::create() + ->map('message', 'node.field_integer.1.value') + ); + $config_entity2 = $this->storage->create([ + 'id' => 'test_rule2', + 'expression_id' => 'rules_rule', + 'event' => 'rules_entity_presave:node', + 'configuration' => $rule2->getConfiguration(), + ]); + $config_entity2->save(); + + // The logger instance has changed, refresh it. + $this->logger = $this->container->get('logger.channel.rules'); + + // Add node.field_integer.0.value to rules log message, read result. + $this->node->field_integer->setValue(['0' => 11, '1' => 22]); // Trigger node save. - $this->node->save(); - // @todo Should we better dispatch rules_entity_presave:node event instead? - /*$entity_type_id = $this->node->getEntityTypeId(); + $entity_type_id = $this->node->getEntityTypeId(); $event = new EntityEvent($this->node, [$entity_type_id => $this->node]); $event_dispatcher = \Drupal::service('event_dispatcher'); - $event_dispatcher->dispatch("rules_entity_presave:$entity_type_id", $event);*/ + $event_dispatcher->dispatch("rules_entity_presave:$entity_type_id", $event); - // Test that the action in the rule logged node value. - $this->assertRulesLogEntryExists('action called'); + // Test that the action in the rule1 logged node value. + $this->assertRulesLogEntryExists(11, 1); + // Test that the action in the rule2 logged node value. + $this->assertRulesLogEntryExists(22, 0); } } From 54c3cd4abdc25fb62f55d969b3234f9393d7916f Mon Sep 17 00:00:00 2001 From: milkovsky Date: Thu, 11 Feb 2016 14:03:34 +0100 Subject: [PATCH 09/30] PR fixes. --- src/Core/RulesEventManager.php | 10 ++++--- src/Entity/ReactionRuleStorage.php | 22 +++++++++++++- .../ConfigurableEventHandlerBase.php | 22 +++++++------- .../ConfigurableEventHandlerEntityBundle.php | 2 +- tests/src/Kernel/EventHandlerTest.php | 29 ++++--------------- 5 files changed, 45 insertions(+), 40 deletions(-) diff --git a/src/Core/RulesEventManager.php b/src/Core/RulesEventManager.php index 97ff125f..df8b702f 100644 --- a/src/Core/RulesEventManager.php +++ b/src/Core/RulesEventManager.php @@ -61,15 +61,17 @@ public function processDefinition(&$definition, $plugin_id) { } /** - * Returns the base name of a configured event name. + * Gets the base name of a configured event name. * - * For a configured event name like node_view--article the base event name - * node_view is returned. + * For a configured event name like {EVENT_NAME}--{SUFFIX}, the base event + * name {EVENT_NAME} is returned. * * @return string * The event base name. + * + * @see RulesConfigurableEventHandlerInterface::getEventNameSuffix() */ - static public function rulesGetEventBaseName($event_name) { + public function getEventBaseName($event_name) { // Cut off any suffix from a configured event name. if (strpos($event_name, '--') !== FALSE) { $parts = explode('--', $event_name, 2); diff --git a/src/Entity/ReactionRuleStorage.php b/src/Entity/ReactionRuleStorage.php index e69af572..29f02b42 100644 --- a/src/Entity/ReactionRuleStorage.php +++ b/src/Entity/ReactionRuleStorage.php @@ -40,6 +40,13 @@ class ReactionRuleStorage extends ConfigEntityStorage { */ protected $drupalKernel; + /** + * The event manager. + * + * @var RulesEventManager + */ + protected $eventManager; + /** * Constructs a ReactionRuleStorage object. * @@ -61,6 +68,19 @@ public function __construct(EntityTypeInterface $entity_type, ConfigFactoryInter $this->drupalKernel = $drupal_kernel; } + /** + * Gets the event manager. + * + * @return RulesEventManager + * The event manager. + */ + protected function eventManager() { + if (!$this->eventManager) { + $this->eventManager = new RulesEventManager($this->moduleHandler()); + } + return $this->eventManager; + } + /** * {@inheritdoc} */ @@ -85,7 +105,7 @@ protected function getRegisteredEvents() { $events = []; foreach ($this->loadMultiple() as $rules_config) { $event = $rules_config->getEvent(); - $event = RulesEventManager::rulesGetEventBaseName($event); + $event = $this->eventManager()->getEventBaseName($event); if ($event && !isset($events[$event])) { $events[$event] = $event; } diff --git a/src/EventHandler/ConfigurableEventHandlerBase.php b/src/EventHandler/ConfigurableEventHandlerBase.php index 43abeae5..e4590583 100644 --- a/src/EventHandler/ConfigurableEventHandlerBase.php +++ b/src/EventHandler/ConfigurableEventHandlerBase.php @@ -25,35 +25,35 @@ abstract class ConfigurableEventHandlerBase extends RulesDefaultEventHandler imp protected $configuration = array(); /** - * @inheritdoc + * {@inheritdoc} */ public static function determineQualifiedEvents(Event $event, $event_name, array &$event_definition) { // Nothing to do by default. } /** - * @inheritdoc + * {@inheritdoc} */ public function summary() { // Nothing to do by default. } /** - * @inheritdoc + * {@inheritdoc} */ public function buildConfigurationForm(array $form, FormStateInterface $form_state) { // Nothing to do by default. } /** - * @inheritdoc + * {@inheritdoc} */ public function validate() { // Nothing to check by default. } /** - * @inheritdoc + * {@inheritdoc} */ public function extractConfigurationFormValues(array &$form, FormStateInterface $form_state) { foreach ($this->defaultConfiguration() as $key => $configuration) { @@ -62,14 +62,14 @@ public function extractConfigurationFormValues(array &$form, FormStateInterface } /** - * @inheritdoc + * {@inheritdoc} */ public function getConfiguration() { return $this->configuration; } /** - * @inheritdoc + * {@inheritdoc} */ public function setConfiguration(array $configuration) { $this->configuration = $configuration + $this->defaultConfiguration(); @@ -77,28 +77,28 @@ public function setConfiguration(array $configuration) { } /** - * @inheritdoc + * {@inheritdoc} */ public function defaultConfiguration() { return array(); } /** - * @inheritdoc + * {@inheritdoc} */ public function getEventNameSuffix() { // Nothing to do by default. } /** - * @inheritdoc + * {@inheritdoc} */ public function refineContextDefinitions() { // Nothing to refine by default. } /** - * @inheritdoc + * {@inheritdoc} */ public function calculateDependencies() { // Nothing to calculate by default. diff --git a/src/EventHandler/ConfigurableEventHandlerEntityBundle.php b/src/EventHandler/ConfigurableEventHandlerEntityBundle.php index 61b132d1..65e11099 100644 --- a/src/EventHandler/ConfigurableEventHandlerEntityBundle.php +++ b/src/EventHandler/ConfigurableEventHandlerEntityBundle.php @@ -15,7 +15,7 @@ class ConfigurableEventHandlerEntityBundle extends ConfigurableEventHandlerBase { /** - * @inheritdoc + * {@inheritdoc} */ public static function determineQualifiedEvents(Event $event, $event_name, array &$event_definition) { $events_suffixes = []; diff --git a/tests/src/Kernel/EventHandlerTest.php b/tests/src/Kernel/EventHandlerTest.php index ab3bb19f..47c9d7b1 100644 --- a/tests/src/Kernel/EventHandlerTest.php +++ b/tests/src/Kernel/EventHandlerTest.php @@ -77,26 +77,11 @@ public function setUp() { } /** - * Tests EventHandlerEntityBundle configuration. - */ - public function testEntityBundleHandlerConfiguration() { - // Create rule with an action 'rules_entity_presave:node–-page'. - $rule = $this->expressionManager->createRule(); - $config_entity = $this->storage->create([ - 'id' => 'test_rule', - 'expression_id' => 'rules_rule', - 'event' => 'rules_entity_presave:node-–page', - 'configuration' => $rule->getConfiguration(), - ]); - $config_entity->save(); - - // @todo Add integrity check that node.field_integer is detected by Rules. - } - - /** - * Tests EventHandlerEntityBundle execution. + * Tests ConfigurableEventHandlerEntityBundle. + * + * @todo Add integrity check that node.field_integer is detected by Rules. */ - public function testEntityBundleHandlerExecution() { + public function testEntityBundleHandler() { // Create rule1 with the 'rules_entity_presave:node--page' event. $rule1 = $this->expressionManager->createRule(); $rule1->addAction('rules_test_log', @@ -107,8 +92,7 @@ public function testEntityBundleHandlerExecution() { 'id' => 'test_rule1', 'expression_id' => 'rules_rule', 'event' => 'rules_entity_presave:node--page', - 'configuration' => $rule1->getConfiguration(), - ]); + ])->setExpression($rule1); $config_entity1->save(); // Create rule2 with the 'rules_entity_presave:node' event. @@ -121,8 +105,7 @@ public function testEntityBundleHandlerExecution() { 'id' => 'test_rule2', 'expression_id' => 'rules_rule', 'event' => 'rules_entity_presave:node', - 'configuration' => $rule2->getConfiguration(), - ]); + ])->setExpression($rule2); $config_entity2->save(); // The logger instance has changed, refresh it. From 03ecf3a429a0698797c1eb32c941f48f8e2e2663 Mon Sep 17 00:00:00 2001 From: milkovsky Date: Thu, 11 Feb 2016 14:07:39 +0100 Subject: [PATCH 10/30] PR fixes. --- tests/src/Kernel/EventHandlerTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/src/Kernel/EventHandlerTest.php b/tests/src/Kernel/EventHandlerTest.php index 47c9d7b1..98aacf05 100644 --- a/tests/src/Kernel/EventHandlerTest.php +++ b/tests/src/Kernel/EventHandlerTest.php @@ -23,7 +23,7 @@ class EventHandlerTest extends RulesDrupalTestBase { /** * {@inheritdoc} */ - public static $modules = ['rules', 'rules_test', 'system', 'node', 'field', 'user']; + public static $modules = ['rules', 'system', 'node', 'field', 'user']; /** * The entity storage for Rules config entities. From 7fbae659fba6f628d410c11dcab1058323accdf1 Mon Sep 17 00:00:00 2001 From: milkovsky Date: Thu, 11 Feb 2016 14:08:09 +0100 Subject: [PATCH 11/30] PR fixes. --- src/EventHandler/ConfigurableEventHandlerBase.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/EventHandler/ConfigurableEventHandlerBase.php b/src/EventHandler/ConfigurableEventHandlerBase.php index e4590583..2cfd94bf 100644 --- a/src/EventHandler/ConfigurableEventHandlerBase.php +++ b/src/EventHandler/ConfigurableEventHandlerBase.php @@ -22,7 +22,7 @@ abstract class ConfigurableEventHandlerBase extends RulesDefaultEventHandler imp * * @var array */ - protected $configuration = array(); + protected $configuration = []; /** * {@inheritdoc} @@ -80,7 +80,7 @@ public function setConfiguration(array $configuration) { * {@inheritdoc} */ public function defaultConfiguration() { - return array(); + return []; } /** From 8e4af1be0772b70385bbfca72551a0065d542104 Mon Sep 17 00:00:00 2001 From: milkovsky Date: Thu, 11 Feb 2016 16:06:33 +0100 Subject: [PATCH 12/30] PR fixes. --- src/Core/RulesEventManager.php | 2 +- src/Entity/ReactionRuleStorage.php | 4 +- .../ConfigurableEventHandlerBase.php | 50 ------------------- .../ConfigurableEventHandlerEntityBundle.php | 43 ++++++++++++++++ ...t.php => ConfigurableEventHandlerTest.php} | 9 ++-- 5 files changed, 52 insertions(+), 56 deletions(-) rename tests/src/Kernel/{EventHandlerTest.php => ConfigurableEventHandlerTest.php} (91%) diff --git a/src/Core/RulesEventManager.php b/src/Core/RulesEventManager.php index df8b702f..160f7325 100644 --- a/src/Core/RulesEventManager.php +++ b/src/Core/RulesEventManager.php @@ -69,7 +69,7 @@ public function processDefinition(&$definition, $plugin_id) { * @return string * The event base name. * - * @see RulesConfigurableEventHandlerInterface::getEventNameSuffix() + * @see \Drupal\rules\Core\RulesConfigurableEventHandlerInterface::getEventNameSuffix() */ public function getEventBaseName($event_name) { // Cut off any suffix from a configured event name. diff --git a/src/Entity/ReactionRuleStorage.php b/src/Entity/ReactionRuleStorage.php index 29f02b42..eec4da22 100644 --- a/src/Entity/ReactionRuleStorage.php +++ b/src/Entity/ReactionRuleStorage.php @@ -43,7 +43,7 @@ class ReactionRuleStorage extends ConfigEntityStorage { /** * The event manager. * - * @var RulesEventManager + * @var \Drupal\rules\Core\RulesEventManager */ protected $eventManager; @@ -71,7 +71,7 @@ public function __construct(EntityTypeInterface $entity_type, ConfigFactoryInter /** * Gets the event manager. * - * @return RulesEventManager + * @return \Drupal\rules\Core\RulesEventManager * The event manager. */ protected function eventManager() { diff --git a/src/EventHandler/ConfigurableEventHandlerBase.php b/src/EventHandler/ConfigurableEventHandlerBase.php index 2cfd94bf..9f88c8d8 100644 --- a/src/EventHandler/ConfigurableEventHandlerBase.php +++ b/src/EventHandler/ConfigurableEventHandlerBase.php @@ -10,7 +10,6 @@ use Drupal\Core\Form\FormStateInterface; use Drupal\rules\Core\RulesConfigurableEventHandlerInterface; use Drupal\rules\Core\RulesDefaultEventHandler; -use Symfony\Component\EventDispatcher\Event; /** * Base class for event handler. @@ -24,34 +23,6 @@ abstract class ConfigurableEventHandlerBase extends RulesDefaultEventHandler imp */ protected $configuration = []; - /** - * {@inheritdoc} - */ - public static function determineQualifiedEvents(Event $event, $event_name, array &$event_definition) { - // Nothing to do by default. - } - - /** - * {@inheritdoc} - */ - public function summary() { - // Nothing to do by default. - } - - /** - * {@inheritdoc} - */ - public function buildConfigurationForm(array $form, FormStateInterface $form_state) { - // Nothing to do by default. - } - - /** - * {@inheritdoc} - */ - public function validate() { - // Nothing to check by default. - } - /** * {@inheritdoc} */ @@ -83,25 +54,4 @@ public function defaultConfiguration() { return []; } - /** - * {@inheritdoc} - */ - public function getEventNameSuffix() { - // Nothing to do by default. - } - - /** - * {@inheritdoc} - */ - public function refineContextDefinitions() { - // Nothing to refine by default. - } - - /** - * {@inheritdoc} - */ - public function calculateDependencies() { - // Nothing to calculate by default. - } - } diff --git a/src/EventHandler/ConfigurableEventHandlerEntityBundle.php b/src/EventHandler/ConfigurableEventHandlerEntityBundle.php index 65e11099..86baa041 100644 --- a/src/EventHandler/ConfigurableEventHandlerEntityBundle.php +++ b/src/EventHandler/ConfigurableEventHandlerEntityBundle.php @@ -7,6 +7,7 @@ namespace Drupal\rules\EventHandler; +use Drupal\Core\Form\FormStateInterface; use Symfony\Component\EventDispatcher\Event; /** @@ -25,4 +26,46 @@ public static function determineQualifiedEvents(Event $event, $event_name, array return $events_suffixes; } + /** + * {@inheritdoc} + */ + public function summary() { + // Nothing to do by default. + } + + /** + * {@inheritdoc} + */ + public function buildConfigurationForm(array $form, FormStateInterface $form_state) { + // Nothing to do by default. + } + + /** + * {@inheritdoc} + */ + public function validate() { + // Nothing to check by default. + } + + /** + * {@inheritdoc} + */ + public function getEventNameSuffix() { + // Nothing to do by default. + } + + /** + * {@inheritdoc} + */ + public function refineContextDefinitions() { + // Nothing to refine by default. + } + + /** + * {@inheritdoc} + */ + public function calculateDependencies() { + // Nothing to calculate by default. + } + } diff --git a/tests/src/Kernel/EventHandlerTest.php b/tests/src/Kernel/ConfigurableEventHandlerTest.php similarity index 91% rename from tests/src/Kernel/EventHandlerTest.php rename to tests/src/Kernel/ConfigurableEventHandlerTest.php index 98aacf05..28c2bfa3 100644 --- a/tests/src/Kernel/EventHandlerTest.php +++ b/tests/src/Kernel/ConfigurableEventHandlerTest.php @@ -2,7 +2,7 @@ /** * @file - * Contains \Drupal\Tests\rules\Integration\Engine\EventHandlerTest. + * Contains \Drupal\Tests\rules\Integration\Engine\ConfigurableEventHandlerTest. */ namespace Drupal\Tests\rules\Kernel; @@ -18,7 +18,7 @@ * * @group rules */ -class EventHandlerTest extends RulesDrupalTestBase { +class ConfigurableEventHandlerTest extends RulesDrupalTestBase { /** * {@inheritdoc} @@ -79,9 +79,12 @@ public function setUp() { /** * Tests ConfigurableEventHandlerEntityBundle. * + * Test that rules are triggered correctly based upon the fully qualified + * event name as well as the base event name. + * * @todo Add integrity check that node.field_integer is detected by Rules. */ - public function testEntityBundleHandler() { + public function testConfigurableEventHandler() { // Create rule1 with the 'rules_entity_presave:node--page' event. $rule1 = $this->expressionManager->createRule(); $rule1->addAction('rules_test_log', From b57e33d5748d80d1a85624e834595203ba227f26 Mon Sep 17 00:00:00 2001 From: milkovsky Date: Thu, 11 Feb 2016 18:11:04 +0100 Subject: [PATCH 13/30] Change rules config to have multiple events. --- config/schema/rules.schema.yml | 36 +++++++++++++++---- src/Engine/RulesComponent.php | 11 +++--- src/Entity/ReactionRuleConfig.php | 18 ++++++---- src/Entity/ReactionRuleStorage.php | 18 ++++++---- .../GenericEventSubscriber.php | 2 +- src/Form/ReactionRuleAddForm.php | 3 +- src/Form/ReactionRuleEditForm.php | 17 +++++---- tests/src/Kernel/EventIntegrationTest.php | 2 +- 8 files changed, 73 insertions(+), 34 deletions(-) diff --git a/config/schema/rules.schema.yml b/config/schema/rules.schema.yml index 4e15b874..d225fb4a 100644 --- a/config/schema/rules.schema.yml +++ b/config/schema/rules.schema.yml @@ -49,9 +49,21 @@ rules.reaction.*: label: type: label label: 'Label' - event: - type: string - label: 'Event' + events: + type: sequence + label: 'Events' + sequence: + type: mapping + label: 'Event' + mapping: + event_name: + type: string + label: 'Name' + configuration: + type: sequence + label: 'Configuration' + sequence: + type: mapping module: type: string label: 'Module' @@ -194,9 +206,21 @@ rules_expression.rules_reaction_rule: uuid: type: string label: 'UUID' - event: - type: string - label: 'Event' + events: + type: sequence + label: 'Events' + sequence: + type: mapping + label: 'Event' + mapping: + event_name: + type: string + label: 'Name' + configuration: + type: sequence + label: 'Configuration' + sequence: + type: mapping conditions: type: rules_expression.[id] label: 'Conditions' diff --git a/src/Engine/RulesComponent.php b/src/Engine/RulesComponent.php index 2788ab59..e65377a4 100644 --- a/src/Engine/RulesComponent.php +++ b/src/Engine/RulesComponent.php @@ -125,11 +125,12 @@ public function getContextDefinitions() { */ public function addContextDefinitionsFrom(ConfigEntityInterface $rules_config) { if ($rules_config instanceof ReactionRuleConfig) { - $event_name = $rules_config->getEvent(); - // @todo Use setter injection for the service. - $event_definition = \Drupal::service('plugin.manager.rules_event')->getDefinition($event_name); - foreach ($event_definition['context'] as $context_name => $context_definition) { - $this->addContextDefinition($context_name, $context_definition); + foreach ($rules_config->getEvents() as $event) { + // @todo Use setter injection for the service. + $event_definition = \Drupal::service('plugin.manager.rules_event')->getDefinition($event['event_name']); + foreach ($event_definition['context'] as $context_name => $context_definition) { + $this->addContextDefinition($context_name, $context_definition); + } } } return $this; diff --git a/src/Entity/ReactionRuleConfig.php b/src/Entity/ReactionRuleConfig.php index d86c8a0a..c3d34423 100644 --- a/src/Entity/ReactionRuleConfig.php +++ b/src/Entity/ReactionRuleConfig.php @@ -36,7 +36,7 @@ * config_export = { * "id", * "label", - * "event", + * "events", * "module", * "description", * "tag", @@ -121,11 +121,15 @@ class ReactionRuleConfig extends ConfigEntityBase { protected $module = 'rules'; /** - * The event name this reaction rule is reacting on. + * The events this reaction rule is reacting on. * - * @var string + * Events array, key - numeric index, value - event array with next structure: + * - event_name: string with the event machine name. + * - configuration: an array containing the event configuration. + * + * @var array */ - protected $event; + protected $events; /** * Sets a Rules expression instance for this Reaction rule. @@ -208,10 +212,10 @@ public function getTag() { } /** - * Returns the event on which this rule will trigger. + * Returns the array of events on which this rule will trigger. */ - public function getEvent() { - return $this->event; + public function getEvents() { + return $this->events; } /** diff --git a/src/Entity/ReactionRuleStorage.php b/src/Entity/ReactionRuleStorage.php index 1de2c0cf..7a4f88b9 100644 --- a/src/Entity/ReactionRuleStorage.php +++ b/src/Entity/ReactionRuleStorage.php @@ -83,9 +83,10 @@ public static function createInstance(ContainerInterface $container, EntityTypeI protected function getRegisteredEvents() { $events = []; foreach ($this->loadMultiple() as $rules_config) { - $event = $rules_config->getEvent(); - if ($event && !isset($events[$event])) { - $events[$event] = $event; + foreach ($rules_config->getEvents() as $event) { + if ($event && !isset($events[$event['event_name']])) { + $events[$event['event_name']] = $event['event_name']; + } } } return $events; @@ -106,10 +107,13 @@ public function save(EntityInterface $entity) { // After the reaction rule is saved, we need to rebuild the container, // otherwise the reaction rule will not fire. However, we can do an - // optimization: if the event was already registered before, we do not have - // to rebuild the container. - if (empty($events_before[$entity->getEvent()])) { - $this->drupalKernel->rebuildContainer(); + // optimization: if every event was already registered before, we do not + // have to rebuild the container. + foreach ($entity->getEvents() as $event) { + if (empty($events_before[$event['event_name']])) { + $this->drupalKernel->rebuildContainer(); + break; + } } return $return; diff --git a/src/EventSubscriber/GenericEventSubscriber.php b/src/EventSubscriber/GenericEventSubscriber.php index 9f591b9c..f4a03c8d 100644 --- a/src/EventSubscriber/GenericEventSubscriber.php +++ b/src/EventSubscriber/GenericEventSubscriber.php @@ -125,7 +125,7 @@ public function onRulesEvent(Event $event, $event_name) { // another rule. foreach ($triggered_events as $triggered_event) { // @todo Only load active reaction rules here. - $configs = $storage->loadByProperties(['event' => $triggered_event]); + $configs = $storage->loadByProperties(['events.*.event_name' => $triggered_event]); // Loop over all rules and execute them. foreach ($configs as $config) { diff --git a/src/Form/ReactionRuleAddForm.php b/src/Form/ReactionRuleAddForm.php index 2fb521bd..ab26b69b 100644 --- a/src/Form/ReactionRuleAddForm.php +++ b/src/Form/ReactionRuleAddForm.php @@ -65,7 +65,8 @@ public function form(array $form, FormStateInterface $form_state) { } } - $form['event'] = [ + $form['events']['#tree'] = TRUE; + $form['events'][]['event_name'] = [ '#type' => 'select', '#title' => $this->t('React on event'), '#options' => $options, diff --git a/src/Form/ReactionRuleEditForm.php b/src/Form/ReactionRuleEditForm.php index 8e47d496..9e8b936c 100644 --- a/src/Form/ReactionRuleEditForm.php +++ b/src/Form/ReactionRuleEditForm.php @@ -48,12 +48,17 @@ public static function create(ContainerInterface $container) { public function form(array $form, FormStateInterface $form_state) { $this->addLockInformation($form); - $event_name = $this->entity->getEvent(); - $event_definition = $this->eventManager->getDefinition($event_name); - $form['event']['#markup'] = $this->t('Event: @label (@name)', [ - '@label' => $event_definition['label'], - '@name' => $event_name, - ]); + foreach ($this->entity->getEvents() as $key => $event) { + $event_definition = $this->eventManager->getDefinition($event['event_name']); + $form['event'][$key] = [ + '#type' => 'item', + '#title' => $this->t('Events') . ':', + '#markup' => $this->t('@label (@name)', [ + '@label' => $event_definition['label'], + '@name' => $event['event_name'], + ]), + ]; + } $form_handler = $this->entity->getExpression()->getFormHandler(); $form = $form_handler->form($form, $form_state); return parent::form($form, $form_state); diff --git a/tests/src/Kernel/EventIntegrationTest.php b/tests/src/Kernel/EventIntegrationTest.php index a13f551c..c21a2161 100644 --- a/tests/src/Kernel/EventIntegrationTest.php +++ b/tests/src/Kernel/EventIntegrationTest.php @@ -161,7 +161,7 @@ public function testInitEvent() { $config_entity = $this->storage->create([ 'id' => 'test_rule', 'expression_id' => 'rules_rule', - 'event' => KernelEvents::REQUEST, + 'events' => [['event_name' => KernelEvents::REQUEST]], 'configuration' => $rule->getConfiguration(), ]); $config_entity->save(); From 7d0d7e2bc2ab0657f1538ad50916edfc1e404f69 Mon Sep 17 00:00:00 2001 From: milkovsky Date: Thu, 11 Feb 2016 18:26:01 +0100 Subject: [PATCH 14/30] Tests for multiple events. --- tests/src/Kernel/EventIntegrationTest.php | 42 ++++++++++++++++++++--- 1 file changed, 38 insertions(+), 4 deletions(-) diff --git a/tests/src/Kernel/EventIntegrationTest.php b/tests/src/Kernel/EventIntegrationTest.php index c21a2161..50cfc73c 100644 --- a/tests/src/Kernel/EventIntegrationTest.php +++ b/tests/src/Kernel/EventIntegrationTest.php @@ -54,7 +54,7 @@ public function testUserLoginEvent() { $config_entity = $this->storage->create([ 'id' => 'test_rule', 'expression_id' => 'rules_rule', - 'event' => 'rules_user_login', + 'events' => [['event_name' => 'rules_user_login']], 'configuration' => $rule->getConfiguration(), ]); $config_entity->save(); @@ -81,7 +81,7 @@ public function testUserLogoutEvent() { $config_entity = $this->storage->create([ 'id' => 'test_rule', 'expression_id' => 'rules_rule', - 'event' => 'rules_user_logout', + 'events' => [['event_name' => 'rules_user_logout']], 'configuration' => $rule->getConfiguration(), ]); $config_entity->save(); @@ -108,7 +108,7 @@ public function testCronEvent() { $config_entity = $this->storage->create([ 'id' => 'test_rule', 'expression_id' => 'rules_rule', - 'event' => 'rules_system_cron', + 'events' => [['event_name' => 'rules_system_cron']], 'configuration' => $rule->getConfiguration(), ]); $config_entity->save(); @@ -134,7 +134,7 @@ public function testSystemLoggerEvent() { $config_entity = $this->storage->create([ 'id' => 'test_rule', 'expression_id' => 'rules_rule', - 'event' => 'rules_system_logger_event', + 'events' => [['event_name' => 'rules_system_logger_event']], 'configuration' => $rule->getConfiguration(), ]); $config_entity->save(); @@ -185,4 +185,38 @@ public function testInitEvent() { $this->assertRulesLogEntryExists('action called'); } + /** + * Test that rules config supports multiple events. + */ + public function testMultipleEvents() { + $rule = $this->expressionManager->createRule(); + $rule->addCondition('rules_test_true'); + $rule->addAction('rules_test_log'); + + $config_entity = $this->storage->create([ + 'id' => 'test_rule', + 'expression_id' => 'rules_rule', + 'events' => [ + ['event_name' => 'rules_user_login'], + ['event_name' => 'rules_user_logout'], + ], + 'configuration' => $rule->getConfiguration(), + ]); + $config_entity->save(); + + // The logger instance has changed, refresh it. + $this->logger = $this->container->get('logger.channel.rules'); + + $account = User::create(['name' => 'test_user']); + // Invoke the hook manually which should trigger the rules_user_login event. + rules_user_login($account); + // Invoke the hook manually which should trigger the rules_user_logout + // event. + rules_user_logout($account); + + // Test that the action in the rule logged something. + $this->assertRulesLogEntryExists('action called'); + $this->assertRulesLogEntryExists('action called', 1); + } + } From 87dca7d0d323776b23bb823a49dfca3f1045c118 Mon Sep 17 00:00:00 2001 From: milkovsky Date: Mon, 15 Feb 2016 11:40:56 +0100 Subject: [PATCH 15/30] PR fixes. --- config/schema/rules.schema.yml | 32 ----------------------- src/Engine/RulesComponent.php | 4 +-- src/Entity/ReactionRuleConfig.php | 25 ++++++++++++++++-- src/Entity/ReactionRuleStorage.php | 10 +++---- src/Form/ReactionRuleEditForm.php | 6 ++--- tests/src/Kernel/EventIntegrationTest.php | 10 +++---- 6 files changed, 38 insertions(+), 49 deletions(-) diff --git a/config/schema/rules.schema.yml b/config/schema/rules.schema.yml index d225fb4a..75cbcb76 100644 --- a/config/schema/rules.schema.yml +++ b/config/schema/rules.schema.yml @@ -196,38 +196,6 @@ rules_expression.rules_rule: type: rules_expression.[id] label: 'Actions' -rules_expression.rules_reaction_rule: - type: rules_expression - label: "Reaction Rule" - mapping: - id: - type: string - label: 'Plugin ID' - uuid: - type: string - label: 'UUID' - events: - type: sequence - label: 'Events' - sequence: - type: mapping - label: 'Event' - mapping: - event_name: - type: string - label: 'Name' - configuration: - type: sequence - label: 'Configuration' - sequence: - type: mapping - conditions: - type: rules_expression.[id] - label: 'Conditions' - actions: - type: rules_expression.[id] - label: 'Actions' - rules.context.definition: type: mapping label: 'Context definition' diff --git a/src/Engine/RulesComponent.php b/src/Engine/RulesComponent.php index e65377a4..0d720f2a 100644 --- a/src/Engine/RulesComponent.php +++ b/src/Engine/RulesComponent.php @@ -125,9 +125,9 @@ public function getContextDefinitions() { */ public function addContextDefinitionsFrom(ConfigEntityInterface $rules_config) { if ($rules_config instanceof ReactionRuleConfig) { - foreach ($rules_config->getEvents() as $event) { + foreach ($rules_config->getEventNames() as $event_name) { // @todo Use setter injection for the service. - $event_definition = \Drupal::service('plugin.manager.rules_event')->getDefinition($event['event_name']); + $event_definition = \Drupal::service('plugin.manager.rules_event')->getDefinition($event_name); foreach ($event_definition['context'] as $context_name => $context_definition) { $this->addContextDefinition($context_name, $context_definition); } diff --git a/src/Entity/ReactionRuleConfig.php b/src/Entity/ReactionRuleConfig.php index c3d34423..fce61480 100644 --- a/src/Entity/ReactionRuleConfig.php +++ b/src/Entity/ReactionRuleConfig.php @@ -123,7 +123,8 @@ class ReactionRuleConfig extends ConfigEntityBase { /** * The events this reaction rule is reacting on. * - * Events array, key - numeric index, value - event array with next structure: + * Events array. The array is numerically indexed and contains arrays with the + * following structure: * - event_name: string with the event machine name. * - configuration: an array containing the event configuration. * @@ -212,12 +213,32 @@ public function getTag() { } /** - * Returns the array of events on which this rule will trigger. + * Gets configuration of all events the rule is reacting on. + * + * @return array + * The events array. The array is numerically indexed and contains arrays + * with the following structure: + * - event_name: string with the event machine name. + * - configuration: an array containing the event configuration. */ public function getEvents() { return $this->events; } + /** + * Gets fully qualified names of all events the rule is reacting on. + * + * @return string[] + * The array of fully qualified event names of the rule. + */ + public function getEventNames() { + $names = []; + foreach ($this->events as $event) { + $names[] = $event['event_name']; + } + return $names; + } + /** * {@inheritdoc} */ diff --git a/src/Entity/ReactionRuleStorage.php b/src/Entity/ReactionRuleStorage.php index 7a4f88b9..50dacac8 100644 --- a/src/Entity/ReactionRuleStorage.php +++ b/src/Entity/ReactionRuleStorage.php @@ -83,9 +83,9 @@ public static function createInstance(ContainerInterface $container, EntityTypeI protected function getRegisteredEvents() { $events = []; foreach ($this->loadMultiple() as $rules_config) { - foreach ($rules_config->getEvents() as $event) { - if ($event && !isset($events[$event['event_name']])) { - $events[$event['event_name']] = $event['event_name']; + foreach ($rules_config->getEventNames() as $event_name) { + if (!isset($events[$event_name])) { + $events[$event_name] = $event_name; } } } @@ -109,8 +109,8 @@ public function save(EntityInterface $entity) { // otherwise the reaction rule will not fire. However, we can do an // optimization: if every event was already registered before, we do not // have to rebuild the container. - foreach ($entity->getEvents() as $event) { - if (empty($events_before[$event['event_name']])) { + foreach ($entity->getEventNames() as $event_name) { + if (empty($events_before[$event_name])) { $this->drupalKernel->rebuildContainer(); break; } diff --git a/src/Form/ReactionRuleEditForm.php b/src/Form/ReactionRuleEditForm.php index 9e8b936c..311be4ef 100644 --- a/src/Form/ReactionRuleEditForm.php +++ b/src/Form/ReactionRuleEditForm.php @@ -48,14 +48,14 @@ public static function create(ContainerInterface $container) { public function form(array $form, FormStateInterface $form_state) { $this->addLockInformation($form); - foreach ($this->entity->getEvents() as $key => $event) { - $event_definition = $this->eventManager->getDefinition($event['event_name']); + foreach ($this->entity->getEventNames() as $key => $event_name) { + $event_definition = $this->eventManager->getDefinition($event_name); $form['event'][$key] = [ '#type' => 'item', '#title' => $this->t('Events') . ':', '#markup' => $this->t('@label (@name)', [ '@label' => $event_definition['label'], - '@name' => $event['event_name'], + '@name' => $event_name, ]), ]; } diff --git a/tests/src/Kernel/EventIntegrationTest.php b/tests/src/Kernel/EventIntegrationTest.php index 50cfc73c..686be03d 100644 --- a/tests/src/Kernel/EventIntegrationTest.php +++ b/tests/src/Kernel/EventIntegrationTest.php @@ -196,12 +196,12 @@ public function testMultipleEvents() { $config_entity = $this->storage->create([ 'id' => 'test_rule', 'expression_id' => 'rules_rule', - 'events' => [ - ['event_name' => 'rules_user_login'], - ['event_name' => 'rules_user_logout'], - ], - 'configuration' => $rule->getConfiguration(), ]); + $config_entity->set('events', [ + ['event_name' => 'rules_user_login'], + ['event_name' => 'rules_user_logout'], + ]); + $config_entity->set('configuration', $rule->getConfiguration()); $config_entity->save(); // The logger instance has changed, refresh it. From a58f03a9240acd1b6ce8e0cba81a5167081d161c Mon Sep 17 00:00:00 2001 From: milkovsky Date: Mon, 15 Feb 2016 18:26:55 +0100 Subject: [PATCH 16/30] Inject the Rules event manager. --- src/Entity/ReactionRuleStorage.php | 23 +++++++---------------- 1 file changed, 7 insertions(+), 16 deletions(-) diff --git a/src/Entity/ReactionRuleStorage.php b/src/Entity/ReactionRuleStorage.php index eec4da22..e03cab6d 100644 --- a/src/Entity/ReactionRuleStorage.php +++ b/src/Entity/ReactionRuleStorage.php @@ -60,25 +60,15 @@ class ReactionRuleStorage extends ConfigEntityStorage { * The language manager. * @param \Drupal\Core\State\StateInterface $state_service * The state service. + * @param \Drupal\rules\Core\RulesEventManager $event_manager + * The Rules event manager. */ - public function __construct(EntityTypeInterface $entity_type, ConfigFactoryInterface $config_factory, UuidInterface $uuid_service, LanguageManagerInterface $language_manager, StateInterface $state_service, DrupalKernelInterface $drupal_kernel) { + public function __construct(EntityTypeInterface $entity_type, ConfigFactoryInterface $config_factory, UuidInterface $uuid_service, LanguageManagerInterface $language_manager, StateInterface $state_service, DrupalKernelInterface $drupal_kernel, RulesEventManager $event_manager) { parent::__construct($entity_type, $config_factory, $uuid_service, $language_manager); $this->stateService = $state_service; $this->drupalKernel = $drupal_kernel; - } - - /** - * Gets the event manager. - * - * @return \Drupal\rules\Core\RulesEventManager - * The event manager. - */ - protected function eventManager() { - if (!$this->eventManager) { - $this->eventManager = new RulesEventManager($this->moduleHandler()); - } - return $this->eventManager; + $this->eventManager = $event_manager; } /** @@ -91,7 +81,8 @@ public static function createInstance(ContainerInterface $container, EntityTypeI $container->get('uuid'), $container->get('language_manager'), $container->get('state'), - $container->get('kernel') + $container->get('kernel'), + $container->get('plugin.manager.rules_event') ); } @@ -105,7 +96,7 @@ protected function getRegisteredEvents() { $events = []; foreach ($this->loadMultiple() as $rules_config) { $event = $rules_config->getEvent(); - $event = $this->eventManager()->getEventBaseName($event); + $event = $this->eventManager->getEventBaseName($event); if ($event && !isset($events[$event])) { $events[$event] = $event; } From cb7f7623505c6bc67c6f21b17404f8ce4c07f648 Mon Sep 17 00:00:00 2001 From: milkovsky Date: Tue, 16 Feb 2016 10:04:38 +0100 Subject: [PATCH 17/30] Code formatting. --- src/Entity/ReactionRuleConfig.php | 8 ++++---- src/Form/ReactionRuleEditForm.php | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/Entity/ReactionRuleConfig.php b/src/Entity/ReactionRuleConfig.php index fce61480..7b8c1ddc 100644 --- a/src/Entity/ReactionRuleConfig.php +++ b/src/Entity/ReactionRuleConfig.php @@ -125,8 +125,8 @@ class ReactionRuleConfig extends ConfigEntityBase { * * Events array. The array is numerically indexed and contains arrays with the * following structure: - * - event_name: string with the event machine name. - * - configuration: an array containing the event configuration. + * - event_name: String with the event machine name. + * - configuration: An array containing the event configuration. * * @var array */ @@ -218,8 +218,8 @@ public function getTag() { * @return array * The events array. The array is numerically indexed and contains arrays * with the following structure: - * - event_name: string with the event machine name. - * - configuration: an array containing the event configuration. + * - event_name: String with the event machine name. + * - configuration: An array containing the event configuration. */ public function getEvents() { return $this->events; diff --git a/src/Form/ReactionRuleEditForm.php b/src/Form/ReactionRuleEditForm.php index 311be4ef..b41df04e 100644 --- a/src/Form/ReactionRuleEditForm.php +++ b/src/Form/ReactionRuleEditForm.php @@ -52,7 +52,7 @@ public function form(array $form, FormStateInterface $form_state) { $event_definition = $this->eventManager->getDefinition($event_name); $form['event'][$key] = [ '#type' => 'item', - '#title' => $this->t('Events') . ':', + '#title' => $this->t('Events:'), '#markup' => $this->t('@label (@name)', [ '@label' => $event_definition['label'], '@name' => $event_name, From 944aa09ca1c2b37d8b8fe93343c2cac983a82c33 Mon Sep 17 00:00:00 2001 From: milkovsky Date: Thu, 18 Feb 2016 16:46:11 +0100 Subject: [PATCH 18/30] After merge fix. --- src/Entity/ReactionRuleConfig.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Entity/ReactionRuleConfig.php b/src/Entity/ReactionRuleConfig.php index 565c6c13..830169d2 100644 --- a/src/Entity/ReactionRuleConfig.php +++ b/src/Entity/ReactionRuleConfig.php @@ -174,7 +174,7 @@ public function getExpression() { */ public function getComponent() { $component = RulesComponent::create($this->getExpression()); - $component->addContextDefinitionsForEvents([$this->getEvent()]); + $component->addContextDefinitionsForEvents($this->getEventNames()); return $component; } From 9ead81eecc9ad76ad5dfd909da195780f52822d1 Mon Sep 17 00:00:00 2001 From: milkovsky Date: Thu, 18 Feb 2016 16:53:14 +0100 Subject: [PATCH 19/30] Initialize events []. --- src/Entity/ReactionRuleConfig.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Entity/ReactionRuleConfig.php b/src/Entity/ReactionRuleConfig.php index 830169d2..4b7395c3 100644 --- a/src/Entity/ReactionRuleConfig.php +++ b/src/Entity/ReactionRuleConfig.php @@ -130,7 +130,7 @@ class ReactionRuleConfig extends ConfigEntityBase { * * @var array */ - protected $events; + protected $events = []; /** * Sets a Rules expression instance for this Reaction rule. From 92aacdc0b1878f3005c77b66acb6e9056f9b94e9 Mon Sep 17 00:00:00 2001 From: milkovsky Date: Thu, 18 Feb 2016 18:34:35 +0100 Subject: [PATCH 20/30] Fix test after merge. --- tests/src/Kernel/ConfigurableEventHandlerTest.php | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/tests/src/Kernel/ConfigurableEventHandlerTest.php b/tests/src/Kernel/ConfigurableEventHandlerTest.php index 28c2bfa3..084ec8bb 100644 --- a/tests/src/Kernel/ConfigurableEventHandlerTest.php +++ b/tests/src/Kernel/ConfigurableEventHandlerTest.php @@ -94,8 +94,12 @@ public function testConfigurableEventHandler() { $config_entity1 = $this->storage->create([ 'id' => 'test_rule1', 'expression_id' => 'rules_rule', - 'event' => 'rules_entity_presave:node--page', - ])->setExpression($rule1); + 'event' => '', + ]); + $config_entity1->set('events', [ + ['event_name' => 'rules_entity_presave:node--page'], + ]); + $config_entity1->set('configuration', $rule1->getConfiguration()); $config_entity1->save(); // Create rule2 with the 'rules_entity_presave:node' event. @@ -107,8 +111,11 @@ public function testConfigurableEventHandler() { $config_entity2 = $this->storage->create([ 'id' => 'test_rule2', 'expression_id' => 'rules_rule', - 'event' => 'rules_entity_presave:node', - ])->setExpression($rule2); + ]); + $config_entity2->set('events', [ + ['event_name' => 'rules_entity_presave:node'], + ]); + $config_entity2->set('configuration', $rule2->getConfiguration()); $config_entity2->save(); // The logger instance has changed, refresh it. From b866850ca35cdbad66e7247c6f6d6d645b38d40e Mon Sep 17 00:00:00 2001 From: milkovsky Date: Thu, 18 Feb 2016 18:38:30 +0100 Subject: [PATCH 21/30] Added ajax reload. --- src/Form/ReactionRuleAddForm.php | 1 + src/Form/RulesComponentFormBase.php | 32 +++++++++++++++++++++++++++++ 2 files changed, 33 insertions(+) diff --git a/src/Form/ReactionRuleAddForm.php b/src/Form/ReactionRuleAddForm.php index ab26b69b..52952c2a 100644 --- a/src/Form/ReactionRuleAddForm.php +++ b/src/Form/ReactionRuleAddForm.php @@ -71,6 +71,7 @@ public function form(array $form, FormStateInterface $form_state) { '#title' => $this->t('React on event'), '#options' => $options, '#required' => TRUE, + '#ajax' => $this->getDefaultAjax(), '#description' => $this->t('Whenever the event occurs, rule evaluation is triggered.'), ]; diff --git a/src/Form/RulesComponentFormBase.php b/src/Form/RulesComponentFormBase.php index ccb8c6dd..a29c7b90 100644 --- a/src/Form/RulesComponentFormBase.php +++ b/src/Form/RulesComponentFormBase.php @@ -19,6 +19,10 @@ abstract class RulesComponentFormBase extends EntityForm { * {@inheritdoc} */ public function form(array $form, FormStateInterface $form_state) { + // Specify the wrapper div used by #ajax. + $form['#prefix'] = '
'; + $form['#suffix'] = '
'; + $form['settings'] = [ '#type' => 'details', '#title' => $this->t('Settings'), @@ -78,4 +82,32 @@ public function exists($id) { return (bool) $this->entityTypeManager->getStorage($type)->load($id); } + /** + * Get default form #ajax properties. + * + * @param string $effect + * (optional) The jQuery effect to use when placing the new HTML (used with + * 'wrapper'). Valid options are 'none' (default), 'slide', or 'fade'. + * + * @return array + */ + public function getDefaultAjax($effect = 'none') { + return array( + 'callback' => '::reloadForm', + 'wrapper' => 'rules-form-wrapper', + 'effect' => $effect, + 'speed' => 'fast', + ); + } + + /** + * Ajax callback to reload the form. + * + * @return array + * The reloaded form. + */ + public function reloadForm(array $form, FormStateInterface $form_state) { + return $form; + } + } From 5b1a9c3eccd4f25ab0d4c7dc190ffe77b55f9fff Mon Sep 17 00:00:00 2001 From: milkovsky Date: Fri, 19 Feb 2016 17:16:07 +0100 Subject: [PATCH 22/30] Bundle select + handler. WIP. --- .../ConfigurableEventHandlerEntityBundle.php | 40 ++++++++++++++++++- src/Form/ReactionRuleAddForm.php | 37 +++++++++++++++++ src/Form/ReactionRuleEditForm.php | 2 +- 3 files changed, 76 insertions(+), 3 deletions(-) diff --git a/src/EventHandler/ConfigurableEventHandlerEntityBundle.php b/src/EventHandler/ConfigurableEventHandlerEntityBundle.php index 86baa041..47afed5c 100644 --- a/src/EventHandler/ConfigurableEventHandlerEntityBundle.php +++ b/src/EventHandler/ConfigurableEventHandlerEntityBundle.php @@ -15,6 +15,24 @@ */ class ConfigurableEventHandlerEntityBundle extends ConfigurableEventHandlerBase { + protected $bundlesInfo; + protected $entityInfo; + protected $entityType; + + /** + * {@inheritdoc} + */ + public function __construct(array $configuration, $plugin_id, $plugin_definition) { + parent::__construct($configuration, $plugin_id, $plugin_definition); + $this->entityType = $this->getEventNameSuffix(); + // @todo Do it in a non-deprecated way. + $this->entityInfo = \Drupal::entityTypeManager()->getDefinition($this->entityType); + $this->bundlesInfo = \Drupal::entityManager()->getBundleInfo($this->entityType); + if (!$this->bundlesInfo) { + throw new \InvalidArgumentException('Unsupported event name passed.'); + } + } + /** * {@inheritdoc} */ @@ -37,7 +55,24 @@ public function summary() { * {@inheritdoc} */ public function buildConfigurationForm(array $form, FormStateInterface $form_state) { - // Nothing to do by default. + $form['bundle'] = array( + '#type' => 'select', + '#title' => t('Restrict by @bundle', array('@bundle' => $this->entityInfo->getBundleLabel())), + '#description' => t('If you need to filter for multiple values, either add multiple events or use the "Entity is of bundle" condition instead.'), + '#default_value' => $this->configuration['bundle'], + '#empty_value' => '', + ); + foreach ($this->bundlesInfo as $name => $bundle_info) { + $form['bundle']['#options'][$name] = $bundle_info['label']; + } + return $form; + } + + /** + * {@inheritdoc} + */ + public function extractConfigurationFormValues(array &$form, FormStateInterface $form_state) { + $this->configuration['bundle'] = $form_state->getValue('bundle'); } /** @@ -51,7 +86,8 @@ public function validate() { * {@inheritdoc} */ public function getEventNameSuffix() { - // Nothing to do by default. + $parts = explode(':', $this->pluginId); + return $parts[1]; } /** diff --git a/src/Form/ReactionRuleAddForm.php b/src/Form/ReactionRuleAddForm.php index 52952c2a..352051e1 100644 --- a/src/Form/ReactionRuleAddForm.php +++ b/src/Form/ReactionRuleAddForm.php @@ -8,6 +8,7 @@ namespace Drupal\rules\Form; use Drupal\Core\Form\FormStateInterface; +use Drupal\rules\Core\RulesConfigurableEventHandlerInterface; use Drupal\rules\Core\RulesEventManager; use Symfony\Component\DependencyInjection\ContainerInterface; @@ -75,6 +76,14 @@ public function form(array $form, FormStateInterface $form_state) { '#description' => $this->t('Whenever the event occurs, rule evaluation is triggered.'), ]; + $form['event_configuration'] = array(); + if ($values = $form_state->getValue('events')) { + $event_name = $values[0]['event_name']; + if ($handler = $this->getEventHandler($event_name)) { + $form['event_configuration'] = $handler->buildConfigurationForm(array(), $form_state); + } + } + return $form; } @@ -82,10 +91,38 @@ public function form(array $form, FormStateInterface $form_state) { * {@inheritdoc} */ public function save(array $form, FormStateInterface $form_state) { + $event_name = $form_state->getValue('events')[0]['event_name']; + if ($handler = $this->getEventHandler($event_name)) { + $handler->extractConfigurationFormValues($form['event_configuration'], $form_state); + // @todo Save in 2 places? + $this->entity->set('configuration', $handler->getConfiguration()); + $this->entity->set('events', [['event_name' => $event_name . '--' . $handler->getConfiguration()['bundle']]]); + // @todo Exception: The "rules_entity_view:node–article" plugin does not exist. + } parent::save($form, $form_state); drupal_set_message($this->t('Reaction rule %label has been created.', ['%label' => $this->entity->label()])); $form_state->setRedirect('entity.rules_reaction_rule.edit_form', ['rules_reaction_rule' => $this->entity->id()]); } + /** + * Gets event handler class. + * + * @param $event_name + * The event base name. + * @param array $configuration + * The event configuration. + * + * @return \Drupal\rules\Core\RulesConfigurableEventHandlerInterface|null + * The event handler, null if there is no proper handler. + */ + protected function getEventHandler($event_name, $configuration = []) { + $event_definition = $this->eventManager->getDefinition($event_name); + $handler_class = $event_definition['class']; + if (is_subclass_of($handler_class, RulesConfigurableEventHandlerInterface::class)) { + $handler = new $handler_class($configuration, $this->eventManager->getEventBaseName($event_name)); + return $handler; + } + } + } diff --git a/src/Form/ReactionRuleEditForm.php b/src/Form/ReactionRuleEditForm.php index 6e211b94..f6e37160 100644 --- a/src/Form/ReactionRuleEditForm.php +++ b/src/Form/ReactionRuleEditForm.php @@ -75,7 +75,7 @@ public function form(array $form, FormStateInterface $form_state) { foreach ($this->entity->getEventNames() as $key => $event_name) { $event_definition = $this->eventManager->getDefinition($event_name); - $form['event'][$key] = [ + $form['events'][$key] = [ '#type' => 'item', '#title' => $this->t('Events:'), '#markup' => $this->t('@label (@name)', [ From df48c33a7a086111a9781f2b2123628a051d0076 Mon Sep 17 00:00:00 2001 From: milkovsky Date: Fri, 26 Feb 2016 10:16:46 +0100 Subject: [PATCH 23/30] After merge fixes. --- src/Form/ReactionRuleEditForm.php | 6 +----- tests/src/Kernel/ConfigurableEventHandlerTest.php | 7 ++----- tests/src/Kernel/EventIntegrationTest.php | 3 +-- 3 files changed, 4 insertions(+), 12 deletions(-) diff --git a/src/Form/ReactionRuleEditForm.php b/src/Form/ReactionRuleEditForm.php index 8a039380..d86dc4fb 100644 --- a/src/Form/ReactionRuleEditForm.php +++ b/src/Form/ReactionRuleEditForm.php @@ -71,8 +71,6 @@ protected function prepareEntity() { * {@inheritdoc} */ public function form(array $form, FormStateInterface $form_state) { - $form['locked'] = $this->rulesUiHandler->addLockInformation(); - foreach ($this->entity->getEventNames() as $key => $event_name) { $event_definition = $this->eventManager->getDefinition($event_name); $form['events'][$key] = [ @@ -84,9 +82,7 @@ public function form(array $form, FormStateInterface $form_state) { ]), ]; } - $form_handler = $this->rulesUiHandler->getComponent() - ->getExpression()->getFormHandler(); - $form = $form_handler->form($form, $form_state); + $form = $this->rulesUiHandler->getForm()->buildForm($form, $form_state); return parent::form($form, $form_state); } diff --git a/tests/src/Kernel/ConfigurableEventHandlerTest.php b/tests/src/Kernel/ConfigurableEventHandlerTest.php index 084ec8bb..57eb1534 100644 --- a/tests/src/Kernel/ConfigurableEventHandlerTest.php +++ b/tests/src/Kernel/ConfigurableEventHandlerTest.php @@ -93,13 +93,11 @@ public function testConfigurableEventHandler() { ); $config_entity1 = $this->storage->create([ 'id' => 'test_rule1', - 'expression_id' => 'rules_rule', - 'event' => '', ]); $config_entity1->set('events', [ ['event_name' => 'rules_entity_presave:node--page'], ]); - $config_entity1->set('configuration', $rule1->getConfiguration()); + $config_entity1->set('expression', $rule1->getConfiguration()); $config_entity1->save(); // Create rule2 with the 'rules_entity_presave:node' event. @@ -110,12 +108,11 @@ public function testConfigurableEventHandler() { ); $config_entity2 = $this->storage->create([ 'id' => 'test_rule2', - 'expression_id' => 'rules_rule', ]); $config_entity2->set('events', [ ['event_name' => 'rules_entity_presave:node'], ]); - $config_entity2->set('configuration', $rule2->getConfiguration()); + $config_entity2->set('expression', $rule2->getConfiguration()); $config_entity2->save(); // The logger instance has changed, refresh it. diff --git a/tests/src/Kernel/EventIntegrationTest.php b/tests/src/Kernel/EventIntegrationTest.php index f70f91c4..7bc7e5d3 100644 --- a/tests/src/Kernel/EventIntegrationTest.php +++ b/tests/src/Kernel/EventIntegrationTest.php @@ -190,13 +190,12 @@ public function testMultipleEvents() { $config_entity = $this->storage->create([ 'id' => 'test_rule', - 'expression_id' => 'rules_rule', ]); $config_entity->set('events', [ ['event_name' => 'rules_user_login'], ['event_name' => 'rules_user_logout'], ]); - $config_entity->set('configuration', $rule->getConfiguration()); + $config_entity->set('expression', $rule->getConfiguration()); $config_entity->save(); // The logger instance has changed, refresh it. From 1b353fb30c551a1a4688e6fa6f8f4466092fe133 Mon Sep 17 00:00:00 2001 From: milkovsky Date: Fri, 26 Feb 2016 11:59:34 +0100 Subject: [PATCH 24/30] Fixed event discovery by base name. --- src/Core/RulesEventManager.php | 2 +- src/Entity/ReactionRuleConfig.php | 27 ++++++++++++++++++++++++++- src/Entity/ReactionRuleStorage.php | 5 ++--- src/Form/ReactionRuleEditForm.php | 3 ++- 4 files changed, 31 insertions(+), 6 deletions(-) diff --git a/src/Core/RulesEventManager.php b/src/Core/RulesEventManager.php index 160f7325..cc58d20e 100644 --- a/src/Core/RulesEventManager.php +++ b/src/Core/RulesEventManager.php @@ -64,7 +64,7 @@ public function processDefinition(&$definition, $plugin_id) { * Gets the base name of a configured event name. * * For a configured event name like {EVENT_NAME}--{SUFFIX}, the base event - * name {EVENT_NAME} is returned. + * name {EVENT_NAME} is returned.s * * @return string * The event base name. diff --git a/src/Entity/ReactionRuleConfig.php b/src/Entity/ReactionRuleConfig.php index 6c10f3ae..9efed6cf 100644 --- a/src/Entity/ReactionRuleConfig.php +++ b/src/Entity/ReactionRuleConfig.php @@ -164,7 +164,7 @@ public function getExpression() { */ public function getComponent() { $component = RulesComponent::create($this->getExpression()); - $component->addContextDefinitionsForEvents($this->getEventNames()); + $component->addContextDefinitionsForEvents($this->getEventBaseNames()); return $component; } @@ -253,6 +253,31 @@ public function getEventNames() { return $names; } + /** + * Gets the base names of all events the rule is reacting on. + * + * For a configured event name like {EVENT_NAME}--{SUFFIX}, the base event + * name {EVENT_NAME} is returned. + * + * @return string[] + * The array of base event names of the rule. + * + * @see \Drupal\rules\Core\RulesConfigurableEventHandlerInterface::getEventNameSuffix() + */ + public function getEventBaseNames() { + $names = []; + foreach ($this->events as $event) { + $event_name = $event['event_name']; + if (strpos($event_name, '--') !== FALSE) { + // Cut off any suffix from a configured event name. + $parts = explode('--', $event_name, 2); + $event_name = $parts[0]; + } + $names[] = $event_name; + } + return $names; + } + /** * {@inheritdoc} */ diff --git a/src/Entity/ReactionRuleStorage.php b/src/Entity/ReactionRuleStorage.php index 1fabfbbf..29c4713c 100644 --- a/src/Entity/ReactionRuleStorage.php +++ b/src/Entity/ReactionRuleStorage.php @@ -95,8 +95,7 @@ public static function createInstance(ContainerInterface $container, EntityTypeI protected function getRegisteredEvents() { $events = []; foreach ($this->loadMultiple() as $rules_config) { - foreach ($rules_config->getEventNames() as $event_name) { - $event_name = $this->eventManager->getEventBaseName($event_name); + foreach ($rules_config->getBaseEventNames() as $event_name) { if (!isset($events[$event_name])) { $events[$event_name] = $event_name; } @@ -122,7 +121,7 @@ public function save(EntityInterface $entity) { // otherwise the reaction rule will not fire. However, we can do an // optimization: if every event was already registered before, we do not // have to rebuild the container. - foreach ($entity->getEventNames() as $event_name) { + foreach ($entity->getEventBaseNames() as $event_name) { if (empty($events_before[$event_name])) { $this->drupalKernel->rebuildContainer(); break; diff --git a/src/Form/ReactionRuleEditForm.php b/src/Form/ReactionRuleEditForm.php index d86dc4fb..4cf4b8c7 100644 --- a/src/Form/ReactionRuleEditForm.php +++ b/src/Form/ReactionRuleEditForm.php @@ -72,7 +72,8 @@ protected function prepareEntity() { */ public function form(array $form, FormStateInterface $form_state) { foreach ($this->entity->getEventNames() as $key => $event_name) { - $event_definition = $this->eventManager->getDefinition($event_name); + $event_base_name = $this->eventManager->getEventBaseName($event_name); + $event_definition = $this->eventManager->getDefinition($event_base_name); $form['events'][$key] = [ '#type' => 'item', '#title' => $this->t('Events:'), From d179fcf23453762d13a0aecb34ef5fa43a099d01 Mon Sep 17 00:00:00 2001 From: milkovsky Date: Fri, 26 Feb 2016 12:02:17 +0100 Subject: [PATCH 25/30] Fixed expression set in rules handler test. --- .../src/Kernel/ConfigurableEventHandlerTest.php | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/tests/src/Kernel/ConfigurableEventHandlerTest.php b/tests/src/Kernel/ConfigurableEventHandlerTest.php index 28c2bfa3..57eb1534 100644 --- a/tests/src/Kernel/ConfigurableEventHandlerTest.php +++ b/tests/src/Kernel/ConfigurableEventHandlerTest.php @@ -93,9 +93,11 @@ public function testConfigurableEventHandler() { ); $config_entity1 = $this->storage->create([ 'id' => 'test_rule1', - 'expression_id' => 'rules_rule', - 'event' => 'rules_entity_presave:node--page', - ])->setExpression($rule1); + ]); + $config_entity1->set('events', [ + ['event_name' => 'rules_entity_presave:node--page'], + ]); + $config_entity1->set('expression', $rule1->getConfiguration()); $config_entity1->save(); // Create rule2 with the 'rules_entity_presave:node' event. @@ -106,9 +108,11 @@ public function testConfigurableEventHandler() { ); $config_entity2 = $this->storage->create([ 'id' => 'test_rule2', - 'expression_id' => 'rules_rule', - 'event' => 'rules_entity_presave:node', - ])->setExpression($rule2); + ]); + $config_entity2->set('events', [ + ['event_name' => 'rules_entity_presave:node'], + ]); + $config_entity2->set('expression', $rule2->getConfiguration()); $config_entity2->save(); // The logger instance has changed, refresh it. From 5eea48cc3233b38018f2b5d3007aff3d5fc2f3cd Mon Sep 17 00:00:00 2001 From: milkovsky Date: Fri, 26 Feb 2016 12:07:49 +0100 Subject: [PATCH 26/30] Fix testMultipleEvents test. --- tests/src/Kernel/EventIntegrationTest.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/tests/src/Kernel/EventIntegrationTest.php b/tests/src/Kernel/EventIntegrationTest.php index f70f91c4..7bc7e5d3 100644 --- a/tests/src/Kernel/EventIntegrationTest.php +++ b/tests/src/Kernel/EventIntegrationTest.php @@ -190,13 +190,12 @@ public function testMultipleEvents() { $config_entity = $this->storage->create([ 'id' => 'test_rule', - 'expression_id' => 'rules_rule', ]); $config_entity->set('events', [ ['event_name' => 'rules_user_login'], ['event_name' => 'rules_user_logout'], ]); - $config_entity->set('configuration', $rule->getConfiguration()); + $config_entity->set('expression', $rule->getConfiguration()); $config_entity->save(); // The logger instance has changed, refresh it. From c936dfc9f441863d026106eee94b64eeda7d2cf7 Mon Sep 17 00:00:00 2001 From: milkovsky Date: Fri, 26 Feb 2016 13:27:41 +0100 Subject: [PATCH 27/30] Implemented summary(). --- .../ConfigurableEventHandlerEntityBundle.php | 23 +++++++++++++++++-- src/Form/ReactionRuleAddForm.php | 4 +--- 2 files changed, 22 insertions(+), 5 deletions(-) diff --git a/src/EventHandler/ConfigurableEventHandlerEntityBundle.php b/src/EventHandler/ConfigurableEventHandlerEntityBundle.php index 47afed5c..b8bbcb6c 100644 --- a/src/EventHandler/ConfigurableEventHandlerEntityBundle.php +++ b/src/EventHandler/ConfigurableEventHandlerEntityBundle.php @@ -15,8 +15,25 @@ */ class ConfigurableEventHandlerEntityBundle extends ConfigurableEventHandlerBase { + /** + * The bundles information for the entity. + * + * @var array + */ protected $bundlesInfo; + + /** + * The entity info plugin definition. + * + * @var mixed + */ protected $entityInfo; + + /** + * The entity type. + * + * @var string + */ protected $entityType; /** @@ -25,7 +42,6 @@ class ConfigurableEventHandlerEntityBundle extends ConfigurableEventHandlerBase public function __construct(array $configuration, $plugin_id, $plugin_definition) { parent::__construct($configuration, $plugin_id, $plugin_definition); $this->entityType = $this->getEventNameSuffix(); - // @todo Do it in a non-deprecated way. $this->entityInfo = \Drupal::entityTypeManager()->getDefinition($this->entityType); $this->bundlesInfo = \Drupal::entityManager()->getBundleInfo($this->entityType); if (!$this->bundlesInfo) { @@ -48,7 +64,10 @@ public static function determineQualifiedEvents(Event $event, $event_name, array * {@inheritdoc} */ public function summary() { - // Nothing to do by default. + $bundle = $this->configuration['bundle']; + $bundle_label = isset($this->bundlesInfo[$bundle]['label']) ? $this->bundlesInfo[$bundle]['label'] : $bundle; + $suffix = isset($bundle) ? ' ' . t('of @bundle-key %name', array('@bundle-key' => $this->entityInfo->getBundleLabel(), '%name' => $bundle_label)) : ''; + return $this->pluginDefinition['label']->render() . $suffix; } /** diff --git a/src/Form/ReactionRuleAddForm.php b/src/Form/ReactionRuleAddForm.php index 352051e1..46783868 100644 --- a/src/Form/ReactionRuleAddForm.php +++ b/src/Form/ReactionRuleAddForm.php @@ -94,10 +94,8 @@ public function save(array $form, FormStateInterface $form_state) { $event_name = $form_state->getValue('events')[0]['event_name']; if ($handler = $this->getEventHandler($event_name)) { $handler->extractConfigurationFormValues($form['event_configuration'], $form_state); - // @todo Save in 2 places? $this->entity->set('configuration', $handler->getConfiguration()); $this->entity->set('events', [['event_name' => $event_name . '--' . $handler->getConfiguration()['bundle']]]); - // @todo Exception: The "rules_entity_view:node–article" plugin does not exist. } parent::save($form, $form_state); @@ -120,7 +118,7 @@ protected function getEventHandler($event_name, $configuration = []) { $event_definition = $this->eventManager->getDefinition($event_name); $handler_class = $event_definition['class']; if (is_subclass_of($handler_class, RulesConfigurableEventHandlerInterface::class)) { - $handler = new $handler_class($configuration, $this->eventManager->getEventBaseName($event_name)); + $handler = new $handler_class($configuration, $this->eventManager->getEventBaseName($event_name), $event_definition); return $handler; } } From a341b281be9783d9e537a4b014ff0f82322c752e Mon Sep 17 00:00:00 2001 From: milkovsky Date: Fri, 26 Feb 2016 18:21:06 +0100 Subject: [PATCH 28/30] Refactoring. --- ...RulesConfigurableEventHandlerInterface.php | 3 ++- .../ConfigurableEventHandlerEntityBundle.php | 4 ++-- src/Form/ReactionRuleAddForm.php | 24 ++++++++++++++----- 3 files changed, 22 insertions(+), 9 deletions(-) diff --git a/src/Core/RulesConfigurableEventHandlerInterface.php b/src/Core/RulesConfigurableEventHandlerInterface.php index 10e6d7d1..e65e55d9 100644 --- a/src/Core/RulesConfigurableEventHandlerInterface.php +++ b/src/Core/RulesConfigurableEventHandlerInterface.php @@ -90,6 +90,7 @@ public function extractConfigurationFormValues(array &$form, FormStateInterface public function validate(); /** + * todo * Provides the event name suffix based upon the plugin configuration. * * If the event is configured and a suffix is provided, the event name Rules @@ -98,7 +99,7 @@ public function validate(); * @return string|false * The suffix string, for FALSE if no suffix should be appended. */ - public function getEventNameSuffix(); + public function getEventNamePrefix(); /** * Refines provided context definitions based upon plugin configuration. diff --git a/src/EventHandler/ConfigurableEventHandlerEntityBundle.php b/src/EventHandler/ConfigurableEventHandlerEntityBundle.php index b8bbcb6c..5be9f575 100644 --- a/src/EventHandler/ConfigurableEventHandlerEntityBundle.php +++ b/src/EventHandler/ConfigurableEventHandlerEntityBundle.php @@ -41,7 +41,7 @@ class ConfigurableEventHandlerEntityBundle extends ConfigurableEventHandlerBase */ public function __construct(array $configuration, $plugin_id, $plugin_definition) { parent::__construct($configuration, $plugin_id, $plugin_definition); - $this->entityType = $this->getEventNameSuffix(); + $this->entityType = $this->getEventNamePrefix(); $this->entityInfo = \Drupal::entityTypeManager()->getDefinition($this->entityType); $this->bundlesInfo = \Drupal::entityManager()->getBundleInfo($this->entityType); if (!$this->bundlesInfo) { @@ -104,7 +104,7 @@ public function validate() { /** * {@inheritdoc} */ - public function getEventNameSuffix() { + public function getEventNamePrefix() { $parts = explode(':', $this->pluginId); return $parts[1]; } diff --git a/src/Form/ReactionRuleAddForm.php b/src/Form/ReactionRuleAddForm.php index 46783868..a255fb67 100644 --- a/src/Form/ReactionRuleAddForm.php +++ b/src/Form/ReactionRuleAddForm.php @@ -74,6 +74,7 @@ public function form(array $form, FormStateInterface $form_state) { '#required' => TRUE, '#ajax' => $this->getDefaultAjax(), '#description' => $this->t('Whenever the event occurs, rule evaluation is triggered.'), + '#submit' => array('::submitForm'), ]; $form['event_configuration'] = array(); @@ -90,13 +91,22 @@ public function form(array $form, FormStateInterface $form_state) { /** * {@inheritdoc} */ - public function save(array $form, FormStateInterface $form_state) { - $event_name = $form_state->getValue('events')[0]['event_name']; - if ($handler = $this->getEventHandler($event_name)) { - $handler->extractConfigurationFormValues($form['event_configuration'], $form_state); - $this->entity->set('configuration', $handler->getConfiguration()); - $this->entity->set('events', [['event_name' => $event_name . '--' . $handler->getConfiguration()['bundle']]]); + public function buildEntity(array $form, FormStateInterface $form_state) { + $entity = parent::buildEntity($form, $form_state); + foreach ($entity->getEventBaseNames() as $event_name) { + if ($handler = $this->getEventHandler($event_name)) { + $handler->extractConfigurationFormValues($form['event_configuration'], $form_state); + $entity->set('configuration', $handler->getConfiguration()); + $entity->set('events', [['event_name' => $event_name . '--' . $handler->getConfiguration()['bundle']]]); + } } + return $entity; + } + + /** + * {@inheritdoc} + */ + public function save(array $form, FormStateInterface $form_state) { parent::save($form, $form_state); drupal_set_message($this->t('Reaction rule %label has been created.', ['%label' => $this->entity->label()])); @@ -106,6 +116,8 @@ public function save(array $form, FormStateInterface $form_state) { /** * Gets event handler class. * + * Currently event handler is available only when the event is configurable. + * * @param $event_name * The event base name. * @param array $configuration From fa7d831827189da6a65f47e78e500bc5f05b72d1 Mon Sep 17 00:00:00 2001 From: milkovsky Date: Fri, 26 Feb 2016 18:24:07 +0100 Subject: [PATCH 29/30] Refactoring. --- src/Core/RulesEventManager.php | 2 +- src/Form/ReactionRuleAddForm.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Core/RulesEventManager.php b/src/Core/RulesEventManager.php index cc58d20e..160f7325 100644 --- a/src/Core/RulesEventManager.php +++ b/src/Core/RulesEventManager.php @@ -64,7 +64,7 @@ public function processDefinition(&$definition, $plugin_id) { * Gets the base name of a configured event name. * * For a configured event name like {EVENT_NAME}--{SUFFIX}, the base event - * name {EVENT_NAME} is returned.s + * name {EVENT_NAME} is returned. * * @return string * The event base name. diff --git a/src/Form/ReactionRuleAddForm.php b/src/Form/ReactionRuleAddForm.php index a255fb67..7b1869e7 100644 --- a/src/Form/ReactionRuleAddForm.php +++ b/src/Form/ReactionRuleAddForm.php @@ -74,7 +74,7 @@ public function form(array $form, FormStateInterface $form_state) { '#required' => TRUE, '#ajax' => $this->getDefaultAjax(), '#description' => $this->t('Whenever the event occurs, rule evaluation is triggered.'), - '#submit' => array('::submitForm'), + '#executes_submit_callback' => array('::submitForm'), ]; $form['event_configuration'] = array(); From 7fecba2b2b2c18360c8d8fd00e3db9e047071048 Mon Sep 17 00:00:00 2001 From: Wolfgang Ziegler // fago Date: Mon, 7 Mar 2016 13:49:11 +0100 Subject: [PATCH 30/30] Worked over bundle configurable event. --- src/Core/RulesDefaultEventHandler.php | 1 + src/Entity/ReactionRuleStorage.php | 2 +- .../ConfigurableEventHandlerEntityBundle.php | 21 +++++++++++-------- 3 files changed, 14 insertions(+), 10 deletions(-) diff --git a/src/Core/RulesDefaultEventHandler.php b/src/Core/RulesDefaultEventHandler.php index f2297bae..1af70b63 100644 --- a/src/Core/RulesDefaultEventHandler.php +++ b/src/Core/RulesDefaultEventHandler.php @@ -22,6 +22,7 @@ public function getContextDefinitions() { $definition = $this->getPluginDefinition(); if ($this instanceof RulesConfigurableEventHandlerInterface) { $this->refineContextDefinitions(); + $definition = $this->getPluginDefinition(); } return !empty($definition['context']) ? $definition['context'] : []; } diff --git a/src/Entity/ReactionRuleStorage.php b/src/Entity/ReactionRuleStorage.php index 29c4713c..50baa766 100644 --- a/src/Entity/ReactionRuleStorage.php +++ b/src/Entity/ReactionRuleStorage.php @@ -95,7 +95,7 @@ public static function createInstance(ContainerInterface $container, EntityTypeI protected function getRegisteredEvents() { $events = []; foreach ($this->loadMultiple() as $rules_config) { - foreach ($rules_config->getBaseEventNames() as $event_name) { + foreach ($rules_config->getEventBaseNames() as $event_name) { if (!isset($events[$event_name])) { $events[$event_name] = $event_name; } diff --git a/src/EventHandler/ConfigurableEventHandlerEntityBundle.php b/src/EventHandler/ConfigurableEventHandlerEntityBundle.php index b8bbcb6c..58362796 100644 --- a/src/EventHandler/ConfigurableEventHandlerEntityBundle.php +++ b/src/EventHandler/ConfigurableEventHandlerEntityBundle.php @@ -34,16 +34,18 @@ class ConfigurableEventHandlerEntityBundle extends ConfigurableEventHandlerBase * * @var string */ - protected $entityType; + protected $entityTypeId; /** * {@inheritdoc} */ public function __construct(array $configuration, $plugin_id, $plugin_definition) { parent::__construct($configuration, $plugin_id, $plugin_definition); - $this->entityType = $this->getEventNameSuffix(); - $this->entityInfo = \Drupal::entityTypeManager()->getDefinition($this->entityType); - $this->bundlesInfo = \Drupal::entityManager()->getBundleInfo($this->entityType); + $this->entityTypeId = $plugin_definition['entity_type_id']; + // @todo: This needs to use dependency injection. + $this->entityInfo = \Drupal::entityTypeManager()->getDefinition($this->entityTypeId); + // @tdo: use EntityTypeBundleInfo service. + $this->bundlesInfo = \Drupal::entityManager()->getBundleInfo($this->entityTypeId); if (!$this->bundlesInfo) { throw new \InvalidArgumentException('Unsupported event name passed.'); } @@ -98,29 +100,30 @@ public function extractConfigurationFormValues(array &$form, FormStateInterface * {@inheritdoc} */ public function validate() { - // Nothing to check by default. + // Nothing to validate. } /** * {@inheritdoc} */ public function getEventNameSuffix() { - $parts = explode(':', $this->pluginId); - return $parts[1]; + return isset($this->configuration['bundle']) ? $this->configuration['bundle'] : FALSE; } /** * {@inheritdoc} */ public function refineContextDefinitions() { - // Nothing to refine by default. + if ($bundle = $this->getEventNameSuffix()) { + $this->pluginDefinition['context']['entity']->setBundles([$bundle]); + } } /** * {@inheritdoc} */ public function calculateDependencies() { - // Nothing to calculate by default. + // @todo: Implement. } }