Laravel notification email change title - laravel

I`m trying to send email notification.
When my emails sent the title is 'Example'.
How can i change the title by toMail() method of Notification class.
public function toMail($notifiable)
{
return (new MailMessage)
->greeting($this->notifMessage['subject'])
->line($this->notifMessage['description']);
}
my code is here.
Thank you! Best regards.

You can change the config/mail.php 'from' field to match your need, however i would advice against doing so, im not saying this is the case but lets imagine you have two different senders, changing the config only allows one sender per website.
So the easy solution is to override the 'from' fields in the toMail() function itself, this way you can have as many senders as you want.
Just add
->from('some_adress','some_name')
to your code.

You can easaly do:
public function toMail($notifiable)
{
return (new MailMessage)
// other options
->from("An amazing sender")
->subject("Amazing email's subject");
}

Related

Access individual data in a collection passing to Notification method

I have queried a list of users based on a filter to send out notifications and i want to use this collection method to send out the notification.
Collection method
As in the documentation i pass the users collection to the notification and my post data
Notification::send($users, new PostAlert($post));
I believe, this collection method is firing notifications in a loop. One-by-one.If it is, how do i access a user's details inside the notification ? i can only access $post details for now
Notification::send($users, new PostAlert($users, $post));
Doing the above passes the collection and i cannot access a single user detail inside the notification.
I know that i can set the firing on a loop, but i believe it is not the cleanest way
foreach($users as $user)
{
Notification::send(new PostAlert($user, $post));
}
It would be very helpful if you could help me how would i access a single model passing from collection.
It is pretty easy, Try it,
You will find a variable called $notifiable
// PostAlert
...
// toMail() or toArray()
public function toMail($notifiable)
{
dd($notifiable,"the user laravel is sending to.");
return (new MailMessage)
->line('The introduction to the notification.')
->action('Notification Action', url('/'))
->line('Thank you for using our application!');
}
...
Happy Codding.

How can I add reply to in Laravel aplication?

I started with the following code:
Mail::to('mail#gmail.com')->send(new ContactFormMail($email_data));
This works fine, but I am not sure how can I add 'reply to' to this code.
Next thing I tried is:
Mail::send('emails.contact-form', $email_data, function ($message) {
$message->from('admin#laravel.com', 'Laravel');
$message->to('admin#laravel.com');
$message->replyTo('admin#laravel.com', 'Laravel');
});
This has the following problem:
No hint path defined for [mail]...
In this case, if I remove #component('mail::message') from the mail view, the message is sent as it should, but it has no styling.
Finally, I do have this piece of code in my Mailable class:
public function build()
{
return $this->markdown('emails.contact-form');
}
Any assistance would be appreciated.
Thanks
The problem you have is that the first argument of Mail::send only accepts either a view email template or a mailable class. however, you passed in a markdown file. so it's not happy with it.
A simple solution is
public function build()
{
return $this->markdown('emails.contact-form')
->replyTo('admin#laravel.com', 'Laravel');
}
Mail::to('mail#gmail.com')->send(new ContactFormMail($email_data));

Send automatical email after save to database

I am new here.
I have a project in Laravel. I have one textarea and data from it is save in datavase. It works good. Now I would like to send automatical email to one specific email address with this data. It must be sent only one time with save to database.
I have no problem with sending email to customer with data but now I need to send email with data from this textarea to one specific email. It is a textarea what we have to buy for customer. It must be sent to our cooperation company.
Is it possible?
Ofcourse this is possible!
You should take a look at the following resources :
Observers
https://laravel.com/docs/6.0/eloquent#observers
Notifications
https://laravel.com/docs/6.0/notifications
-> specifically : https://laravel.com/docs/6.0/notifications#mail-notifications
yes, you can just trigger your function after saving: for example, after saving in controller.
public function store(Request $request){
$var = new Property; //your model
$var->title=$request->title; // the input that being save to database.
$var ->save();
// Send email to that input
Mail::send('email',['email'=>$request->title],function ($mail) use($request){
$mail->from('info#sth.com');
$mail->to($request->title);
});
return redirect()->back()->with('message','Email Successfully Sent!');
}

Add extra question to Laravel forgotten password form and custom its error messages

I'd like to customize the forgotten password form in Laravel.
When asking to reset the password, the user will have to answer a simple question (the name your first pet, the name of your childhood best friend, etc) besides inserting his/her email. This is to avoid other people asking password reset if they know the account's email, but are not the owner of the account.
I also would like to custom the errors messages to, actually, not show errors. For example, if an invalid email is inserted, it would not show the error message "We can't find a user with that e-mail address." I don't like it because someone may guess the email of a user by trying different emails until she/he stops getting the error message. Instead, I would like to show the message "If the information provided is correct, you will receive an email with the link to reset your password."
How to add these functionalities to Laravel auth?
I am looking for a solution that I don't have to create an entire login system from scratch (I think that if I try to design everything from scratch I'd probably miss something and create security vulnerabilities). I'd like to keep the Laravel auth system and just add these two features.
Feel free to suggest other ways to achieve the desired result and to make my question clearer. I'll appreciate that.
The good news is you don't need to rewrite everything.
The bad news is, you need to understand traits and how to extend/override them, which can be a little confusing.
The default controller that Laravel creates ForgotPasswordController doesn't do much. Everything it does is in the trait. The trait SendsPasswordResetEmails contains a few methods, most importantly for the validation in validateEmail method.
You can override this validateEmail method with one that checks for an answered question. You override traits by altering the 'use' statement.
For example change;
use SendsPasswordResetEmails
to:
use SendsPasswordResetEmails {
validateEmail as originValidateEmail
}
This will tell the code to re-name the original method validateEmail to originValidateEmail allowing you to create a new validateEmail in your own ForgotPasswordController.
You can then, inside ForgotPasswordController add a replacement which will be called by the default reset password code:
protected function validateEmail(Request $request)
{
// add in your own validation rules, etc.
$request->validate(['email' => 'required|email', 'questionfield' => 'required']);
}
To alter the error message, you can simply edit the language file found in resources/lang/en/passwords.php
Hope that helps.
Thanks to the user #Darryl E. Clarke, I managed to solve the problem. Here is what I did:
Add this line at the top of the file ForgotPasswordController, after namespace:
use App\User;
Add these 3 methods in the same file:
/**
* Send a reset link to the given user.
*
* #param \Illuminate\Http\Request $request
* #return \Illuminate\Http\RedirectResponse|\Illuminate\Http\JsonResponse
*/
public function sendResetLinkEmail(Request $request)
{
$this->validateRequest($request);
// We will send the password reset link to this user. Regardless if that
// worked, we will send the same response. We won't display error messages
// That is because we do not want people guessing the users' email. If we
// send an error message telling that the email is wrong, then a malicious
// person may guess a user' email by trying until he/she stops getting that
// error message.
$user = User::whereEmail($request->email)->first();
if ($user == null) {
return $this->sendResponse();
}
if ($user->secrete_question != $request->secrete_question) {
return $this->sendResponse();
}
$this->broker()->sendResetLink(
$this->credentials($request)
);
return $this->sendResponse();
}
/**
* Validate the given request.
*
* #param \Illuminate\Http\Request $request
* #return void
*/
protected function validateRequest(Request $request)
{
$request->validate(['email' => 'required|email', 'secrete_question' => 'required|string']);
}
/**
* Get the response for a password reset link.
*
* #return \Illuminate\Http\RedirectResponse|\Illuminate\Http\JsonResponse
*/
protected function sendResponse()
{
$response = 'If the information provided is correct, you will receive an email with a link to reset your password.';
return back()->with('status', $response);
}
Customize it the way you want.
Hope that it will helps others!!

Database notifications don't show up after testing notify

I have a unit test with the following:
use \Illuminate\Notifications\DatabaseNotification;
public function testMailSentAndLogged()
{
Notification::fake();
$user = factory(User::class)->create();
$emailAddress = $user->emailAddress;
$emailAddress->notify(new UserCreated);
Notification::assertSentTo(
$emailAddress,
UserCreated::class
);
error_log('DatabaseNotification '.print_r(DatabaseNotification::get()->toArray(), 1));
$this->assertEquals(1, $emailAddress->notifications->count());
}
My Notification has this for the via():
public final function via($notifiable)
{
// complex logic...
error_log('mail, database');
return ['mail', 'database'];
}
The code fails on the $this->assertEquals code. the error_log produces the following:
[03-Jan-2018 01:23:01 UTC] mail, database
[03-Jan-2018 01:23:01 UTC] DatabaseNotification Array
(
)
WHY don't the $emailAddress->notifications pull up anything? Why doesn't DatabaseNotification::get() pull anything?;
In your test, you are calling the method
Notification::fake();
As stated in Laravel's documentation on Mocking,
You may use the Notification facade's fake method to prevent
notifications from being sent.
Actually, this bit of code is the assertion that the Notification would have been sent, under normal circumstances (ie in prod) :
Notification::assertSentTo();
If you remove the call to Notification::fake(), your notification should appear in your testing database.
So you kinda have two solutions. The first one is to remove the call to fake(), thus really sending the notification, which will appear in the database. the second is not to test if the notification was written successfully in the database : it's Laravel's responsibility, not your application's. I recommand the second solution :)

Resources