NigelDorning's avatar

MustVerifyEmail - it is not a trait

A couple of days I was doing some tests with the new Laravel features and was able to set up the Email Verifications no problem, but I came to setup a new project today and for some reason it's just no longer.

I went back to the documentation to see if I had missed something and even watched the laracast video, following instructions, but it just keeps giving me the following error:

App\User cannot use Illuminate\Contracts\Auth\MustVerifyEmail - it is not a trait

The code in the documentation is as follows,

namespace App;

use Illuminate\Notifications\Notifiable;
use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Foundation\Auth\User as Authenticatable;

class User extends Authenticatable implements MustVerifyEmail
{
    use MustVerifyEmail, Notifiable;

    // ...
}

And the code in my User model is,

namespace App;

use Illuminate\Notifications\Notifiable;
use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Foundation\Auth\User as Authenticatable;

class User extends Authenticatable implements MustVerifyEmail
{
    use MustVerifyEmail, Notifiable;

    /**
     * The attributes that are mass assignable.
     *
     * @var array
     */
    protected $fillable = [
        'name', 'email', 'password',
    ];

    /**
     * The attributes that should be hidden for arrays.
     *
     * @var array
     */
    protected $hidden = [
        'password', 'remember_token',
    ];
}

I've set up a few new test laravel projects thinking it might just be a problem with the install and I've updated the laravel installer. Any ideas let me know.

Thanks a lot

0 likes
14 replies
tykus's avatar

It must be an error... it is clearly an Interface. Just remove the use trait syntax inside the model.

NigelDorning's avatar

Ah okay.

So there's a few steps it seems that are missing from the documentation and the Laracast video (at least in the way Laravel was installed in my project).

The User model needed this code:

<?php

namespace App;

use Illuminate\Auth\MustVerifyEmail;
use Illuminate\Notifications\Notifiable;
use Illuminate\Contracts\Auth\MustVerifyEmail as MustVerifyEmailContract;
use Illuminate\Foundation\Auth\User as Authenticatable;

class User extends Authenticatable implements MustVerifyEmailContract
{
    use MustVerifyEmail, Notifiable;

    /**
     * The attributes that are mass assignable.
     *
     * @var array
     */
    protected $fillable = [
        'name', 'email', 'password',
    ];

    /**
     * The attributes that should be hidden for arrays.
     *
     * @var array
     */
    protected $hidden = [
        'password', 'remember_token',
    ];
}

Not sure why the documentation and the Laracast video show something different?

NigelDorning's avatar

Hmm most likely, but then surely now they already have outdated documentation and tutorial videos for their latest version?

Anyway I've got it working after being confused for a couple of hours :)

Cronix's avatar

Hmm most likely, but then surely now they already have outdated documentation and tutorial videos for their latest version?

Feel free to make a pull request and fix them: https://github.com/laravel/docs

1 like
NigelDorning's avatar

Ah I wasn't aware you could do that. I will take a look, thanks.

Snapey's avatar

@JeffreyWay need to know if the laracast video is wrong. He definately only adds implements mustVerifyEmail... no sign of a trait

Snapey's avatar
Snapey
Best Answer
Level 122

Actually, the trait is pulled in by the Authenticatable (User model) class

vendor/laravel/framework/src/Illuminate/Foundation/Auth/User.php


class User extends Model implements
    AuthenticatableContract,
    AuthorizableContract,
    CanResetPasswordContract
{
    use Authenticatable, Authorizable, CanResetPassword, MustVerifyEmail;
}


So you should not have needed to add the trait.

I think you just confused contract and trait

1 like
NigelDorning's avatar

Hi Snapey,

You know what? You're absolutely right I must have just been conflating the documentation and the video for some reason.

Thanks a lot

martin.allchin's avatar

Laravel 5.7 docs example shows the trait included but it isn't required.

It was when 5.7.0 was released but I see the verification code has been in development over the past few days with changes in 5.7.1 and 5.7.2.

It is confusing as the docs say to start a new project using laravel new blog but as-of today this installs 5.7.2 which appears to be work in progress, and also doesn't match the 5.7 documentation.

So, what version should we be using to stay in-line with the documentation?

pokhrelashok2's avatar

Hey guys, i am trying to use email verification on different model, not in users model by using this trait and it is not working atm. Can anyone suggest how to implement a similar feature but not on users model? You can view my question here:

Ok so i have a model named SiteEmail. Basically i have a model named Site and it can have multiple emails associated with it, which has to be verified by sending an email. I want to use the laravel email verification that ships with laravel which i have used on the user model. I have implemented the MustVerifyEmail interface on the SiteEmail model and it is using the Notifiable trait. The emails are being sent fine, but on clicking on the verify button, it says invalid signature.

class SiteEmail extends Model implements MustVerifyEmail { use Notifiable; protected $fillable = ['site_id', 'user_id', 'email', 'email_verified_at'];

    /**
    * Determine if the user has verified their email address.
    *
    * @return bool
    */
    public function hasVerifiedEmail()
    {
        return $this->email_verified_at != null;
    }

    /**
    * Mark the given user's email as verified.
    *
    * @return bool
    */
    public function markEmailAsVerified()
    {
        $this->update([
        'email_verified_at' => now(),
        ]);
    }

    /**
    * Send the email verification notification.
    *
    * @return void
    */
    public function sendEmailVerificationNotification()
    {
        $this->notify(new VerifyEmail);
    }

    /**
    * Get the email address that should be used for verification.
    *
    * @return string
    */
    public function getEmailForVerification()
    {
        return $this->email;
    }
}

How do i approach email verification on such models? It works fine on the User model, but i don't think this is the correct way to verify custom models. Any help is appreciated! Thanks!

PS: I think this might be happening because the signature generated is being tested against the user's email?

Please or to participate in this conversation.