Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

bashy's avatar
Level 65

Extending Validation with Custom Message Attribute

So I extended the validator and added my own rule (works great). It shows the custom message below but when I try and use :values or :other it just prints that out in text. :attribute works fine.

Just wondering how they're set or how to use them.

"empty_when" => "The :attribute must be blank when :other is entered.",
0 likes
10 replies
usman's avatar
usman
Best Answer
Level 27

@bashy you need to define a replacer method for your rule inside your extended class:

    protected function replaceEmptyWhen($message, $attribute, $rule, $parameters)
    {
        //dd($parameters); --> will help
        return str_replace(array(':other', ':value'), $parameters, $message);
    }

Update://

You can also use the Validator::replacer() method to register the replacer using a Closure. You might have missed this because it is the last heading on the documentation page: http://laravel.com/docs/5.0/validation#custom-validation-rules

Usman.

bashy's avatar
Level 65

@usman Thanks, I've opted to extend the validator class so I can easily add more and use that function instead of a closure. I think I saw it at the bottom but didn't click in my head that that was it... :P

bashy's avatar
Level 65

Note, I used this to account for multiple fields being added (empty_when:title,slug,...)

protected function replaceEmptyWhen($message, $attribute, $rule, $parameters)
{
    return str_replace(':other', implode(' / ', $parameters), $message);
}
1 like
camiloclc's avatar

Seems like kind of a hack, but this is how i got it working:

\Validator::extend('greater', function($attribute, $value, $parameters) {
    $validator = \func_get_arg(3);
    $validator->addReplacer('greater', function($message, $attribute, $rule, $parameters) use ($validator) {
        return \str_replace(':other', $validator->getCustomAttributes()[$parameters[0]], $message);
    });
    $other = \Input::get($parameters[0]);
    return isset($other) and \intval($value) > \intval($other);
});
3 likes
bashy's avatar
Level 65

@camiloclc The solution provided worked fine, not sure why you're replying to a 5 month old answered thread :P that looks messy as well!

huconglobal's avatar

I have a (late) follow-up question to your solution, @bashy. I've defined my custom validation rule and replacer pretty much exactly like you did.

I'm trying to find a way to have the replacer use the attributes()-function of my form request class so that I can control how each of the items in $parameters are finally displayed in the returned error message.

Example: The empty_when-rule is set for 'library' and the :other-parameter could be 'book_id'. But I want the final message to say something like "The Library-name must be blank when Book is entered.'

The key here being it says 'Book' instead of 'book_id'. Since I've entered 'library_name' => 'Library-name' in the attributes()-method of my form request class, the validator automagically replaces this for me. Not so with 'book_id'. I haven't been able to figure out how to do this so far.

huconglobal's avatar

@basy My custom message looks like this:

'emptyWith' => 'The :attribute field must be empty when :other is present.'

  • :attribute is replaced with 'Library-name'
  • :other is replaced with 'book_id'

I want my replacer-method to use the form request class' attributes()-method so that the parameters that replaces :other, in this case 'book_id' get pretty names like Book (similar to how :attribute is ends up as 'Library-name' and not 'library_name').

Tl;dr: No :c)

bashy's avatar
Level 65

@effkay I don't know how so I'd just do a message for each field?

public function messages()
{
    return [
        "library_name.empty_when" => "The :attribute must be blank when Book is entered.",
        "book_id.empty_when" => "The :attribute must be blank when Library-name is entered.",
    ];
}
finder2's avatar

I know this post is old but i finally solved it a bit easier:

use Illuminate\Support\Facades\Validator;

Validator::extend('example', function($attribute, $value, $parameters, $validator) {
     return false; // fancy condition here
});

Validator::replacer('example', function ($message, $attribute, $rule, $parameters) {
    return str_replace(':attribute', $attribute, __('errors.notPresent'));
});

Important is that it is the same name

Please or to participate in this conversation.