Laravel : How to customize title of email when sending email with Mailable? - laravel-5

I write a mailable to send email when user registers,I do it following the document(https://laravel.com/docs/5.5/mail):
first,generating a mailable:
php artisan make:mail UserRegistered
Ok,thus there is a UserRegistered.php file in the app/Mail directory,and I write the build() method like this:
public function build()
{
return $this->view('emails.activate-user')
->with([
'name' => $this->user->name,
'url' => route('activateUser',['token'=>$this->user->confirmation_token])
]);
}
The email can be sent successfully,the title of the email is User Registered,I want to customize the title ,how to do it?

You have to use subject method
public function build()
{
return $this->view('emails.activate-user')
->subject("My mail title")
->with([
'name' => $this->user->name,
'url' => route('activateUser',['token'=>$this->user->confirmation_token])
]);
}
Or update your mails class's constructor
public function __construct()
{
$this->subject('Sample title');
}

If you want to change mail title you need to change it in .env file. Same Like as given below:
You need to change it here for mail title.
And if you just want to change only subject then you can you use subject() function while sending mail to add you subject.
For Example:
public function build()
{
return $this->subject('Reset Password')
->view('emails.forgotpass');
}
and the final result will be like this where my APP_NAME is Laravel.
Result 1:
Result 2:

Related

How to specify from on the fly in laravel 8 mail::send

From the contact form on my website, I send an confirmation email to the visitor and an email to the website admin. Both email are coming to the email address defined in .env.
How can I change the from field for the email sent to admin?
My current code where the second Mail:: gives an error.
// send html email to user
Mail::to(request('email'))
->send(new ContactWebsite($emailFields));
// send html email to admin
Mail::to("newemail#address")
->from(request('email'))
->send(new ContactWebsite($emailFields));
Daniel solution is good but how do I implement it in my case?
In the Contact Contoller store function, I put the fromAddress in the $emailFields object:
$emailFields = (object) [
'fromName' => $fullnameUser,
'fromEmail' => request('email'),
'fromAddress' => $fullnameUser.' <'.request('email').'>',
'subject' => '...',
'body' => request('body')
];
Then in the Mailable:
public function __construct($emailFields) {
$this->emailFields = $emailFields;
$this->fromAddress = $emailAddress['fromAddress'];
}
public function build() {
return $this->markdown('emails.contact-confirm-user');
}
Is the syntax correct in the __construct function?
And how do I pass the $this->fromAddress in the build function?
You are supposed to define the ->from() part in your Mailable class's build() function (in your case ContactWebsite) either as part of the $emailFields, or as a second parameter. Then you just use it in the build function:
class ContactWebsite extends Mailable
{
use Queueable, SerializesModels;
private $fromAddress = 'default#value.com';
public function __construct($emailFields, $fromAddress = null)
{
if ($fromAddress) {
$this->fromAddress = $fromAddress;
}
}
public function build()
{
return $this->from($this->fromAddress)
// Whatever you want here
->send()
}
}

Laravel Mail Notification - modify from address

I created a Notification with a mail notifiable. My problem is that I cant figure out how to set the from address.
Here's my toMail:
public function toMail($notifiable)
{
return (new MailMessage)
->from($this->email, $this->name)
->subject('Contact Form')
->line('Name: '.$this->name)
->line('Email: '.$this->email)
->line('Message: '.$this->message);
}
The from method does not work, and instead it uses the default mail config. Any ideas on why this is not working?
You need to use the from method within your mailable class' build method:
public function build()
{
return $this->from('example#example.com')
->view('emails.orders.shipped');
}
You can also have a global from email. You do that in the config/mail.php configuration file:
'from' => ['address' => 'example#example.com', 'name' => 'App Name']
this will be used if no from address is specified in the mailable class' build method
Here's a reference to the laravel documentation that explains the mail function in detail.

I cannot send email using gmail even though I already allowed less secure apps | Laravel

I have an observer that fires off an event if a user updated his email address.
public function updated(User $user)
{
if($user->isDirty('email')){
$new_email = $user->email;
$old_email = $user->getOriginal('email');
//dd($user);
event(new UserUpdate($user, $old_email));
}
}
In the UserUpdate event I have the following inside the constructor:
public function __construct($user, $old_email)
{
$this->user = $user;
$this->old_email = $old_email;
}
In the event listener, I want to send an email to the old email address.
public function handle(UserUpdate $event)
{
$user = $event->user;
Mail::to($event->old_email)->send(new UserUpdated($user));
}
And the Mail class looks like this:
public function __construct($user)
{
$this->user = $user;
}
public function build()
{
$this->subject("Updated Email");
return $this->view('emails.updatedUser');
}
When I update the user, I get the following error:
Expected response code 250 but got code "530", with message "530 5.7.1 Authentication required
I setup the email in the .env
MAIL_DRIVER=smtp
MAIL_HOST=smtp.gmail.com
MAIL_PORT=587
MAIL_USERNAME=example#gmail.com
MAIL_PASSWORD=******
MAIL_ENCRYPTION=tls
in the mail.php I also edited a few details:
'host' => env('MAIL_HOST', 'smtp.gmail.com'),
'from' => [
'address' => env('MAIL_FROM_ADDRESS', 'example#gmail.com'),
'name' => env('MAIL_FROM_NAME', 'Admin Email'),
],
I went to my email and enabled the option to allow less secure apps.
How can I get my emails to work?
Using this question as a reference, I then noticed that all I needed to do was to restart my server and clear cache.

How to return custom response when validation has fails using laravel form requests

When we use Laravel Form Requests in our controllers and the validation fails then the Form Request will redirect back with the errors variable.
How can I disable the redirection and return a custom error response when the data is invalid?
I'll use form request to GET|POST|PUT requests type.
I tried the Validator class to fix my problem but I must use Form Requests.
$validator = \Validator::make($request->all(), [
'type' => "required|in:" . implode(',', $postTypes)
]);
if ($validator->fails()) {
return response()->json(['errors' => $validator->errors()]);
}
Creating custom FormRequest class is the way to go.
namespace App\Http\Requests;
use Illuminate\Contracts\Validation\Validator;
use Illuminate\Validation\ValidationException;
use Illuminate\Http\Exceptions\HttpResponseException;
class FormRequest extends \Illuminate\Foundation\Http\FormRequest
{
protected function failedValidation(Validator $validator)
{
if ($this->expectsJson()) {
$errors = (new ValidationException($validator))->errors();
throw new HttpResponseException(
response()->json(['data' => $errors], 422)
);
}
parent::failedValidation($validator);
}
}
Class is located in app/Http/Requests directory. Tested & works in Laravel 6.x.
This is the same but written differently:
protected function failedValidation(Validator $validator)
{
$errors = (new ValidationException($validator))->errors();
throw new HttpResponseException(
response()->json([
'message' => "",
'errors' => $errors
], JsonResponse::HTTP_UNPROCESSABLE_ENTITY)
);
}
Base class FormRequest has method failedValidation. Try to override it in your FormRequest descendant
use Illuminate\Contracts\Validation\Validator;
class SomeRequest extends FormRequest
{
...
public function failedValidation(Validator $validator)
{
// do your stuff
}
}
use this on function
dont forget to take on top // use App\Http\Requests\SomeRequest;
$validatedData = $request->validated();
\App\Validator::create($validatedData);
create request php artisan make:request SomeRequest
ex.
use Illuminate\Contracts\Validation\Validator;
class SomeRequest extends FormRequest
{
public function rules()
{
return [
'health_id' => 'required',
'health' => 'required',
];
}
}

Customise Reset Password Email and pass User Data in Laravel 5.3

I am using Laravel 5.3 and customizing the Password Reset Email Template. I have done the following changes to create my own html email for the notification using a custom Mailable class. This is my progress so far:
ForgotPasswordController:
public function postEmail(Request $request)
{
$this->validate($request, ['email' => 'required|email']);
$response = Password::sendResetLink($request->only('email'), function (Message $message) {
$message->subject($this->getEmailSubject());
});
switch ($response) {
case Password::RESET_LINK_SENT:
return Response::json(['status' => trans($response)], 200);
case Password::INVALID_USER:
return Response::json(['email' => trans($response)], 400);
}
}
User Model:
public function sendPasswordResetNotification($token)
{
Mail::queue(new ResetPassword($token));
}
ResetPassword Mailable Class:
protected $token;
public function __construct($token)
{
$this->token = $token;
}
public function build()
{
$userEmail = 'something'; // How to add User Email??
$userName = 'Donald Trump'; // How to find out User's Name??
$subject = 'Password Reset';
return $this->view('emails.password')
->to($userEmail)
->subject($subject)
->with([
'token' => $this->token
'userEmail' => $userEmail,
'userName' => $userName
]);
}
If you noticed above, I am not sure how do I pass the user's name and find out the user's email address. Do I need to send this data from the User Model or do I query it from the Mailable class? Can someone show me how I can do that please?
Usually you ask for the user email in order to send a reset password email, that email should come as a request parameter to your route controller.
By default, L5.3 uses post('password/email) route to handle a reset password request. This route execute sendResetLinkEmail method which is defined in the 'SendsPasswordResetEmails' trait used by the App\Http\Controllers\Auth\ForgotPasswordController.
From here you can take one of 2 options:
1st: You could overwrite the route to call another function in the same controller (or any other controller, in this case could be your postEmail function) which search for the user model by the email you received, then you can pass the user model as function parameter to the method which execute the queue mail action (this may or may not require to overwrite the SendsPasswordResetEmails, depends on how you handle your reset password method).
This solution would looks something like this:
In routes/web.php
post('password/email', 'Auth\ForgotPasswordController#postEmail')
in app/Mail/passwordNotification.php (for instance)
protected $token;
protected $userModel;
public function __construct($token, User $userModel)
{
$this->token = $token;
$this->userModel = $userModel;
}
public function build()
{
$userEmail = $this->userModel->email;
$userName = $this->userModel->email
$subject = 'Password Reset';
return $this->view('emails.password')
->to($userEmail)
->subject($subject)
->with([
'token' => $this->token
'userEmail' => $userEmail,
'userName' => $userName
]);
}
in app/Http/Controllers/Auth/ForgotPasswordController
public function postEmail(Request $request)
{
$this->validate($request, ['email' => 'required|email']);
$userModel = User::where('email', $request->only('email'))->first();
Mail::queue(new ResetPassword($token));
//Manage here your response
}
2nd: You could just overwirte the trait SendsPasswordResetEmails to search for the user model by the email and use your customized function in sendResetLinkEmail function. There you could use your function but notice that you still have to handle somehow an status to create a response as you already have it on ForgotPasswordController.
I hope it helps!

Resources