2

I'm attempting to follow this documentation to add a custom constraint to a field in a Paragraph but I'm having trouble in adding constraint to that field.

Currently I have book content type with paragraph type bibliographic_information. This paragraph type has a field named as field_book_edition. This field accepts a string value. I'd like to be able to add a constraint to the field so that it accepts a certain string pattern as input.

I've created constrain and tried using hook_entity_bundle_field_info_alter, when ever I try to save the node I am getting the following error.

The website encountered an unexpected error. Please try again later.

InvalidArgumentException: Field field_bibliographic_information is unknown. in Drupal\Core\Entity\ContentEntityBase->getTranslatedField() (line 587 of core/lib/Drupal/Core/Entity/ContentEntityBase.php).

My Code is as follows :

book_content.module

use Drupal\Core\Entity\EntityTypeInterface; /** * Implements hook_entity_bundle_field_info_alter(). */ function book_content_entity_bundle_field_info_alter(&$fields, EntityTypeInterface $entity_type, $bundle) { // Refer https://drupal.stackexchange.com/a/277438/ if ($entity_type->id() === 'paragraph' && $bundle === 'bibliographic_information' && isset($fields['field_book_edition'])) { // Add our custom validation to the book edition field. $fields['field_book_edition']->addConstraint('BookContentEditionConstraint'); } } 

BookContentEditionConstraintValidator.php

namespace Drupal\book_content\Plugin\Validation\Constraint; use Symfony\Component\Validator\Constraint; use Symfony\Component\Validator\ConstraintValidator; /** * Validates the Book Content constraint. */ class BookContentEditionConstraintValidator extends ConstraintValidator { /** * {@inheritdoc} */ public function validate($entity, Constraint $constraint) { $node = $entity->getEntity(); // Get referenced paragraph entities. $referenceItem = $node->get('field_bibliographic_information')->referencedEntities(); foreach ($referenceItem as $data) { $fields = [ 'field_book_author' => $data->field_book_price->value, 'field_book_edition' => $data->field_book_edition->value, 'field_book_language' => $data->field_book_language->value, 'field_book_pages' => $data->field_book_pages->value, 'field_book_price' => $data->field_book_price->value, 'field_book_published_year' => $data->field_book_published_year->value, 'field_book_synopsis' => $data->field_book_synopsis->value, 'field_website' => $data->field_website->getValue()[0]['uri'], ]; } // Check if the book edition matches or not. if ($fields['field_book_edition'] != 'asdfg') { $this->context->addViolation($constraint->invalidEdition, ['@edition' => $fields['field_book_edition']]); } } } 

Attached the Node and Paragraph structures screenshot.

I have gone through similar questions and read their comments/answers but coundn't find what exactly is the error in the code.

Add Constraint to Paragraph Field answer by Carlos

Adding Constraint to Paragraph field comment by 4k4

I implemented the same what is mentioned in both the links.But still it is not working.

For debugging purpose I have added the above constraint to a node field and it worked as expected.

From what I read if you provide the correct $entity_type->id() all the fields for the particular entity id will be rendered in $fields variable in hook_entity_bundle_field_info_alter , is my understanding is correct ?

Should I be implementing hook_entity_bundle_field_info_alter or hook_form_alter for adding a custom constraint to a paragraph field ?

Paragraph Structure Node Structure

EDIT 1:

After further debugging if I add

if ($node->hasField('field_bibliographic_information')) { \Drupal::logger('book_content')->info('Hello'); $referenceItem = $node->get('field_bibliographic_information')->referencedEntities(); ....remaining code..... } 

in validate method the code inside the loop doesn't get executed.

4
  • Your constraint is receiving an entity, then you need to add it to the entity type, see drupal.stackexchange.com/questions/224229/… Commented Jun 22, 2020 at 12:57
  • Hi @4k4 thank you for your response. Are you referring to use hook_entity_type_alter ? If so isnt it is for whole entity type and not for a specific field in entity type ? Can you please elaborate what you re referring to ? Commented Jun 22, 2020 at 14:16
  • 1
    A constraint with validate($entity) has to be attached to an entity, not a field. Besides from being an entity or field constraint you attach it to a paragraph and then expect that it has a node field. Commented Jun 22, 2020 at 15:43
  • Hi @4k4 I am completely lost can you please share a code snippet or any reference contrib module so that I can have a look. I also added additional debug info to the question, can you please have a look ? Commented Jun 22, 2020 at 16:06

1 Answer 1

2

I am able to achieve this finally.

Basically what I was doing wrong was I was assuming the $entity is a node object and but it actually is paragraph object.

<?php namespace Drupal\book_content\Plugin\Validation\Constraint; use Symfony\Component\Validator\Constraint; use Symfony\Component\Validator\ConstraintValidator; /** * Validates the Book Content constraint. */ class BookContentEditionConstraintValidator extends ConstraintValidator { /** * {@inheritdoc} */ public function validate($items, Constraint $constraint) { if (!$item = $items->first()) { return; } $field_name = $items->getFieldDefinition()->getName(); /** @var \Drupal\Core\Entity\EntityInterface $entity */ $entity = $items->getEntity(); if ($entity->hasField('field_book_edition')) { $edition = $entity->field_book_edition->value; // Check if the book edition matches or not. if ($edition != 'asdfg') { $this->context->addViolation($constraint->invalidEdition, ['@edition' => $edition]); } } } } 

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.