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.
Related
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');
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 new to Laravel. I just created a custom login with laravel 5.7. When I tried to reset password I'm getting this error:
"Declaration of
App\Employee::sendEmailVerificationNotification($token) should be
compatible with
Illuminate\Foundation\Auth\User::sendEmailVerificationNotification()"
Does anyone know how to resolve this error?
You may do something like this
class Employee extends Model implements MustVerifyEmail {
public function sendEmailVerificationNotification()
{
$this->notify(new VerifyEmail);
}
}
if you want to call it like Employee::sendEmailVerificationNotification() and if you want to verify the token you should extend the VerifyEmail notification something like
<?php
namespace App\Notifications;
use Illuminate\Bus\Queueable;
use Illuminate\Notifications\Notification;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Notifications\Messages\MailMessage;
use Illuminate\Support\Carbon;
use Illuminate\Support\Facades\URL;
use Illuminate\Support\Facades\Lang;
use Illuminate\Auth\Notifications\VerifyEmail;
class VerifyEmailNotification extends VerifyEmail
{
use Queueable;
/**
* Create a new notification instance.
*
* #return void
*/
public function __construct($token)
{
//verify token
}
/**
* Get the notification's delivery channels.
*
* #param mixed $notifiable
* #return array
*/
public function via($notifiable)
{
return ['mail'];
}
/**
* Get 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);
}
return (new MailMessage)
->subject(Lang::getFromJson('Verify Email Address'))
->line(Lang::getFromJson('Please click the button below to verify your email address'))
->action(
Lang::getFromJson('Verify Email Address'),
$this->verificationUrl($notifiable)
)
->line(Lang::getFromJson('If you did not create an account, no further action is required.'));
}
/**
* Get the array representation of the notification.
*
* #param mixed $notifiable
* #return array
*/
public function toArray($notifiable)
{
return [
//
];
}
}
Then in Employee model
public function sendEmailVerificationNotification($token)
{
$this->notify(new VerifyEmailNotification($token)); // your custom notification
}
You have to follow the same method signature if you want to override it-
You are overriding this method-
Illuminate\Foundation\Auth\User::sendEmailVerificationNotification()
to this-
App\Employee::sendEmailVerificationNotification($token)
If you notice the difference, you have passed $token in the method while the original method definition does not support that.
Create a different method if you need a different signature from the original method.
Im trying to send some text-messages using Nexmo with Laravel.
When I send the message directly in the route it works fine:
Route::get('/sms/send/{to}', function(\Nexmo\Client $nexmo, $to){
$message = $nexmo->message()->send([
'to' => $to,
'from' => '#me',
'text' => 'Sending SMS from Laravel. yay!!!'
]);
Log::info('sent message: ' . $message['message-id']);
});
But when I try to sen an sms using a Notification-class I get the error "Bad credentials". I've been following the official documentation from:
https://laravel.com/docs/5.5/notifications#sms-notifications
Here is the class that extends Notification:
<?php
namespace App\Notifications;
use Illuminate\Bus\Queueable;
use Illuminate\Notifications\Notification;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Notifications\Messages\MailMessage;
use Illuminate\Notifications\Messages\NexmoMessage;
class KeepGoing extends Notification
{
use Queueable;
/**
* Create a new notification instance.
*
* #return void
*/
public function __construct()
{
//
}
/**
* Get the notification's delivery channels.
*
* #param mixed $notifiable
* #return array
*/
public function via($notifiable)
{
return ['nexmo'];
}
/**
* Get the mail representation of the notification.
*
* #param mixed $notifiable
* #return \Illuminate\Notifications\Messages\MailMessage
*/
public function toNexmo($notifiable)
{
return (new NexmoMessage)
->content('Your SMS message content');
}
I cant figure out why I get a "Bad credentials"-error when trying to use the Notification-class while its working when done in the route-file?
Thank you!
EDIT:
The controller that calls notify():
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\User;
use App\Notifications\KeepGoing;
class NotificationController extends Controller
{
public function index()
{
$user = User::first();
$user->notify(new KeepGoing());
}
}
I should also add that toNexmo() gets called:
public function toNexmo($notifiable)
{
// If i dump($notifiable) I can see the user.
// The $notifiable has the attribute phone_number which is
// what the notificationsystem looks for...
return (new NexmoMessage)
->content('Your SMS message content');
}
Turns out the error was caused by a silly mistake, I messed up the nexmo-config in config/services.php:
'nexmo' => [
'key' => env('NEXMO_KEY'),
'secret' => env('NEXMO_SECRET'),
'sms_from' => '15556666666',
],
I put in the actual key and secret in the above...
You haven't mentioned how you send notifications when you are getting the error but if you use queues, you should make sure you run
php artisan queue:restart
to make process run in queue see your changes (for example modified .env or config)