-1

Working on an existing project, so keeping the code structure the same as other developers is critical.

I've created a new Rule and added my Validator::extend to the boot(). However I can't get the validation error to display my custom message. Instead is just displays a default "validation.ruleName"

I'm writing a Validation rule that uses ImLiam's NHS Number validation package. The validate() and passes() work successfully. But the error message never changes.

How can I get the messages() method to display the custom output of the exception? (Instead of "validation.nhsnumber" in screenshot below?

enter image description here

App\Forms\MyForm: (using Kris Forms)

public function buildForm()
{
    $this->add('nhs_number', 'number', [
        'label' => 'NHS Number',
        'rules' => 'nullable|nhsnumber',
    ]);
    ...
}

App\Providers\AppServiceProvider:

public function boot()
{

        Validator::extend('nhsnumber', \App\Rules\ValidNhsNumber::class);
}

App\Rules\ValidNhsNumber:

namespace App\Rules;

use Illuminate\Contracts\Validation\Rule;
use ImLiam\NhsNumber\InvalidNhsNumberException;
use ImLiam\NhsNumber\NhsNumber;

class ValidNhsNumber implements Rule
{
    private $message;

    /**
     * Create a new rule instance.
     *
     * @return void
     */
    public function __construct()
    {
        //
    }

    /**
     * Determine if the validation rule passes.
     *
     * @param string $attribute
     * @param mixed $value
     * @return bool
     */
    public function passes($attribute, $value): bool
    {
        try {
            $nhsNumber = new NhsNumber($value);
            $nhsNumber->validate(); // Will throw exception here if false
            return true;
        } catch (InvalidNhsNumberException $e) {
            $this->message = $e->getMessage();
        }
    }

    public function validate($attribute, $value, $params): bool
    {
        return $this->passes($attribute, $value);
    }

    /**
     * Get the validation error message.
     *
     * @return string
     */
    public function message()
    {
        return $this->message;
    }
}
Fred
  • 69
  • 9

3 Answers3

0

Your message property is null. Laravels validator will attempt to get the error message calling your message() method, and if nothing is returning it'll use get_class($this) and then attempt to construct an error message.

This method can either return a translation placeholder such as validation.nhsnumber or it can return the actual message. In the example you have given, it's just not returning anything.

ollieread
  • 6,018
  • 1
  • 20
  • 36
0

Did you try to dump $this->message;? What does it display if you dump it? Do you even get to the public function message()? Try to put a dd($this-message) in the message() method.

Edit:

In your catch you are not returning anything at all. When it enters the catch it's not returning false or true. It's returning null.

Kristian Vasilev
  • 504
  • 8
  • 26
0

Turns out this is a conflict with KrisForms.

But you can get the desired outcome by slightly changing the way you ask it to process rules.

In App\Forms\MyForm: I changed:

$this->add('nhs_number', 'number', [
            'label' => 'NHS Number',
            'rules' => 'nullable|nhsnumber',
]);

To This:

$this->add('nhs_number', 'number', [
            'label' => 'NHS Number',
            'rules' => [
                'nullable',
                new ValidNhsNumber()
            ]
]);

And then ensured that in the catch block I'm returning false in passes().

Fred
  • 69
  • 9