Support conditions through Entity Validation API

Created on 5 November 2020, over 4 years ago
Updated 6 August 2024, 11 months ago

Problem/Motivation

It should be possible to add conditions to a giftcard.
The scope of this ticket is to provide an API so developers can create constraints.
Out of scope: a backend UI, extra default conditions.

Proposed resolution

As discussed with Berdir on Slack, we can use the Entity Validation API for this.

Examples

Here is an example of adding your own custom constraints. This one adds an expiration date of 1 year to the giftcard.

my_module.module

/**
 * Implements hook_entity_base_field_info_alter().
 */
function my_module_entity_base_field_info_alter(&$fields, EntityTypeInterface $entity_type) {
  if ($entity_type->id() === 'commerce_order') {
    if (array_key_exists('commerce_giftcards', $fields) && $fields['commerce_giftcards'] instanceof BaseFieldDefinition) {
      /** @var BaseFieldDefinition $commerce_giftcards */
      $commerce_giftcards = &$fields['commerce_giftcards'];
      $commerce_giftcards->addConstraint('GiftcardExpirationDate');
    }
  }
}

GiftcardExpirationDate.php

<?php

namespace Drupal\my_module\Plugin\Validation\Constraint;

use Symfony\Component\Validator\Constraint;

/**
 * Ensures gift card isn't expired.
 *
 * @Constraint(
 *   id = "GiftcardExpirationDate",
 *   label = @Translation("Giftcard expiration date", context = "Validation")
 * )
 */
class GiftcardExpirationDate extends Constraint {

  public $message = 'The giftcard has expired.';

}

GiftcardExpirationDateValidator.php

<?php

namespace Drupal\my_module\Plugin\Validation\Constraint;

use Drupal\commerce_giftcard\Entity\GiftcardInterface;
use Drupal\Core\Datetime\DrupalDateTime;
use Drupal\Core\Field\EntityReferenceFieldItemListInterface;
use Drupal\datetime\Plugin\Field\FieldType\DateTimeItemInterface;
use Symfony\Component\Validator\Constraint;
use Symfony\Component\Validator\ConstraintValidator;

/**
 * Validates the GiftcardExpirationDate constraint.
 */
class GiftcardExpirationDateValidator extends ConstraintValidator {

  /**
   * {@inheritdoc}
   */
  public function validate($value, Constraint $constraint) {
    assert($value instanceof EntityReferenceFieldItemListInterface);

    foreach ($value as $delta => $item) {
      $giftcard = $item->entity;
      if ($giftcard instanceof GiftcardInterface) {
        $expiration_date = DrupalDateTime::createFromTimestamp($giftcard->getCreatedTime());
        $expiration_date->add(new \DateInterval('P1Y'));
        $now = new DrupalDateTime('now');

        if ($now > $expiration_date) {
          $created = DrupalDateTime::createFromTimestamp($giftcard->getCreatedTime());

          $this->context->buildViolation($constraint->message)
            ->atPath($delta)
            ->setInvalidValue($created->format(DateTimeItemInterface::DATETIME_STORAGE_FORMAT))
            ->addViolation();
        }
      }
    }
  }

}
Feature request
Status

Needs work

Version

1.0

Component

Code

Created by

🇧🇪Belgium matthiasm11

Live updates comments and jobs are added and updated live.
Sign in to follow issues

Comments & Activities

Not all content is available!

It's likely this issue predates Contrib.social: some issue and comment data are missing.

Production build 0.71.5 2024