Laravel | Problem send email with variables - laravel

I have a problem send email with variables.
I recived this error:
$login is undefined
view loginsucesso.blade.php
<p>Foi efetuado login na plataforma. {{ $login['nome'] }}</p>
Controller:
$login = array (
'nome' => "NAME TESTE"
);
Mail::to($request->email)->send(new emailteste($login));
Mail/emailteste:
class EmailTeste extends Mailable
{
use Queueable, SerializesModels;
public $login;
/**
* Create a new message instance.
*
* #return void
*/
public function __construct($login)
{
$this->login = $login;
}
/**
* Build the message.
*
* #return $this
*/
public function build()
{
return $this
->subject('Plataforma - Acesso efetuado com sucesso ')
->view('email/loginsucesso')
->with(['login'=>$this->login]);
}
}
I try pass array $login to view and recive error $login is undefined
Thanks!

From the docs;
Typically, you will still pass data via the mailable class' constructor; however, you should set this data to protected or private properties so the data is not automatically made available to the template. Then, when calling the with method, pass an array of data that you wish to make available to the template:
So I think your public property is conflicting with the data passed to the view. Do one or the other, not both.

Related

Laravel send notification as super-admin from admin controller

I have Super-Admin and Admin roles. In Admin view I've added button to request verification email. The problem I'm having is that when Admin clicks the button to receive verification email, the email is from Admin, not Super-Admin.
How to make this to be sent to Admin from Super-Admin, instead of from Admin?
Route:
Route::post('/dashboard/SendEmailVerification', 'AdminDashboardController#SendEmailVerification')->name('dashboard.SendEmailVerification');
In AdminDashboardController:
use App\Notifications\EmailVerification;
use App\User;
.............
public function SendEmailVerification(Request $request){
$user = User::where('email_verification_code', $request->code)
->withoutGlobalScope('active')
->first();
$user->notify(new EmailVerification($user));
return Reply::success('Email sent!');
}
And the notification email:
namespace App\Notifications;
use App\Traits\SmtpSettings;
use Illuminate\Bus\Queueable;
use Illuminate\Notifications\Notification;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Notifications\Messages\MailMessage;
use App\User;
class EmailVerification extends Notification implements ShouldQueue
{
use Queueable, SmtpSettings;
protected $user;
/**
* Create a new notification instance.
*
* #return void
*/
public function __construct(User $user)
{
$this->user = $user;
$this->setMailConfigs();
}
/**
* Get the notification's delivery channels.
*t('mail::layout')
* #param mixed $notifiable
* #return array
*/
public function via($notifiable)
{
$via = ['mail'];
return $via;
}
/**
* Get the mail representation of the notification.
*
* #param mixed $notifiable
* #return \Illuminate\Notifications\Messages\MailMessage
*/
public function toMail($notifiable)
{
return (new MailMessage)
->subject('Confirm your email')
->greeting(__('Hello!'))
->line(__('email.emailVerify.text'))
->action('Confirm', getDomainSpecificUrl(route('front.get-email-verification', $this->user->email_verification_code), $this->user->company));
#->line(__('email.thankyouNote'));
}
/**
* Get the array representation of the notification.
*
* #param mixed $notifiable
* #return array
*/
public function toArray($notifiable)
{
return $notifiable->toArray();
}
}
You're getting wrong sender address because you never defined who's the sender in your Notification configuration. There are two ways to do this:
First: The first one is a really simple, but non-dynamic solution. In your .env configuration config, add these lines:
MAIL_FROM_NAME="My Name"
MAIL_FROM_ADDRESS=support#example.com
When you configure this, add this in yout config/mail.php configuration:
'from' => [
'address' => env('MAIL_FROM_ADDRESS', 'default value if not found in .env'),
'name' => env('MAIL_FROM_NAME', 'default value if not found in .env'),
],
Note: Don't forget to clear your cache, and restart queue when you do this:
Second: This is a more dynamic solution, since you can load the sender email address from your database. In your SendEmailVerification method, you can query up the super-admin user, and pass to the EmailVerification class:
public function SendEmailVerification(Request $request){
$user = User::where('email_verification_code', $request->code)
->withoutGlobalScope('active')
->first();
$superAdminUser = User::where('role', 'super-admin')->first();
$user->notify(new EmailVerification($user, $superAdminUser));
return Reply::success('Email sent!');
}
Then, change your EmailVerification class:
public $user;
public $superUser;
public function __construct(User $user, User $superUser)
{
$this->user = $user;
$this->superUser = $superUser;
$this->setMailConfigs();
}
And in your toMail() method, add another from() method:
public function toMail($notifiable)
{
return (new MailMessage)
->subject('Confirm your email')
->from($superAdminUser->email, $superAdminUser->first_name)
->greeting(__('Hello!'))
->line(__('email.emailVerify.text'))
->action('Confirm', getDomainSpecificUrl(route('front.get-email-verification', $this->user->email_verification_code), $this->user->company));
#->line(__('email.thankyouNote'));
}
Note: Also clear your cache and restart your queue.
Hope that this can resolve your issue. Let me know if you have any problems with these solutions.
You can read more about notifications on official documentation.

Laravel. How to get id of database notification?

I use database notifications, in notification code I have method toDatabase:
public function toDatabase($notifiable)
{
$user = \App\SomeUsers::where('id', $notifiable->id)->first();
return [
'message' => $message,
];
}
it returns data array which is being sent to database channel mentioned in via method of current notification:
public function via($notifiable)
{
return ['database'];
}
Everything is as usual, BUT... The problem is I need id of notification in database here in current notification file so that I could broadcast message (from current notification file) to frontend which contains id of notificaion in db (so I could somehow identify it to mark as read). How to get it?
P.S. Moreover, database notification may be queueable, so... it seems that I can't get id...
P.P.S Another words I need broadcast message which contains ["id" => "id of just added corresponding database notification"].
<?php
namespace App\Notifications;
use App\Channels\SocketChannel;
use Illuminate\Bus\Queueable;
use Illuminate\Notifications\Notification;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Notifications\Messages\MailMessage;
use Redis;
class MyCustomNotification extends Notification implements ShouldQueue
{
use Queueable;
/**
* Create a new notification instance.
*
* #return void
*/
public function __construct($param)
{
$this->param = $param;
}
/**
* Get the notification's delivery channels.
*
* #param mixed $notifiable
* #return array
*/
public function via($notifiable)
{
$channels = ['database'];
return $channels;
}
/**
* Get the mail representation of the notification.
*
* #param mixed $notifiable
* #return \Illuminate\Notifications\Messages\MailMessage
*/
public function toMail($notifiable)
{
}
/**
* Get the array representation of the notification.
*
* #param mixed $notifiable
* #return array
*/
public function toDatabase($notifiable)
{
info("This is the current notification ID, it's generated right here before inserting to database");
info($this->id);
return [
'id' => **$this->id**,
'message' => 'Notification message',
];
}
}
$this->id solves the problem.
https://laracasts.com/discuss/channels/laravel/get-database-notification-id-in-push-notification
P.S. I want to draw attention to one fact. When I posted this question, I knew about $this->id, but I couldn't make it work. The reason was: when I dive deeper to my target code from the top level I made changes to code, but they didn't apply. The reason is queues. You need to restart laravel worker to apply settings as Laravel caches logic or you need temporarily delete those: implements ShouldQueue and use Queueable.
In order to retrieve the actual ID of the notifications table in Laravel, you need to cast the ID column to string. First, you need to create a new model called, Notification.
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class Notification extends Model
{
/**
* Cast variables to specified data types
*
* #var array
*/
protected $casts = [
'data' => 'array',
'id' => 'string'
];
}
This way, if you retrieve the model, it will give you the actual ID of the table.
{
"id": "212829d6-5579-449f-a8e5-e86f0a08e0f9",
"type": "App\\Notifications\\CronFailureNotification",
....
}
The accepted answer did not provide a solution for me in Laravel 8. To properly get the id of the notification, listen for the NotificationSent event and retrieve the id there. Example code:
EventServiceProvider.php
protected $listen = [
NotificationSent::class => [
DispatchBroadcastNotification::class
]
];
DispatchBroadcastNotification.php
<?php
namespace App\Listeners;
use App\Notifications\BroadcastNotification;
use Illuminate\Notifications\Events\NotificationSent;
class DispatchBroadcastNotification
{
/**
* Create the event listener.
*
* #return void
*/
public function __construct()
{
//
}
/**
* Handle the event.
*
* #param NotificationSent $event
* #return void
*/
public function handle(NotificationSent $event)
{
$event->notifiable->notify(
new BroadcastNotification($event->notification->id)
);
}
}
BroadcastNotification.php
<?php
namespace App\Notifications;
use App\Models\Tenant\User;
use Illuminate\Contracts\Broadcasting\ShouldBroadcast;
use Illuminate\Notifications\Messages\BroadcastMessage;
use Illuminate\Notifications\Notification;
class BroadcastNotification extends Notification implements ShouldBroadcast
{
public $notificationId;
public function __construct($notificationId)
{
$this->notificationId = $notificationId;
}
/**
* Get the notification's delivery channels.
*
* #param mixed $notifiable
* #return array
*/
public function via(User $notifiable): array
{
return ['broadcast'];
}
public function toBroadcast(User $notifiable)
{
return new BroadcastMessage([
'notificationId' => $this->notificationId
]);
}
}

Why the value coming from a get request isn't accessable in the blade file?

I have the following controller method, where I would like to make the $clientId able to be accessed in mails.projectRequest blade file.
I tried to do that through the ProjectRequestMailclass but it does not work. Is there something wrong or this is not the way to do that?
My controller method:
public function sendProjectTeam($projectClientId) {
$projectClientEmail = Client::where('id', $projectClientId)->value('email');
Mail::to($projectClientEmail)->send(new ProjectRequestMail($projectClientId));
return ['success' => true, 'message' => 'Email was sent'];
}
ProjectRequestMail class:
class ProjectRequestMail extends Mailable implements ShouldQueue
{
use Queueable, SerializesModels;
/**
* #var
*/
public $projectClientId;
/**
* Create a new message instance.
*
* #param $user
*/
public function __construct($projectClientId)
{
//
$this->project_client_id = $projectClientId;
}
/**
* Build the message.
*
* #return $this
*/
public function build()
{
$this->from('hello#signifly.com');
$this->subject('New Project Request from Signifly');
return $this->markdown('mails.projectRequest');
}
}
and finally ProjectRequest blade
#component('mail::message')
Hello,
You have received a new request regarding your project.
#component('mail::button', ['url' => env('APP_URL'). '/#/project-requests/' . $projectClientId ])
See request
#endcomponent
Best regards,<br>
The ... team
#endcomponent

Check user settings before sending an email notification in Laravel

I have a receiveEmail boolean field in the User model of a Laravel application. How do I ensure that mail notifications respect this field, and only sends the email to the user if the field is true?
What I want is that this code:
$event = new SomeEvent($somedata);
Auth::user()->notify($event);
where SomeEvent is a class that extends Notification and implements 'mail' on the via() method, only sends an email if the user has allowed emails.
Have any one checked this via() method:
https://laravel.com/docs/6.x/notifications#specifying-delivery-channels
public function via($notifiable)
{
// $notifiable object is User instance for most cases
$wantsEmail = $notifiable->settings['wants_email']; // your own logic
if(!$wantsEmail){
// no email only database log
return ['database'];
}
return ['database', 'mail'];
}
I hope this will work while sending notifications to multiple users too. Thanks
I ended up creating a new Channel that implements the checking. In app/channels, add your channel, something like this:
namespace App\Channels;
use App\User;
use Illuminate\Notifications\Channels\MailChannel;
use Illuminate\Notifications\Notification;
use Illuminate\Support\Arr;
class UserCheckMailChannel extends MailChannel
{
/**
* Send the given notification.
*
* #param mixed $notifiable
* #param \Illuminate\Notifications\Notification $notification
* #return void
*/
public function send($notifiable, Notification $notification)
{
// check if user should receive emails. Do whatever check you need here.
if ($notifiable instanceof User && !$notifiable->receiveEmails) {
return;
}
// yes, convert to mail and send it
$message = $notification->toMail($notifiable);
if (!$message) {
return;
}
parent::send($notifiable, $notification);
}
}
Then bind your class on Providers/AppServiceProvider.php to the old mail class:
/**
* Register any application services.
*
* #return void
*/
public function register()
$this->app->bind(
\Illuminate\Notifications\Channels\MailChannel::class,
UserCheckMailChannel::class
);
}
try to create new method in user model like this..
user model file..
public function scopeNotifyMail() {
if($this->receiveEmail == true) { //if field is enable email other wise not send..
$event = new SomeEvent($somedata);
$this->notify($event);
}
}
and now call like this in controller..
Auth::user()->notifyMail();
or
App\User::find(1)->notifyMail();
or
App\User::where('id',1)->first()->notifyMail();

Laravel : Call to a member function send() on string on Listeners

I am trying to do pushnotification when a new user signup.So I created events called MemberNotificationEvents, when I fired an event event(new MemberNotificationEvent($UserDetails)); on my signUpController flow is completely going but on the MemberNotificationListener a public function handle(MemberNotificationEvent $event) return error that :
Call to a member function send() on string
I put full code of MemberNotificationListener :
<?php
namespace App\Listeners;
use App\Events\MemberNotificationEvent;
use App\Services\PushNotificationService;
use Illuminate\Contracts\Queue\ShouldQueue;
class MemberNotificationListener implements ShouldQueue
{
private $pushNotificationService;
/**
* Create the event listener.
*
* #return void
*/
public function __construct()
{
$this->pushNotificationService = PushNotificationService::class;
}
private function getMessageBody($username)
{
return "Awesome! Welcome " . $username . " to IDM";
}
/**
* Handle the event.
*
* #param object $event
* #return void
*/
public function handle(MemberNotificationEvent $event)
{
$username = $event->UserDetails->name;
$message = $this->getMessageBody($username);
$this->pushNotificationService->send($event,['body' => $message]); // throw error
}
}
What is the problem in my code?
The problem is with this line:
$this->pushNotificationService = PushNotificationService::class;
When you do SomeClass::class, it means you supply the class name - not the actual class.
Hence, when you later do $this->pushNotificationService->send(...), the push notification service is just the class name and not the service class.
The second part of the problem is that you need an actual object to put in there. Laravel can inject it for you in the constructor, and then you can supply it. Like this:
public function __construct(PushNotificationService $service)
{
$this->pushNotificationService = $service;
}

Resources