{"id":60378,"date":"2024-02-27T11:32:06","date_gmt":"2024-02-27T06:02:06","guid":{"rendered":"https:\/\/www.tothenew.com\/blog\/?p=60378"},"modified":"2024-02-27T11:32:06","modified_gmt":"2024-02-27T06:02:06","slug":"create-custom-validation-constraints-in-drupal-10","status":"publish","type":"post","link":"https:\/\/www.tothenew.com\/blog\/create-custom-validation-constraints-in-drupal-10\/","title":{"rendered":"Create custom validation constraints in Drupal 10"},"content":{"rendered":"<h2><strong>Introduction<\/strong><\/h2>\n<p>Drupal core uses the validation API(Constraints) to validate the fields, Now, Drupal provides the flexibility to use the core validator to validate your own entity without writing the validation. We can also create a custom validator if needed. For uses <em>constraints<\/em> to write custom validators.<\/p>\n<h2><strong>Limitations on the form based validation<\/strong><\/h2>\n<p>Generally, we use form based validation if we would like to add any validation on the form or entity with the help of HOOK_form_alter, But now, with the help of constraints, we can use the existing validator.<\/p>\n<p>There are some limitations if we use form based validation.<\/p>\n<ul>\n<li>\u00a0Can not add validation on the entity fields without adding the form validation<\/li>\n<li>\u00a0Create a node from REST API, it does not trigger the validation because the form does not render,<\/li>\n<\/ul>\n<p>We can add validation to the fields\/entities with the help of constraints, which are implemented as plugins.<\/p>\n<h2><strong>Creating a custom constraint requires three steps<\/strong><\/h2>\n<ul>\n<li>Define the constraint<\/li>\n<li>Create the validation for the constraint<\/li>\n<li>Set the constraint to the entity type or field it needs to validate<\/li>\n<\/ul>\n<p><strong>Step : 1: Define the Constraints<\/strong><\/p>\n<p>The constraint definition will go in the namespace <em>Drupal\\[MODULENAME]\\Plugin\\Validation\\Constraint<\/em>\u00a0and will extend <em>Symfony\\Component\\Validator\\Constraint.<\/em> In this class, the types of constraint violations are defined, along with the error messages that will be displayed for the given violations.<\/p>\n<p>Filename: IntegerConstraint.php<\/p>\n<div>\n<pre>&lt;?php\r\nnamespace Drupal\\learning\\Plugin\\Validation\\Constraint;\r\nuse Symfony\\Component\\Validator\\Constraint;\r\n\r\n\/**\r\n\u00a0* Checks that the submitted value is a unique integer.\r\n\u00a0*\r\n\u00a0* @Constraint(\r\n\u00a0* \u00a0 id = \"Integer\",\r\n\u00a0* \u00a0 label = @Translation(\"Integer\", context = \"Validation\"),\r\n\u00a0* \u00a0 type = \"string\"\r\n\u00a0* )\r\n\u00a0*\/\r\n\r\nclass IntegerConstraint extends Constraint {\r\n\u00a0 \/\/ The message that will be shown if the value is not an integer.\r\n\u00a0 public $notIntegerMessage = '%value is not an integer';\r\n}<\/pre>\n<p><strong style=\"font-family: Consolas, Monaco, monospace;\">Step 2: Create the Validator for the Constraint<\/strong><\/p>\n<\/div>\n<p>The next step is to create the class that will validate the constraint.<\/p>\n<p>The constraint validation will go in the namespace <em>Drupal\\[MODULENAME]\\Plugin\\Validation\\Constraint <\/em>and will extend <em>Symfony\\Component\\Validator\\ConstraintValidator. <\/em>In this class, the submitted values will be returned, and any violations will be registered.<\/p>\n<p>Filename : <em>IntegerConstraintValidator.php<\/em><\/p>\n<div>\n<pre>&lt;?php\r\n\r\nnamespace Drupal\\learning\\Plugin\\Validation\\Constraint;\r\nuse Symfony\\Component\\Validator\\Constraint;\r\nuse Symfony\\Component\\Validator\\ConstraintValidator;\r\n\/**\r\n\u00a0* Validates the Integer constraint.\r\n\u00a0*\/\r\nclass IntegerConstraintValidator extends ConstraintValidator {\r\n\u00a0 \/**\r\n\u00a0 \u00a0* {@inheritdoc}\r\n\u00a0 \u00a0*\/\r\n\u00a0 public function validate($value, Constraint $constraint) {\r\n\u00a0 \u00a0 foreach ($value as $item) {\r\n\u00a0 \u00a0 \u00a0 if (!is_int($item-&gt;value)) {\r\n\u00a0 \u00a0 \u00a0 \u00a0 $this-&gt;context-&gt;addViolation($constraint-&gt;notIntegerMessage, ['%value' =&gt; $item-&gt;value]);\r\n\u00a0 \u00a0 \u00a0 }\r\n\u00a0 \u00a0 }\r\n\u00a0 }\r\n}<\/pre>\n<\/div>\n<p><strong>Step 3: Set the Constraint to the Entity or Field it Needs to Validate<\/strong><\/p>\n<p>Drupal provides some hooks to trigger the validation constraints.<\/p>\n<p><strong> 3.1 &#8211; Adding a Constraint to the Bundle Field of an Entity\/content Type <\/strong><\/p>\n<p>This method is used to add constraints to a field on an entity type defined in an other module or field added in the entity manually. but not the core field like entity title, created etc.<\/p>\n<div>\n<pre>\/**\r\n\u00a0* Implements hook_entity_bundle_field_info_alter().\r\n\u00a0*\/\r\nfunction learning_entity_bundle_field_info_alter(&amp;$fields, \\Drupal\\Core\\Entity\\EntityTypeInterface $entity_type, $bundle) {\r\n  \/\/Here test is the content type, and i added a field {field_name}\r\n\u00a0 if ($entity_type-&gt;id() === 'node' &amp;&amp; $bundle === 'test') {\r\n\u00a0 \u00a0 if (isset($fields['field_name'])) {\r\n\u00a0 \u00a0 \u00a0 \/\/ Use the ID as defined in the annotation of the constraint definition\r\n\u00a0 \u00a0 \u00a0 $fields['field_name']-&gt;addConstraint('Integer');\r\n\u00a0 \u00a0 }\r\n\u00a0 }\r\n}\r\n<\/pre>\n<p><strong>3.2 Adding a Constraint to an Entity Type Not Defined by Your Module <\/strong><\/p>\n<p>This hook is used to add constraints to whole entity type <strong><em>hook_entity_type_alter() <\/em><\/strong><\/p>\n<pre>\/**\r\n\u00a0* Implements hook_entity_type_alter().\r\n\u00a0*\/\r\n\u00a0 function learning_entity_type_alter(array &amp;$entity_types) {\r\n\u00a0 \u00a0 \/\/ Add validation constraint to the node entity\r\n\u00a0 \u00a0 $entity_types['node']-&gt;addConstraint('Integer');\r\n\u00a0 }<\/pre>\n<p><strong>3.3 Adding a Constraint to an Entity basefield <\/strong><\/p>\n<pre>\/**\r\n\u00a0* Implements hook_entity_base_field_info_alter().\r\n\u00a0*\/\r\nfunction learning_entity_base_field_info_alter(&amp;$fields, \\Drupal\\Core\\Entity\\EntityTypeInterface $entity_type) {\r\n\u00a0 \u00a0 if ($entity_type-&gt;id() == 'node' &amp;&amp; !empty($fields['title'])) {\r\n\u00a0 \u00a0 \u00a0 $fields['title']-&gt;addConstraint('Integer');\r\n\u00a0 \u00a0 }\r\n\u00a0 }<\/pre>\n<div><\/div>\n<div><img decoding=\"async\" loading=\"lazy\" class=\"alignnone wp-image-60377 size-large\" src=\"\/blog\/wp-ttn-blog\/uploads\/2024\/02\/Screenshot-2024-02-19-193319-1024x592.png\" alt=\"validation constraint\" width=\"625\" height=\"361\" srcset=\"\/blog\/wp-ttn-blog\/uploads\/2024\/02\/Screenshot-2024-02-19-193319-1024x592.png 1024w, \/blog\/wp-ttn-blog\/uploads\/2024\/02\/Screenshot-2024-02-19-193319-300x173.png 300w, \/blog\/wp-ttn-blog\/uploads\/2024\/02\/Screenshot-2024-02-19-193319-768x444.png 768w, \/blog\/wp-ttn-blog\/uploads\/2024\/02\/Screenshot-2024-02-19-193319-624x361.png 624w, \/blog\/wp-ttn-blog\/uploads\/2024\/02\/Screenshot-2024-02-19-193319.png 1247w\" sizes=\"(max-width: 625px) 100vw, 625px\" \/><\/div>\n<\/div>\n<h2><strong>Conclusion\u00a0<\/strong><\/h2>\n<p>We learned about the validator and its uses and also explored how to create custom constraints within Drupal 10.<\/p>\n<p>We can create any kind of validator and reuse that code anywhere in the application. Some of the core constraint validators already exist in the Drupal core, to check the existing constraints follow the reference link.<\/p>\n<p><strong>Reference :<\/strong><\/p>\n<p>Drupal custom constraints &#8211; <a href=\"https:\/\/api.drupal.org\/api\/drupal\/9\/search\/ConstraintValidator\" target=\"_blank\" rel=\"noopener\">https:\/\/api.drupal.org\/api\/drupal\/9\/search\/ConstraintValidator<\/a><\/p>\n<div class=\"ap-custom-wrapper\"><\/div><!--ap-custom-wrapper-->","protected":false},"excerpt":{"rendered":"<p>Introduction Drupal core uses the validation API(Constraints) to validate the fields, Now, Drupal provides the flexibility to use the core validator to validate your own entity without writing the validation. We can also create a custom validator if needed. For uses constraints to write custom validators. Limitations on the form based validation Generally, we use [&hellip;]<\/p>\n","protected":false},"author":1509,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"iawp_total_views":547},"categories":[3602],"tags":[4862],"aioseo_notices":[],"_links":{"self":[{"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/posts\/60378"}],"collection":[{"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/users\/1509"}],"replies":[{"embeddable":true,"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/comments?post=60378"}],"version-history":[{"count":4,"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/posts\/60378\/revisions"}],"predecessor-version":[{"id":60473,"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/posts\/60378\/revisions\/60473"}],"wp:attachment":[{"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/media?parent=60378"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/categories?post=60378"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/tags?post=60378"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}