How can I send Email in Laravel command instead of controller - php

I'm working on a project using Laravel where I want to be able to send an email when it is scheduled to send.
So far I've only found solutions to send a mail through a Route but I want to be able to send the mail when cron activates my self made command. I've already made a view of the mail that should be sent and made a page sendMail with php artisan make:mail sendMail that returns the mail view.
sendMail.php
<?php
namespace App\Mail;
use Illuminate\Support\Facades\DB;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Mail\Mailable;
use Illuminate\Queue\SerializesModels;
class sendMail extends Mailable
{
use Queueable, SerializesModels;
/**
* Create a new message instance.
*
* #return void
*/
public function __construct()
{
$winnersposts = DB::select('select post_id from winners group by post_id');
$posts = DB::select('select * from posts ');
$this->winnerposts =$winnersposts;
$this->posts=$posts;
}
/**
* Build the message.
*
* #return $this
*/
public function build()
{
return $this ->from('ivanrompa#gmail.com')
->view('emails.template');
}
}
mailAdmin.php
public function handle()
{
}
My command handle is still empty but I previously tried to implement to logic from my controller above in my command but it didn't work.
Am I writing the wrong code and is that the reason it just doesn't work or should I approach it in a different way? It is maybe good to know that I am still learning Laravel and I have never sent an email before through code. Any tips or solutions are welcome.

Assuming you have set your email configuration correctly.
Add this in your mailAdmin.php
use Mail;
use App\Mail\sendMail
public function handle()
{
Mail::to('recipient#gmail.com')->send(new sendMail);
}
Then run the command

Related

'Undefined variable' in Laravel 8 blade template on sending email

In my Laravel 8 project I try to send HTML e-mail, but get Undefined variable error.
I have this code in my controller:
// here the $client has a model value
Mail::to($client)->send(new ClientCreated($client));
In my app/Mail/ClientCreated.php file:
<?php
namespace App\Mail;
use App\Client;
use Illuminate\Bus\Queueable;
use Illuminate\Mail\Mailable;
use Illuminate\Queue\SerializesModels;
class ClientCreated extends Mailable
{
use Queueable, SerializesModels;
private $client;
/**
* Create a new message instance.
*
* #return void
*/
public function __construct(Client $client)
{
$this->client = $client;
}
/**
* Build the message.
*
* #return $this
*/
public function build()
{
// here the $this->client has a model value
return $this->view('emails.client.created');
}
}
Finally in my resources/views/emails/client/created.blade.php I have this code:
<p>Dear{{ $client->name }}!</p>
And I got this error message:
Undefined variable: client (View: /home/vagrant/Code/myproject/laravel/resources/views/emails/client/created.blade.php)
I read the docs and search on the Stackoverflow, but not found any help.
Any idea what I made wrong?
If you passed the variable to the view properly, but it still does not work, try to restart the queue in the console:
php artisan queue:restart
You should make $client public not private:
public $client;
"There are two ways you may make data available to your view. First, any public property defined on your mailable class will automatically be made available to the view"
Laravel 8.x Docs - Mail - Writing Mailables - View Data - Via Public Properties
The other method would be calling with:
$this->view(...)->with('client', $this->client);
"If you would like to customize the format of your email's data before it is sent to the template, you may manually pass your data to the view via the with method."
Laravel 8.x Docs - Mail - Writing Mailables - View Data - Via the with Method
If you do not want to change $client to public then use the second method.
You should make $client public
public $client;
Once the data has been set to a public property, it will automatically be available in your view, so you may access it like you would access any other data in your Blade templates.
https://laravel.com/docs/8.x/mail#view-data

Laravel Mailer queue with Redis showing error "The script tried to execute a method or access a property of an incomplete object."

This is the complete error.
Illuminate\Mail\SendQueuedMailable::handle(): The script tried to
execute a method or access a property of an incomplete object. Please
ensure that the class definition "Security\Mail\WelcomeMail" of the
object you are trying to operate on was loaded before unserialize()
gets called or provide an autoloader to load the class definition in
/var/www/html/vendor/laravel/framework/src/Illuminate/Mail/SendQueuedMailable.php
We are using Laravel 5.5. And executing the following code
Mail::to($customer)->queue(new WelcomeMail($customer));
The mailer is the default mailer that comes with laravel, but we're queueing jobs to redis. Customer is a User object. The WelcomeMail is the following
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Mail\Mailable;
use Illuminate\Queue\SerializesModels;
class WelcomeMail extends Mailable implements ShouldQueue
{
use Queueable, SerializesModels;
public $user;
/**
* Create a new message instance.
*
* #return void
*/
public function __construct($user)
{
$this->user = $user;
}
/**
* Build the message.
*
* #return $this
*/
public function build()
{
return $this->view('security::emails.welcome');
}
}
I figured out what was my problem. It was more than one server (localhost, staging etc... ) had a queue listener on the same Redis instance.

Laravel 5.5 email setup using Mailgun and Bogardo

