From b8abc327b01c9232cefa08ad75e6670a34ee5beb Mon Sep 17 00:00:00 2001 From: dannylamb Date: Fri, 15 Nov 2019 18:46:01 +0000 Subject: [PATCH] Adding OR logic to NodeHasTerm and ilk --- config/schema/islandora.schema.yml | 9 +++++ src/Plugin/Condition/NodeHasTerm.php | 42 ++++++++++++++++++++---- tests/src/Functional/NodeHasTermTest.php | 26 +++++++++++++-- 3 files changed, 69 insertions(+), 8 deletions(-) diff --git a/config/schema/islandora.schema.yml b/config/schema/islandora.schema.yml index 8fd719ce..f63e4341 100644 --- a/config/schema/islandora.schema.yml +++ b/config/schema/islandora.schema.yml @@ -78,6 +78,9 @@ condition.plugin.node_has_term: uri: type: text label: 'Taxonomy Term URI' + logic: + type: string + label: 'Logic (AND or OR)' condition.plugin.node_has_parent: type: condition.plugin @@ -95,6 +98,9 @@ condition.plugin.media_has_term: uri: type: text label: 'Taxonomy Term URI' + logic: + type: string + label: 'Logic (AND or OR)' condition.plugin.parent_node_has_term: type: condition.plugin @@ -102,6 +108,9 @@ condition.plugin.parent_node_has_term: uri: type: text label: 'Taxonomy Term URI' + logic: + type: string + label: 'Logic (AND or OR)' condition.plugin.file_uses_filesystem: type: condition.plugin diff --git a/src/Plugin/Condition/NodeHasTerm.php b/src/Plugin/Condition/NodeHasTerm.php index dae52ad0..c912ea9b 100644 --- a/src/Plugin/Condition/NodeHasTerm.php +++ b/src/Plugin/Condition/NodeHasTerm.php @@ -79,6 +79,16 @@ class NodeHasTerm extends ConditionPluginBase implements ContainerFactoryPluginI ); } + /** + * {@inheritdoc} + */ + public function defaultConfiguration() { + return array_merge( + ['logic' => 'and'], + parent::defaultConfiguration() + ); + } + /** * {@inheritdoc} */ @@ -100,6 +110,16 @@ class NodeHasTerm extends ConditionPluginBase implements ContainerFactoryPluginI '#required' => TRUE, ]; + $form['logic'] = [ + '#type' => 'radios', + '#title' => $this->t('Logic'), + '#description' => $this->t('Whether to use AND or OR logic to evaluate multiple terms'), + '#options' => [ + 'and' => 'And', + 'or' => 'Or', + ], + '#default_value' => $this->configuration['logic'], + ]; return parent::buildConfigurationForm($form, $form_state); } @@ -124,6 +144,9 @@ class NodeHasTerm extends ConditionPluginBase implements ContainerFactoryPluginI $this->configuration['uri'] = implode(',', $uris); } } + + $this->configuration['logic'] = $form_state->getValue('logic'); + parent::submitConfigurationForm($form, $form_state); } @@ -168,7 +191,7 @@ class NodeHasTerm extends ConditionPluginBase implements ContainerFactoryPluginI // FALSE if there's no URIs on the node. if (empty($haystack)) { - return $this->isNegated() ? TRUE : FALSE; + return FALSE; } // Get the URIs to look for. It's a required field, so there @@ -176,12 +199,19 @@ class NodeHasTerm extends ConditionPluginBase implements ContainerFactoryPluginI $needles = explode(',', $this->configuration['uri']); // TRUE if every needle is in the haystack. - if (count(array_intersect($needles, $haystack)) == count($needles)) { - return $this->isNegated() ? FALSE : TRUE; + if ($this->configuration['logic'] == 'and') { + if (count(array_intersect($needles, $haystack)) == count($needles)) { + return TRUE; + } + return FALSE; + } + // TRUE if any needle is in the haystack. + else { + if (count(array_intersect($needles, $haystack)) > 0) { + return TRUE; + } + return FALSE; } - - // Otherwise, FALSE. - return $this->isNegated() ? TRUE : FALSE; } /** diff --git a/tests/src/Functional/NodeHasTermTest.php b/tests/src/Functional/NodeHasTermTest.php index a27cf474..7d336de0 100644 --- a/tests/src/Functional/NodeHasTermTest.php +++ b/tests/src/Functional/NodeHasTermTest.php @@ -77,14 +77,36 @@ class NodeHasTermTest extends IslandoraFunctionalTestBase { $condition->setContextValue('node', $node); $this->assertFalse($condition->execute(), "Condition should fail if node does not have both terms"); - // Create a node with both tags. + // Check for two tags this time. + // Node still only has one. + $condition = $condition_manager->createInstance( + 'node_has_term', + [ + 'uri' => 'http://purl.org/coar/resource_type/c_c513,http://pcdm.org/use#PreservationMasterFile', + 'logic' => 'or', + ] + ); + $condition->setContextValue('node', $node); + $this->assertTrue($condition->execute(), "Condition should pass if has one of two terms using OR logic."); + + // Create a node with both tags and try it with OR. $node = $this->container->get('entity_type.manager')->getStorage('node')->create([ 'type' => 'test_type', 'title' => 'Test Node', 'field_tags' => [$this->imageTerm->id(), $this->preservationMasterTerm->id()], ]); $condition->setContextValue('node', $node); - $this->assertTrue($condition->execute(), "Condition should pass if node has both terms"); + $this->assertTrue($condition->execute(), "Condition should pass if node has both terms using OR logic"); + + // Try it with AND. + $condition = $condition_manager->createInstance( + 'node_has_term', + [ + 'uri' => 'http://purl.org/coar/resource_type/c_c513,http://pcdm.org/use#PreservationMasterFile', + ] + ); + $condition->setContextValue('node', $node); + $this->assertTrue($condition->execute(), "Condition should pass if node has both terms using AND logic"); } }