I have a PDF coded in base 64, it is an attribute in my database, and I send emails through Laravel but I do not know how can I send the base64 as a PDF.
public function toMail()
{
$pdf_decoded = base64_decode($this->table->raw_label);
$message = (new MailMessage)
->subject(env('APP_NAME').' - HI #'. $this->order->id)
->greeting('¡Hi!');
if(env('APP_URL') == 'http://test.test'){
$message->bcc(['test#test.com']);
}
return $message;
}
I know attach property, but I do not know hot to implement it.
You can actually do this through the Mail or Notification class, personally I would use a Notification but it's up to you. Just use the ->attach($pathToFile) method and give it the file path as a parameter.
Here's an example using a Notification, hope this helps!
/**
* Get the mail representation of the notification.
*
* #param mixed $notifiable
* #return \Illuminate\Notifications\Messages\MailMessage
*/
public function toMail($notifiable)
{
return (new MailMessage)
->line('Please download the PDF.')
->attach(public_path($this->filename), [
'as' => 'filename.pdf',
'mime' => 'text/pdf',
]);
}
Related
I want to send email verification when a user signs up with a new Email Address. So at the Register Controller I added this:
public function register(Request $request)
{
if(Session::has('email')){
return Redirect::back()->withErrors(['msg' => 'Email was already sent to you, please check the spam folder too.']);
}else{
$validatedEmail = $request->validate([
'user_input' => 'required|unique:users,usr_email|regex:/(.+)#(.+)\.(.+)/i|max:125|min:3',
],[
'user_input.required' => 'You must enter this field',
'user_input.unique' => 'This email is already registered',
'user_input.regex' => 'This email is not correct',
'user_input.max' => 'Maximum length must be 125 characters',
'user_input.min' => 'Minimum length must be 3 characters',
]);
$register = new NewRegisterMemberWithEmail();
return $register->register();
}
}
So if the email was valid, it will call a helper class NewRegisterMemberWithEmail which goes like this:
class NewRegisterMemberWithEmail
{
public function register()
{
try{
$details = [
'title' => 'Verify email'
];
Mail::to(request()->all()['user_input'])->send(new AuthMail($details));
Session::put('email',request()->all()['user_input']);
return redirect()->route('login.form');
}catch(\PDOException $e){
dd($e);
}
}
}
So it used to work fine and correctly sends the email for verification, but I don't know why it does not send email nowadays.
In fact I have tested this with different mail service providers and for both Yahoo & Gmail the email did not received somehow!
But for local mail service provider based in my country the email was sent properly!
I don't know really what's going on here because the logic seems to be fine...
So if you know, please let me know... I would really really appreciate any idea or suggestion from you guys.
Also here is my AuthMail Class if you want to take a look at:
class AuthMail extends Mailable
{
use Queueable, SerializesModels;
public $details;
/**
* Create a new message instance.
*
* #return void
*/
public function __construct($details)
{
$this->details = $details;
}
/**
* Build the message.
*
* #return $this
*/
public function build()
{
return $this->subject('Sitename')->view('emails.AuthMail');
}
}
Once I was faced same problem when I was used Gmail as smtp.
Reason:
when we used our Gmail password directly in smtp settings then due to some Gmail policies it'll be blocked after sometime (months) and stopped email sending.
Solution:
we need to create an app-password from our Gmail security and use that password in smtp settings. below google article will guide:
How to create app-password on gmail
.env smtp setting for laravel:
MAIL_MAILER=smtp
MAIL_HOST=smtp.gmail.com
MAIL_PORT=587
MAIL_USERNAME=<your-email>
MAIL_PASSWORD=<app-password>
MAIL_ENCRYPTION=tls
I hope that'll help you.
If you use google mail to send email then we have the same problem.
On May 30, 2022 Google stop supporting less secure applications or third party application.
This is I think the reason why your send mail does not work (consider this answer if you use google mail as mail sender)
I was having issues when sending email, especially to gmail accounts. So I have changed my approach and overcome that issue.
Please check my answer below
Laravel Email
Example Mail Class
<?php
namespace App\Mail;
use Illuminate\Bus\Queueable;
use Illuminate\Mail\Mailable;
use Illuminate\Queue\SerializesModels;
use Symfony\Component\Mime\Email;
class OrderInfoMail extends Mailable
{
use Queueable, SerializesModels;
/**
* Create a new message instance.
*
* #return void
*/
public $data;
public function __construct($data)
{
$this->data = $data;
}
/**
* Build the message.
*
* #return $this
*/
public function build()
{
$this
->subject('Order Confirmation')
->from('noreply#app.xxx.co.uk', 'XXX Portal')
->view('orders.templates.order-form')
->with([
'name' => $this->data->name,
'sales_representative_name' => $this->data->sales_representative_name,
'sales_representative_phone' => $this->data->sales_representative_phone,
"items" => $this->data->items,
"address" => $this->data->address,
"net" => $this->data->net,
"payment" => $this->data->payment,
"balance" => $this->data->balance,
]);
$this->withSymfonyMessage(function (Email $message) {
$message->getHeaders()->addTextHeader(
'X-Mailer', 'PHP/' . phpversion()
);
});
return $this;
}
}
Usage
$email = 'a#b.com'; // pls change
$name = 'ab';// pls change
$data = new \stdClass();
$data->name = $name;
$data->sales_representative_name = \App\User::find(Auth::user()->id)->name;
$data->sales_representative_phone = \App\User::find(Auth::user()->id)->phones->first()->number;
$data->items = $order_items;
$data->address = $address;
$data->net = $net;
$data->payment = $payment;
$data->balance = $balance;
Mail::to($email)->send(new \App\Mail\OrderInfoMail($data));
I don't think the issue is your code. I think it is related to you sending practices. A solution is to use a service that is designed to send emails like SparkPost (full disclosure I work for SparkPost). There are many others. These services can help you make sure you are following email best practices.
You can make this work without an email service but at the very least you should verify you are following the best practices presented by MAAWG: https://www.m3aawg.org/published-documents
I am trying to send notifications to individual users with laravel 6 using the documentation here: https://laravel.com/docs/6.x/notifications#slack-notifications
My from and to functions don't seem to be doing anything.
// call notification
Notification::route('slack', $slackUrl)->notify(new notifyHours($event->user));
App\Notifications\notifyHours
// send DM
public function toSlack($notifiable)
{
return (new SlackMessage())
->from('Puffin', ':puffin:') // doesn't seem to do anything
->to('#U4KFXXXXX') // doesn't seem to do anything
->image('https://XXX.png')
->content("Hi! Make sure I am up to date!")
->attachment(function(SlackAttachment $attachment) use ($notifiable) {
$attachment->title('Your Hours', 'https://xxx/tasks')
->fields([
'Today' => $this->hours->today.' hours',
'This Week' => 'You worked '.$this->hours->week. ' hours.'
]);
});
}
How come the notification is sent to an entire channel, instead of the user I define in the to() function?
According to the code the to() method only accepts a channel not a user of that team.
/**
* Set the Slack channel the message should be sent to.
*
* #param string $channel
* #return $this
*/
public function to($channel)
{
$this->channel = $channel;
return $this;
}
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.
How can I send e-mail with attached image if I receive the data in base64 format?
Here is mail template:
<h1>You got mail from - {{$user->name}}</h1>
<h2>Date:</h2>
<p>{{$post->created_at}}</p>
<h2>Message:</h2>
<p>{{$post->body}}</p>
<img src="data:image/png;base64, {{$image}}">
<div>
</div>
And the logic:
public function createPost()
{
$user = JWTAuth::toUser();
$user->posts()->create(['user_id' => $user->id, 'body' => Input::get('comment.body')]);
Mail::send('mail.template', [
'image' => Input::get('image'),
'user' => $user,
'post' => Post::where('user_id', $user->id)->get()->last(),
], function ($m) use ($user) {
$m->from('xyz#app.com', 'XYZ');
$m->to('xyz#gmail.com', $user->name)->subject('Subject');
});
}
From this I only get mail with full base64 string...img tag gets ignored
Attachments
To add attachments to an email, use the attach method within the
mailable class' build method. The attach method accepts the full path
to the file as its first argument:
/**
* Build the message.
*
* #return $this
*/
public function build()
{
return $this->view('emails.orders.shipped')
->attach('/path/to/file');
}
More information here (for Laravel 5.3).
I hope, it will be helpful.
The solution I came up with is to save the image first in order to attach it as Viktor suggested although I don't have Laravel 5.3. so the method is somehow different.
User may or may not send the picture, so the method is as follows:
$destinationPath = null;
if($request->has('image')){
// save received base64 image
$destinationPath = public_path() . '/uploads/sent/uploaded' . time() . '.jpg';
$base64 = $request->get('image');
file_put_contents($destinationPath, base64_decode($base64));
}
And then attach the saved image to the mail:
Mail::send('mail.template', [
'user' => $user,
'post' => Post::where('user_id', $user->id)->get()->last(),
], function ($m) use ($user) {
$m->from('xyz#app.com', 'XYZ');
$m->to('xyz#gmail.com', $user->name)->subject('Subject');
if($request->has('image')){
$m->attach($destinationPath);
}
});
The mail template:
<h1>You got mail from - {{$user->name}}</h1>
<h2>Date:</h2>
<p>{{$post->created_at}}</p>
<h2>Message:</h2>
<p>{{$post->body}}</p>
I'm doing a simple application laravel 5.1, and I want to reset the password for users. I dont have a problem with that.
I just have not found a way to change the path of some files.
Among them is file "password.blade.php" which is what is sent to the user's mail containing the link to the token. This file must be in the Resources / views / emails / route.
Would you like to change: the name and path of the file. ?
Or if you can select a different view to be sent?
Thank you, any information would be appreciated ).
There is an $emailView variable in PasswordBroker.
/**
* The view of the password reset link e-mail.
*
* #var string
*/
protected $emailView;
If you set this to your view in your Password Controller, you should be able to change it's path and name.
If it doesn't work you can overwrite the emailResetLink function in your Password controller and change the view there. Here is the one from Laravel 5.2. You can get 5.1 from your PasswordBroker.php if it's different.
/**
* Send the password reset link via e-mail.
*
* #param \Illuminate\Contracts\Auth\CanResetPassword $user
* #param string $token
* #param \Closure|null $callback
* #return int
*/
public function emailResetLink(CanResetPasswordContract $user, $token, Closure $callback = null)
{
// We will use the reminder view that was given to the broker to display the
// password reminder e-mail. We'll pass a "token" variable into the views
// so that it may be displayed for an user to click for password reset.
$view = $this->emailView;
return $this->mailer->send($view, compact('token', 'user'), function ($m) use ($user, $token, $callback) {
$m->to($user->getEmailForPasswordReset());
if (! is_null($callback)) {
call_user_func($callback, $m, $user, $token);
}
});
}