why the schedule not working automatically - laravel

I try to send a notification to the users of a course 1 hour prior to starting exam so, I made command which send notification, the problem is when I run php artisan schedule:work in cmd the notification will saved in the database and schedule works but when I expect it run automatically noting saved in the database.
thanks in advance
kernel.php
protected function schedule(Schedule $schedule)
{
$schedule->command('users:notify')->everyMinute();
}
NotifyUsers.php
class NotifyUsers extends Command
{
protected $signature = 'users:notify';
protected $description = 'notify to users';
public function handle(){
$quizzes = Quiz::whereDate('start_date', now()->addHour())->get();
$students = [];
$titles = [];
foreach($quizzes as $quiz){
$students = $quiz->course->users;
$title = $quiz->title;
array_push($titles, $title );
}
foreach($titles as $title){
foreach($students as $student){
Notification::send($student, new timeToExam($title));
}
}
}
timeToExam.php // notification
class timeToExam extends Notification
{
use Queueable;
public $title;
public function __construct($title)
{
$this->title = $title;
}
public function via($notifiable)
{
return ['database'];
}
public function toArray($notifiable)
{
return [
'title' => $this->title,
];
}

You just need to set a cron job on your windows machine.
This link may help you find your solution.

Related

How to send data to view on send email in Laravel

i try this but it show Undefinded data
public function forgotPassword(Request $req){
$token = rand();
$data = $token;
Mail::to($req->email)->send(new sendPass($data));
}
First up, that code is a little bit inefficient. Why write :
$token = rand();
$data = $token;
Mail::to($req->email)->send(new sendPass($data));
when you could just write :
Mail::to($req->email)->send(new sendPass(rand()));
The issue is almost certainly because you've not declared $data in your SendPass class as a private variable :
class SendPass extends Mailable {
use Queueable, SerializesModels;
private $data;
public function __construct(string $data)
{
$this->data = $data;
}
public function build()
{
$data = $this->$data;
... rest of your code goes here.
}

Laravel error when sending email notification

Laravel Version: 8.78.1
PHP Version: 8.0.10
I've created a custom command to run on a schedule and email a notification.
My Command class handle method:
public function handle()
{
$sql = "SELECT * FROM Licences WHERE (Expired = 1)";
$list = DB::select($sql);
return (new NotifyExpiredLicences($list))->toMail('me#gmail.com');
}
My notification method:
public function toMail($notifiable)
{
return (new MailMessage)
->subject('Clients with Expired Licences')
->markdown('vendor/notifications/expiredlicences',
['clients' => $this->list, 'toname' => 'Me']);
}
Whenever I test this by running it manually with php artisan email:expired-licences I get the following error Object of class Illuminate\Notifications\Messages\MailMessage could not be converted to int from my command class in the handle method.
However, the preview of my email works fine & displays as expected:
Route::get('/notification', function () {
return (new SendExpiredLicences())->handle();
});
If I remove the return statement from my handle() method, then although I get no errors, neither in my console or in storage\logs, also the preview stops working.
At this point I'm sure I've missed something important from the way this is supposed to be done, but after going through the Laravel docs and looking at online tutorials/examples, I've no idea what.
I've got everything working - though not entirely sure it's the "Laravel way".
If anyone's got suggestions for improving it - add a comment or new answer and I'll try it out.
Console\Kernel.php:
protected function schedule(Schedule $schedule)
{
$schedule->command('email:expired-licences')
->weekdays()
->at('08:30');
}
App\Console\Commands\SendExpiredLicences.php:
class SendExpiredLicences extends Command
{
protected $signature = 'email:expired-licences';
protected $description = 'Email a list of expired licences to Admin';
private $mail;
public function _construct()
{
$clients = DB::select("[Insert SQL here]");
$this->mail = (new NotifyExpiredLicences($clients))->toMail('admin#example.com');
parent::__construct();
}
public function handle()
{
Mail::to('admin#example.com')->send($this->mail);
return 0;
}
public function preview()
{
return $this->mail;
}
}
App\Notifications\NotifyExpiredLicences.php:
class NotifyExpiredLicences extends Notification
{
public function __construct(protected $clients)
{
}
public function via($notifiable)
{
return ['mail'];
}
public function toMail($notifiable)
{
return (new Mailable($this->clients));
}
}
App\Mail\ExpiredLicences.php:
class ExpiredLicences extends Mailable
{
public function __construct(private $clients)
{
}
public function build()
{
return $this
->subject('Clients with Expired Licences')
->markdown('emails/expiredlicences',
['clients' => $this->clients, 'toname' => 'Admin']);
}
}
resources\views\emails\expiredlicences.blade.php:
#component('mail::message')
# Hi {!! $toname !!},
#component('mail::table')
| Client | Expired |
| ------------- | --------:|
#foreach ($clients as $client)
|{!! $client->CompanyName !!} | {!! $client->Expired !!}|
#endforeach
#endcomponent
<hr />
Thanks, {!! config('app.name') !!}
#endcomponent
For previewing with the browser routes\web.php:
Route::get('/notification', function () {
return (new SendExpiredLicences())->preview();
});
Ok just to save more commenting, here's what I'd recommend doing. This is all based on the Laravel docs, but there are multiple ways of doing it, including what you've used above. I don't really think of them as "right and wrong," more "common and uncommon."
Console\Kernel.php: I'd keep this mostly as-is, but pass the email to the command from a config file, rather than having it fixed in the command.
use App\Console\Commands\SendExpiredLicences;
…
protected function schedule(Schedule $schedule)
{
$recipient = config('myapp.expired.recipient');
$schedule->command(SendExpiredLicences::class, [$recipient])
->weekdays()
->at('08:30');
}
config/myapp.php:
<?php
return [
'expired' => [
'recipient' => 'admin#example.com',
],
];
App\Console\Commands\SendExpiredLicences.php: update the command to accept the email address as an argument, use on-demand notifications, and get rid of preview() method. Neither the command or the notification need to know about the client list, so don't build it yet.
<?php
namespace App\Console\Commands;
use App\Console\Command;
use App\Notifications\NotifyExpiredLicences;
use Illuminate\Support\Facade\Notification;
class SendExpiredLicences extends Command
{
protected $signature = 'email:expired-licences {recipient}';
protected $description = 'Email a list of expired licences to the given address';
public function handle()
{
$recip = $this->argument('recipient');
Notification::route('email', $recip)->notify(new NotifyExpiredLicences());
}
}
App\Notifications\NotifyExpiredLicences.php: the toMail() method should pass the notifiable object (i.e. the user getting notified) along, because the mailable will be responsible for adding the To address before the thing is sent.
<?php
namespace App\Notifications;
use App\Mail\ExpiredLicenses;
use Illuminate\Notifications\Notification;
class NotifyExpiredLicences extends Notification
{
public function via($notifiable)
{
return ['mail'];
}
public function toMail($notifiable)
{
return (new ExpiredLicenses($notifiable));
}
}
App\Mail\ExpiredLicences.php: since the mail message actually needs the list of clients, this is where we build it. We get the recipient here, either from the user's email or the anonymous object.
<?php
namespace App\Mail;
use App\Models\Client;
use Illuminate\Notifications\AnonymousNotifiable;
class ExpiredLicences extends Mailable
{
private $email;
public function __construct(private $notifiable)
{
// this allows the notification to be sent to normal users
// not just on-demand
$this->email = $notifiable instanceof AnonymousNotifiable
? $notifiable->routeNotificationFor('mail')
: $notifiable->email;
}
public function build()
{
// or whatever your object is
$clients = Client::whereHas('licenses', fn($q)=>$q->whereExpired(1));
return $this
->subject('Clients with Expired Licences')
->markdown(
'emails.expiredlicences',
['clients' => $clients, 'toname' => $this->notifiable->name ?? 'Admin']
)
->to($this->email);
}
}
For previewing with the browser routes\web.php:
Route::get('/notification', function () {
// create a dummy AnonymousNotifiable object for preview
$anon = Notification::route('email', 'no#example.com');
return (new ExpiredLicencesNotification())
->toMail($anon);
});

laravel Notification Undefined index: user_id

I going to do massage notification, I already make the notifications steps,
but gives me this error
when I do dd($notifiable); I found all data
Undefined index: user_id OR
Undefined index: name
public function store(Request $request)
{
$chating=new chats();
$chating->chat = $request->input('chat');
$chating->user_id = Auth::id();
$chating->employee_id = $request->input('employeeid');
$chating->save();
$user_id=$request->input('employeeid');
auth()->user()->notify(new SendMassages($user_id));
return redirect()->back();
}
database notifications table coulmn data {"user_id":5,"name":"Ibrahim"}
Model
protected $user_id;
protected $name;
public function __construct($user_id)
{
$this->user_id = $user_id;
}
public function via($notifiable)
{
return ['database'];
}
public function toDatabase($notifiable)
{
return [
'user_id' => $this->user_id,
'user'=>$notifiable
];
}
View:
{{ $notification->data['name'] }}
Model:
class SendMassages extends Notification
{
use Queueable;
public $user;
public $user_id;
public function __construct($user_id)
{
$this->user_id = $user_id;
}
public function via($notifiable)
{
return ['database'];
}
public function toDatabase($notifiable)
{
// dd($notifiable);
return [
'user_id' => $this->user_id,
'user'=>$notifiable
];
}
}
It seems that you have problem with encapsulation in your code. First you have to make the property of your model into public if you want the quick and not-safe way but if you want the OOP way, You must write setters to do that logic for you.
First and not-safe approach :
class YourModel {
public $user_id;
.
.
.
}
The OOP way:
Class {
public function setUserId(int $userId)
{
$this->user_id = $userId;
}
.
.
.
}
if you are willing to get the exact answer please copy your controllerclass and model in here.

laravel notifications not storing into my database plus error

i couldn't store the notification into my notification table inside my database,
i was trying to make notification every time there is a new Post how can i make this work.
Error:
Notification:
use Queueable;
public $post;
public function __construct()
{
}
public function via($notifiable)
{
return ['database'];
}
public function toDatabase($notifiable)
{
return [
'title' => $this->post->title,
];
}
public function toArray($notifiable)
{
return [
];
}
}
Post Controller:
public function store(Request $request)
{
$this->validate($request, [
'title'=>'required|max:100',
'body' =>'required',
]);
$title = $request['title'];
$body = $request['body'];
$post = Post::create($request->only('title', 'body'));
Auth::user()->notify(new NotifyPost($post));
return redirect()->route('posts.index')
->with('flash_message', 'Article,
'. $post->title.' created');
}
You need to inject the post within the construct, or else it never gets resolved.
protected $post;
public function __construct(Post $post)
{
$this->post = $post;
}

Laravel queue to store data

I wanna try to store data into database via database queue Laravel.
But I always get this error "Undefined offset: 0"
this is my controller :
public function store(Request $request)
{
$order = new Order;
$order->code = $request->code;
$order->created_at = $request->created_at;
$this->dispatch(new SalesOrder($order));
}
and this is my SalesOrder Jobs :
protected $order;
public function __construct(Order $order)
{
$this->order= $order;
}
public function handle()
{
$this->order->save();
}
is there something wrong in my code? Please somebody help me fix this issue. Than's anyway.
Instead of pass Order object pass in job order data, And the in job save order.
Controller code.
public function store(Request $request)
{
$data['code'] = $request->code;
$data['created_at'] = $request->created_at;
$this->dispatch(new SalesOrder($data));
}
Job code
protected $data;
public function __construct(array $data)
{
$this->data = $data;
}
public function handle(Order $order)
{
if (!$order->craete($this->data)) {
// when not saved try again
$this->release();
}
return true;
}
Try running
$order = new Order;
$order->code = $request->code;
$order->created_at = $request->created_at;
inside your job so it looks like this
protected $order;
protected $request
public function __construct($request)
{
$this->order = new Order;
$this->request = $request;
}
public function handle()
{
$this->order->code = $request->code;
$this->order->created_at = $request->created_at;
$this->order->save();
}
and in your controller
public function store(Request $request)
{
$this->dispatch(new SalesOrder($request));
}
This should work. Did not test this am writing on my phone.

Resources