3

I have created a complex field type (my class extends DateRangeItem) that supports recurring dates by adding a property for storing an RRULE string:

class DateTimeRecurItem extends DateRangeItem {

  /**
   * {@inheritdoc}
   */
  public static function propertyDefinitions(FieldStorageDefinitionInterface $field_definition) {
    $properties = parent::propertyDefinitions($field_definition);
    // Prevent early t() calls by using the TranslatableMarkup.
    $properties['rrule_string'] = DataDefinition::create('string')
      ->setLabel(new TranslatableMarkup('RRule String'))
      ->setRequired(FALSE);

    return $properties;
  }

  ...

I want to validate the RRule string (there's a RFC to validate it against). I can do this by creating a custom constraint and applying it like this:

$properties['rrule_string'] = DataDefinition::create('string')
  ->setLabel(new TranslatableMarkup('RRule String'))
  ->setConstraint('MyCustomConstraint')
  ->setRequired(FALSE);

The problem is I also need to know the value for the value property of the field (which is inherited by DateRangeItem). Implemented as above, my constraint validator will only be passed the raw string value of the rrule_string property.

I can't figure out how I can define a constraint that applies to the entire field (thereby having access to all of its field properties). There seems to be no interface for doing that.

To be clear, this is not a field I've added to a custom entity definition. This is just a custom field I defined that can be added to any entity.

2 Answers 2

3

In case of a field type, you can simply put it in the annotation.

Have a look at FileItem for example:

/**
 * Plugin implementation of the 'file' field type.
 *
 * @FieldType(
 *   id = "file",
 *   label = @Translation("File"),
 *   description = @Translation("This field stores the ID of a file as an integer value."),
 *   category = @Translation("Reference"),
 *   default_widget = "file_generic",
 *   default_formatter = "file_default",
 *   list_class = "\Drupal\file\Plugin\Field\FieldType\FileFieldItemList",
 *   constraints = {"ReferenceAccess" = {}, "FileValidation" = {}}
 * )
 */
class FileItem extends EntityReferenceItem {

Actually a bit surprised that the date classes don't have any constraints, that sounds like a bug.

1
  • Thanks! I originally looked at the FieldType annotation class but didn't see a defined property for constraints so I didn't think this was possible.
    – Brian
    Jan 23, 2017 at 13:15
0

Override the getConstraints method.

public function getConstraints() {
  $constraint_manager = \Drupal::typedDataManager()->getValidationConstraintManager();
  $constraints = parent::getConstraints();
  $constraints[] = $constraint_manager->create('CustomConstraint', array()); 
  return $constraints;
} 
1
  • Alternatively $constraint_manager = $this->getTypedDataManager()->getValidationConstraintManager()
    – Tim
    Jan 4 at 11:53

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.