Trying to send email using command in laravel 5.4 - php

I'm trying to send email using task scheduler in laravel 5.4 and below is code
I made a mail controller
namespace App\Http\Controllers;
use Auth;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Mail;
# MAiler
use App\Mail\Mailtrap;
use App\Mail\EmailNotification;
class MailController extends Controller
{
/**
* Send email
* #return
*/
public function index(){
$user = Auth::user();
Mail::to($user)->send(new EmailNotification());
}
}
Next, I created a command and use the controller in there
namespace App\Console\Commands;
use Illuminate\Console\Command;
use App\Http\Controllers\MailController;
class SendNotifications extends Command
{
/**
* The name and signature of the console command.
*
* #var string
*/
protected $signature = 'SendNotifications:notification';
/**
* The console command description.
*
* #var string
*/
protected $description = 'This will send email';
/**
* Create a new command instance.
*
* #return void
*/
public function __construct()
{
parent::__construct();
}
/**
* Execute the console command.
*
* #return mixed
*/
public function handle()
{
$mail = new MailController();
$mail->index();
}
}
and in kernel
namespace App\Console;
use Illuminate\Console\Scheduling\Schedule;
use Illuminate\Foundation\Console\Kernel as ConsoleKernel;
class Kernel extends ConsoleKernel
{
/**
* The Artisan commands provided by your application.
*
* #var array
*/
protected $commands = [
'App\Console\Commands\SendNotifications'
];
/**
* Define the application's command schedule.
*
* #param \Illuminate\Console\Scheduling\Schedule $schedule
* #return void
*/
protected function schedule(Schedule $schedule)
{
$schedule->command('SendNotifications:notification')
->everyMinute();
}
/**
* Register the Closure based commands for the application.
*
* #return void
*/
protected function commands()
{
require base_path('routes/console.php');
}
}
when I try to send email in controller using route in web.php, it successfully send an email to mailtrap.io but, when i try to send it in the background using this command
php artisan SendNotification:notification
I got this error
Trying to get property of non-object
I don't know why it was supposed to be successful because it just called the email in the controller or I implemented this wrong
can you guide me with this?

Because you work on different sessions. You probably logged in on browser and created session for this user however this session is not same in your command line.
So your problem occurs in this line $user = Auth::user();
If you dd($user) on your console command you will notice $user is empty
and thats why you are getting try to get property of non object error

Related

How can send Task Email Reminders for Users before end deadline task

