eca-1.0.x-dev/modules/content/src/Plugin/ECA/Condition/EntityFieldValueChanged.php
modules/content/src/Plugin/ECA/Condition/EntityFieldValueChanged.php
<?php
namespace Drupal\eca_content\Plugin\ECA\Condition;
use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Field\BaseFieldDefinition;
use Drupal\Core\Field\FieldConfigInterface;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Plugin\Context\ContextDefinition;
use Drupal\Core\StringTranslation\TranslatableMarkup;
use Drupal\eca\Attribute\EcaCondition;
use Drupal\eca\EntityOriginalTrait;
use Drupal\eca\Plugin\ECA\Condition\ConditionBase;
use Drupal\eca\TypedData\PropertyPathTrait;
/**
* Plugin implementation of the ECA condition for changed entity field value.
*/
#[EcaCondition(
id: 'eca_entity_field_value_changed',
label: new TranslatableMarkup('Entity: field value changed'),
context_definitions: [
'entity' => new ContextDefinition(
data_type: 'entity',
label: new TranslatableMarkup('Entity'),
),
],
description: new TranslatableMarkup('Evaluates against the change of a value field of an entity.'),
version_introduced: '1.0.0',
)]
class EntityFieldValueChanged extends ConditionBase {
use EntityOriginalTrait;
use PropertyPathTrait;
/**
* {@inheritdoc}
*/
public function evaluate(): bool {
$entity = $this->getValueFromContext('entity');
$field_name = $this->tokenService->replaceClear($this->configuration['field_name']);
$options = ['access' => FALSE, 'auto_item' => FALSE];
$original = $this->getOriginal($entity);
if (($entity instanceof EntityInterface) && ($original instanceof EntityInterface) && ($property = $this->getTypedProperty($entity->getTypedData(), $field_name, $options)) && ($original_property = $this->getTypedProperty($original->getTypedData(), $field_name, $options))) {
$value = $property->getValue();
$original_value = $original_property->getValue();
if (is_countable($value) && count($value) !== count($original_value)) {
return $this->negationCheck(TRUE);
}
$dataDefinition = $property->getDataDefinition();
if ($dataDefinition instanceof FieldConfigInterface || $dataDefinition instanceof BaseFieldDefinition) {
$type = $dataDefinition->getFieldStorageDefinition()->getType();
if (in_array($type, ['boolean', 'entity_reference'], TRUE)) {
foreach ($value as $key => $item) {
switch ($type) {
case 'boolean':
$value[$key]['value'] = (bool) $item['value'];
$original_value[$key]['value'] = (bool) $original_value[$key]['value'];
break;
case 'entity_reference':
$value[$key] = [
'target_id' => $item['target_id'],
'weight' => $item['weight'] ?? 0,
];
$original_value[$key] = [
'target_id' => $original_value[$key]['target_id'],
'weight' => $original_value[$key]['weight'] ?? $value[$key]['weight'],
];
break;
default:
ksort($value[$key]);
}
}
}
}
return $this->negationCheck($value !== $original_value);
}
return FALSE;
}
/**
* {@inheritdoc}
*/
public function defaultConfiguration(): array {
return [
'field_name' => '',
] + parent::defaultConfiguration();
}
/**
* {@inheritdoc}
*/
public function buildConfigurationForm(array $form, FormStateInterface $form_state): array {
$form['field_name'] = [
'#type' => 'textfield',
'#title' => $this->t('Field name'),
'#description' => $this->t('The field name of the entity to check, if its value has changed.'),
'#default_value' => $this->configuration['field_name'],
'#weight' => -10,
];
return parent::buildConfigurationForm($form, $form_state);
}
/**
* {@inheritdoc}
*/
public function submitConfigurationForm(array &$form, FormStateInterface $form_state): void {
$this->configuration['field_name'] = $form_state->getValue('field_name');
parent::submitConfigurationForm($form, $form_state);
}
}
