Add a support of targeting subelements during validation

Created on 23 August 2018, about 6 years ago
Updated 20 September 2024, 2 months ago

I'm trying to write a validator to validate a specific field of the paragraph, but as a result when I add a contraint I can target only the paragraph itself, but not the form items of the paragraph.
For example: I have a paragraph with two fields field_one and field_two. I add a constraint for the field_one like this:

function entity_reference_validators_entity_bundle_field_info_alter(&$fields, EntityTypeInterface $entity_type, $bundle) {
  foreach ($fields as $key => $field) {
    if ($key == 'field_my_paragraph') {
      $field->addConstraint('MyContratint');
    }

and then try to target it using the path:

// MyContratint validation

$this->context->buildViolation($constraint->message)
            ->setInvalidValue($value)
            ->atPath($delta . '.subform.field_one') // This how target it
            ->addViolation();

but still the current paragraph is selected.
I tried different combinations of the path and debugged validation element ($error_element) in WidgetBase.php class, but it always returns the paragraph

✨ Feature request
Status

Closed: duplicate

Version

1.0

Component

Code

Created by

πŸ‡§πŸ‡ͺBelgium lobsterr

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

Merge Requests

Comments & Activities

Not all content is available!

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

  • πŸ‡ͺπŸ‡ͺEstonia pjotr.savitski

    It seems that there is an issue with the current code that prevents a certain field form being targeted.

    The issue is with the !empty($error->arrayPropertyPath) check of the errorElement method that will return false regardless of the real value of arrayPropertyPath property that seems to be fetched through the magic __get method. The solution could be either to define a local variable and use that instead or use the getPropertyPath method instead.

    The resulting code would be either

      public function errorElement(array $element, ConstraintViolationInterface $error, array $form, FormStateInterface $form_state) {
        // Validation errors might be a about a specific (behavior) form element
        // attempt to find a matching element.
        $path = $error->arrayPropertyPath;
        if (!empty($path) && $sub_element = NestedArray::getValue($element, $path)) {
          return $sub_element;
        }
        return $element;
      }
    

    or

      public function errorElement(array $element, ConstraintViolationInterface $error, array $form, FormStateInterface $form_state) {
        // Validation errors might be a about a specific (behavior) form element
        // attempt to find a matching element.
        if (!empty($error->getPropertyPath()) && $sub_element = NestedArray::getValue($element, $error->arrayPropertyPath)) {
          return $sub_element;
        }
        return $element;
      }
    
  • Open in Jenkins β†’ Open on Drupal.org β†’
    Core: 10.1.4 + Environment: PHP 8.1 & MariaDB 10.3.22
    last update 9 months ago
    182 pass
  • Pipeline finished with Failed
    9 months ago
    Total: 268s
    #95836
  • πŸ‡ΊπŸ‡¦Ukraine Mokys

    Hello, you can use "combine" with this patch to make it work. It adds magic method that was removed in the new version of Drupal.

    https://www.drupal.org/project/drupal/issues/3359645 πŸ› Using $error->arrayPropertyPath returns empty everytime Active

  • Status changed to Closed: duplicate 2 months ago
  • πŸ‡¨πŸ‡¦Canada tame4tex

    I believe this has been fixed by Stop using $error->arrayPropertyPath (3333974) β†’ and is in release 1.18. Thus I am closing as duplicate.

Production build 0.71.5 2024