Score:0

How to use setConstraints() for a custom constraint on BaseFieldDefinition?

cn flag

I'm refactoring a node content type into a custom entity.

On this entity, I add a datetime field:

$fields['target_date'] = BaseFieldDefinition::create('datetime')
          ->setLabel(t('Target date'))
          ->setCardinality(1)
          ->setRequired(TRUE)
          ->setConstraints(['DateTimeMidnightOnly' => DateTimeMidnightOnlyValidator::class])
          ->setSetting('datetime_type', 'datetime')
          ->setDisplayConfigurable('form', TRUE)
          ->setDisplayOptions('form', [
            'weight' => 10,
          ])
          ->setDisplayConfigurable('view', TRUE);

However, when I attempt to save a new entity of this entity type, I'm getting the following error:

Drupal\Core\Entity\EntityStorageException: No default option is configured for constraint "Drupal\mymodule\Plugin\Validation\Constraint\DateTimeMidnightOnly". in Drupal\Core\Entity\Sql\SqlContentEntityStorage->save() (line 811 of /app/web/core/lib/Drupal/Core/Entity/Sql/SqlContentEntityStorage.php).

I also tried this:

          ->setConstraints(['DateTimeMidnightOnly'])

Which gives the error:

Drupal\Core\Entity\EntityStorageException: The "0" plugin does not exist. Valid plugin IDs for Drupal\Core\Validation\ConstraintManager are: Callback, Blank, NotBlank, Email, CKEditor5Element, CKEditor5ToolbarItemDependencyConstraint, StyleSensibleElement, CKEditor5MediaAndFilterSettingsInSync, SourceEditingRedundantTags, CKEditor5EnabledConfigurablePlugins, CKEditor5FundamentalCompatibility, SourceEditingPreventSelfXssConstraint, UniqueLabelInList, CKEditor5ToolbarItemConditionsMet, CKEditor5ToolbarItem, CommentName, DateTimeFormat, ValidDynamicReference, FileValidation....

I'm clearly calling setConstraints() wrong, because this constraint worked when I added it on my content type using hook_entity_bundle_field_info_alter():

function mymodule_entity_bundle_field_info_alter(array &$fields, EntityTypeInterface $entity_type, string $bundle): void {
  $entity_type = $entity_type->id();
  if ($entity_type === 'node') {
    if (isset($fields['field_datetime_review_target'])) {
      $fields['field_datetime_review_target']->addConstraint('DateTimeMidnightOnly');
    }
  }
}

What's the right way to set ->setConstraints() to add a custom constraint plugin? Or, is this actually the wrong way and I should always use hook_entity_bundle_field_info_alter()?

4uk4 avatar
cn flag
You can use `setConstraints()` to set an entire array, but then you need to apply the correct array structure, where the options are the array values. `addConstraint()` is more user friendly and it should work in your case as well.
cn flag
@4uk4 Yeah, I was using the wrong method, as you point out. I think your comment is the answer so please repost as an answer so that I can accept.
miststudent2011 avatar
fr flag
If you still wanted to use setConstraint() here is a working example https://git.drupalcode.org/sandbox/Bhanu951-3103712/-/blob/8.x-dev/omdb_api/src/Entity/OmdbApiEntity.php#L793
I sit in a Tesla and translated this thread with Ai:

mangohost

Post an answer

Most people don’t grasp that asking a lot of questions unlocks learning and improves interpersonal bonding. In Alison’s studies, for example, though people could accurately recall how many questions had been asked in their conversations, they didn’t intuit the link between questions and liking. Across four studies, in which participants were engaged in conversations themselves or read transcripts of others’ conversations, people tended not to realize that question asking would influence—or had influenced—the level of amity between the conversationalists.