How can i pass the variables in the Mail body with laravel? - laravel

I want to pass the variables in my mail body how can I do that.
I am doing.
I want to send the mail template which is coming from DB, In that template, I have defined the variables to be get replaced when it is sent.
`$record = DB::table('email_templates')->select('content','em_temp_id')->where('em_temp_id',
$request->select_temp)->where('is_active', 1)->first();
$body = htmlspecialchars_decode($record->content);' //the html body
and my mail function
'Mail::send([],[], function($message) use ($Toarray, $ToCCarray, $ToBCCarray, $subject, $body,
$is_plainOrHtml){
$message->to($Toarray, '');
$message->cc($ToCCarray, '');
$message->bcc($ToBCCarray, '');
$message->subject($subject);
$message->setBody($body, 'text/html'); //for plain text email
});'
Template in DB is like:
`<p>Dear {{$userName}},</p>
<p>The {{$service_provider}}, requesting you to join <strong>{{$channel}}</strong> service.
</p>`
Array to pass:
`$arr_pass['userName'] = 'John';
$arr_pass['service_provider'] = 'abc.com';
$arr_pass['channel'] = 'Tom';`
How can i pass this array in the mail body?

You can use Blade::compileString, which will translate the blade template that you read from the database. There is one tricky part when you do so - how to send the variables' data.
Here are some hints:
You could use this library: https://github.com/TerrePorter/StringBladeCompiler
You could use a BladeCompiler similar to Is there any way to compile a blade template from a string?
Roll your own compiler by checking the implementation of https://laravel.com/api/8.x/Illuminate/View/Compilers/BladeCompiler.html

You can create a new Mail class by extending Mailable class and pass your array to the constructor of the Mail class.
Here in the below example, RFIRequestMail is a Mail class created in App\Mail Directory.
RFIRequestMail.php
<?php
namespace App\Mail;
use Illuminate\Bus\Queueable;
use Illuminate\Mail\Mailable;
use Illuminate\Queue\SerializesModels;
use Illuminate\Contracts\Queue\ShouldQueue;
class RFIRequestMail extends Mailable
{
use Queueable, SerializesModels;
public $verifierData;
/**
* Create a new message instance.
*
* #return void
*/
public function __construct($data)
{
$this->data = $data;
}
/**
* Build the message.
*
* #return $this
*/
public function build()
{
return $this->view('mail-view-template');
}
}
MailController
$sendData = User::find($id);
$data = User::find($company_id);
$sendData["link"] = env("APP_URL");
$sendData["year"] = $request->get("year");
$sendData["user"] = $data->first_name.' '.$data->last_name;
Mail::to($data->email)->send(new RFIRequestMail($sendData));

Related

Telegram notifications in Octobercms plugin

I would like to send a telegram message to a specific user at 17:00 using laravel's Telegram notification channel, I however can't seem to get it going. I currently use a cmd command for testing, but keep getting errors and don't know what to do.
Here are my files for the command and notification:
SendNotification.php
<?php
namespace Rogier\Lab\Console;
use Illuminate\Console\Command;
use Rogier\Lab\Notifications\DailyTelegram;
class SendNotifications extends Command
{
protected $name = 'lab:notifications:send';
protected $description = 'Send notifications';
protected $userid = 919871501;
/**
* Execute the console command.
* #return void
*/
public function handle()
{
$this->output->writeln('Sending notifications');
$notification = new DailyTelegram($this->userid);
$notification->via()->toTelegram();
$this->output->writeln('Done');
}
}
and DailyTelegram.php
<?php
namespace Rogier\Lab\Notifications;
use NotificationChannels\Telegram\TelegramChannel;
use NotificationChannels\Telegram\TelegramMessage;
use Illuminate\Notifications\Notification;
use Illuminate\Notifications\Notifiable;
class DailyTelegram extends Notification
{
protected $userid = 919871501;
public function via()
{
return [TelegramChannel::class];
}
public function toTelegram()
{
return TelegramMessage::create()
// Optional recipient user id.
->to($this->userid)
// Markdown supported.
->content("Hello there!\nYour invoice has been *PAID*");
}
}
I currently get the error "Call to a member function toTelegram() on array", but I feel like I tried everything, maybe I'm doing it completely wrong. Does anyone know how I should do it?
thanks in advance
Yes, you are doing it wrong. Notifiables have notify() method, you should use it:
$user->notify(new DailyTelegram);
In this example $user is App\User instance (which is notifiable out of the box).
You should check out both Laravel's sending notifications and laravel-notification-channels/telegram docs.

Laravel 5: HTML with variables from DB for Mailable class

So I need to store my blade email templates in database.
And now I am having problem to use db content with view, because dynamic informations are not rendered.
Here is the code to elaborate a bit more problem which I am facing:
Mailable class:
namespace App\Mail;
use Illuminate\Bus\Queueable;
use Illuminate\Mail\Mailable;
use Illuminate\Queue\SerializesModels;
use Illuminate\Contracts\Queue\ShouldQueue;
use App\User;
class activateUser extends Mailable
{
public $html;
public $user;
use Queueable, SerializesModels;
/**
* Create a new message instance.
*
* #return void
*/
public function __construct(User $user)
{
//this actually is much longer text coming from the DB - basicly coopied blade email template into the db
$this->html = 'Hi {{ $user->first_name }},<br /><br /> Your profile on our site has been activated.<br /><br />';
$this->user = $user;
}
/**
* Build the message.
*
* #return $this
*/
public function build()
{
return $this->view('emails.activateUser')->subject('Your account is activated');
}
}
Then the view emails.activateUser.blade.php looks like this:
{{ $html }}
And Inside of my controller I am calling this:
Mail::to($user->email)->send(new activateUser($user));
Problem is that actual username of the user will not be printed in the email and {{ }} will stay as well in email content.
Any ideas how to solve this, since my email template content needs to come from DB
You can use the Blade template compiler to compile a string:
public function compileBladeString(string $template, $data = []): string
{
$bladeCompiler = app('blade.compiler');
ob_start() && extract($data, EXTR_SKIP);
eval('?>' . $bladeCompiler->compileString($template));
$compiled = ob_get_contents();
ob_end_clean();
return $compiled;
}
You can then simply invoke this method with a string containing your template from the database.

Attaching PDF generated through Laravel to Mailable

At the moment I currently use laravel-snappy to generate my PDFs from pages, I do this primarily because it plays really nice with some JavaScript scripts I have on a few of my generated pages.
I know it's possible to attach an attachment of sorts to a mailable, which is what I have been using at the suggestions of others until the notifiables get a few more things worked on with them.
But I am stuck as to whether or not it's possible to attach a generated PDF to a mailable.
At the moment, I send the PDFs to generate through a route:
Route::get('/shipments/download/{shipment}','ShipmentController#downloadPDF');
Which is then sent to here in the controller:
public function downloadPDF(Shipment $shipment){
$shipment_details = $shipment->shipment_details;
$pdf = PDF::loadView('shipments.pdf', compact('shipment','shipment_details'))
->setOption('images', true)
->setOption('enable-javascript', true)
->setOption('javascript-delay', 100);
return $pdf->download('shipment'.$shipment->url_string.'.pdf');
}
My mailable is defined as such:
<?php
namespace App\Mail;
use Illuminate\Bus\Queueable;
use Illuminate\Mail\Mailable;
use Illuminate\Queue\SerializesModels;
use Illuminate\Contracts\Queue\ShouldQueue;
use App\Shipment;
class newFreightBill extends Mailable
{
use Queueable, SerializesModels;
/**
* Create a new message instance.
*
* #return void
*/
public $shipment;
public function __construct(Shipment $shipment)
{
$this->shipment = $shipment;
$this->attachmentURL = $shipment->url_string;
$this->proNumber = $shipment->pro_number;
}
/**
* Build the message.
*
* #return $this
*/
public function build()
{
return $this->from('billing#cmxtrucking.com')
->subject('New Freight Bill Created - '. $this->proNumber)
->view('emails.shipments.created');
}
}
So, is it possible to attach a generated PDF?
You can use attach to send files via mail. For example:-
public function build()
{
return $this->from('billing#cmxtrucking.com')
->subject('New Freight Bill Created - '. $this->proNumber)
->view('emails.shipments.created')
->attach($your_pdf_file_path_goes_here);
}
This worked for me while i was trying. Hope it works for you too.
Here i am using laravel package "vsmoraes/laravel-pdf" for pdf generation
steps :
1) render view with dynamic data
2) load this view to pdf
3) attach pdf data to the mail
$html = view('pdf',compact('result','score'))->render();
$pdf = PDF::Load($html);
\Mail::send('mail.analysis',['user'=>$data],function($message) use($pdf,$user){
$message->to($user->email)->subject("Page Speed Aanlysis Generated");
$message->attachData($pdf->output(),'pdf_name.pdf');
});

How do I translate the subject of my password reset email in laravel 5

I am new to laravel and I am currently building a multilingual app. I am implementing password reset using laravels shipped methods. After looking at this method in ResetsPasswords trait:
protected function getEmailSubject()
{
return isset($this->subject) ? $this->subject : 'Your Password Reset Link';
}
I noticed that I can specify a variable for my subject in the PasswordController like so:
protected $subject = 'Password Reset';
How do I get this value from a language file and assign to the variable?
Use the trans() helper function in the contructor
<?php
namespace App\Http\Controllers\Auth;
use App\Http\Controllers\Controller;
use Illuminate\Foundation\Auth\ResetsPasswords;
class PasswordController extends Controller
{
use ResetsPasswords;
/**
* Create a new password controller instance.
*
* #return void
*/
public function __construct()
{
$this->subject = trans('passwords.subject');
$this->middleware($this->guestMiddleware());
}
}
After doing some digging I found the answer as shown below.
protected function getEmailSubject(){
return Lang::has('passwords.password_reset')
? Lang::get('passwords.password_reset')
: 'Your Password Reset Link.';
}
Using method overriding, I overrode the getEmailSubject method in the ResetsPasswords trait and provided the necessary implementation as shown in the body of the email. passwords.password_reset is a key for a text in my language file.

Only use translations from messages.php in Laravel 5

I would like to load all our translations into a flat array in resources/lang/en/messages.php and resources/lang/fr/messages.php
I would like to translate them in the view simply with trans('key') rather than trans('file.key')
Anyway to enable this behaviour? Seems it does not come out of the box. Thanks.
Figured out how, first define your own provider in App\Providers. Have it use your own custom class instead.
<?php namespace App\Providers;
use App\Utilities\TranslationUtility;
use Illuminate\Translation\TranslationServiceProvider;
class SimpleTranslationProvider extends TranslationServiceProvider {
/**
* Register the service provider.
*
* #return void
*/
public function register()
{
$this->registerLoader();
$this->app->singleton('translator', function($app)
{
$loader = $app['translation.loader'];
$locale = $app['config']['app.locale'];
$trans = new TranslationUtility($loader, $locale);
$trans->setFallback($app['config']['app.fallback_locale']);
return $trans;
});
}
}
Custom class:
<?php namespace App\Utilities;
use Illuminate\Translation\Translator;
class TranslationUtility extends Translator {
public function get($key, array $replace = array(), $locale = NULL)
{
return parent::get('messages.' . $key);
}
}
Then add your service provider in config/app.php instead of 'Illuminate\Translation\TranslationServiceProvider'

Resources