Hi i need to send a reminder mail use mailtrap for each user has a task that still have open status before one day from deadline
using mail
here tasks table
public function up()
{
Schema::create('tasks', function (Blueprint $table) {
$table->id();
$table->string('title');
$table->text('description');
$table->foreignId('user_id')->constrained();
$table->foreignId('client_id')->constrained();
$table->foreignId('project_id')->constrained();
$table->date('deadline');
$table->string('status')->default('open');
$table->softDeletes();
$table->timestamps();
});
}
This could be helpful.
First configure the email section on the .env file the parameters can be obtained directly from mailtrap under SMTP settings.
You can leave the QUEUE_CONNECTION=sync , later on i would suggest to use redis or sqs.
And leverage the queue component with information from here,
Laravel Queues
1- Create a model Reminder: php artisan make:model Reminder
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class Reminder extends Model
{
protected $guarded = [];
public function Task()
{
return $this->belongsTo(Task::class);
}
public function getStatusAttribute($value)
{
return ucfirst($value);
}
}
2- Define a command: php artisan make:command SendReminderEmails
Add the following code
<?php
namespace App\Console\Commands;
use App\User;
use App\Models\Reminder;
use Illuminate\Console\Command;
use App\Mail\ReminderEmailDigest;
use Illuminate\Support\Facades\Mail;
class SendReminderEmails extends Command
{
/**
* The name and signature of the console command.
*
* #var string
*/
protected $signature = 'reminder:emails';
/**
* The console command description.
*
* #var string
*/
protected $description = 'Command description';
/**
* Create a new command instance.
*
* #return void
*/
public function __construct()
{
parent::__construct();
}
/**
* Execute the console command.
*
* #return mixed
*/
public function handle()
{
// Get all reminders for today
$reminders = Reminder::query()
->with(['task'])
->where('deadline', date('Y-m-d H:i:s', strtotime('+1 day', now())))
->where('status', 'open')
->orderByDesc('user_id')
->get();
// group all reminders by user
$data = [];
foreach ($reminders as $reminder) {
$data[$reminder->user_id][] = $reminder->toArray();
}
foreach ($data as $userId => $reminders) {
$this->sendEmailToUser($userId, $reminders);
}
}
private function sendEmailToUser($userId, $reminders)
{
$user = User::find($userId);
Mail::to($user)->send(new ReminderEmailDigest($reminders));
}
}
3- Create two files /resources/views/emails/reminder-digest.blade.php and /app/Mail/ReminderEmailDigest.php
Add to /app/Mail/ReminderEmailDigest.php
<?php
namespace App\Mail;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Mail\Mailable;
use Illuminate\Queue\SerializesModels;
class ReminderEmailDigest extends Mailable implements ShouldQueue
{
use Queueable, SerializesModels;
private $reminders;
/**
* Create a new message instance.
*
* #return void
*/
public function __construct($reminders)
{
$this->reminders = $reminders;
}
/**
* Build the message.
*
* #return $this
*/
public function build()
{
return $this->markdown('emails.reminder-digest')
->with('reminders', $this->reminders);
}
}
4- Add to /resources/views/emails/reminder-digest.blade.php
#component('mail::message')
# You have some reminders to follow up. Below are their details:
#component('mail::table')
|Reminder|Task title|Task description|
|:-------|:--------|:----|
#foreach($reminders as $reminder)
|{{$reminder['reminder']}}|{{$reminder['task']['title']}}|{{$reminder['task']['description']}}
#endforeach
#endcomponent
Thanks,<br>
{{ config('app.name') }}
#endcomponent
5-Add to /app/Console/Kernel.php
<?php
namespace App\Console;
use Illuminate\Console\Scheduling\Schedule;
use App\Console\Commands\SendReminderEmails;
use Illuminate\Foundation\Console\Kernel as ConsoleKernel;
class Kernel extends ConsoleKernel
{
/**
* The Artisan commands provided by your application.
*
* #var array
*/
protected $commands = [
SendReminderEmails::class
];
/**
* Define the application's command schedule.
*
* #param \Illuminate\Console\Scheduling\Schedule $schedule
* #return void
*/
protected function schedule(Schedule $schedule)
{
// $schedule->command('inspire')
// ->hourly();
}
/**
* Register the commands for the application.
*
* #return void
*/
protected function commands()
{
$this->load(__DIR__.'/Commands');
require base_path('routes/console.php');
}
}
6- while running the app run: php artisan queue:listen

How to fix local.ERROR: failed loading cafile stream using Laravel

I have problem regarding on local.ERROR: failed loading cafile stream: `C:\xampp\apache\bin\curl-ca-bundle.crt', before that Currently I'm developing new system Cron Job is an daily email scheduling. now I just create a basic concept of emailing. and I use Laravel to create this system.
I just follow this instruction failed loading cafile stream: `C:\xampp\apache\bin\curl-ca-bundle.crt'
however, on my laravel logs still shows
[2019-07-29 05:21:55] local.ERROR: failed loading cafile stream: `C:\xampp\apache\bin\curl-ca-bundle.crt' {"exception":"[object] (ErrorException(code: 0): failed loading cafile stream: `C:\\xampp\\apache\\bin\\curl-ca-bundle.crt' at C:\\xampp\\htdocs\\CronSystem\\vendor\\swiftmailer\\swiftmailer\\lib\\classes\\Swift\\Transport\\StreamBuffer.php:94)
[stacktrace]
I will share to you guys my codes.
On my Mail Folder
<?php
namespace App\Mail;
use Illuminate\Bus\Queueable;
use Illuminate\Mail\Mailable;
use Illuminate\Queue\SerializesModels;
use Illuminate\Contracts\Queue\ShouldQueue;
class SendMailApplication extends Mailable
{
use Queueable, SerializesModels;
/**
* Create a new message instance.
*
* #return void
*/
public function __construct()
{
//
}
/**
* Build the message.
*
* #return $this
*/
public function build()
{
return $this->view('Emailing')
->to('hiddeeeee#gmail.com','hideeee')
->from('noreplyhideee#gmail.com', 'New Applicant');
}
}
My Command:
<?php
namespace App\Console\Commands;
use Illuminate\Console\Command;
use DB;
use App\User;
use App\Mail\SendMailApplication;
class Emailing extends Command
{
/**
* The name and signature of the console command.
*
* #var string
*/
protected $signature = 'emailing:cron';
/**
* The console command description.
*
* #var string
*/
protected $description = 'Ready to fire emailing each user...';
/**
* Create a new command instance.
*
* #return void
*/
public function __construct()
{
parent::__construct();
}
/**
* Execute the console command.
*
* #return mixed
*/
public function handle()
{
\Mail::send(new SendMailApplication());
// $users = User::all();
// foreach($users as $user) {
// // Create a unique 8 character promo code for user
// // $new_promo_code = new PromoCode([
// // 'promo_code' => str_random(8),
// // ]);
// // $user->promo_code()->save($new_promo_code);
// // Send the email to user
// Mail::send('emailing', ['user' => $user], function ($mail) use ($user) {
// $mail->to($user['email'])
// ->from('noreplyhfiofi#gmail.com', 'Company')
// ->subject('Happy Birthday!');
// });
// }
// $this->info('Birthday messages sent successfully!');
// // \Log::info("Email sent!");
// //script which you have run in cron
}
}
My Kernel:
<?php
namespace App\Console;
use Illuminate\Console\Scheduling\Schedule;
use Illuminate\Foundation\Console\Kernel as ConsoleKernel;
class Kernel extends ConsoleKernel
{
/**
* The Artisan commands provided by your application.
*
* #var array
*/
protected $commands = [
//
'App\Console\Commands\Emailing',
];
/**
* Define the application's command schedule.
*
* #param \Illuminate\Console\Scheduling\Schedule $schedule
* #return void
*/
protected function schedule(Schedule $schedule)
{
//Schedule happen here...
$schedule->command('emailing:cron')
->everyMinute();
}
/**
* Register the commands for the application.
*
* #return void
*/
protected function commands()
{
$this->load(__DIR__.'/Commands');
require base_path('routes/console.php');
}
}
.env
MAIL_DRIVER=smtp
MAIL_HOST=smtp.gmail.com
MAIL_PORT=587
MAIL_USERNAME=noreplyhfiofi#gmail.com
MAIL_PASSWORD=hiflyer123
MAIL_ENCRYPTION=tls

