1
votes

I'm trying to implement one of Laravel's new features "Custom Validation Rules" and I'm running into the following error:

Object of class Illuminate\Validation\Validator could not be converted to string

I'm following the steps in this video: New in Laravel 5.5: Project: Custom validation rule classes (10/14)

It's an attempt Mailgun API's Email Validation tool.

Simple form that requests: first name, last name, company, email and message

Here is my code:

web.php

Route::post('contact', 'StaticPageController@postContact');

StaticPageController.php

use Validator;
use App\Http\Validation\ValidEmail as ValidEmail;

public function postContact(Request $request) {
        return Validator::make($request->all(), [
            'firstname'    => 'required|max:90',
            'lastname'    => 'required|max:120',
            'company'    => 'max:120',
            'email'    => [
                'required', 'string', 'max:255',
                new ValidEmail(new \GuzzleHttp\Client)
            ],
            'message'    => 'required',
        ]);
}

ValidEmail.php

<?php 

namespace App\Http\Validation;

use Illuminate\Contracts\Validation\Rule;
use GuzzleHttp\Exception\GuzzleException;
use GuzzleHttp\Client as Guzzle;

class ValidEmail implements Rule
{
    protected $client;
    protected $message = 'Sorry, invalid email address.';

    public function __construct(Guzzle $client)
    {
        $this->client = $client;
    }

    public function passes($attribute, $value)
    {
        $response = $this->getMailgunResponse($value);
    }

    public function message()
    {
        return $this->message;
    }

    protected function getMailgunResponse($address)
    {
        $request = $this->client->request('GET', 'https://api.mailgun.net/v3/address/validate', [
            'query' => [
                'api_key' => env('MAILGUN_KEY'),
                'address' => $address
            ]
        ]);
        dd(json_decode($request->getBody()));
    }
}

Expectation

I'm expecting to see something like this:

{
    +"address": "[email protected]"
    +"did_you_mean": null
    +"is_disposable_address": false
    +"is_role_address": false
    +"is_valid": false
    +"parts": {
        ...
    }
}

Any help is much appreciated. I've been trying to get this simple example to work for over two hours now. Hopefully someone with my experience can help!

2
I got it working, do you still need this? - user3253002

2 Answers

0
votes

In your controller

Try this:

$validator = Validator::make($request->all(), [
    'firstname'    => 'required|max:90',
    'lastname'    => 'required|max:120',
    'company'    => 'max:120',
    'email'    => [
        'required', 'string', 'max:255',
        new ValidEmail(new \GuzzleHttp\Client)
    ],
    'message'    => 'required',
]);


if ($validator->fails()) {
    return redirect()->back()
        ->withErrors($validator)
        ->withInput();
}

// if valid ...
0
votes

According to your route, the postContact method is the method to handle the route. That means the return value of this method should be the response you want to see.

You are returning a Validator object, and then Laravel is attempting to convert that to a string for the response. Validator objects cannot be converted to strings.

You need to do the validation, and then return the correct response based on that validation. You can read more about manual validators in the documenation here.

In short, you need something like this:

public function postContact(Request $request) {
    $validator = Validator::make($request->all(), [
        'firstname'    => 'required|max:90',
        'lastname'    => 'required|max:120',
        'company'    => 'max:120',
        'email'    => [
            'required', 'string', 'max:255',
            new ValidEmail(new \GuzzleHttp\Client)
        ],
        'message'    => 'required',
    ]);

    // do your validation
    if ($validator->fails()) {
        // return your response for failed validation
    }

    // return your response on successful validation
}