My custom Mail Notification isn't sending while all the other are - php

I have a weird issue in my website. I have several Notifications such as Email Verification and Password Reset that are sending properly. However, I made my own notification that sends an url with a UUID to the user and unfortunately, it doesn't send.
I tried every way: 'Notification::route', notify the user directly, nothing works. Actually, notifying the user directly would be bad since I need to send it to an email address not attached to any model.
Anyway, here's the code for the notification. Keep in mind the other notifications work, so I doubt it is the issue.
<?php
namespace App\Notifications;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Notifications\Messages\MailMessage;
use Illuminate\Notifications\Notification;
class NewEmail extends Notification
{
use Queueable;
/**
* Create a new notification instance.
*
* #return void
*/
public function __construct($uuid)
{
$this->uuid = $uuid;
}
/**
* Get the notification's delivery channels.
*
* #param mixed $notifiable
* #return array
*/
public function via($notifiable)
{
return ['mail'];
}
/**
* Get the mail representation of the notification.
*
* #param mixed $notifiable
* #return \Illuminate\Notifications\Messages\MailMessage
*/
public function toMail($notifiable)
{
return (new MailMessage)
->line(__('messages.newEmailAsked'))
->action(__('messages.newEmailConfirm'), config('app.frontend_url') . '/verify-new-email?code=' . $this->uuid)
->line(__('messages.newEmailIgnore'));
}
/**
* Get the array representation of the notification.
*
* #param mixed $notifiable
* #return array
*/
public function toArray($notifiable)
{
return [
//
];
}
}
public function addNewEmail($email) {
if(User::where('email', $email)->count() === 0) {
$uuid = Str::uuid();
NewEmail::create(['email' => $email, 'unique_code' => $uuid, 'user_id' => $this->id]);
Notification::route('mail', $email)->notify(new \App\Notifications\NewEmail($uuid));
} else {
return 'Email already exists.';
}
}
I really don't get why this notification isn't sent while the other are...

Weirdly enough, the problem fixed itself when I did the actual path the user would take instead of using Tinker.
Just had to $user->addNewEmail($newEmailHere) and it worked properly...

You have not defined the $uuid variable in your Queueable class

Related

Laravel 8: Undefined property: App\Notifications\ResetPassword::$queue

