FieldValueVariantCondition.php 3.63 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
<?php

namespace Drupal\typed_entity\WrappedEntityVariants;

use Drupal\Core\Entity\EntityFieldManager;
use Drupal\Core\Entity\FieldableEntityInterface;
use Drupal\Core\Field\FieldStorageDefinitionInterface;
use Drupal\Core\StringTranslation\StringTranslationTrait;
use Drupal\typed_entity\InvalidValueException;

e0ipso's avatar
e0ipso committed
11
12
13
/**
 * Configurable variant condition that checks for a given value in a field.
 */
14
15
16
17
18
class FieldValueVariantCondition implements VariantConditionInterface, ContextAwareInterface {

  use ContextAwareTrait;
  use StringTranslationTrait;

e0ipso's avatar
e0ipso committed
19
20
21
22
23
  /**
   * Inverse the result of the evaluation.
   *
   * @var bool
   */
24
  protected $isNegated = FALSE;
e0ipso's avatar
e0ipso committed
25
26
27
28
29
30

  /**
   * Name of the field that contains the data.
   *
   * @var string
   */
31
  protected $fieldName = '';
e0ipso's avatar
e0ipso committed
32
33
34
35
36
37

  /**
   * The value to check for.
   *
   * @var null
   */
38
  protected $value = NULL;
e0ipso's avatar
e0ipso committed
39
40
41
42
43
44

  /**
   * The FQN of the wrapper class for the variant.
   *
   * @var string
   */
45
46
47
48
49
50
  protected $variant;

  /**
   * FieldValueVariantCondition constructor.
   *
   * @param string $field_name
e0ipso's avatar
e0ipso committed
51
52
53
54
55
56
57
58
59
   *   Name of the field that contains the data.
   * @param mixed $value
   *   The value to check for.
   * @param string $variant
   *   The FQN of the wrapper class for the variant.
   * @param bool $is_negated
   *   Inverse the result of the evaluation.
   *
   * @SuppressWarnings(PHPMD.BooleanArgumentFlag)
60
   */
e0ipso's avatar
e0ipso committed
61
  public function __construct(string $field_name, $value, string $variant, bool $is_negated = FALSE) {
62
63
64
65
66
67
    $this->isNegated = $is_negated;
    $this->fieldName = $field_name;
    $this->value = $value;
    $this->variant = $variant;
  }

e0ipso's avatar
e0ipso committed
68
69
70
  /**
   * {@inheritdoc}
   */
71
72
73
74
  public function isNegated(): bool {
    return $this->isNegated;
  }

e0ipso's avatar
e0ipso committed
75
76
77
78
79
80
81
  /**
   * {@inheritdoc}
   *
   * @throws \Drupal\typed_entity\InvalidValueException
   *
   * @SuppressWarnings(PHPMD.StaticAccess)
   */
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
  public function evaluate(): bool {
    $this->validateContext();
    $entity = $this->getContext('entity');
    assert($entity instanceof FieldableEntityInterface);
    // Check if the any of the values for the field match the configured value.
    $values = $entity->get($this->fieldName)->getValue();
    // TODO: explore the field configuration to learn about the main property.
    $field_manager = \Drupal::service('entity_field.manager');
    assert($field_manager instanceof EntityFieldManager);
    $definition = $field_manager->getFieldStorageDefinitions($entity->getEntityTypeId())[$this->fieldName];
    assert($definition instanceof FieldStorageDefinitionInterface);
    $main_property = $definition->getMainPropertyName();
    $result = array_reduce($values, function ($carry, $value) use ($main_property) {
      return $carry || ($value[$main_property] ?? NULL) == $this->value;
    }, FALSE);
    return $this->isNegated() ? !$result : $result;
  }

e0ipso's avatar
e0ipso committed
100
101
102
  /**
   * {@inheritdoc}
   */
103
104
105
106
107
108
109
  public function summary(): string {
    return $this->t('Active when the %field is %value.', [
      '%field' => $this->fieldName,
      '%value' => $this->value,
    ]);
  }

e0ipso's avatar
e0ipso committed
110
111
112
  /**
   * {@inheritdoc}
   */
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
  public function variant(): string {
    return $this->variant;
  }

  /**
   * {@inheritdoc}
   */
  public function validateContext(): void {
    $entity = $this->getContext('entity');
    if (!$entity instanceof FieldableEntityInterface) {
      throw new InvalidValueException('The context for the entity was not fulfilled');
    }
    if (!$entity->hasField($this->fieldName)) {
      $message = sprintf(
        'The entity type "%s" with bundle "%s" does not have a field by name "%s".',
        $entity->getEntityTypeId(),
        $entity->bundle(),
        $this->fieldName
      );
      throw new InvalidValueException($message);
    }
  }

}