I have used markdown mailables which is a new feature in laravel 5.4. I have successfully implemented a mail sender. It seems, the subject of the mail is named as the name of the mailable class. I need to change the subject of the mail and it's hard to find any resources regarding this.
There is subject method in laravel mailables.
All of a mailable class' configuration is done in the build method. Within this method, you may call various methods such as from, subject, view, and attach to configure the email's presentation and delivery. : https://laravel.com/docs/5.4/mail#writing-mailables
You can achieve this like this :
/**
* Build the message.
*
* #return $this
*/
public function build()
{
return $this->from('example#example.com')
->subject('Your Subject')
->markdown('emails.orders.shipped');
}
You may need to execute php artisan view:clear after modifying your class.
If the email subject is the same for all emails then just overload the $subject parameter in your extended Mailable class.
/**
* The subject of the message.
*
* #var string
*/
public $subject;
complete code (tested)
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use Mail;
class ContactController extends Controller {
public function sendContactMail(Request $request) {
$this->validate($request, [
'name' => 'required',
'email' => 'required|email',
'subject' => 'required',
'user_message' => 'required'
]);
Mail::send('contact_email',
array(
'name' => $request->get('name'),
'email' => $request->get('email'),
'subject' => $request->get('subject'),
'user_message' => $request->get('user_message'),
), function($message) use ($request)
{
$message->from($request->email );
$message->subject("Your Subject");
$message->to('email to');
});
return back()->with('success', 'Your message was sent successfully');
}
}
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 have created a User Registration page with verifying mail using Laravel 7. But my markdown mail is not working.
Giving "InvalidArgumentException No hint path defined for [mail]. (View: C:\xampp\htdocs\user_mgmt\resources\views\mail\VerifyMail.blade.php)" error.
Here is my RegistrationController Page.
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Users_Profile;
use App\User;
use App\Mail\VerifyMail;
use Sentinel;
use Activation;
use Mail;
use Illuminate\Support\Facades\Validator;
class RegisterController extends Controller
{
function register(Request $req)
{
$users_profile= new Users_Profile;
$this->validate($req, [
'username' => ['required', 'string', 'max:50', 'unique:users', 'alpha_dash'],
'email' => ['required', 'string', 'email', 'max:255', 'unique:users'],
'password' => ['required', 'string', 'min:8', 'confirmed'],
]);
$user = Sentinel::register($req->all());
$users_profile->email=$req->input('email');
$users_profile->save();
$req->session()->put('user',$req->input('username'));
$activate = Activation::create($user);
$this->sendActivationEmail($user, $activate->code);
return redirect('verify');
}
public function sendActivationEmail($user, $code) {
Mail::send(
'mail.VerifyMail',
['user' => $user, 'code' =>$code],
function($message) use ($user) {
$message->to($user->email);
$message->subject("Hello $user->name Activate Your Account.");
}
);
}
}
Here is my Mail Blade Template
#component('mail::message')
#Thank you for registering in LMS
Please, click on the Link below to activate your account
#component('mail::button', ['url' => 'www.google.com' ])
Verify
#endcomponent
Thanks,<br>
{{ config('app.name') }}
#endcomponent
In my Mail controller I am using markdown instead of view in the build function.
Your should use a mailable. It's cleaner and more concise. In Laravel, each type of email sent by your application is represented as a "mailable" class. To fix your case, you need to call the markdown() method in the build() method of your mailable - not the view() method. See the example below:
/**
* Build the message.
*
* #return $this
*/
public function build()
{
return $this->from('example#example.com')
->markdown('emails.orders.shipped');
}
So I'm gonna use laravel broadcasting for a chat app,
I followed Laravel Broadcasting approach,
Uncommented App\Providers\BroadcastServiceProvider
from providers array inside config/app.php
Registered in pusher website, made a channel
and filled the fields below inside .env file with my pusher channel info
PUSHER_APP_ID
PUSHER_APP_KEY
PUSHER_APP_SECRET
PUSHER_APP_CLUSTER
Inside my broadcast.php config file where I set the default driver to pusher, I also added
'options' => [
'cluster' => 'us2',
'encrypted' => true,
],
to pusher array inside connections array based on my channel info in pusher panel
Installed pusher php package on my laravel project using composer require pusher/pusher-php-server "~3.0" command
Here is my event class
<?php
namespace App\Events;
use App\User;
use App\TherapyMessage;
use Illuminate\Broadcasting\Channel;
use Illuminate\Queue\SerializesModels;
use Illuminate\Broadcasting\PrivateChannel;
use Illuminate\Broadcasting\PresenceChannel;
use Illuminate\Foundation\Events\Dispatchable;
use Illuminate\Broadcasting\InteractsWithSockets;
use Illuminate\Contracts\Broadcasting\ShouldBroadcast;
use App\AppLog;
use Illuminate\Contracts\Broadcasting\ShouldBroadcastNow;
class TherapyMessageSent implements ShouldBroadcastNow
{
use Dispatchable, InteractsWithSockets, SerializesModels;
/**
* User that sent the message
*
* #var User
*/
public $user;
/**
* Message details
*
* #var Message
*/
public $message;
/**
* Create a new event instance.
*
* #return void
*/
public function __construct(User $user, TherapyMessage $message)
{
$this->user = $user;
$this->message = $message;
}
/**
* Get the channels the event should broadcast on.
*
* #return Channel|array
*/
public function broadcastOn()
{
$message_id = $this->message->id;
$user = $this->user;
AppLog::create([
'file_name' => __FILE__,
'message' => "broadcast before send with Message ID of $message_id from $user->full_name"
]);
return new PrivateChannel("therapy-chat.$message_id");
}
}
The AppLog is a model that I use for logging inside the project
I tried implementing ShouldBroadcast interface at first but that didn't work either
I also registered my event inside EventServiceProvider.php file and run php artisan event:generate command, here is the EventServiceProvider $listen array:
protected $listen = [
Registered::class => [
SendEmailVerificationNotification::class,
TherapyMessageSent::class
],
];
I also imported the event namespace next to other namespaces inside the file:
use \App\Events\TherapyMessageSent;
Here is the channel that I defined inside routes/channels.php file:
use App\AppLog;
Broadcast::channel('therapy-chat.{message_id}', function ($user, $message_id) {
AppLog::create([
'file_name' => __FILE__,
'message' => "broadcast sending with Message ID of $message_id to $user->full_name"
]);
if (!Auth::check()) return false;
$message = \App\TherapyMessage::find($message_id);
if (!$message) {
AppLog::create([
'file_name' => __FILE__,
'message' => "Message with ID of $message_id Not Found for broadcasting"
]);
return false;
}
$will_send = false;
if ($therapist = $user->therapist) {
$will_send = $therapist->id === $message->therapist_id;
} else if ($patient = $user->patient) {
$will_send = $message->patient_id === $patient->id;
}
if ($will_send) {
AppLog::create([
'file_name' => __FILE__,
'message' => "Message with ID of $message_id broadcasted to $user->full_name"
]);
}
return $will_send;
});
Finally, this is my controller method:
public function sendToTherapist(Request $request) {
$validation = \Validator::make($request->all(), ['message' => 'required']);
if ($validation->fails()) return $this->validationError($validation);
$user = \Auth::user();
$patient = $user->patient;
$therapist = $patient->therapist;
if (!$therapist) return $this->errorWithMessage('Patient does not have Therapist');
$message = \App\TherapyMessage::create([
'patient_id' => $patient->id,
'therapist_id' => $therapist->id,
'type' => TherapyMessageType::TEXT,
'text' => $request->message,
'sender_role' => TherapyMessageSenderRole::PATIENT
]);
broadcast(new TherapyMessageSent($user, $message))->toOthers();
return $this->success(['id' => $message->id]);
}
My controller class extends from BaseController which is a custom controller class with helper methods such as success(), validationError() and errorWithMessage()
As you see in the code above
I filled $user and $message with correct values and the request works without any error
I think the channel method won't even be fired,
as I check the AppLog table when I call broadcast method, only the log inside TherapyMessageSent event broadcastOn function is saved
and even the log that I save at the beginning of channels.php method, isn't saved so I think this method is never executed.
If anyone could help me with the problem, I'd be thankful.
I have a contact form where someone provides his name and email. I want to send him an email now with Laravel.
I found in the docs
To send a message, use the to method on the Mail facade. The to method
accepts an email address, a user instance, or a collection of users.
and in fact
\Mail::to('example#gmail.com')->send(new \App\Mail\Hello);
works. But is it also possible to provide the name for the email receipt?
I wanted to look that up in the Laravel API for the Mail Facade but to my surprise the facade has no to function?
So how can I find out what the to function really does and if I can pass a name parameter as well?
In laravel 5.6, answer to your question is: use associative array for every recpient with 'email' and 'name' keys, should work with $to, $cc, $bcc
$to = [
[
'email' => $email,
'name' => $name,
]
];
\Mail::to($to)->send(new \App\Mail\Hello);
You can use the Mail::send() function that inject a Message class in the callable. The Message class has a function to($email, $name) with the signature you're searching, i.e.:
Mail::send($view, $data, function($message) use ($email, $name) {
$m->to($email, $name);
$m->from('youremail#example.com', 'Your Name');
$m->subject('Hi there');
})
The $view could be a string (an actual view) or an array like these:
['text'=> 'body here']
['html'=> 'body here']
['raw'=> 'body here']
The $data argument will be passed to the $view.
For Laravel < 5.6 one can use this:
$object = new \stdClass();
$object->email = $email;
$object->name = $user->getName();
\Mail::to($object)->queue($mailclass);
see here
I prefer this solution as more readable (no need to use arrays and static string keys).
\Mail::send((new \App\Mail\Hello)
->to('example#gmail.com', 'John Doe');
You can use Mailable class in Laravel:
https://laravel.com/docs/5.5/mail
php artisan make:mail YouMail
These classes are stored in the app/Mail directory.
In config/mail.php you can configue email settings:
'from' => ['address' => 'example#example.com', 'name' => 'App Name'],
for Laravel 8 is like this:
$user = new User;
$user->email = 'example#example.com';
Mail::to($user)->send(new YourMail);
YourMail is Mailable class created by php artisan make:mail YourMail
I'm new to coding and Laravel 5.1, and after watching the tutorials by Laracasts I have been creating my own webpage. I came across and error that I cant fix...
Method [send] does not exist.
My code looks like this:
namespace App\Http\Controllers;
use Mail;
use App\User;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
class ContactController extends Controller
{
/**
*
* #param Request $request
*/
public function emailContactForm (Request $request){
$msg = $request->input('message');
$name = $request->input('name');
$email = $request->input('email');
//
$this->validate($request, [
'title' => 'required|max 500',
'name' => 'required',
'email' => 'required',
]);
//
Mail::send(
'emails.contactForm',
[
'message'=>$msg,
'name'=>$name,
],
function($m) use ($email) {
$m->to('jessica.blake#autumndev.co.uk', 'say hi')
->subject('new message')
->from($email);
}
);
//
return;
}
}
I'm trying to use the mail function, which we have now got working, but the send still doesn't? Any suggestions? Thanks!
EDIT: Full stack trace as per laravel log file: http://pastebin.com/ZLiQ7Wgu
At the very first sight, you are calling the controller method send() but you actually named it emailContactForm()
You dont post routes and actions so the quick fix by now is trying to rename emailContactForm to send, despite instead you should probably need to review all your related routing logic.