Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Custom Validation Rule Error: {field}, {param} , {value} Placeholders Not Replaced in Error Messages #9218

Open
maniaba opened this issue Oct 9, 2024 · 4 comments

Comments

@maniaba
Copy link
Contributor

maniaba commented Oct 9, 2024

PHP Version

8.1, 8.2

CodeIgniter4 Version

4.5.5

CodeIgniter4 Installation Method

Composer (using codeigniter4/appstarter)

Which operating systems have you tested for this bug?

Windows, Linux

Which server did you use?

apache

Database

No response

What happened?

When creating a custom validation rule, the custom error message returned from the rule does not allow for including specific data about the field being validated.
Even if we include the {field} placeholder in the message, it does not get replaced with the actual field name, which limits the usefulness of the error message.

Steps to Reproduce

  1. Define a custom validation rule (e.g., valid_enum) in your validation rules.
  2. Inside the rule, try to return a custom error message with the {field} placeholder.
  3. Perform validation using this rule and check the returned error message.
$validation->setRules([
    'status' => [
        'label' => 'Status',
        'rules' => 'valid_enum[active,inactive]',
    ],
    'user' => [
        'label' => 'User',
        'rules' => 'valid_enum[active,inactive]',
    ],
]);

// Custom validation rule
function valid_enum($value, $params, $data = null, &$error = null): bool
{
    $validValues = explode(',', $params);
    if (!in_array($value, $validValues)) {
        $error = 'The field {field} must be one of: ' . implode(', ', $validValues);
        return false;
    }
    return true;
}

Expected Output

The expected behavior is that the {field} placeholder should be replaced with the actual field name being validated, in this case, status. For example, the error message should be:

The field Status must be one of the valid values.

However, the {field} placeholder does not get replaced, and the error message is returned without the field name, reducing the clarity of the validation error.

Anything else?

This limitation affects all custom rules where dynamic placeholders such as {field}, {param} , {value} are expected to be replaced by the validation system. Without this, the error messages lack context, making it difficult to identify which field caused the validation failure.

@maniaba maniaba added the bug Verified issues on the current code behavior or pull requests that will fix them label Oct 9, 2024
@neznaika0
Copy link
Contributor

See PR #9201

@maniaba
Copy link
Contributor Author

maniaba commented Oct 9, 2024

See PR #9201

This isn't the same issue, as I am referring here to updating the &$error parameter directly. Validation::getErrorMessage will never run when we set $error.
However, I did notice that we now have a new $field parameter in the method as the fifth input parameter, which I can use to solve this.

The only limitation is that if the validation rule doesn’t include $params, then $field won't be passed into the function.

? $set->{$rule}($value, $error)

@michalsn
Copy link
Member

Just use language translations:

// app/Language/en/Validation.php
return [
    'example' => 'The {field} field name is here.'
];
// app/Validation/ExtraRules.php
public function example($str)
{
    if (empty($str)) {
        return false;
    }

    return true;
}

The other option is to declare an empty params, like:

$rules = [
    'field' => ['label' => 'My example', 'rules' => 'example[]'],
];

Then you can use the extended version of parameters in your rule.

@michalsn michalsn removed the bug Verified issues on the current code behavior or pull requests that will fix them label Oct 11, 2024
@maniaba
Copy link
Contributor Author

maniaba commented Oct 13, 2024

Just use language translations:

// app/Language/en/Validation.php
return [
    'example' => 'The {field} field name is here.'
];
// app/Validation/ExtraRules.php
public function example($str)
{
    if (empty($str)) {
        return false;
    }

    return true;
}

The other option is to declare an empty params, like:

$rules = [
    'field' => ['label' => 'My example', 'rules' => 'example[]'],
];

Then you can use the extended version of parameters in your rule.

I believe it would be beneficial for the $error variable to also pass through the getErrorMessage method. This would allow custom validation rules to take advantage of the same dynamic placeholder replacement system used by built-in rules, ensuring that placeholders like {field}, {param}, and {value} are properly replaced in custom error messages.

$this->errors[$fieldForErrors] = $error ?? $this->getErrorMessage(

@maniaba maniaba changed the title Bug: Custom Validation Rule Error: {field}, {param} , {value} Placeholders Not Replaced in Error Messages Custom Validation Rule Error: {field}, {param} , {value} Placeholders Not Replaced in Error Messages Oct 13, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants