Pass different data on a Laravel Mailable - php

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.

Related

Laravel email Templates

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 }}

Send a email with Laravel Nova Actions

I would like to send a mail from a button on Laravel Nova with an action (which I think is the most appropriate).
I already have a template of the mail saved in the mailable, I have made my resource but I don't know what to put inside since I need to retrieve information from this resource like for example the name, a price or the date when the line was created (in my table related to my resource).
My resource code:
<?php
namespace App\Nova;
use App\Image;
use Gloudemans\Shoppingcart\Cart;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Laravel\Nova\Fields\Currency;
use Laravel\Nova\Fields\Date;
use Laravel\Nova\Fields\Heading;
use Laravel\Nova\Fields\ID;
use Laravel\Nova\Fields\Text;
use Laravel\Nova\Http\Requests\NovaRequest;
use Techouse\IntlDateTime\IntlDateTime;
class Order extends Resource
{
/**
* The model the resource corresponds to.
*
* #var string
*/
public static $model = \App\Order::class;
public static $group = 'Paramètres';
public static function label()
{
return __('Commandes');
}
public static function singularLabel()
{
return __('Commande');
}
/**
* The single value that should be used to represent the resource when being displayed.
*
* #var string
*/
public static $title = 'id';
/**
* The columns that should be searched.
*
* #var array
*/
public static $search = [
'id',
];
/**
* Get the fields displayed by the resource.
*
* #param \Illuminate\Http\Request $request
* #return array
*/
public function fields(Request $request)
{
return [
ID::make()->sortable(),
Text::make('Nom du client', 'name'),
IntlDateTime::make('Passée le', 'created_at')
->locale('fr')
->readonly(),
Currency::make('Prix', 'total')->currency('EUR'),
Text::make('Mode de paiement', 'gateway')
->readonly(),
Text::make('Numéro de téléphone', 'phone'),
Heading::make('Adresse de livraison'),
Text::make('Adresse', 'address')
->hideFromIndex(),
Text::make('Code postal', 'postal_code')
->hideFromIndex(),
Text::make('Ville', 'city')
->hideFromIndex(),
Text::make('Pays', 'country')
->hideFromIndex(),
];
}
/**
* Get the cards available for the request.
*
* #param \Illuminate\Http\Request $request
* #return array
*/
public function cards(Request $request)
{
return [];
}
/**
* Get the filters available for the resource.
*
* #param \Illuminate\Http\Request $request
* #return array
*/
public function filters(Request $request)
{
return [];
}
/**
* Get the lenses available for the resource.
*
* #param \Illuminate\Http\Request $request
* #return array
*/
public function lenses(Request $request)
{
return [];
}
/**
* Get the actions available for the resource.
*
* #param \Illuminate\Http\Request $request
* #return array
*/
public function actions(Request $request)
{
return [];
}
}
My mailable code:
<?php
namespace App\Mail;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Mail\Mailable;
use Illuminate\Queue\SerializesModels;
class ResendOrder extends Mailable
{
use Queueable, SerializesModels;
/**
* Elements de contact
* #var array
*/
public $contact;
/**
* Create a new message instance.
*
* #return void
*/
public function __construct(Array $contact)
{
$this->contact = $contact;
}
/**
* Build the message.
*
* #return $this
*/
public function build()
{
return $this->view('emails.orderconfirmation')
->subject("Confirmation de commande");
}
}
And finally my Action code:
<?php
namespace App\Nova\Actions;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Support\Collection;
use Laravel\Nova\Actions\Action;
use Laravel\Nova\Fields\ActionFields;
class EmailOrderConfirmation extends Action
{
use InteractsWithQueue, Queueable;
/**
* Perform the action on the given models.
*
* #param \Laravel\Nova\Fields\ActionFields $fields
* #param \Illuminate\Support\Collection $models
* #return mixed
*/
public $name = 'Renvoyer le mail de confirmation de commande';
public function handle(ActionFields $fields, Collection $models)
{
return Action::message('Mail envoyé');
}
/**
* Get the fields available on the action.
*
* #return array
*/
public function fields()
{
return [];
}
}
I don't really know where to go and what to use, if you could enlighten me on that I would be very grateful, thank you!
// in EmailOrderConfirmation --nova action
// declare what you are using
// use Illuminate\Support\Facades\Mail;
// use App\Mail\ResendOrder;
public function handle(ActionFields $fields, Collection $models)
{
//loop over the orders that have been selected in nova
foreach ($models as $order) {
$contact = $order->contract; //however you are getting contract data
//assuming you have a $order->user order belongs to user relationship
//send mail to the user, with the order/contract details to create your email
Mail::to($order->user->email)->send(new ResendOrder($contact));
}
//return a message to nova
return Action::message('Mail envoyé');
}
// in Order /Nova resource
// declare what you are using
// use App\Nova\Actions\EmailOrderConfirmation;
public function actions(Request $request)
{
return [new EmailOrderConfirmation];
}

Multiple Queue on Homestead is failing and Events don't get fired

I currently have a live app that i am making huge changes too so i am working locally using Homestead. I previously used One Queue but with changes and all that i had to run multiple queues. The previous default queues was meant to make rows in a database table and one of the recent ones was to send emails. then i needed another one that I need to make rows in another table as well...issue is sometimes it works and other times it fails and sometimes it only creates one row before failing. the most annoying thing is that it is supposed to fire an event per row created in the database but that does not even occur at all. I had done it effectively before and it never failed me even the default queue still works fine.
here is the controller:
<?php
namespace App\Http\Controllers;
use Redirect;
use App\Short;
use App\Wallet;
use \SplFixedArray;
use App\Jobs\ShortQueuer;
use Illuminate\Http\Request;
use App\Http\Requests\SlotRequest;
class ShortController extends Controller
{
/**
* Display a listing of the resource.
*
* #return \Illuminate\Http\Response
*/
public function index()
{
return view('short_term_goals');
}
/**
* Show the form for creating a new resource.
*
* #return \Illuminate\Http\Response
*/
public function create()
{
//
}
/**
* Store a newly created resource in storage.
*
* #param \Illuminate\Http\Request $request
* #return \Illuminate\Http\Response
*/
public function store(SlotRequest $request)
{
$quota = 2;
$slotquota = request('slotamount') + $quota;
if ( auth()->user()->wallet->balance < $slotquota ) {
return Redirect::back()->with('low_balance', 'You do not have a sufficient wallet balance to reserve these SLOTS. Please Load Up Your Wallet');
} else {
// Getting SLOTS as objects of an array
$slotquantity = new SplFixedArray(request('slotamount'));
$slotquantity = $slotquantity->toArray();
$user = auth()->user();
ShortQueuer::dispatch($slotquantity, $user)->onQueue('shorts');
}
//Sorting Wallet Balance
$wallet = Wallet::where('user_id', auth()->user()->id)->first();
$wallet->balance = $wallet->balance - $slotquota;
$wallet->save();
//Returning View With Message
return Redirect::back()->with('reserved', 'Your Short Term Goals are Currently being met .');
}
/**
* Display the specified resource.
*
* #param \App\Short $short
* #return \Illuminate\Http\Response
*/
public function show(Short $short)
{
//
}
/**
* Show the form for editing the specified resource.
*
* #param \App\Short $short
* #return \Illuminate\Http\Response
*/
public function edit(Short $short)
{
//
}
/**
* Update the specified resource in storage.
*
* #param \Illuminate\Http\Request $request
* #param \App\Short $short
* #return \Illuminate\Http\Response
*/
public function update(Request $request, Short $short)
{
//
}
/**
* Remove the specified resource from storage.
*
* #param \App\Short $short
* #return \Illuminate\Http\Response
*/
public function destroy(Short $short)
{
//
}
}
Here is the job
<?php
namespace App\Jobs;
use App\Short;
use Illuminate\Bus\Queueable;
use Illuminate\Queue\SerializesModels;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
class ShortQueuer implements ShouldQueue
{
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
protected $slotquantity;
protected $user;
/**
* Create a new job instance.
*
* #return void
*/
public function __construct(array $slotquantity, $user)
{
$this->slotquantity = $slotquantity;
$this->user = $user;
}
/**
* Execute the job.
*
* #return void
*/
public function handle()
{
// Inserting Rows in SLOTS Table
foreach ($this->slotquantity as $short) {
$short = new Short();
$short->user_id = $this->user->id;
$short->save();
//Slot Counting Event
event(new ShortCounter);
}
}
public $tries = 1;
public $timeout = 86400;
public $retryAfter = 87000;
}
here is the event
<?php
namespace App\Events;
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 ShortCounter
{
use Dispatchable, InteractsWithSockets, SerializesModels;
/**
* Create a new event instance.
*
* #return void
*/
public function __construct()
{
//
}
/**
* Get the channels the event should broadcast on.
*
* #return \Illuminate\Broadcasting\Channel|array
*/
public function broadcastOn()
{
return new PrivateChannel('channel-name');
}
}
Here is the listener
<?php
namespace App\Listeners;
use App\Short;
use App\Goal;
use App\Events\ShortCounter;
use Illuminate\Http\Request;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Contracts\Queue\ShouldQueue;
class GoalCreator
{
/**
* Create the event listener.
*
* #return void
*/
public function __construct()
{
//
}
/**
* Handle the event.
*
* #param ShortCounter $event
* #return void
*/
public function handle(ShortCounter $event)
{
$shortcount = Short::all()->count();
if($shortcount == 800) {
$goalshort = Short::latest()->first();
$goal = new Goal();
$goal->gid = unique_random('goals', 'sgid', 8);
$goal->grc = unique_random('goals', 'sgrc', 12);
$goal->status = 0;
$goal->amount = 200;
$goal->user_id = $goalshort->user_id;
$goal->save();
Short::truncate();
}
}
}
I sort it out.....I went through the error logs and solved the errors one after the other. First I forgot to include the Event Class in the Job, then a column name in my database was wrong then I restarted my server.

How t solve Call to undefined method stdClass::notify()

laravel notify() undefined method. how to solved it....help me..
Error is:-
Call to undefined method stdClass::notify()
My Controller Code Here:
use Illuminate\Http\Request;
use \App\Notifications\ResetLink;
use Auth;
use App\User;
use DB;
use App\Password;
public function forgot(){
return view('forgot');
}
public function forgotPw(Request $request){
if($user = User::where('email',$request->email)->first()){
DB::table('password_resets')->insert([
'token' => $this->token(),
'email' => $user->email
]);
$pr = DB::table('password_resets')->where('email',$user->email)- >first();
$pr->notify(new ResetLink($pr));
request()->session()->flash('success', "Forgot Link Successfully Sent...");
return redirect('login');
} else {
request()->session()->flash('error', "Forgot Link Not Sent...");
return redirect('forgot');
}
}
My Notification Code Here:
namespace App\Notifications;
use Illuminate\Bus\Queueable;
use Illuminate\Notifications\Notification;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Notifications\Messages\MailMessage;
class ResetLink extends Notification
{
use Queueable;
/**
* Create a new notification instance.
*
* #return void
*/
public function __construct()
{
public $pr;
}
/**
* 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)
{
return (new MailMessage)
->line('Click the Button and Reset Password!')
->action('Password Reset', url('/reset'))
->line('Thank you for using our application!');
}
/**
* Get the array representation of the notification.
*
* #param mixed $notifiable
* #return array
*/
public function toArray($notifiable)
{
return [
//
];
}
}
I tried to last 2 hours but No send mail in mailtrap....
Thank You Advance for Help me..

Laravel 5.7 Multilogin SendEmailVerificationNotification error

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.

Categories