I generated a new email object through the artisan command to notify users about cumulative notifications. I succeeded using a custom template through the build method of the Email object:
public function build()
{
return $this->view('email.cumulative-notifications')
->with(['amount' => $this->amount])
->subject('You have some notifications!');
}
I want to use the template that is used for the reset password email which can be filled with lines and links like the ResetPassword does:
public function toMail($notifiable)
{
return (new MailMessage)
->subject('Reset Password')
->greeting('Hello!')
->line('...')
->action('Reset Password', url('password/reset', $this->token))
->line('...');
}
Should I use Notifications objects instead of Emails?
Related
In my AuthServiceProvider I was trying to add the users name to to email body. I tried the following method to accomplish that but it didn't work as expected.
When the page redirect to the verification page directly after registration it fails to get the auth user and results in an error. But when that page is closed and tried to login from the login page the it could get the auth()->user();
public function boot()
{
$this->registerPolicies();
VerifyEmail::toMailUsing(function ($notifiable, $url) {
$user_name = Auth::user()->name;
return (new MailMessage)
->greeting("Hello {$user_name}!")
->subject('Verify Email Address')
->line('Please click the button below to verify your email address.')
->action('Verify Email Address', $url)
->line('If you did not create an account, no further action is required.');
});
}
Well, this can be achieved by using VerifyEmail::toMailUsing(). I used this function in my AuthServiceProvider. And the user's name can be accessed by using the $notifiable. This has all the information about the registered user.
public function boot()
{
$this->registerPolicies();
VerifyEmail::toMailUsing(function ($notifiable, $url) {
return (new MailMessage)
->greeting("Hello {$notifiable->name}!")
->subject('Verify Email Address')
->line('Please click the button below to verify your email address.')
->action('Verify Email Address', $url)
->line('If you did not create an account, no further action is required.');
});
}
Laravel 5.5
Controller
public function sendBookingSms(){
$checkState = session()->get('checkState');
$staffs = Staff::whereIn('staffId',$checkState)->get();
foreach ($staffs as $staff) {
$email = str_replace(" ","","44".substr($staff->mobile, 1)).'#mail.mightytext.net';
Notification::send($email, new NewBooking($email));
}
return $staffs;
session()->forget('checkState');
return redirect(route('booking.current'))->with('message','Succesfully Send SMS to selected staffs !!');
}
NewBooking.php (Notification)
public function toMail($notifiable)
{
return (new MailMessage)
->line('The introduction to the notification.')
->action('Notification Action', url('/'))
->line('Thank you for using our application!');
}
When calling this controller I am getting this error.
$staffs.
{
"staffId":45,
"forname":"Eldhose",
"surname":"John",
"categoryId":2,
"email":"devhelloworld#gmail.com",
"mobile":"07588593278",
"whatsappNumber":"57656578658",
"gender":1,
"address":"Poole",
"pincode":null,
"modeOfTransport":1,
"pickupLocation":"Office",
"branchId":0,
"zoneId":1,
"bandId":1,
"paymentMode":1,
"payRateWeekday":10,
"payRateWeekNight":20,
"payRateWeekendDay":10,
"payRateWeekendNight":20,
"payRateSpecialBhday":11,
"payRateSpecialBhnight":15,
"payRateBhday":11,
"payRateBhnight":15,
"status":1,
"deleted_at":null,
"created_at":"2018-02-26 22:16:44",
"updated_at":"2018-02-26 22:16:44"
}
Please help me on this.... Thanks
Notification::send() requires the first argument to be an object, usually one that uses the Notifiable trait. You pass just a string holding email address, hence the error.
If you simply want to send a notification to given email address, you'll need to use on-demand notifications. The following should do the trick:
Notification::route('mail', $email)->notify(new NewBooking($email));
For more details see the docs: https://laravel.com/docs/5.6/notifications#sending-notifications
Latest docs: https://laravel.com/docs/9.x/notifications#on-demand-notifications
I used two tutorials to create code which notifies me on a new user registration. mail-notifications and redirect-login-register-add-method/
This works now
I am just sending a notification to default email defined here in my User model:
This is my desired goal
I want to send newly registered user's email in the emailed notification. Also, I wish to customize recipient for this specific HelloUser notification.
public function routeNotificationForMail()
{
return 'name#gmail.com';
}
The notification is fired by the code in my RegisterController.php:
protected function redirectTo()
{
$user = Auth::user();
$user->notify(new \App\Notifications\HelloUser());
return '/'; // redirects to main page
}
The above solution works, but I after many attempts I am still unable to get these extended result:
to do 1
I will have several notifications, which I want to mail to 2-3 emails, not just one.
My attempt
In my notification file App\Notifications\\HelloUser.php I tried to add
extra line. (Note tha the line is now commented)
public function toMail($notifiable)
{
return (new MailMessage)
->line('The introduction to the notification.')
->action('Notification Action', url('/'))
->line('The new user email is ');
// ->to('name#gmail.com');
}
... but I failed. I could define global recipient as described here in the documentation
My question #1
How I can I define a separate recipient for each Notification?
TO DO 2
I also tried to get the newly registered user's email into the emailed notification.
For this purpose I tried to copy my solution from Mailables. So in RegisterControler.php I tried to pass $user variable in the function:
protected function redirectTo()
{
$user = Auth::user();
$user->notify(new \App\Notifications\HelloUser($user));
return '/';
}
and then in my Notification file App\Notifications\HelloUser I did this:
public $user;
public function __construct($user)
{
$email = $user->email;
}
in a hope that this piece would produce a notification with new user's email:
public function toMail($notifiable)
{
return (new MailMessage)
->line('The introduction to the notification.')
->action('Notification Action', url('/'))
->line('The new user email is '.$user->email);
}
The result: I just get Undefined variable: user.
TO DO
How to make this code work?
Thank you for your time.
=============
Edit:
upon #Arun_jai request I place here the dd($notifiable). It seems that it is generated properly and the object is just instance of the User model. The relevant part:
#attributes: array:6 [▼
"name" => "Peter attempt 16"
"email" => "name#gmail.com"
"password" => "$2t9WHLFY14XNf0$nj7TYDYAxiZ/kdfrUy$1vC2"
"updated_at" => "2018-01-18 07:08:12"
"created_at" => "2018-01-18 07:08:12"
"id" => 270
]
Regarding the Undefined variable: user error, try instantiating the $user variable in your constructor, instead of the email. Your constructor should look like this:
public function __construct($user)
{
$this->user = $user;
}
Then you will be able to get the users' email by calling it with $this->user in any place of that class, so your MailMessage creation would look like this:
return (new MailMessage)
->line('The introduction to the notification.')
->action('Notification Action', url('/'))
->line('The new user email is ' . $this->user->email);
I am beginner in Laravel. Currently I am learning this framework. My curent Laravel version is 5.3.
I am scaffolding my auth by using php artisan make:auth All are working fine. Also I configured gmail smtp in my .env file and mail.php in config directgory. All are perfectly working. But I saw by-default the forgot password email subject is going Reset Password. I want to change that.
I saw some blog. I found some blog. I have implement that in my site. But same output coming.
I followed these links -
https://laracasts.com/discuss/channels/general-discussion/laravel-5-password-reset-link-subject
https://laracasts.com/discuss/channels/general-discussion/reset-password-email-subject
https://laracasts.com/discuss/channels/laravel/how-to-override-message-in-sendresetlinkemail-in-forgotpasswordcontroller
You can change your password reset email subject, but it will need some extra work. First, you need to create your own implementation of ResetPassword notification.
Create a new notification class insideapp\Notifications directory, let's named it ResetPassword.php:
<?php
namespace App\Notifications;
use Illuminate\Notifications\Notification;
use Illuminate\Notifications\Messages\MailMessage;
class ResetPassword extends Notification
{
public $token;
public function __construct($token)
{
$this->token = $token;
}
public function via($notifiable)
{
return ['mail'];
}
public function toMail($notifiable)
{
return (new MailMessage)
->subject('Your Reset Password Subject Here')
->line('You are receiving this email because we received a password reset request for your account.')
->action('Reset Password', url('password/reset', $this->token))
->line('If you did not request a password reset, no further action is required.');
}
}
You can also generate the notification template using artisan command:
php artisan make:notification ResetPassword
Or you can simply copy-paste the above code. As you may notice this notification class is pretty similar with the default Illuminate\Auth\Notifications\ResetPassword. You can actually just extend it from the default ResetPassword class.
The only difference is here, you add a new method call to define the email's subject:
return (new MailMessage)
->subject('Your Reset Password Subject Here')
You may read more about Mail Notifications here.
Secondly, on your app\User.php file, you need to override the default sendPasswordResetNotification() method defined by Illuminate\Auth\Passwords\CanResetPassword trait. Now you should use your own ResetPassword implementation:
<?php
namespace App;
use Illuminate\Notifications\Notifiable;
use Illuminate\Foundation\Auth\User as Authenticatable;
use App\Notifications\ResetPassword as ResetPasswordNotification;
class User extends Authenticatable
{
use Notifiable;
...
public function sendPasswordResetNotification($token)
{
// Your your own implementation.
$this->notify(new ResetPasswordNotification($token));
}
}
And now your reset password email subject should be updated!
Hope this help!
You may easily modify the notification class used to send the password reset link to the user. To get started, override the sendPasswordResetNotification method on your User model. Within this method, you may send the notification using any notification class you choose. The password reset $token is the first argument received by the method, See the Doc for Customization
/**
* Send the password reset notification.
*
* #param string $token
* #return void
*/
public function sendPasswordResetNotification($token)
{
$this->notify(new ResetPasswordNotification($token));
}
Hope this helps!
In Laravel 5.7 the default implementation is similar to this:
return (new MailMessage)
->subject(Lang::getFromJson('Reset Password Notification'))
->line(Lang::getFromJson('You are receiving this email because we received a password reset request for your account.'))
->action(Lang::getFromJson('Reset Password'), url(config('app.url').route('password.reset', $this->token, false)))
->line(Lang::getFromJson('This password reset link will expire in :count minutes.', ['count' => config('auth.passwords.users.expire')]))
->line(Lang::getFromJson('If you did not request a password reset, no further action is required.'));
All you have to do is change your locale from config/app.php for example to ro, then in your resources/lang, create a file ro.json similar to this:
{
"Reset Password Notification": "Viața Medicală CMS :: Resetare parolă",
"Hello!": "Salut,",
"You are receiving this email because we received a password reset request for your account.": "Primești acest email deoarece am primit o solicitare de resetare a parolei pentru contul tău.",
"Reset Password": "Reseteză parola",
"This password reset link will expire in :count minutes.": "Acest link va expira în :count de minute.",
"If you did not request a password reset, no further action is required.": "Dacă nu ai solicitat resetarea parolei, nu este necesară nicio altă acțiune.",
"Regards": "Toate cele bune",
"Oh no": "O, nu",
"Whoops!": "Hopa!",
"If you’re having trouble clicking the \":actionText\" button, copy and paste the URL below\ninto your web browser: [:actionURL](:actionURL)": "Dacă nu reușești să dai click pe butonul de \":actionText\", dă copy-paste la URL-ul de mai jos în browser:\n [:actionURL](:actionURL)"
}
It will translate both the subject (first key) and the mail body.
UPDATE for Laravel 6.*
This can be also used for VerifyEmail.php notification.
Laravel 8
In AuthServiceProvider.php
Add these code.
ResetPassword::toMailUsing(function ($notifiable, $url) {
return (new MailMessage)
->subject(Lang::get('Reset Password Notification'))
->line(Lang::get('You are receiving this email because we received a password reset request for your account.'))
->action(Lang::get('Reset Password'), $url)
->line(Lang::get('This password reset link will expire in :count minutes.', ['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.'));
});
To everyone asking how to update the Hello, Regards, and subcopy text:
php artisan vendor:publish (option 11)
then in views/vendor/notifications/email.blade.php
In this file there will be the text like Hello, wich you can change by changing:
for example:
line 9# #lang('Hallo!, Hei!, Bonjour!, Guten Tag!, Geia!')
You can create a custom function that will create the reset password token like this.
$user = User::where('email', 'example#name.com' )->first();
$password_broker = app(PasswordBroker::class); //so we can have dependency injection
$token = $password_broker->createToken($user); //create reset password token
$password_broker->emailResetLink($user, $token, function (Message $message) {
$message->subject('Custom Email title');
});//send email.
a note about this answer :
https://stackoverflow.com/a/40574428/9784378
you can copy vendor file functions and paste them into Resetpassword.php file
that you have created in notification folder .
Just add the line:
->subject('New Subjetc')
in the the method toMail of the file Illuminate\Auth\Notifications\ResetPassword
like this:
public function toMail($notifiable)
{
return (new MailMessage)
->subject('New Subjetc')
->line('You are receiving this email because we received a password reset request for your account.')
->action('Restaurar Contraseña', url(config('app.url').route('password.reset', $this->token, false)))
->line('If you did not request a password reset, no further action is required.');
}
I am using built in laravel auth functionality.Its working fine.I am trying to override following two functionality.
1.send forgot password email using mandrill.
2.send verification email while registering account.
Can any one help me to solve this issue
My aim is to use mandril instead of default email
I can see auth built in methods but i didnt got idea how i can override that
trait ResetsPasswords
{
use RedirectsUsers;
/**
* Display the password reset view for the given token.
*
* If no token is present, display the link request form.
*
* #param \Illuminate\Http\Request $request
* #param string|null $token
* #return \Illuminate\Contracts\View\Factory|\Illuminate\View\View
*/
public function showResetForm(Request $request, $token = null)
{
return view('auth.passwords.reset')->with(
['token' => $token, 'email' => $request->email]
);
}
/**
* Reset the given user's password.
*
* #param \Illuminate\Http\Request $request
* #return \Illuminate\Http\Response
*/
public function reset(Request $request)
{
$this->validate($request, $this->rules(), $this->validationErrorMessages());
// Here we will attempt to reset the user's password. If it is successful we
// will update the password on an actual user model and persist it to the
// database. Otherwise we will parse the error and return the response.
$response = $this->broker()->reset(
$this->credentials($request), function ($user, $password) {
$this->resetPassword($user, $password);
}
);
// If the password was successfully reset, we will redirect the user back to
// the application's home authenticated view. If there is an error we can
// redirect them back to where they came from with their error message.
return $response == Password::PASSWORD_RESET
? $this->sendResetResponse($response)
: $this->sendResetFailedResponse($request, $response);
}
As answered by Mahfuzal, Laravel comes with a bunch of mail drivers out of the box. So just update your .env file to use the right driver.
As for sending a verification email when creating an account, you just need to override the postRegister() function inside the Auth/AuthController like so:
public function postRegister(Request $request)
{
$validator = $this->validator($request->all());
if ($validator->fails()) {
$this->throwValidationException(
$request, $validator
);
}
$confirmation_code = str_random(30);
$newUser = new User;
$newUser->username = $request->username;
$newUser->email = $request->email;
$newUser->password = bcrypt($request->password);
$newUser->confirmation_code = $confirmation_code;
$newUser->save();
$data = array('confirmation_code' => $confirmation_code, 'username' => $request->username);
Mail::send('emails.verify', $data, function ($message) use ($newUser){
$message->to($newUser->email, $newUser->username);
$message->subject('Please verify your email address');
});
return redirect('/auth/login');
}
This will execute the above code when registering a user rather than what Laravel does default out of the box so just tweak it to your needs.
You then just need to create a function that will check the token and verify their account when they click the link. For that, I use something similar to what is explained here.
Laravel provides drivers for SMTP, Mailgun, Mandrill, Amazon SES,
PHP's mail function, and sendmail, allowing you to quickly get started
sending mail through a local or cloud based service of your choice.
Open your .env file and change following by your Mandrill credentials and then you're good to go.
MAIL_DRIVER=mandrill
MAIL_HOST=
MAIL_PORT=2525
MAIL_USERNAME=null
MAIL_PASSWORD=null
MAIL_ENCRYPTION=null
You can create your own reset method in the controller that uses the trait to override the method in the trait.