commit 23ae5b0b6e122d54bcad5d25b1f24aaf842952d6 Author: fago Date: Wed Mar 27 13:49:00 2013 +0100 Issue #1472752 by David Stosik, fago, Simon Georges: Add an 'entity is of bundle' condition. diff --git a/modules/entity.eval.inc b/modules/entity.eval.inc index 7c5adf2..200c874 100644 --- a/modules/entity.eval.inc +++ b/modules/entity.eval.inc @@ -157,3 +157,10 @@ function rules_condition_entity_has_field($wrapper, $field_name, $settings, $sta function rules_condition_entity_is_of_type($wrapper, $type) { return $wrapper->type() == $type; } + +/** + * Condition: Entity is of type and bundle. + */ +function rules_condition_entity_is_of_type_bundle($wrapper, $type, $bundles) { + return $wrapper->type() == $type && in_array($wrapper->getBundle(), $bundles); +} diff --git a/modules/entity.rules.inc b/modules/entity.rules.inc index 4d16907..40159a3 100644 --- a/modules/entity.rules.inc +++ b/modules/entity.rules.inc @@ -269,6 +269,23 @@ function rules_entity_type_options($key = NULL) { } /** + * Options list callback for getting a list of possible entity bundles. + * + * @param $element + * The element to return options for. + */ +function rules_entity_bundle_options(RulesAbstractPlugin $element) { + $bundles = array(); + if (isset($element->settings['type'])) { + $entity_info = entity_get_info($element->settings['type']); + foreach ($entity_info['bundles'] as $bundle_name => $bundle_info) { + $bundles[$bundle_name] = $bundle_info['label']; + } + } + return $bundles; +} + +/** * Entity actions access callback. * * Returns TRUE if at least one type is available for configuring the action. @@ -348,6 +365,32 @@ function rules_entity_condition_info() { 'group' => t('Entities'), 'base' => 'rules_condition_entity_is_of_type', ), + 'entity_is_of_bundle' => array( + 'label' => t('Entity is of bundle'), + 'parameter' => array( + 'entity' => array( + 'type' => 'entity', + 'label' => t('Entity'), + 'description' => t('Specifies the entity for which to evaluate the condition.'), + ), + 'type' => array( + 'type' => 'token', + 'label' => t('Entity type'), + 'description' => t('The type of the checked entity.'), + 'options list' => 'rules_entity_action_type_options', + 'restriction' => 'input', + ), + 'bundle' => array( + 'type' => 'list', + 'label' => t('Entity bundle'), + 'description' => t('The condition is met if the entity is of one of the selected bundles.'), + 'options list' => 'rules_entity_bundle_options', + 'restriction' => 'input', + ), + ), + 'group' => t('Entities'), + 'base' => 'rules_condition_entity_is_of_type_bundle', + ), ); } @@ -397,5 +440,80 @@ function rules_condition_entity_is_of_type_assertions($element) { } /** + * Assert the selected entity type and bundle. + */ +function rules_condition_entity_is_of_type_bundle_assertions($element) { + if ($bundle = $element->settings['bundle']) { + $assertions = array(); + $assertions['entity']['type'] = $element->settings['type']; + $assertions['entity']['bundle'] = $bundle; + return $assertions; + } +} + +/** + * Process callback for the condition entity_is_of_type_bundle. + */ +function rules_condition_entity_is_of_type_bundle_process(RulesAbstractPlugin $element) { + // If we know the entity type, auto-populate it. + if (($info = $element->getArgumentInfo('entity')) && $info['type'] != 'entity') { + $element->settings['type'] = $info['type']; + } +} + +/** + * Form alter callback for the condition entity_is_of_type_bundle. + * + * Use multiple steps to configure the condition as the needed bundle field list + * depends on the selected entity type. + */ +function rules_condition_entity_is_of_type_bundle_form_alter(&$form, &$form_state, $options, RulesAbstractPlugin $element) { + if (empty($element->settings['entity:select'])) { + $step = 1; + } + elseif (empty($element->settings['type'])) { + $step = 2; + } + else { + $step = 3; + } + + $form['reload'] = array( + '#weight' => $form['submit']['#weight'] + 1, + '#type' => 'submit', + '#name' => 'reload', + '#value' => $step != 3 ? t('Continue') : t('Reload form'), + '#limit_validation_errors' => array(array('parameter', 'entity'), array('parameter', 'type')), + '#submit' => array('rules_form_submit_rebuild'), + '#ajax' => rules_ui_form_default_ajax('fade'), + '#attributes' => array('class' => array('rules-hide-js')), + ); + // Use ajax and trigger as the reload button. + $form['parameter']['type']['settings']['type']['#ajax'] = $form['reload']['#ajax'] + array( + 'event' => 'change', + 'trigger_as' => array('name' => 'reload'), + ); + + switch ($step) { + case 1: + $form['reload']['#limit_validation_errors'] = array(array('parameter', 'entity')); + unset($form['parameter']['type']); + unset($form['reload']['#attributes']['class']); + // NO break; + case 2: + $form['negate']['#access'] = FALSE; + unset($form['parameter']['bundle']); + unset($form['submit']); + break; + case 3: + if (($info = $element->getArgumentInfo('entity')) && $info['type'] != 'entity') { + // Hide the entity type parameter if not needed. + unset($form['parameter']['type']); + } + break; + } +} + +/** * @} */ diff --git a/tests/rules.test b/tests/rules.test index 1b3246c..a37da06 100644 --- a/tests/rules.test +++ b/tests/rules.test @@ -1455,6 +1455,53 @@ class RulesIntegrationTestCase extends DrupalWebTestCase { function testEntityIntegration() { global $user; + // Test entiy_is_of_bundle condition. + $page = $this->drupalCreateNode(array('type' => 'page')); + $article = $this->drupalCreateNode(array('type' => 'article')); + + $result = rules_condition('entity_is_of_bundle', array( + 'type' => 'node', + 'bundle' => array('article'), + ))->execute(entity_metadata_wrapper('node', $page)); + $this->assertFalse($result, 'Entity is of bundle condition has not been met.'); + $result = rules_condition('entity_is_of_bundle', array( + 'type' => 'node', + 'bundle' => array('article'), + ))->execute(entity_metadata_wrapper('node', $article)); + $this->assertTrue($result, 'Entity is of bundle condition has been met.'); + + // Also test a full rule so the integrity check must work. + $term_wrapped = entity_property_values_create_entity('taxonomy_term', array( + 'name' => $this->randomName(), + 'vocabulary' => 1, + ))->save(); + $rule = rule(array( + 'node' => array('type' => 'node'), + )); + $rule->condition('entity_is_of_bundle', array( + 'entity:select' => 'node', + 'bundle' => array('article'), + )); + $rule->action('data_set', array('data:select' => 'node:field_tags', 'value' => array($term_wrapped->getIdentifier()))); + $rule->integrityCheck(); + $rule->execute($article); + $this->assertEqual($term_wrapped->getIdentifier(), $article->field_tags[LANGUAGE_NONE][0]['tid'], 'Entity is of bundle condition has been met.'); + + // Test again using an entity variable. + $article = $this->drupalCreateNode(array('type' => 'article')); + $rule = rule(array( + 'entity' => array('type' => 'entity'), + )); + $rule->condition('entity_is_of_bundle', array( + 'entity:select' => 'entity', + 'type' => 'node', + 'bundle' => array('article'), + )); + $rule->action('data_set', array('data:select' => 'entity:field_tags', 'value' => array($term_wrapped->getIdentifier()))); + $rule->integrityCheck(); + $rule->execute(entity_metadata_wrapper('node', $article)); + $this->assertEqual($term_wrapped->getIdentifier(), $article->field_tags[LANGUAGE_NONE][0]['tid'], 'Entity is of bundle condition has been met.'); + // Test CRUD actions. $action = rules_action('entity_create', array( 'type' => 'node',