I want tp apply queue for my Notifications, so I implemented that at my Notification which ResetPassword:
class ResetPassword extends Notification implements ShouldQueue
Then I ran php artisan queue:table and migrate it so the table jobs created successfully at the DB.
And also change the QUEUE_CONNECTION to database at .env file and re-run php artisan serve.
But when I test this and clicked on reset password link, a new table row must be added to jobs table but it does not.
And instead of that, this error returns:
ErrorException Undefined property:
App\Notifications\ResetPassword::$queue
...\notification\vendor\laravel\framework\src\Illuminate\Notifications\NotificationSender.php:195
So what is going wrong here ? How can I fix this issue ?
I would really appreciate any idea or suggestion from you guys...
Thanks in advance.
UPDATE #1:
ResetPassword.php:
<?php
namespace App\Notifications;
use Illuminate\Notifications\Messages\MailMessage;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Notifications\Notification;
use Illuminate\Support\Facades\Lang;
class ResetPassword extends Notification implements ShouldQueue
{
/**
* The password reset token.
*
* #var string
*/
public $token;
/**
* The callback that should be used to build the mail message.
*
* #var \Closure|null
*/
public static $toMailCallback;
/**
* Create a notification instance.
*
* #param string $token
* #return void
*/
public function __construct($token)
{
$this->token = $token;
}
/**
* Get the notification's channels.
*
* #param mixed $notifiable
* #return array|string
*/
public function via($notifiable)
{
return ['mail'];
}
/**
* Build the mail representation of the notification.
*
* #param mixed $notifiable
* #return \Illuminate\Notifications\Messages\MailMessage
*/
public function toMail($notifiable)
{
if (static::$toMailCallback) {
return call_user_func(static::$toMailCallback, $notifiable, $this->token);
}
return (new MailMessage)
->subject('subject goes here')
->line('This email is sent to you')
->action(Lang::get('Reset Password'), url(config('app.url').route('password.reset', ['token' => $this->token, 'email' => $notifiable->getEmailForPasswordReset()], false)))
->line(Lang::get('Until the next 60 minutes you can use this link', ['count' => config('auth.passwords.'.config('auth.defaults.passwords').'.expire')]))
->line(Lang::get('If you did not request a password reset, no further action is required.'));
}
/**
* Set a callback that should be used when building the notification mail message.
*
* #param \Closure $callback
* #return void
*/
public static function toMailUsing($callback)
{
static::$toMailCallback = $callback;
}
}
Look Like you have forgot to use Queueable Trait in your notification
use Illuminate\Bus\Queueable;
class ResetPassword extends Notification implements ShouldQueue
{
use Queueable;
Queueable trait has propety $queue
Ref:https://laravel.com/docs/8.x/notifications#queued-notifications-and-database-transactions

Laravel 5.7 Multilogin SendEmailVerificationNotification error

I'm new to Laravel. I just created a custom login with laravel 5.7. When I tried to reset password I'm getting this error:
"Declaration of
App\Employee::sendEmailVerificationNotification($token) should be
compatible with
Illuminate\Foundation\Auth\User::sendEmailVerificationNotification()"
Does anyone know how to resolve this error?
You may do something like this
class Employee extends Model implements MustVerifyEmail {
public function sendEmailVerificationNotification()
{
$this->notify(new VerifyEmail);
}
}
if you want to call it like Employee::sendEmailVerificationNotification() and if you want to verify the token you should extend the VerifyEmail notification something like
<?php
namespace App\Notifications;
use Illuminate\Bus\Queueable;
use Illuminate\Notifications\Notification;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Notifications\Messages\MailMessage;
use Illuminate\Support\Carbon;
use Illuminate\Support\Facades\URL;
use Illuminate\Support\Facades\Lang;
use Illuminate\Auth\Notifications\VerifyEmail;
class VerifyEmailNotification extends VerifyEmail
{
use Queueable;
/**
* Create a new notification instance.
*
* #return void
*/
public function __construct($token)
{
//verify token
}
/**
* Get the notification's delivery channels.
*
* #param mixed $notifiable
* #return array
*/
public function via($notifiable)
{
return ['mail'];
}
/**
* Get the mail representation of the notification.
*
* #param mixed $notifiable
* #return \Illuminate\Notifications\Messages\MailMessage
*/
public function toMail($notifiable)
{
if (static::$toMailCallback) {
return call_user_func(static::$toMailCallback, $notifiable);
}
return (new MailMessage)
->subject(Lang::getFromJson('Verify Email Address'))
->line(Lang::getFromJson('Please click the button below to verify your email address'))
->action(
Lang::getFromJson('Verify Email Address'),
$this->verificationUrl($notifiable)
)
->line(Lang::getFromJson('If you did not create an account, no further action is required.'));
}
/**
* Get the array representation of the notification.
*
* #param mixed $notifiable
* #return array
*/
public function toArray($notifiable)
{
return [
//
];
}
}
Then in Employee model
public function sendEmailVerificationNotification($token)
{
$this->notify(new VerifyEmailNotification($token)); // your custom notification
}
You have to follow the same method signature if you want to override it-
You are overriding this method-
Illuminate\Foundation\Auth\User::sendEmailVerificationNotification()
to this-
App\Employee::sendEmailVerificationNotification($token)
If you notice the difference, you have passed $token in the method while the original method definition does not support that.
Create a different method if you need a different signature from the original method.

laravel 5.6 Undefined variable: user when trying to send email

I am trying to send an email using Notification class in laravel 5.6 which I am new to.
I am trying to pass user and book information but every time I get the following :
Undefined variable: user
here is my successEmail.php:
<?php
namespace BOOK_DONATION\Notifications;
use Illuminate\Bus\Queueable;
use Illuminate\Notifications\Notification;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Notifications\Messages\MailMessage;
class successEmail extends Notification
{
use Queueable;
public $user;
public $book;
/**
* Create a new notification instance.
*
* #return void
*/
public function __construct($user,$book)
{
//
$this->user=$user;
$this->book=$book;
}
/**
* Get the notification's delivery channels.
*
* #param mixed $notifiable
* #return array
*/
public function via($notifiable)
{
return ['mail'];
}
/**
* Get the mail representation of the notification.
*
* #param mixed $notifiable
* #return \Illuminate\Notifications\Messages\MailMessage
*/
public function toMail($notifiable)
{
return (new MailMessage)
->greeting('Dear'.$user->name.'thak you for creating donation for '.$book->name);
}
/**
* Get the array representation of the notification.
*
* #param mixed $notifiable
* #return array
*/
public function toArray($notifiable)
{
return [
//
];
}
}
and here is the function that call the class successEmail:
public function doBook(Request $request){
$validatedData = $request->validate([
'title' => 'string|required|max:255',
'Author'=> 'string|required|max:255',
'Cover_image' => 'required|image|mimes:jpeg,png,jpg,gif,svg|max:2048',
'Book_description'=>'string|required|max:255',
]);
$path= $request->Cover_image->store('images');
$uid=Auth::user()->id;
$country=Auth::user()->country;
$city=Auth::user()->city;
$book=Book::create(['title'=>$request->input('title'),
'Author'=>$request->input('Author'),
'user_id'=>$uid,
'country'=>$country,
'city' =>$city,
'Book_description'=>$request->input('Book_description'),
'path'=>$path,
]);
$user = Auth::user();
$user->notify(new successEmail($user,$book));
return redirect('/donation/create')->with('status', 'Thank you for your donation');
}
as you see I passed the user and the book variable to the constructor and declared them as public so what is that I am missing?
Those variables do not exist in the function scope but they do exist as class properties so they should be treated as such.
return (new MailMessage)
->greeting('Dear '.$this->user->name.' thank you for creating donation for '.$this->book->name);
You need to make the call to $this->user to access the variable in the class scope.
/**
* Get the mail representation of the notification.
*
* #param mixed $notifiable
* #return \Illuminate\Notifications\Messages\MailMessage
*/
public function toMail($notifiable)
{
return (new MailMessage)
->greeting('Dear'.$this->user->name.'thak you for creating donation for '.$this->book->name);
}
You should try this:
use Auth;
public function toMail($notifiable)
{
return (new MailMessage)
->greeting('Dear'.$this->user->name.'thak you for creating donation for '.$this->book->name);
}
That happened to me too. In the function toMail you need to redeclare the variables like this
$user= $this->user;
And then you call the variable like this
->line('user:'.''.$user,'')

laravel 5.3 database notification customization

I am creating laravel 5.3 database notifications.I have created notifications as per video published on https://laracasts.com/series/whats-new-in-laravel-5-3/episodes/10 ,
Now i want to add custom fields to the notification table as per my requirements.
Please help me how to pass custom data to notification and access it.
When I needed to put custom fields to Notification, I'd just put on data field, as it is a Json field, works perfectly. Like this:
namespace App\Notifications;
use Illuminate\Bus\Queueable;
use Illuminate\Notifications\Notification;
class TaskNotification extends Notification
{
use Queueable;
private $message;
/**
* #param String $message
*/
public function __construct($message=false)
{
if ($message)
$this->message = $message;
}
/**
* Get the notification's delivery channels.
*
* #param mixed $notifiable
* #return array
*/
public function via($notifiable)
{
return ['database'];
}
/**
* Get the array representation of the notification.
*
* #param mixed $notifiable
* #return array
*/
public function toArray($notifiable)
{
return [
'message' => $this->message,
'link' => route('mymodel.show'),
'task'=> 1, // This is one variable which I've created
'done'=> 0 // This is one variable which I've created
];
}
}

How do I append the email address to the url when doing password reset in laravel 5.3

I am to append the users email address in the URL when doing password reset, so the reset url would look like this http://blog.dev/password/reset/4cfbb048346474aab7080c88f16c34b9ea377b9ea35804387216fce303a38855?email=test%40gmail.com
However I get the error FatalErrorException in CustomResetPassword.php line 54: Call to undefined method App\Notifications\CustomResetPassword::getEmailForPasswordReset()
I am sending the reset email through a custom notification class the code is as follows
namespace App\Notifications;
use Illuminate\Bus\Queueable;
use Illuminate\Notifications\Notification;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Notifications\Messages\MailMessage;
class CustomResetPassword extends Notification
{
use Queueable;
public $token;
/**
* Create a new notification instance.
*
* #return void
*/
public function __construct($token)
{
$this->token = $token;
}
/**
* Get the notification's delivery channels.
*
* #param mixed $notifiable
* #return array
*/
public function via($notifiable)
{
return ['mail'];
}
/**
* Get the mail representation of the notification.
*
* #param mixed $notifiable
* #return \Illuminate\Notifications\Messages\MailMessage
*/
public function toMail($notifiable)
{
return (new MailMessage)
->subject('Reset Password')
->line('You are receiving this email because we received a password reset request for your account.')
->action('Reset Password', url('password/reset', $this->token).'?email='.urlencode($this->getEmailForPasswordReset()))
->line('If you did not request a password reset, no further action is required.');
}
/**
* Get the array representation of the notification.
*
* #param mixed $notifiable
* #return array
*/
public function toArray($notifiable)
{
return [
//
];
}
}
Am I missing something here?
$this refer to your actual class, you're trying to use getEmailForPasswordReset method of CustomResetPassword but this method doesn't exist.
You can pass the email to the notification as you did for the token.

Categories