CodeIgniter4
CodeIgniter4 copied to clipboard
Bug: Print errors in array validations
Hello I am trying to print the errors when I validate an array structure for example:
<select multiple name="categories[]">
# validation rules
'categories.*' => 'is_not_unique[categories.id]'
# return errors
return redirect()->back()
->with('errors', $this->validator->getErrors())
then I try to print the errors in my html but it cannot show them, I suppose it is because of the key format that the function to obtain the errors returns
<?=session('errors.categories.*')?>
I think it is not the most practical way to return errors when it comes to array validations :(
thanks for everything!
If you use <?= print_r(session('errors.categories'), true) ?> will there be outputs?
Hello Paul!
try to print it that way but a null value is returned, the format of the array returned in session is as follows
array (5) {
// ...
["categories.*"] =>
string (80) "The categories.* field must contain a previously existing value in the database."
}
It would be quite nice if the ". *" Could be omitted in the name of the keys when dealing with array validations, or how could I get the error message?
Cheers!
Try setting a label to your validation rules:
// validation rules
'categories.*' => ['rules' => 'is_not_unique[categories.id]', 'label' => 'categories'],
// The categories field ...
But note that the array key will still be categories.* since this is the field name passed to the errors array.
It seems that the name of the label is not associated with the name of the error key because I have tried to put a label to the configuration and it keeps returning categories.*
'categories.*' => [
'rules' => 'is_not_unique[categories.id]',
'label' => 'categories',
],

as I mentioned before if I try to print the error as = session ('errors.categories. *')?> it returns null
It seems like a bug related to fact that we're using dot syntax to handle the nested array values.
Until we solve this I guess you should be able to use something like this:
<?= session('errors')['categories.*'] ?>
But note that the array key will still be
categories.*since this is the field name passed to the errors array.
It seems that the name of the label is not associated with the name of the error key because I have tried to put a label to the configuration and it keeps returning
categories.*'categories.*' => [ 'rules' => 'is_not_unique[categories.id]', 'label' => 'categories', ],
as I mentioned before if I try to print the error as it returns null
Yes, as I've said earlier, the field name will still be used as the array key.
This is because of the following line in Validation::processRules.
https://github.com/codeigniter4/CodeIgniter4/blob/e2e5ecabf25b7c64fe6f0f3e2dcfe3f367ee507f/system/Validation/Validation.php#L326
The $field is used as the index for storing the error messages in the $this->errors array.
@michalsn The simple fix I see is using rtrim on $field before being used as index, like $this->errors[rtrim('$field', '.*')] = .. but I'm not sure if this will not cause a confusion because categories, or any other multiple-value fields, will look like a single-value field much like the other fields.
@paulbalandan Yes, this might be confusing and a little too "magical". Also it would introduce a breaking compatibility, since this bug is valid only if we want to display errors via session.
I was thinking more about adding some new (optional) value to validation array, like:
'categories.*' => [
'rules' => 'is_not_unique[categories.id]',
'label' => 'Categories',
'as' => 'categories',
],
With a note in the user guide that as should contain only alpha numeric value with dash or underscore. This way everything would be easier to understand. But these are just my initial thoughts.
There is a workaround for this bug, so it's nothing urgent, I think.
It seems to be a good idea from michals, although it is not something urgent to solve since it can be solved with this <?= session('errors')['categories.*'] ?>, by the way, nice that you are here again @michalsn :)
Since v4.2 getErrors() returns like this:
https://github.com/codeigniter4/CodeIgniter4/blob/6b077b7953f1ac4c34d38cd154ce23dce43f2f51/tests/system/Validation/ValidationTest.php#L873-L879
Ref #5609
So it seems session('errors')['categories.*'] does not work.
$validation->getError('categories.*') returns all found errors that will be combined into one line separated by the EOL character:
https://github.com/codeigniter4/CodeIgniter4/blob/6b077b7953f1ac4c34d38cd154ce23dce43f2f51/tests/system/Validation/ValidationTest.php#L881-L885
session('errors.categories.*') searches an item with dot notation, and there is no such key in the array.
Because the array key is categories.* (at the time the bug was reported), and dot_array_search() does not find such a key. So it returns null.
So this does not seem a bug.