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 {
...
}