In my Laravel application I have a Notification that sends a Mailable when a User is deleted.
The Notification class:
<?php
namespace App\Notifications;
use Illuminate\Bus\Queueable;
use Illuminate\Notifications\Notification;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Notifications\Messages\MailMessage;
use App\User;
use App\Mail\UserDeleted as UserDeletedEmail;
class UserDeleted extends Notification implements ShouldQueue
{
use Queueable;
/**
* The user instance being passed to the notification
*
* #var User $user
*/
protected $user;
/**
* Create a new notification instance.
*
* #return void
*/
public function __construct(User $user)
{
$this->user = $user;
}
/**
* Get the notification's delivery channels.
*
* #param mixed $notifiable
* #return array
*/
public function via($notifiable)
{
return ['mail', 'database'];
}
/**
* Get the mail representation of the notification.
*
* #param mixed $notifiable
* #return \Illuminate\Notifications\Messages\MailMessage
*/
public function toMail($notifiable)
{
return (new UserDeletedEmail($notifiable, $this->user));
}
/**
* Get the array representation of the notification.
*
* #param mixed $notifiable
* #return array
*/
public function toArray($notifiable)
{
return [
'user_id' => $this->user['id'],
'user_username' => $this->user['username'],
'user_email' => $this->user['email'],
'user_full_name' => $this->user['full_name'],
];
}
}
In this case $notifiable is an instance of User but soo is $user as this is the user that has been deleted.
The Mailable looks like this:
<?php
namespace App\Mail;
use Illuminate\Bus\Queueable;
use Illuminate\Mail\Mailable;
use Illuminate\Queue\SerializesModels;
use Spatie\Permission\Models\Role;
use Illuminate\Contracts\Queue\ShouldQueue;
use App\User;
class UserDeleted extends Mailable
{
use Queueable, SerializesModels;
/**
* The order instance.
*
* #var User
*/
public $user;
/**
* Create a new message instance.
*
* #return void
*/
public function __construct(User $user)
{
$this->user = $user;
}
/**
* Build the message.
*
* #return $this
*/
public function build()
{
return $this
->to($this->user->email)
->subject("{$this->user->full_name} been deleted from the Citibase Intranet")
->markdown('mail.user-deleted');
}
}
The issue is, as they're both instances of User I'm effectively passing the wrong instance in the subject line.
Everything is triggered through the UserObserver.
/**
* Handle the user "deleted" event.
*
* #param \App\User $user
* #return void
*/
public function deleted(User $user)
{
Log::notice("A user has been deleted: {$user->full_name} by " . optional(auth()->user())->full_name ?? "System");
User::role(['admin'])->get()
->each->notify(
(new UserDeleted($user))->delay(now()->addSeconds(10))
);
}
At the moment your UserDeleted mailables constructor is only accepting the user that should receive the email, you can add the other user as well and you will have access to both.
Something like this:
class UserDeleted extends Mailable
{
use Queueable, SerializesModels;
/**
* #var User
*/
public $admin;
/**
* #var User
*/
public $deletedUser;
/**
* Create a new message instance.
*
* #return void
*/
public function __construct(User $admin, User $deletedUser)
{
$this->admin = $admin;
$this->deletedUser = $deletedUser;
}
/**
* Build the message.
*
* #return $this
*/
public function build()
{
return $this
->to($this->admin->email)
->subject("{$this->deletedUser->full_name} been deleted from the Citibase Intranet")
->markdown('mail.user-deleted');
}
}
Related
I have a notification in the database. I need to show it to the user when he clicks the button. But it doesn't work for me, I'm new to laravel. I create toDatabase function in InvoicePaid.php
private.blade.php:
#extends('layouts.app')
#section('title-block')
Профиль
#endsection
#section('content')
<?php
$user = auth()->user();
foreach ($user->unreadNotifications as $notification) {
echo $notification->type;
}
?>
#endsection
notifications_table:
<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreateNotificationsTable extends Migration
{
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::create('notifications', function (Blueprint $table) {
$table->uuid('id')->primary();
$table->string('type');
$table->morphs('notifiable');
$table->text('data');
$table->timestamp('read_at')->nullable();
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
Schema::dropIfExists('notifications');
}
}
Notifications/InvoicePaid.php:
<?php
namespace App\Notifications;
use Illuminate\Bus\Queueable;
use Illuminate\Notifications\Notification;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Notifications\Messages\MailMessage;
class InvoicePaid 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 ['database'];
}
/**
* Get the mail representation of the notification.
*
* #param mixed $notifiable
* #return \Illuminate\Notifications\Messages\MailMessage
*/
public function toMail($notifiable)
{
return (new MailMessage)
->line('The introduction to the notification.')
->action('Notification Action', url('/'))
->line('Thank you for using our application!');
}
/**
* Get the array representation of the notification.
*
* #param mixed $notifiable
* #return array
*/
public function toDatabase($notifiable)
{ return [
'message'=>'Уведомление'
];
}
public function toArray($notifiable)
{
return [
'message'=>'Уведомление'
];
}
}
User.php:
<?php
namespace App;
use Illuminate\Notifications\Notifiable;
use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Support\Facades\Hash;
class User extends Authenticatable
{
use Notifiable;
/**
* The attributes that are mass assignable.
*
* #var array
*/
protected $fillable = [
'name', 'email', 'password','surname','number','fathers_name','parents_number','class','studies'
];
/**
* The attributes that should be hidden for arrays.
*
* #var array
*/
protected $hidden = [
'password', 'remember_token',
];
/**
* The attributes that should be cast to native types.
*
* #var array
*/
protected $casts = [
'email_verified_at' => 'datetime',
];
public function setPasswordAttribute($password){
$this->attributes['password'] = Hash::make($password);
}
}
Picture from my database
enter image description here
I want to translate the notification email when a user is registering but it's always the default language that is sent. I have CustomEmailVerificationNotification class that is overwriting the default vendor / SendEmailVerificationNotification.
This project is using laravel-localization package.
protected $listen = [
Registered::class => [
SendEmailVerificationNotification::class,
],
];
<?php
namespace App\Notifications;
use Illuminate\Notifications\Messages\MailMessage;
use Illuminate\Notifications\Notification;
use Illuminate\Support\Carbon;
use Illuminate\Support\Facades\Config;
use Illuminate\Support\Facades\Lang;
use Illuminate\Support\Facades\URL;
class CustomEmailVerificationNotification extends Notification
{
/**
* The callback that should be used to create the verify email URL.
*
* #var \Closure|null
*/
public static $createUrlCallback;
/**
* The callback that should be used to build the mail message.
*
* #var \Closure|null
*/
public static $toMailCallback;
/**
* 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)
{
$verificationUrl = $this->verificationUrl($notifiable);
if (static::$toMailCallback) {
return call_user_func(static::$toMailCallback, $notifiable, $verificationUrl);
}
return $this->buildMailMessage($verificationUrl);
}
/**
* Get the verify email notification mail message for the given URL.
*
* #param string $url
* #return \Illuminate\Notifications\Messages\MailMessage
*/
protected function buildMailMessage($url)
{
return (new MailMessage)
->greeting(Lang::get('custom_email_verification_notification_greeting'))
->subject(Lang::get('custom_email_verification_notification_subject'))
->line(Lang::get('custom_email_verification_notification_line_one'))
->action(Lang::get('custom_email_verification_notification_action'), $url)
->line(Lang::get('custom_email_verification_notification_line_two'));
}
/**
* Get the verification URL for the given notifiable.
*
* #param mixed $notifiable
* #return string
*/
protected function verificationUrl($notifiable)
{
if (static::$createUrlCallback) {
return call_user_func(static::$createUrlCallback, $notifiable);
}
return URL::temporarySignedRoute(
'verification.verify',
Carbon::now()->addMinutes(Config::get('auth.verification.expire', 60)),
[
'id' => $notifiable->getKey(),
'hash' => sha1($notifiable->getEmailForVerification()),
]
);
}
/**
* Set a callback that should be used when creating the email verification URL.
*
* #param \Closure $callback
* #return void
*/
public static function createUrlUsing($callback)
{
static::$createUrlCallback = $callback;
}
/**
* 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;
}
}
I tried to add preferredLocale like they do in documentation:
use Illuminate\Contracts\Translation\HasLocalePreference;
class User extends Authenticatable implements MustVerifyEmail, HasLocalePreference
{
public function preferredLocale()
{
return $this->locale;
}
public function sendEmailVerificationNotification()
{
$this->notify(new CustomEmailVerificationNotification);
}
}
and then in notification to make $notificable->locale but its empty.
Try this option:
use Illuminate\Contracts\Translation\HasLocalePreference;
class User extends Model implements HasLocalePreference{
/**
* Get the user's preferred locale.
*
* #return string
*/
public function preferredLocale() {
return $this->locale;
}
}
guys in my laravel application i'm trying to send my users a custom verification email, as i'm using language translations
So as the first step I've created following custom email template in my App/Notifications folder CustomVerifyEmailNotification.php
<?php
namespace Illuminate\Auth\Notifications;
use Illuminate\Notifications\Messages\MailMessage;
use Illuminate\Notifications\Notification;
use Illuminate\Support\Carbon;
use Illuminate\Support\Facades\Config;
use Illuminate\Support\Facades\Lang;
use Illuminate\Support\Facades\URL;
class CustomVerifyEmailNotification extends Notification
{
/**
* The callback that should be used to build the mail message.
*
* #var \Closure|null
*/
public static $toMailCallback;
/**
* 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)
{
$verificationUrl = $this->verificationUrl($notifiable);
if (static::$toMailCallback) {
return call_user_func(static::$toMailCallback, $notifiable, $verificationUrl);
}
return (new MailMessage)
->subject(Lang::get(''.('sentence.Hello friend. Verify Email Address').''))
->line(Lang::get(''.('sentence.If you did not create an account, no further action is required.').''));
}
/**
* Get the verification URL for the given notifiable.
*
* #param mixed $notifiable
* #return string
*/
protected function verificationUrl($notifiable)
{
return URL::temporarySignedRoute(
'verification.verify',
Carbon::now()->addMinutes(Config::get('auth.verification.expire', 60)),
[
'id' => $notifiable->getKey(),
'hash' => sha1($notifiable->getEmailForVerification()),
]
);
}
/**
* 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;
}
}
and following is my User.php
<?php
namespace App;
use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
use Laravel\Cashier\Billable;
use Spatie\Permission\Traits\HasRoles;
class User extends Authenticatable implements MustVerifyEmail
{
use Notifiable,Billable;
use HasRoles;
/**
* The attributes that are mass assignable.
*
* #var array
*/
protected $fillable = [
'name','last_name', 'email', 'password','username','mobile','propic','user_roles','user_source',
];
/**
* The attributes that should be hidden for arrays.
*
* #var array
*/
protected $hidden = [
'password', 'remember_token',
];
/**
* The attributes that should be cast to native types.
*
* #var array
*/
protected $casts = [
'email_verified_at' => 'datetime',
];
}
How can I inject my custom email template here?
I'm using laravel 6 and following is my MustVerifyEmail.php trait
<?php
namespace Illuminate\Auth;
use Illuminate\Auth\Notifications\VerifyEmail;
trait MustVerifyEmail
{
/**
* Determine if the user has verified their email address.
*
* #return bool
*/
public function hasVerifiedEmail()
{
return ! is_null($this->email_verified_at);
}
/**
* Mark the given user's email as verified.
*
* #return bool
*/
public function markEmailAsVerified()
{
return $this->forceFill([
'email_verified_at' => $this->freshTimestamp(),
])->save();
}
/**
* Send the email verification notification.
*
* #return void
*/
public function sendEmailVerificationNotification()
{
$this->notify(new VerifyEmail);
}
/**
* Get the email address that should be used for verification.
*
* #return string
*/
public function getEmailForVerification()
{
return $this->email;
}
}
Current verification process works properly but I need to send that customized email to my users.
Now you have to ovewrite sendEmailVerificationNotification() function in order to use your Notification CustomVerifyEmailNotification.
So, in your User.php you have to write a function sendEmailVerificationNotification like:
<?php
namespace App;
use App\Notifications\CustomVerifyEmailNotification; // use your custom Notification
use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
use Laravel\Cashier\Billable;
use Spatie\Permission\Traits\HasRoles;
class User extends Authenticatable implements MustVerifyEmail
{
use Notifiable,Billable;
use HasRoles;
public function sendEmailVerificationNotification()
{
$this->notify(new CustomVerifyEmailNotification);
}
}
Then you can customize the email in your custom notification
I am using a github project named mnabialek/laravel-modular. The package works fine but I cant pass requests to a different controller in diffrent module. How can I do that.
TestModule Controller
<?php
namespace App\Modules\TestModule\Http\Controllers;
use App\Http\Requests;
use App\Http\Controllers\Controller;
use Illuminate\Http\Response;
use App\Modules\TestModule\Http\Requests\TestModuleRequest;
use App\Modules\Admin\Http\Requests\AdminRequest;
use App\Modules\TestModule\Repositories\TestModuleRepository;
use App\Modules\TestModule\Services\TestModuleService;
class TestModuleController extends Controller
{
/**
* #var TestModuleRepository
*/
protected $repo;
/**
* #var TestModuleService
*/
protected $service;
/**
* TestModuleController constructor.
*
* #param TestModuleRepository $repo
* #param TestModuleService $service
*/
public function __construct(TestModuleRepository $repo, TestModuleService $service)
{
$this->repo = $repo;
$this->service = $service;
}
/**
* Display a listing of the resource.
*
* #return Response
*/
public function index()
{
//
//echo "Here you are";
//$data["data"] = "Here you are";
//return view("welcome")->with($data);
$working = "Its Working";
$message = App::make("App\\Modules\\Admin\\Http\\Controllers\\AdminController")->create($working);
}
/**
* Show the form for creating a new resource.
*
* #return Response
*/
}
AdminController.php
<?php
namespace App\Modules\Admin\Http\Controllers;
use App\Http\Requests;
use App\Http\Controllers\Controller;
use Illuminate\Http\Response;
use App\Modules\Admin\Http\Requests\AdminRequest;
use App\Modules\Admin\Repositories\AdminRepository;
use App\Modules\Admin\Services\AdminService;
class AdminController extends Controller
{
/**
* #var AdminRepository
*/
protected $repo;
/**
* #var AdminService
*/
protected $service;
/**
* AdminController constructor.
*
* #param AdminRepository $repo
* #param AdminService $service
*/
public function __construct(AdminRepository $repo, AdminService $service)
{
$this->repo = $repo;
$this->service = $service;
}
/**
* Display a listing of the resource.
*
* #return Response
*/
public function index()
{
//
}
/**
* Show the form for creating a new resource.
*
* #return Response
*/
public function create($working)
{
die(print_r($working));
//
}
}
Here is the error I am getting.
Class 'App\Modules\TestModule\Http\Controllers\App' not found
Try the following:
$message = Illuminate\Support\Facades\App::make("App\\Modules\\Admin\\Http\\Controllers\\AdminController")->create($working);
As App does not exist in the current namespace, you have to call it from where it is defined.
I am trying to broadcast a notification in laravel 5.3 when i write
public function via($notifiable)
{
return ['broadcast','database'];
}
error occurs in console 500 internal server error and when i remove broadcast error removes please help here is my notification code
<?php
namespace App\Notifications;
use Illuminate\Bus\Queueable;
use Illuminate\Notifications\Notification;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Notifications\Messages\MailMessage;
use Illuminate\Broadcasting\InteractsWithSockets;
use Illuminate\Contracts\Broadcasting\ShouldBroadcast;
use Illuminate\Notifications\Messages\BroadcastMessage;
class userLiked extends Notification implements ShouldBroadcast, ShouldQueue
{
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 ['broadcast','database'];
}
/**
* Get the array representation of the notification.
*
* #param mixed $notifiable
* #return array
*/
public function toDatabase($notifiable)
{
return [
'status'=>'liked',
'user'=>auth()->user(),
];
}
/**
* Get the array representation of the notification.
*
* #param mixed $notifiable
* #return array|BroadcastMessage
*/
public function toBroadcast($notifiable)
{
return new BroadcastMessage(array(
'status'=>'liked',
'user'=>auth()->user(),
));
}
/**
* Get the array representation of the notification.
*
* #param mixed $notifiable
* #return array
*/
public function toArray($notifiable)
{
return [
//
];
}
}
Here is my cotroller code where i am calling notification
$like = new like();
$like->userId = $request['userId'];
$like->crushId = $request['crushId'];
$like->liked = true;
$like->save();
User::find($like->crushId)->notify(new userLiked());
And here is my user model
<?php
namespace App;
use Illuminate\Support\Facades\Auth;
use Illuminate\Notifications\Notifiable;
use Illuminate\Foundation\Auth\User as Authenticatable;
class User extends Authenticatable
{
use Notifiable;
public function likes(){
$this->hasMany('App\like');
}
/**
* The attributes that are mass assignable.
*
* #var array
*/
protected $fillable = [
'username', 'email', 'password',
];
/**
* The attributes that should be hidden for arrays.
*
* #var array
*/
protected $hidden = [
'password', 'remember_token',
];
/**
* #return string
*/
public function receivesBroadcastNotificationsOn()
{
return 'user.'.$this->id;
}
}
Please help i am sick of it