I'm facing the following error in the failed_jobs database table:
ErrorException: Undefined property: stdClass::$subscription in
/home/sm/public_html/app/Mail/NewCustomer.php:45
This is pretty basic. It means the property $subscription does not exists, but...the problem is that I don't call $subscription anywhere in the class code.
In the controller I assign the values:
$to = ['email' => 'someemail#gmail.com', 'name' => 'Name test'];
$mail = new \stdClass;
$mail->to = $to;
$mail->subject = 'Subject test';
$mail->body = 'Body test';
\Mail::queue(new \App\Mail\NewCustomer($mail));
And the NewCustomer class contains:
namespace App\Mail;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Mail\Mailable;
use Illuminate\Queue\SerializesModels;
class NewCustomer extends Mailable
{
use Queueable, SerializesModels;
/**
* Holds the item content
*
* #var Array
*/
protected $item;
/**
* Create a new message instance.
*
* #param Array
*
* #return void
*/
public function __construct($item)
{
$this->item = $item;
}
/**
* Build the message.
*
* #return $this
*/
public function build()
{
$this->to($this->item->to['email'], $this->item->to['name'])
->subject($this->item->subject)
->view('mails/new_customer')
->with('item', $this->item);
return $this;
}
}
The view mails/new_customer also does not contain anything related with $subscription.
Is this some cache problem or something? I can't figure out where the variable $subscription comes from.
If instead of Queue I send the email immediately, it works great:
\Mail::send(new \App\Mail\NewCustomer($mail));
Solved.
It was indeed a cache problem. Run php artisan queue:restart in terminal or through laravel:
\Artisan::call('queue:restart');
Related
I need to send confirmation emails on a checkout page. But with the current way I only pass $checkout.
This is the database structure of what data I need to pass:
this is how the $checkout gets passed to the Mailable
// send confirmation email to customer
Mail::to($request->email)->send(new CheckoutConfirmation($checkout));
Mailable:
<?php
namespace App\Mail;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Mail\Mailable;
use Illuminate\Queue\SerializesModels;
use App\Models\Events;
class CheckoutConfirmation extends Mailable
{
use Queueable, SerializesModels;
/**
* Create a new message instance.
*
* #return void
*/
public function __construct($checkout)
{
$this->checkout = $checkout;
// get the course data from the database
$event = Events::query()
->where('id', '=', $this->checkout->event_id)
->first();
// this needs to be passed, along $checkout
// $event->title;
// $event->start;
// $event->end;
}
/**
* Build the message.
*
* #return $this
*/
public function build()
{
return $this->view('emails.checkout.customer')->subject('Wir freuen uns schon auf Sie! Hier ist die Bestätigung Ihrer Buchung.')->with('checkout', $this->checkout);
}
}
the issue with how it is currently handeled is that I can only call:
$checkout->xxx
but I also need to call $event->xxx in the email blade.
Look at this example
/**
* The user details.
*
* #var $details
*/
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->to(data_get($this->details,'email'), env('APP_NAME'))
->replyTo(config('mail.from.address'), ucwords(data_get($this->details, 'name')))
->subject(data_get($this->details, 'subject'))
->view('emails.contact_us');
}
You can use $details;
then use data_get you can put $this->details then get the key whatever email or anything else .
In Controller when called Class Mail in this way
Mail::send(new ContactUsMail($request->validated()));
Based on this StackOverflow answer, I changed my Mailable to the following:
<?php
namespace App\Mail;
use App\Models\Events;
use App\Models\Checkout;
use Illuminate\Bus\Queueable;
use Illuminate\Mail\Mailable;
use Illuminate\Queue\SerializesModels;
class CheckoutConfirmation extends Mailable
{
use Queueable, SerializesModels;
/**
* Create a new message instance.
*
* #return void
*/
public function __construct($checkout)
{
$this->checkout = Checkout::query()->where('event_id', '=', $checkout->event_id)->first();;
$this->event = Events::query()->where('id', '=', $this->checkout->event_id)->first();
}
/**
* Build the message.
*
* #return $this
*/
public function build()
{
return $this->view('emails.checkout.customer')->subject('Wir freuen uns schon auf Sie! Hier ist die Bestätigung Ihrer Buchung.')->with(['checkout'=>$this->checkout, 'event'=>$this->event]);
}
}
now I can pass arrays to the template: ->with(['checkout'=>$this->checkout, 'event'=>$this->event])
this allows to add as much data as needed.
Hello I want to send e-mails rendered from templates that can be created / modifed by admin from a form (with placeholders).As in the example below and I want to send it to 100 users at the same time, I don't know how to do it, can you help?
Hi { { name } },
email: {{email } }
phone: { { phone } }
my controllers:
public function mailSend(Uye $uye, IcerikSablon $icerikSablon){
$dil_id=$uye->ulke->dil_id;
$icerikSablon->load(['translation'=>function($q)use ($dil_id){
$q->where('dil_id',$dil_id);
}]);
$icerik_sablon_icerik=$icerikSablon->translation->icerik;
$uye_name=$uye->name;
$uye_phone=$uye->phone;
$uye_mail=$uye->email;
$icerik_sablon_icerik= str_replace('{{name}}', $uye_name, $icerik_sablon_icerik;
$icerik_sablon_icerik=str_replace('{{phone}}', $uye_phone, $icerik_sablon_icerik);
$icerik_sablon_icerik=str_replace('{{email}}', $uye_mail, $icerik_sablon_icerik;
}
You should really look into the documentation for mailables and notifications for Laravel, it seems you are missing some basic setup. https://laravel.com/docs/8.x/mail
From the docs:
php artisan make:mail OrderShipped --markdown=emails.orders.shipped
Then pass in the parameters you want to dynamically have in the OrdersShipped class constructor, and assign them as variables in your class. You can then reference these variables within your blade template.
For example:
<?php
namespace App\Mail\Users;
use Illuminate\Bus\Queueable;
use Illuminate\Mail\Mailable;
use Illuminate\Queue\SerializesModels;
class OrdersShipped extends Mailable
{
use Queueable, SerializesModels;
/**
* someVar
*
* #var $someVar;
*/
protected $someVar;
/**
* Create a new message instance.
*
* #param string $someVar
*
* #return void
*/
public function __construct($someVar)
{
$this->someVar = $someVar;
}
/**
* Build the message.
*
* #return $this
*/
public function build()
{
return $this->from('test#test.com')
->subject('Password Reset Request')
// Pass your vars in here using `with`
->with([
'someVar' => $this->someVar,
])
->view('emails.orders.shipped');
}
}
In emails.order.shipped blade you will be able to reference {{ someVar }}
I want tp apply queue for my Notifications, so I implemented that at my Notification which ResetPassword:
class ResetPassword extends Notification implements ShouldQueue
Then I ran php artisan queue:table and migrate it so the table jobs created successfully at the DB.
And also change the QUEUE_CONNECTION to database at .env file and re-run php artisan serve.
But when I test this and clicked on reset password link, a new table row must be added to jobs table but it does not.
And instead of that, this error returns:
ErrorException Undefined property:
App\Notifications\ResetPassword::$queue
...\notification\vendor\laravel\framework\src\Illuminate\Notifications\NotificationSender.php:195
So what is going wrong here ? How can I fix this issue ?
I would really appreciate any idea or suggestion from you guys...
Thanks in advance.
UPDATE #1:
ResetPassword.php:
<?php
namespace App\Notifications;
use Illuminate\Notifications\Messages\MailMessage;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Notifications\Notification;
use Illuminate\Support\Facades\Lang;
class ResetPassword extends Notification implements ShouldQueue
{
/**
* The password reset token.
*
* #var string
*/
public $token;
/**
* The callback that should be used to build the mail message.
*
* #var \Closure|null
*/
public static $toMailCallback;
/**
* Create a notification instance.
*
* #param string $token
* #return void
*/
public function __construct($token)
{
$this->token = $token;
}
/**
* Get the notification's channels.
*
* #param mixed $notifiable
* #return array|string
*/
public function via($notifiable)
{
return ['mail'];
}
/**
* Build the mail representation of the notification.
*
* #param mixed $notifiable
* #return \Illuminate\Notifications\Messages\MailMessage
*/
public function toMail($notifiable)
{
if (static::$toMailCallback) {
return call_user_func(static::$toMailCallback, $notifiable, $this->token);
}
return (new MailMessage)
->subject('subject goes here')
->line('This email is sent to you')
->action(Lang::get('Reset Password'), url(config('app.url').route('password.reset', ['token' => $this->token, 'email' => $notifiable->getEmailForPasswordReset()], false)))
->line(Lang::get('Until the next 60 minutes you can use this link', ['count' => config('auth.passwords.'.config('auth.defaults.passwords').'.expire')]))
->line(Lang::get('If you did not request a password reset, no further action is required.'));
}
/**
* Set a callback that should be used when building the notification mail message.
*
* #param \Closure $callback
* #return void
*/
public static function toMailUsing($callback)
{
static::$toMailCallback = $callback;
}
}
Look Like you have forgot to use Queueable Trait in your notification
use Illuminate\Bus\Queueable;
class ResetPassword extends Notification implements ShouldQueue
{
use Queueable;
Queueable trait has propety $queue
Ref:https://laravel.com/docs/8.x/notifications#queued-notifications-and-database-transactions
I'm trying to build a task scheduler for sending email routine and i got this error when i try to get approval_code from auth.
Here are my code in mail:
<?php
namespace App\Mail;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Mail\Mailable;
use Illuminate\Queue\SerializesModels;
use Illuminate\Support\Facades\DB;
use App\Services\GetApprovalPersonByRouteCode;
use App\HabisKontrak;
class HabisKontrakMail extends Mailable
{
use Queueable, SerializesModels;
/**
* Create a new message instance.
* #param HabisKontrak $habisKontrak
* #param [type] $person
* #param [type] $justInfo
*
*/
public function __construct()
{
//
// $this->link = $link;
}
/**
* Build the message.
*
* #return $this
*/
public function build()
{
$reminder_kontrak=HabisKontrak::all();
$person = GetApprovalPersonByRouteCode::getPerson(auth()->user()->approval_code,HabisKontrak::KODE_MODUL);
return $this->subject('Pemberitahuan Karyawan Habis Kontrak')
->view('mail.reminder.habisKontrak')
->with([
'reminder_kontrak' => $reminder_kontrak,
'person' => $person
]);
// }
}
}
and here are code for the GetApprovalPersonByRouteCode
<?php
namespace App\Services;
use DB;
use App\PermintaanKendaraan;
class GetApprovalPersonByRouteCode{
/**
* Get person approval / just info
*
* #param string $approvalCode
* #param string $kode_modul
* #return void
*/
public static function getPerson($approvalCode, $kode_modul){
return DB::table('approvalroutedetail')
->select([
'approvalroutedetail.nik',
'approvalroutedetail.sequence',
'approvalroutedetail.just_info',
'approvalroutedetail.modul',
'approvalroutedetail.approvalroute_id',
'karyawan.nama',
'karyawan.departemensubsub',
'karyawan.email',
'karyawan.jabatan'
])->join('karyawan','approvalroutedetail.nik','karyawan.nik')
->where('approvalroutedetail.modul', $kode_modul)
->where('approvalroutedetail.approvalroute_id', $approvalCode)
->orderBy('approvalroutedetail.sequence','asc')
->orderBy('approvalroutedetail.just_info','asc')
->get();
}
}
I tried to pass the data via constructor like this
<?php
namespace App\Mail;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Mail\Mailable;
use Illuminate\Queue\SerializesModels;
use Illuminate\Support\Facades\DB;
use App\Services\GetApprovalPersonByRouteCode;
use App\HabisKontrak;
use App\Reminder;
use DateTime;
class HabisKontrakMail extends Mailable
{
use Queueable, SerializesModels;
protected $person; //approver (collection: GetApprovalPersonByRouteCode::getPerson)
/**
* Create a new message instance.
* #param HabisKontrak $habisKontrak
* #param [type] $person
* #param [type] $justInfo
*
*/
public function __construct($person)
{
//
$this->person = $person;
}
/**
* Build the message.
*
* #return $this
*/
public function build()
{
$reminder_kontrak=HabisKontrak::all();
return $this->subject('Pemberitahuan Karyawan Habis Kontrak')
->view('mail.reminder.habisKontrak')
->with([
'reminder_kontrak' => $reminder_kontrak,
'person' => $this->person
]);
// }
}
}
And then i got the error massage
Too few arguments to function
App\Mail\HabisKontrakMail::__construct(), 0 passed
I try to get this value getPerson(auth()->user()->approval_code,HabisKontrak::KODE_MODUL), Thankyou.
Task scheduler does not have a user session, thus auth()->user() can only return null (non-object).
To fix this, your crontab command can provide the user argument along. And your command can get a user with arguments:
Arguments
All user supplied arguments and options are wrapped in curly braces. In the following example, the command defines one required argument: user:
/**
* The name and signature of the console command.
*
* #var string
*/
protected $signature = 'mail:send {user}';
You may also make arguments optional or define default values for arguments:
// Optional argument...
mail:send {user?}
// Optional argument with default value...
mail:send {user=foo}
Simply pass the load a User object with the user argument (probably the user id or the user name). Pass this User on to HabisKontrakMail object, then you're good to go.
Wait. Doesn't that mean the same user is sending every time?
One catch is you can only have 1 user sending all the notification email. But according to the code you showed, the database don't seem to contain which user actually initiated the notification.
If you need to actually check it, you'll have to store the user id / username for the notification before it is scheduled. And I don't have enough information to suggest anything.
mailService.php
<?php
namespace App\Http\Services;
use Illuminate\Bus\Queueable;
use Illuminate\Mail\Mailable;
use Illuminate\Queue\SerializesModels;
use Illuminate\Contracts\Queue\ShouldQueue;
class mailService extends Mailable
{
use Queueable, SerializesModels;
/**
* The data instance.
*
* #param $data
*/
public $data;
/**
* Create a new message instance.
*
* #return void
*/
public function __construct($data)
{
$this->data = $data;
}
public function build()
{
$address = 'janeexampexample#example.com';
$subject = 'This is a demo!';
$name = 'Jane Doe';
return $this->view('emails.test')
->from($address, $name)
->cc($address, $name)
->bcc($address, $name)
->replyTo($address, $name)
->subject($subject)
->with([ 'test_message' => $this->data['message'] ]);
}
}
clientService.php
use App\Http\Services\mailService as EmailService;
/**
* #param $clientId
* #param $comp_id
*
* #return \App\Http\Models\clients|\Illuminate\Database\Eloquent\Model
*/
public function getClient($clientId, $comp_id)
{
$data = ['message' => 'This is a test!'];
Mail::to('test#test.com')->send(new EmailService($data));
return $this->clientsRepository->getClient($clientId, $comp_id);
}
When I pass the argument $data to a new instance of EmailService I get an error saying
too few arguments passed to constructor function
but I don't understand why if I'm passing $data in the clientService, thank you for your help in advance.
I'm using the Lumen Framework 5.3 and PHP 7.2 and this code sample was taken from Sendgrid docs.