Search code examples
phplaravelvalidationriot-games-api

Laravel 6 - Modify the `validator` method of the `RegisterController`


I'm a beginner in programming, so please excuse my misunderstanding of validation in Laravel.

I'm trying to create a website for gamers of a specific game, where users can register. When they submit the form, I have to verify whether their account exists or not. To do this I have an external api (api from the game) which I can use to verify their account.

I tried to solve it like this in my RegisterController:

protected function validator(array $data)
{
    $validation = $this->isSummonerValid($data['summonername']);
    if ($validation) {
        return Validator::make($data, [
            'summonername' => ['required', 'string', 'max:255'],
            'email' => ['required', 'string', 'email', 'max:255', 'unique:users'],
            'region' => ['required', 'string'],
            'rank' => ['required', 'string'],
            'lane' => ['required', 'array'],
            'password' => ['required', 'string', 'min:8', 'confirmed'],
        ]);
    } else {
        return view('auth.register');
    }
}

Everything which isSummonerValid() does is, it uses the API and returns true if the user exists in the game and false if not.

protected function isSummonerValid($summonerName)
{
    $client = new Client();
    try {
        $response = $client->request('GET',
            'https://euw1.api.riotgames.com/lol/summoner/v4/summoners/by-name/' . $summonerName .
            '?api_key=' . APIKEY);
    } catch (ClientException $e) {
        return false;
    }
    return true;
}

When the API call succeeds, everything works fine. User gets created and can login.

When the API call fails (user doesn't exist) I get this error:

Method Illuminate\View\View::validate does not exist.

Can someone explain how I can create a custom validator in Laravel which calls an external API?


Solution

  • The validator() method of the RegisterController must always return an instance of Illuminate\Contracts\Validation\Validator class but you're returning lluminate\View\View on else condition, try to change the validator to this:

    /**
     * Get a validator for an incoming registration request.
     *
     * @param  array  $data
     * @return \Illuminate\Contracts\Validation\Validator
     */
    protected function validator(array $data)
    {
        return tap(Validator::make($data, [
                'summonername' => ['required', 'string', 'max:255'],
                'email' => ['required', 'string', 'email', 'max:255', 'unique:users'],
                'region' => ['required', 'string'],
                'rank' => ['required', 'string'],
                'lane' => ['required', 'array'],
                'password' => ['required', 'string', 'min:8', 'confirmed'],
            ]),
            function ($validator) use ($data) {
                $validator->after(function ($validator) use ($data) {
                    if (! $this->isSummonerValid($data['summonername'])) {
                        $validator->errors()->add('summonername', 'Something is wrong with this field!');
                    }
                });
            }
        );
    }