Browse Source

Allowing NodeHasTerm to check for multiple tags using AND logic (#167)

pull/729/head
dannylamb 5 years ago committed by Seth Shaw
parent
commit
e0d70b6059
  1. 53
      src/Plugin/Condition/NodeHasTerm.php
  2. 90
      tests/src/Functional/NodeHasTermTest.php

53
src/Plugin/Condition/NodeHasTerm.php

@ -83,11 +83,12 @@ class NodeHasTerm extends ConditionPluginBase implements ContainerFactoryPluginI
* {@inheritdoc}
*/
public function buildConfigurationForm(array $form, FormStateInterface $form_state) {
$default = [];
if (isset($this->configuration['uri']) && !empty($this->configuration['uri'])) {
$default = $this->utils->getTermForUri($this->configuration['uri']);
$uris = explode(',', $this->configuration['uri']);
foreach ($uris as $uri) {
$default[] = $this->utils->getTermForUri($uri);
}
else {
$default = NULL;
}
$form['term'] = [
@ -96,6 +97,7 @@ class NodeHasTerm extends ConditionPluginBase implements ContainerFactoryPluginI
'#tags' => TRUE,
'#default_value' => $default,
'#target_type' => 'taxonomy_term',
'#required' => TRUE,
];
return parent::buildConfigurationForm($form, $form_state);
@ -108,12 +110,18 @@ class NodeHasTerm extends ConditionPluginBase implements ContainerFactoryPluginI
// Set URI for term if possible.
$this->configuration['uri'] = NULL;
$value = $form_state->getValue('term');
$uris = [];
if (!empty($value)) {
$tid = $value[0]['target_id'];
foreach ($value as $target) {
$tid = $target['target_id'];
$term = $this->entityTypeManager->getStorage('taxonomy_term')->load($tid);
$uri = $this->utils->getUriForTerm($term);
if ($uri) {
$this->configuration['uri'] = $uri;
$uris[] = $uri;
}
}
if (!empty($uris)) {
$this->configuration['uri'] = implode(',', $uris);
}
}
parent::submitConfigurationForm($form, $form_state);
@ -144,18 +152,35 @@ class NodeHasTerm extends ConditionPluginBase implements ContainerFactoryPluginI
* TRUE if entity has all the specified term(s), otherwise FALSE.
*/
protected function evaluateEntity(EntityInterface $entity) {
foreach ($entity->referencedEntities() as $referenced_entity) {
if ($referenced_entity->getEntityTypeId() == 'taxonomy_term' && $referenced_entity->hasField(IslandoraUtils::EXTERNAL_URI_FIELD)) {
$field = $referenced_entity->get(IslandoraUtils::EXTERNAL_URI_FIELD);
if (!$field->isEmpty()) {
$link = $field->first()->getValue();
if ($link['uri'] == $this->configuration['uri']) {
return $this->isNegated() ? FALSE : TRUE;
}
}
// Find the terms on the node.
$terms = array_filter($entity->referencedEntities(), function ($entity) {
return $entity->getEntityTypeId() == 'taxonomy_term' &&
$entity->hasField(IslandoraUtils::EXTERNAL_URI_FIELD) &&
!$entity->get(IslandoraUtils::EXTERNAL_URI_FIELD)->isEmpty();
});
// Get their URIs.
$haystack = array_map(function ($term) {
return $term->get(IslandoraUtils::EXTERNAL_URI_FIELD)->first()->getValue()['uri'];
},
$terms
);
// FALSE if there's no URIs on the node.
if (empty($haystack)) {
return $this->isNegated() ? TRUE : FALSE;
}
// Get the URIs to look for. It's a required field, so there
// will always be one.
$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;
}
// Otherwise, FALSE.
return $this->isNegated() ? TRUE : FALSE;
}

90
tests/src/Functional/NodeHasTermTest.php

@ -0,0 +1,90 @@
<?php
namespace Drupal\Tests\islandora\Functional;
/**
* Tests the NodeHasTerm condition.
*
* @package Drupal\Tests\islandora\Functional
* @group islandora
*/
class NodeHasTermTest extends IslandoraFunctionalTestBase {
/**
* {@inheritdoc}
*/
public function setUp() {
parent::setUp();
// Set up two tags so we can test the condition.
// Doesn't really matter what they are or what
// vocab they belong to.
$this->createImageTag();
$this->createPreservationMasterTag();
}
/**
* @covers \Drupal\islandora\Plugin\Condition\NodeHasTerm
*/
public function testNodeHasTerm() {
// Create a new node with the tag.
$node = $this->container->get('entity_type.manager')->getStorage('node')->create([
'type' => 'test_type',
'title' => 'Test Node',
'field_tags' => [$this->imageTerm->id()],
]);
// Create and execute the condition.
$condition_manager = $this->container->get('plugin.manager.condition');
$condition = $condition_manager->createInstance(
'node_has_term',
[
'uri' => 'http://purl.org/coar/resource_type/c_c513',
]
);
$condition->setContextValue('node', $node);
$this->assertTrue($condition->execute(), "Condition should pass if node has the term");
// Create a new node without the tag.
$node = $this->container->get('entity_type.manager')->getStorage('node')->create([
'type' => 'test_type',
'title' => 'Test Node',
]);
$condition->setContextValue('node', $node);
$this->assertFalse($condition->execute(), "Condition should fail if the node does not have any terms");
// Create a new node with the wrong tag.
$node = $this->container->get('entity_type.manager')->getStorage('node')->create([
'type' => 'test_type',
'title' => 'Test Node',
'field_tags' => [$this->preservationMasterTerm->id()],
]);
$condition->setContextValue('node', $node);
$this->assertFalse($condition->execute(), "Condition should fail if the node has terms, but not the one we want.");
// 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',
]
);
$condition->setContextValue('node', $node);
$this->assertFalse($condition->execute(), "Condition should fail if node does not have both terms");
// Create a node with both tags.
$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");
}
}
Loading…
Cancel
Save