Laravel $schedule to read/send email

I´m trying to create $schedule job in Laravel to read Email with PHP IMAP package. If I go to route, package read email and does all correctly, but need to do this every 5 minutes.
I create a new command class and add this
use Illuminate\Http\Request;
class ReadMail extends Command implements SelfHandling {
protected $name = 'read:mail';
/**
* Create a new command instance.
*
* #return void
*/
public function __construct()
{
parent::__construct();
}
/**
* Execute the command.
*
* #return void
*/
public function fire()
{
$request = Request::create($this->option('App\Http\Controllers\MailController#index'), 'GET');
$this->info(app()['Illuminate\Contracts\Http\Kernel']->handle($request));
}
In kernel
protected $commands = [
'App\Console\Commands\ReadMail',
];
protected function schedule(Schedule $schedule)
{
$schedule->call('read:mail')
->everyFiveMinutes();
}
I'm not sure if this code it´is correct, but does not work properly. Any idea about it?
Thank in advance for your help.
UPDATE
I launch this
php artisan read:mail and return
Argument 1 passed to Illuminate\Console\Application::add() must be an instance of Symfony\Component\Console\Command\Command, instance of App\Commands\ReadMail given
The code of ReadMail class
<?php namespace App\Commands;
use App\Commands\Command;
use Illuminate\Contracts\Bus\SelfHandling;
use Illuminate\Http\Request;
class ReadMail extends Command implements SelfHandling {
protected $signature = 'read:mail';
/**
* Create a new command instance.
*
* #return void
*/
public function __construct()
{
//
}
/**
* Execute the command.
*
* #return void
*/
public function fire()
{
$request = Request::create($this->option('App\Http\Controllers\MailController#index'), 'GET');
$this->info(app()['Illuminate\Contracts\Http\Kernel']->handle($request));
}
}
UPDATE 2: SOLVED - ALL CODE
Kernel
use Illuminate\Console\Scheduling\Schedule;
use Illuminate\Foundation\Console\Kernel as ConsoleKernel;
class Kernel extends ConsoleKernel {
/**
* The Artisan commands provided by your application.
*
* #var array
*/
protected $commands = [
'App\Commands\ReadMail',
];
/**
* Define the application's command schedule.
*
* #param \Illuminate\Console\Scheduling\Schedule $schedule
* #return void
*/
protected function schedule(Schedule $schedule)
{
$schedule->command('read:mail')
->everyFiveMinutes();
}
}
ReadMail
<?php namespace App\Commands;
use Illuminate\Contracts\Bus\SelfHandling;
use Illuminate\Http\Request;
use Illuminate\Console\Command;
use App\Http\Controllers\MailController;
class ReadMail extends Command implements SelfHandling {
protected $name = 'read:mail';
/**
* Create a new command instance.
*
* #return void
*/
public function __construct()
{
parent::__construct();
}
/**
* Execute the command.
*
* #return void
*/
public function handle()
{
MailController::index();
}
}
MailController
<?php namespace App\Http\Controllers;
use App\Http\Requests;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use PhpImap\Mailbox as ImapMailbox;
use App\Models\Escalas;
class MailController extends Controller {
public static function index()
{
$mailbox = new ImapMailbox('{imap.gmail.com:993/imap/ssl}INBOX', '', '','');
$mailsIds = $mailbox->searchMailbox('UNSEEN');
if(!$mailsIds) {
die('Mailbox is empty');
}
$mail=[];
foreach ($mailsIds as $index=>$data){
$mail[]=$mailbox->getMail($mailsIds[$index]);
Escalas::insert([
['' => $mail[$index]->textPlain,
'' => $mail[$index]->date,
''=>$mail[$index]->subject,
''=>$mail[$index]->fromName,
''=>$mail[$index]->fromAddress,
''=>$mail[$index]->toString],
]);
}
}
}
Try changing
protected $name = 'read:mail';
with protected $signature= 'read:mail';
in your ReadMail class and then run in Kernel like this
$schedule->command('read:mail')->everyFiveMinutes();
Check whether your scheduled tasks are set up properly (see docs for Laravel 5.0) Make sure you've added a cronjob to trigger Laravel's scheduled commands. To check you cronjobs are running, look for a file like /logs/crond.log. When opening this file, you should see lines showing at what times this ran. This is the command that triggers Laravel's scheduled jobs.
If all that is correct, then try running your command via your terminal on localhost to check the command is all set. This should reveal any problems with the command setup. Your functionality itself seems allright, since you mentioned everything works when triggered via a route.

Laravel 5.1 - Get artisan arguments from internal call

I do
when I run artisan queue:work or artisan queue:listen it runs the current commands with their corresponding Arguments. Now my question is, how can I Access those Arguments?
As you can see in the following Picture, the Arguments are there but I have no clue how to Access them?
In a project which follow a "standard project structure"
You must have a class in app/Console named Kernel which extends Illuminate\Foundation\Console\Kernel, an example of how to implement it is as follows:
<?php
namespace App\Console;
use Illuminate\Console\Scheduling\Schedule;
use Illuminate\Foundation\Console\Kernel as ConsoleKernel;
class Kernel extends ConsoleKernel
{
/**
* {#inheritdoc}
*/
protected $commands = [
//here you have to put your commands class
];
/**
* Define the application's command schedule.
*
* #param \Illuminate\Console\Scheduling\Schedule $schedule
* #return void
*/
protected function schedule(Schedule $schedule): void
{
}
/**
* Register the Closure based commands for the application.
*
* #return void
*/
protected function commands(): void
{
require base_path('routes/console.php');
}
}
so now let's create a new command, call it "print" and it will accept a parameter called text, here is the implementation :
<?
namespace App\Console\Commands;
use Illuminate\Console\Command;
class TestCommand extends Command
{
/**
* {#inheritdoc}
*/
protected $signature = 'test {text}';
/**
* {#inheritdoc}
*/
protected $description = 'Test command.';
/**
* {#inheritdoc}
*/
public function handle()
{
$this->info($this->argument('text'));
}
}
as you can see, the new command accept a parameter called text and print it in console.
So to retrieve the parameter sent to an command call, you have to use the argument method in the follow way:
$commandInstance->argument('key_of_parameter');
To get more info read the docs

How to call Model via artisan command in Laravel 5?

For the background, I'm a laravel 5 newbie, but I did use laravel 4 in my past projects.
In laravel 4 I just call the model straight in the artisan command but now, how do I call a model inside an artisan command. here's my current code:
<?php
namespace App\Console\Commands;
use Illuminate\Console\Command;
use App\Models\sampleModel as sampleModel;
class testCommand extends Command {
/**
* The console command name.
*
* #var string
*/
protected $name = 'test';
/**
* The console command description.
*
* #var string
*/
protected $description = 'Command description.';
/**
* Create a new command instance.
*
* #return void
*/
public function __construct()
{
parent::__construct();
}
/**
* Execute the console command.
*
* #return mixed
*/
public function fire()
{
sampleModel::sampleMethod();
}
}
Your issue isn't related to the command, you can use Model in commands.
Issue is in your Model, add this to the beginning of the Model:
use DB;
Note 1, Laravel models should be named with first capital: SampleModel, not sampleModel;
Note 2, as sampleModel is excess as model already named as sampleModel.

Categories