A problem that we probably didn't know about when switching to PHP 8+: Very often, in the rules we created earlier, we returned a message like this:
public function message(): array
{
return [$this->validator->errors()->messages()];
}
When using PHP 7.4 - this isn't a problem, but not for PHP 8+
Since looking "deeper" into how the laravel framework forms messages, we get an error in the replaceAttributePlaceholder method of the FormatsMessages class:
/**
* Replace the : attribute placeholder in the given message.
*
* @param string $message
* @param string $value
* @return string
*/
protected function replaceAttributePlaceholder($message, $value)
{
return str_replace(
[':attribute', ':ATTRIBUTE', ':Attribute'],
[$value, Str::upper($value), Str::ucfirst($value)],
$message
);
}
And indeed, if we open any editor and run the same code, but for two different versions, we'll get:
If you return the message like this:
public function message(): array
{
return $this->validator->errors()->messages();
}
We will avoid the error, but accordingly, the format of the message will be different - this doesn't suit me, and the format of the message should remain the same. Does anyone have any ideas on how to save the format and fix the error?
To solve this problem I had to follow these steps:
$this->app->make('validator')->resolver(function ($translator, $data, $rules, $messages) {
return new App\Validation\Validator($translator, $data, $rules, $messages);
});
<?php
namespace App\Validation;
use Illuminate\Validation\Concerns\FormatsMessages;
use Illuminate\Validation\Validator as ValidationValidator;
class Validator extends ValidationValidator
{
use FormatsMessages {
replaceAttributePlaceholder as protected traitReplaceAttributePlaceholder;
}
/**
* Replace the :attribute placeholder in the given message.
*
* @param string $message
* @param string $value
* @return string
*/
protected function replaceAttributePlaceholder($message, $value)
{
if (is_string($message)) {
return $this->traitReplaceAttributePlaceholder($message, $value);
}
$messages = $message;
foreach ($messages as $key => $message) {
if (is_array($message)) {
$this->replaceAttributePlaceholder($message, $key);
}
$messages[$key] = $this->replaceAttributePlaceholder($message, $key);
}
return $messages;
}
}