I am attempting to setup automated email notification in my Laravel 5.5 app using Mailgun. I have the Mailgun SDK installed along with the recommended Laravel library - Bogardo. The reason I am using the Bogardo library instead of just using the Mailgun SDK or built in Laravel email functionality is neither of these allow for click tracking, bounces and other analytic functionality (that I know of). I am able to send emails just fine using Tinker. However, I am not 100% sure how to properly call my new mailable to send an email that way. Here is my mailable class:
<?php
namespace App\Mail;
use Illuminate\Bus\Queueable;
use Illuminate\Mail\Mailable;
use Illuminate\Queue\SerializesModels;
use Illuminate\Contracts\Queue\ShouldQueue;
class BaseEmail extends Mailable
{
use Queueable, SerializesModels;
/**
* Create a new message instance.
*
* #return void
*/
public function __construct()
{
//
}
/**
* Build the message.
*
* #return $this
*/
public function build()
{
$data = ['This is a message from Mailgun!'];
return Mailgun::raw($data, function($message) {
$message
->to('email#domain.com', 'Name Name')
->subject('Yoohoo!')
->from('otheremail#domain.com', 'Name')
->tag(['tag','tag2']);
});
}
}
When I call:
$mail = new App\Mail\BaseEmail();
$mail->send();
I get the following error
TypeError: Too few arguments to function Illuminate\Mail\Mailable::send(), 0 passed in /web/vendor/psy/psysh/src/Psy/ExecutionLoop/Loop.php(90) : eval()'d code on line 1 and exactly 1 expected
and
$mail->send('this');
I get
TypeError: Argument 1 passed to Illuminate\Mail\Mailable::send() must be an instance of Illuminate\Contracts\Mail\Mailer, string given on line 1
Sorry if this is trivial, but I have been following their docs and have Googled everything that I can think of with no luck.
Any direction would be fantastic!
Thanks!
It appears that the Bogardo package does not support Laravel Mailables...
https://github.com/Bogardo/Mailgun/issues/72
You don't need to use the send() method when you're using raw().This code will send an email:
Mailgun::raw($data, function($message) {
$message->to('email#domain.com', 'Name Name')
->subject('Yoohoo!')
->from('otheremail#domain.com', 'Name')
->tag(['tag','tag2']);
});
You also don't need to use Mailable when you're using the package.

Laravel 5.4 - Can't queue a mail

For some reason whenever I run
Mail::to($user)->queue(new WelcomeEmail($user))
it sends immediately instead of queuing it. I've already followed the Driver Prerequsites.
I tried to run it on artisan tinker and it still doesn't add to the queue.
This is my WelcomeEmail class:
<?php
namespace App\Mail\User;
use Illuminate\Bus\Queueable;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Mail\Mailable;
use Illuminate\Queue\SerializesModels;
use App\Modules\User\User;
class WelcomeEmail extends Mailable
{
use Queueable, SerializesModels;
/**
* #var Model
*/
public $user;
/**
* Create a new message instance.
* #param User $user
*/
public function __construct(User $user)
{
$this->user = $user;
}
/**
* Build the message.
*
* #return $this
*/
public function build()
{
return $this->markdown('emails.user.registered');
}
}
Is it because I'm running on a Windows machine?
Based on your comment in the question, the trouble is that you have your queue_driver set to SYNC in your .env file. This "driver" will process everything immediately, this is useful when developping.
You need to set it to "database" if you want to use the database driver, or "redis" for the redis driver.

Laravel echo pusher not receiving broadcast events

I've a problem that I'm trying to fix all day now. I've followed
this tutorial. The goal is to make a chat with Laravel echo, vue.js and pusher.
I've done everything exactly like the tutorial but for some reason I do not receive any events in my pusher console. Only the connection shows up:
But no events. The event that I fire looks like this:
<?php
namespace App\Events;
use App\Message;
use App\User;
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;
class MessageSent implements ShouldBroadcast
{
use Dispatchable, InteractsWithSockets, SerializesModels;
/**
* #var
*/
public $user;
/**
* #var
*/
public $message;
/**
* MessageSent constructor.
* #param User $user
* #param Message $message
*/
public function __construct(User $user, Message $message)
{
$this->user = $user;
$this->message = $message;
}
/**
* Get the channels the event should broadcast on.
*
* #return Channel|array
*/
public function broadcastOn()
{
return new PrivateChannel('chat');
}
}
I fire the event like this:
broadcast(new MessageSent($user, $message))->toOthers();
When I dd('test'); like this in my MessageSent event class:
public function broadcastOn()
{
dd('test');
return new PrivateChannel('chat');
}
The dd('test'); shows up in my network tab.
I'm using Laravel 5.4 and Vue.js 2.0 with Homestead. What could be going on here?!
It looks likes you are following this tutorial. I also had a hard time to figure it out. I already answered here. Can you please check it out?
I worked on typing feature in the chat system. Please take a look at the code on GitHub.
Let me know if you have any questions. Thanks :)
By the looks of your debug console screenshot you are never managing to subscribe to any channels, have you set up the necessary authentication for the private channel subscription?
The complete demo code for the tutorial that you've been following is on github so you might want to take a look at that and see where yours differs.
If you are on Laravel 5.4, make sure you have set-up the channel authentication.
For example, in your routes/channels.php file, there should be something like this:
Broadcast::channel('chat', function ($user) {
return true; // change this to your authentication logic
});

Categories