Search code examples
phplaravelemail

Overriding the "email" attribute on Notifiable Trait Laravel


I'm trying to use the Notifiable Trait of Laravel in a Model which doesn't have an email attribute (It has a payer_email in fact)

so I went deep inside in Notifiable trait code and found it uses an routeNotificationFor method from RoutesNotifications Trait so I decided to override it for my desired behavior.

The original method code is:

    public function routeNotificationFor($driver)
{
    if (method_exists($this, $method = 'routeNotificationFor'.Str::studly($driver))) {
        return $this->{$method}();
    }

    switch ($driver) {
        case 'database':
            return $this->notifications();
        case 'mail':
            return $this->email;
        case 'nexmo':
            return $this->phone_number;
    }
}

and I overrided it in my Payment Model in this way:

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Str;
use Illuminate\Notifications\Notifiable;
use App\Notifications\PaymentNotify;

class Payment extends Model
{

    use Notifiable;
   
    public function routeNotificationFor($driver)
    {
       if (method_exists($this, $method = 'routeNotificationFor'.Str::studly($driver))) {
           return $this->{$method}();
       }

       switch ($driver) {
            case 'database':
                return $this->notifications();
            case 'mail':
                return $this->payer_email;
            case 'nexmo':
                return $this->phone_number;
       }
    }
}

But when I test it, does not work. (I've used Notifiable trait on others two models and it works, without the override...)


Solution

  • I just created a method named routeNotificationForMail like @Jonathon suggested and I worked like deserved.

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

    The above code works in Laravel 5.x, which was current when this answer was posted, and still works in 11.x today. In 6.x, the ability to return a name along with the email address was added, which may be used like this:

    public function routeNotificationForMail(){
        return [$this->payer_email => $this->payer_name];
    }