Validation attachment fails when plugin handler class name differs from the name of the plugin

Created on 30 November 2021, about 3 years ago
Updated 24 June 2023, over 1 year ago

Problem/Motivation

Where a field_validation validator plugin is defined but the name of the handler class is different to the plugin name attachment is aborted during field_validation_field_attach_validate

Essentially, this forces the developer to implement the following:

// @file validator_example.inc

$plugin = [
    'label' => t('Example Validator'),
    'description' => t('Some example validator'),
    'handler' => [
        'class' => 'validator_example'
    ]
];

class validator_example extends field_validation_validator {
    ...
}

Whereas if a developer wished to separate their plugin definitions from class definitions (when using PSR-4 autoloading for example) the current checks in place in field_validation_field_attach_validate will inhibit this.

The problematic code in field_validation_field_attach_validate:

function field_validation_field_attach_validate($entity_type, $entity, &$errors) {
    ...
    ctools_include('plugins');
    $plugin = ctools_get_plugins('field_validation', 'validator', $rule->validator);
    $class = ctools_plugin_get_class($plugin, 'handler');
    if (empty($class)) {
        continue;
    }
    // The below is the problematic check
    if (!is_subclass_of($rule->validator, 'field_validation_validator')) {
        drupal_set_message(t("Plugin '@validator' should extends 'field_validation_validator'.", array('@validator' => $rule->validator)));
        continue;
    }
    ...
}

$rule->validator will only ever contain the plugin's ID, thus forcing the handler class to be named the same.

Steps to reproduce

Create a field validation validator plugin where the handler class name differs from the plugin ID (derived from the plugin's file name).

Proposed resolution

Update the is_subclass_of condition above, to check the actual plugin's class instead of the plugin's ID as stored against the $rule

Changes would be as follows:

function field_validation_field_attach_validate($entity_type, $entity, &$errors) {
    ...
    // Simply swap $rule->validator to $class
    //  if (!is_subclass_of($rule->validator, 'field_validation_validator')) {
    if (!is_subclass_of($class, 'field_validation_validator')) {
        drupal_set_message(t("Plugin '@validator' should extends 'field_validation_validator'.", array('@validator' => $rule->validator)));
        continue;
    }
    ...
}

Allowing the following implementations:

// @file validator_example.inc

$plugin = [
    'label' => t('Example Validator'),
    'description' => t('Some example validator'),
    'handler' => [
        'class' => 'validator_example'
    ]
];

class validator_example extends field_validation_validator {
    ...
}
// @file validator_example.inc
$plugin = [
    'label' => t('Example Validator'),
    'description' => t('Some example validator'),
    'handler' => [
        'class' => 'AnExternalValidatorClass'
    ]
];

// @file AnExternalValidatorClass.php
class AnExternalValidatorClass field_validation_validator {
    ...
}
🐛 Bug report
Status

Fixed

Version

2.0

Component

Code

Created by

🇬🇧United Kingdom JParkinson1991

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

Comments & Activities

Not all content is available!

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

Production build 0.71.5 2024