How to send only one event in Pusher channel and then for database notification store for all users - laravel

I've created a broadcast channel App.Models.Admin.Notify where all the admin users will be subscribed to this channel by default.
<?php
use Illuminate\Support\Facades\Broadcast;
Broadcast::channel('App.Models.Admin.Notify', function ($m) {
return !is_null($m) && $m->getMorphClass() === 'admin';
});
And this is the Notifications/Base.php where i've set ['database', 'broadcast', OneSignal::class] as notification channels
<?php
namespace App\Notifications;
use Illuminate\Bus\Queueable;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Notifications\Notification;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Contracts\Broadcasting\ShouldBroadcast;
use Illuminate\Notifications\Messages\BroadcastMessage;
use NotificationChannels\OneSignal\OneSignalMessage;
use App\Channels\OneSignal;
abstract class Base extends Notification implements ShouldBroadcast, ShouldQueue
{
use Queueable;
public $model;
protected string $icon;
public function __construct(mixed $m = null)
{
$this->model = $m;
}
/**
* Get notify id
*
* #return string
*/
protected function getNotifyId(): string
{
return $this->id;
}
/**
* Get icon path
*
* #return string
*/
protected function getIcon(): string
{
return asset('favicon.ico');
}
/**
* Get notification link
*
* #return string
*/
protected function getLink(): string
{
return asset('favicon.ico');
}
/**
* Get the notification's delivery channels.
*
* #param mixed $notifiable
* #return \App\Channels\PusherBeams\PusherMessage
*/
public function via($notifiable)
{
return [
'database',
'broadcast',
OneSignal::class
];
}
/**
* Get the array representation of the notification.
*
* #param mixed $notifiable
* #return array
*/
public function toArray($notifiable)
{
return array_merge(
[
'link' => $this->getLink(),
'icon' => $this->getIcon(),
],
$this->getData($notifiable)
);
}
/**
* Get data of message.
*
* #param mixed $notifiable
* #return array
*/
protected function getData($notifiable)
{
return [
'title' => 'hello',
'body' => 'world'
];
}
/**
* Create onesignal message of Web
* #param mixed $notifiable
* #return \NotificationChannels\OneSignal\OneSignalMessage
*/
public function toWeb($notifiable)
{
$data = $this->toArray($notifiable);
return OneSignalMessage::create()
->setSubject($data['title'])
->setBody($data['body'])
->setUrl($data['link']);
}
/**
* Create onesignal message of Android
* #param mixed $notifiable
* #return \NotificationChannels\OneSignal\OneSignalMessage
*/
public function toAndroid($notifiable)
{
$data = $this->toArray($notifiable);
return OneSignalMessage::create()
->setSubject($data['title'])
->setBody($data['body'])
->setData('url', str_replace('https://', 'gamepts://', $data['link']));
}
/**
* Websocket message
*
* #param mixed $notifiable
* #return \Illuminate\Notifications\Messages\BroadcastMessage
*/
public function toBroadcast($notifiable)
{
return (new BroadcastMessage($this->toArray($notifiable)))->onQueue('pusher');
}
}
So this is the basic setup for my Notifications and broadcasting.
I've a job which runs every minutes and if any reports are found then it should send the notification if any reports are found.
<?php
namespace App\Console\Commands;
use Carbon\Carbon;
use App\Models\MerchantDeposit;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Notification;
class CheckCashIn extends Command
{
/**
* The name and signature of the console command.
*
* #var string
*/
protected $signature = 'check:cashin';
/**
* The console command description.
*
* #var string
*/
protected $description = 'Check expiration of cash in orders';
/**
* Create a new command instance.
*
* #return void
*/
public function __construct()
{
parent::__construct();
}
/**
* Execute the console command.
*
* #return mixed
*/
public function handle()
{
$setting = app(\App\Settings\CurrencySetting::class)->currency;
$expired_limit = app(\App\Settings\AdminSetting::class)->expired_payin_limit_notify;
$reports = [];
foreach ($setting as $currency => $s) {
$expired_minutes = $s['expired_minutes'];
$k = MerchantDeposit::where('status', MerchantDeposit::STATUS['PENDING'])
->where('currency', $currency)
->where('created_at', '<=', Carbon::now()->subMinutes($expired_minutes))
->update(['status' => MerchantDeposit::STATUS['EXPIRED']]);
$o = MerchantDeposit::where('merchant_deposits.status', MerchantDeposit::STATUS['EXPIRED'])
->join('reseller_bank_cards', 'reseller_bank_cards.id', 'merchant_deposits.reseller_bank_card_id')
->join('resellers', 'resellers.id', 'reseller_bank_cards.reseller_id')
->where('merchant_deposits.currency', $currency)
->where('merchant_deposits.created_at', '<=', Carbon::now()->subMinutes($expired_minutes))
->having(DB::raw('COUNT(resellers.name)'), '>=', $expired_limit)
->select('resellers.name', DB::raw('COUNT(resellers.name) AS total_expired'), DB::raw('TRUNCATE(SUM(merchant_deposits.amount), 2) AS total_amount'), 'merchant_deposits.currency')
->groupBy('resellers.name', 'merchant_deposits.currency')
->get();
if (!empty($o->toArray()) && $k > 0) {
$reports[$currency] = [];
foreach ($o as $k => $v) {
$reports[$currency][$v->name] = $v->total_expired;
$reports[$currency]['Total Amount'] = $v->total_amount;
}
}
}
if (!empty($reports)) {
Notification::send(\App\Models\Admin::all(), new \App\Notifications\DepositExpiredReport($reports));
}
}
}
And in Model/Admin.php i've set receivesBroadcastNotificationsOn to update the channel name for the broadcast to send into pusher.
<?php
namespace App\Models;
use App\Trait\HasJWTSubject;
use App\Trait\UserLogsActivity;
use Illuminate\Auth\Authenticatable;
use Illuminate\Contracts\Auth\Access\Authorizable as AuthorizableContract;
use Illuminate\Contracts\Auth\Authenticatable as AuthenticatableContract;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Facades\Hash;
use Illuminate\Notifications\Notifiable;
use Laravel\Lumen\Auth\Authorizable;
use Tymon\JWTAuth\Contracts\JWTSubject;
use Spatie\Permission\Traits\HasRoles;
/**
* Model of admin
* #package Models
*/
class Admin extends Model implements AuthenticatableContract, AuthorizableContract, JWTSubject
{
use Authenticatable, Authorizable, HasFactory, HasJWTSubject;
use UserLogsActivity;
use Notifiable;
use HasRoles;
protected $fillable = [
'name',
'username',
'password',
'status',
'timezone'
];
protected $hidden = [
'password',
];
protected $casts = [
'status' => 'boolean',
];
public const STATUS = [
'DISABLED' => false,
'ACTIVE' => true,
];
public function getIsSuperAdminAttribute()
{
return $this->hasRole('Super Admin');
}
public function setPasswordAttribute($value)
{
$this->attributes['password'] = Hash::needsRehash($value) ? Hash::make($value) : $value;
}
public function devices()
{
return $this->morphMany(Device::class, 'user');
}
public function receivesBroadcastNotificationsOn()
{
return 'App.Models.Admin.Notify';
}
}
When the notification is triggered from Notification::send(\App\Models\Admin::all(), new \App\Notifications\DepositExpiredReport($reports)); it will send broadcast notification multiple times to same broadcast channel as shown in the screenshot below
From Notification::send(\App\Models\Admin::all(), new \App\Notifications\DepositExpiredReport($reports)); it is fine to save the notification records for all the admin in database notification but for pusher i want the notification event to sent only once instead of sending multiple times ie 'x' number of admins.
Lets say i have 100 admin users then now pusher will send the event to same channel 100 times. So i want to minimize the pusher event to just 1 channel where all the admin users subscribed can receive the notification but it should also save the records for 100 users in the notification table of database.

Related

Add Multiple OneSignal APP in Custom Notification in laravel

I have two Notification channels
app/Channels/Reseller/Web/OneSignalWeb.php
<?php
namespace App\Channels\Reseller\Web;
use Berkayk\OneSignal\OneSignalClient;
use Illuminate\Notifications\Notification;
use Illuminate\Support\Facades\Log;
use NotificationChannels\OneSignal\Exceptions\CouldNotSendNotification;
use NotificationChannels\OneSignal\OneSignalChannel;
class OneSignalWeb extends OneSignalChannel
{
public function __construct()
{
$client = new OneSignalClient(
env("ONESIGNAL_RESELLER_APP_ID"),
env("ONESIGNAL_RESELLER_REST_API_KEY"),
''
);
parent::__construct($client);
}
/**
* Send the given notification.
*
* #param mixed $notifiable
* #param \Illuminate\Notifications\Notification $notification
*
* #return \Psr\Http\Message\ResponseInterface
* #throws \NotificationChannels\OneSignal\Exceptions\CouldNotSendNotification
*/
public function send($notifiable, Notification $notification)
{
if (!$userIds = $notifiable->devices()->where('platform', 'web')->pluck('uuid')->toArray()) {
return;
}
/** #var ResponseInterface $response */
$response = $this->oneSignal->sendNotificationCustom(
$this->payload($notifiable, $notification, $userIds)
);
if ($response->getStatusCode() !== 200) {
throw CouldNotSendNotification::serviceRespondedWithAnError($response);
}
return $response;
}
}
app/Channels/Merchant/Web/OneSignalWeb.php
<?php
namespace App\Channels\Merchant\Web;
use Berkayk\OneSignal\OneSignalClient;
use Illuminate\Notifications\Notification;
use Illuminate\Support\Facades\Log;
use NotificationChannels\OneSignal\Exceptions\CouldNotSendNotification;
use NotificationChannels\OneSignal\OneSignalChannel;
class OneSignalWeb extends OneSignalChannel
{
public function __construct()
{
$client = new OneSignalClient(
env("ONESIGNAL_MERCHANT_APP_ID"),
env("ONESIGNAL_MERCHANT_REST_API_KEY"),
''
);
parent::__construct($client);
}
/**
* Send the given notification.
*
* #param mixed $notifiable
* #param \Illuminate\Notifications\Notification $notification
*
* #return \Psr\Http\Message\ResponseInterface
* #throws \NotificationChannels\OneSignal\Exceptions\CouldNotSendNotification
*/
public function send($notifiable, Notification $notification)
{
if (!$userIds = $notifiable->devices()->where('platform', 'web')->pluck('uuid')->toArray()) {
return;
}
/** #var ResponseInterface $response */
$response = $this->oneSignal->sendNotificationCustom(
$this->payload($notifiable, $notification, $userIds)
);
if ($response->getStatusCode() !== 200) {
throw CouldNotSendNotification::serviceRespondedWithAnError($response);
}
return $response;
}
}
In both of these channel only the difference is that in __constructwe load different keys for both Reseller and Merchant
public function __construct()
{
$client = new OneSignalClient(
env("ONESIGNAL_RESELLER_APP_ID"),
env("ONESIGNAL_RESELLER_REST_API_KEY"),
''
);
parent::__construct($client);
}
And this is the Nofications/Base.php where i've load both ResellerWeb and MerchantWeb Notification in via methods
public function via($notifiable)
{
return [
'database',
'broadcast',
ResellerWeb::class,
MerchantWeb::class,
];
}
I want to optimize the norification where instead of loading MerchantWeb::class and ResellerWeb::cass i want to create and load a general channel lets say NotificationWeb::class and want to use it for both Reseller and Merchant. And when i use it i will need to switch the env() keys based on for which i use.
How can this be achieved

retrive relation table in login request with laravel breeze

Hello I want to include my relation table roles when I login. I used Laravel Breeze for authentication.
Models/User.php
namespace App\Models;
use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
use Laravel\Sanctum\HasApiTokens;
class User extends Authenticatable
{
use HasApiTokens, HasFactory, Notifiable;
/**
* The attributes that are mass assignable.
*
* #var string[]
*/
protected $fillable = [
'name',
'email',
'password',
];
/**
* The attributes that should be hidden for serialization.
*
* #var array
*/
protected $hidden = [
'password',
'remember_token',
];
/**
* The attributes that should be cast.
*
* #var array
*/
protected $casts = [
'email_verified_at' => 'datetime',
];
//old
public function bookmarks(){
return $this->hasMany('App\Model\Post','post_bookmarks','user_id','post_id')->get();
}
public function roles(){
return $this->belongsTo('App\Models\Roles','roles','role_id','id');
}
}
AuthenticatedSessionController.php
namespace App\Http\Controllers\Auth;
use App\Http\Controllers\Controller;
use App\Http\Requests\Auth\LoginRequest;
use App\Providers\RouteServiceProvider;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
class AuthenticatedSessionController extends Controller
{
/**
* Display the login view.
*
* #return \Illuminate\View\View
*/
public function create()
{
return view('auth.login');
}
/**
* Handle an incoming authentication request.
*
* #param \App\Http\Requests\Auth\LoginRequest $request
* #return \Illuminate\Http\RedirectResponse
*/
public function store(LoginRequest $request)
{
$request->authenticate();
$request->session()->regenerate();
return redirect()->intended(RouteServiceProvider::HOME);
}
/**
* Destroy an authenticated session.
*
* #param \Illuminate\Http\Request $request
* #return \Illuminate\Http\RedirectResponse
*/
public function destroy(Request $request)
{
Auth::guard('web')->logout();
$request->session()->invalidate();
$request->session()->regenerateToken();
return redirect('/');
}
}
LoginRequest.php
namespace App\Http\Requests\Auth;
use Illuminate\Auth\Events\Lockout;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\RateLimiter;
use Illuminate\Support\Str;
use Illuminate\Validation\ValidationException;
class LoginRequest extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
*
* #return bool
*/
public function authorize()
{
return true;
}
/**
* Get the validation rules that apply to the request.
*
* #return array
*/
public function rules()
{
return [
'email' => ['required', 'string', 'email'],
'password' => ['required', 'string'],
];
}
/**
* Attempt to authenticate the request's credentials.
*
* #return void
*
* #throws \Illuminate\Validation\ValidationException
*/
public function authenticate()
{
$this->ensureIsNotRateLimited();
if (! Auth::attempt($this->only('email', 'password'), $this->boolean('remember'))) {
RateLimiter::hit($this->throttleKey());
throw ValidationException::withMessages([
'email' => __('auth.failed'),
]);
}
RateLimiter::clear($this->throttleKey());
}
/**
* Ensure the login request is not rate limited.
*
* #return void
*
* #throws \Illuminate\Validation\ValidationException
*/
public function ensureIsNotRateLimited()
{
if (! RateLimiter::tooManyAttempts($this->throttleKey(), 5)) {
return;
}
event(new Lockout($this));
$seconds = RateLimiter::availableIn($this->throttleKey());
throw ValidationException::withMessages([
'email' => trans('auth.throttle', [
'seconds' => $seconds,
'minutes' => ceil($seconds / 60),
]),
]);
}
/**
* Get the rate limiting throttle key for the request.
*
* #return string
*/
public function throttleKey()
{
return Str::lower($this->input('email')).'|'.$this->ip();
}
}
I have used Laravel-breeze for the authentication. It's all working fine but I want to add Role name also when user gets login. As you can see I have also used relationship but I'm confused where can I write the code to get my relation table. This is my code, Can anyone please tell me how can I do?
For Ex.
login email: poojan#gmail.com
role_id = 1
in roles table
id: 1, role_name = "Wholseler"
So when I logged in currently I'm getting user data, But I want roles table data too.
Thanks in Advance
you can use attribute in your user model
protected $appends = ['role_name'];
public function getRoleNameAttribute()
{
return $this->roles->first()->role_name ?? 'N/A';
}
using the above code you will get the role_name attribute in the user instance
if you want roles data into relations of user data try this in user model
protected $with = ['roles'];

Date and Time localization not works in Laravel-mix

I have Laravel mix installed on my server. there is a chat part on website and I use some kind of class :
class ActivityCell extends Component {
getTimestamp() {
const {message} = this.props;
return (
<span className="font-weight-semi-bold">
{utcDateCalendarTime(message.created_at)}
</span>
);
}
And here is my AppServiceProvider.php file :
<?php
namespace App\Providers;
use Illuminate\Http\Resources\Json\Resource;
use Illuminate\Support\Facades\File;
use Illuminate\Support\Facades\Schema;
use Illuminate\Support\ServiceProvider;
class AppServiceProvider extends ServiceProvider
{
/**
* Register any application services.
*
* #return void
*/
public function boot()
{
setlocale(LC_ALL, Config::get('app.lc_all'));
Carbon::setLocale(Config::get('app.locale'));
}
public function register()
{
$this->registerPlugins();
}
/**
* Bootstrap any application services.
*
* #return void
*/
public function boot()
{
$this->bootDatabase();
$this->bootResource();
}
/**
* Boot database schema
*
* #return void
*/
private function bootDatabase()
{
Schema::defaultStringLength(191);
}
/**
* Boot resource
*
* #return void
*/
private function bootResource()
{
Resource::withoutWrapping();
}
/**
* Register plugins
*
* #return void
*/
private function registerPlugins()
{
$pluginDirs = File::directories(base_path('app/Plugins'));
foreach ($pluginDirs as $pluginDir) {
$class = "App\\Plugins\\" . basename($pluginDir) . "\\PluginServiceProvider";
if (class_exists($class) && is_subclass_of($class, ServiceProvider::class)) {
$this->app->register($class);
}
}
}
}
I tried to put setlocale(LC_TIME, 'tr'); on top of the class file but there is no success. Then tried to use carbon in order to make the date is viewed in different languages when I change the website language.
I added the following codes in app/config.php :
'locale' => env('APP_LOCALE', 'az'),
'lc_all' => env('APP_LC_ALL', 'az_AZ.UTF-8'),
and added following to the env file :
APP_LOCALE = az
APP_LC_ALL = az_AZ.UTF-8
in both methods, I was not successful. I am pretty sure that I am doing a mistake somewhere but can not find where exactly. Maybe I am missing to add something else to add. Any help would be highly appreciated.
EDIT : Adding Chat.php :
<?php
namespace App\Models;
use App\Events\ChatParticipationChanged;
use App\Events\ChatUpdated;
use App\Http\Resources\ChatMessage as ChatMessageResource;
use App\Http\Resources\MarketplaceTrade as MarketplaceTradeResource;
use ArrayObject;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Str;
use JSsVPSDioNXpfRC;
use DateTimeInterface;
class Chat extends Model
{
protected $lastMessageAttribute;
protected $lastMarketplaceTradeAttribute;
/**
* The attributes that aren't mass assignable.
*
* #var array
*/
protected $guarded = [];
/**
* The event map for the model.
*
* #var array
*/
protected $dispatchesEvents = [
'updated' => ChatUpdated::class
];
/**
* Indicates if the IDs are auto-incrementing.
*
* #var bool
*/
public $incrementing = false;
/**
* Get the route key for the model.
*
* #return string
*/
protected function serializeDate(DateTimeInterface $date)
{
return $date->translatedFormat('A B M');
}
public function getRouteKeyName()
{
return 'id';
}
/**
* #return \Illuminate\Database\Eloquent\Relations\BelongsTo
*/
public function creator()
{
return $this->belongsTo(User::class, 'creator_id', 'id');
}
/**
* Participants for this chat
*
* #return \Illuminate\Database\Eloquent\Relations\HasMany
*/
public function participants()
{
return $this->hasMany(ChatParticipant::class, 'chat_id', 'id');
}
/**
* Messages for this chat
*
* #return \Illuminate\Database\Eloquent\Relations\HasMany
*/
public function messages()
{
return $this->hasMany(ChatMessage::class, 'chat_id', 'id');
}
/**
* Update user's participation record
*
* #param User $user
*/
public function updateParticipation($user)
{
$this->participants()->where('user_id', $user->id)
->update(['last_read_at' => now()]);
broadcast(new ChatParticipationChanged($this, $user));
}
/**
* All marketplace trades hosted by this chat
*
* #return \Illuminate\Database\Eloquent\Relations\HasMany
*/
public function marketplaceTrades()
{
return $this->hasMany(MarketplaceTrade::class, 'chat_id', 'id')
->has('buyer')->has('seller');
}
/**
* #return Model|\Illuminate\Database\Eloquent\Relations\HasMany|mixed|object|null
*/
public function getLatestMarketplaceTrade()
{
if (!isset($this->lastMarketplaceTradeAttribute)) {
$trade = $this->marketplaceTrades()->latest()->first();
$this->lastMarketplaceTradeAttribute = new MarketplaceTradeResource($trade);
}
return $this->lastMarketplaceTradeAttribute;
}
/**
* Last chat message
*
* #return ChatMessageResource|ArrayObject|mixed
*/
public function getLatestMessage()
{
if (!isset($this->lastMessageAttribute)) {
$message = $this->messages()->latest()->first();
if ($message) {
$this->lastMessageAttribute = new ChatMessageResource($message);
} else {
$this->lastMessageAttribute = new ArrayObject();
}
}
return $this->lastMessageAttribute;
}
/**
* #param User $user
* #return array
*/
public function getParticipation($user)
{
$participant = $this->participants()
->where('user_id', $user->id)->without('user')
->first();
$unreadMessagesCount = ($participant && $participant->last_read_at) ?
$this->messages()->where('user_id', '!=', $user->id)
->where('created_at', '>', $participant->last_read_at)
->count() :
$this->messages()->where('user_id', '!=', $user->id)
->count();
return [
'user_id' => $user->id,
'unread_messages_count' => $unreadMessagesCount
];
}
/**
* If user should be allowed in this chat
*
* #param User $user
* #return bool
*/
public function shouldAllowUser($user)
{
$isParticipant = $this->participants()
->where('user_id', $user->id)->exists();
return (
$isParticipant ||
$user->can('moderate_chats')
);
}
/**
* #return string
*/
public function attachmentsDir()
{
return "chats/{$this->id}/message-attachments";
}
}
The problem is on your namespace :
// Using PHP callable syntax
use Carbon\Carbon;
Or,
// Using string syntax
\Carbon\Carbon::setLocale('ru');
You also need to use translatedFormat() method on your blade for use the translate format, like :
{{ Carbon\Carbon::now()->translatedFormat('A B M') }} // утра 428 фев
You can use serializeDate() method on your model, to change timestamp column as a translated dataTime format :
use DateTimeInterface;
protected function serializeDate(DateTimeInterface $date)
{
return $date->translatedFormat('A B M');
}

Single page application notification problem

I have a single page application. I use a vuejs as a front-end and laravel 5.7 as a backend. I'm using a webPush and service worker to push notifications to users. The problem is when the user is offline and return back online a lot of notifications are pushed. I need to push only the last notifications in service worker queue and the number of other notifications in the queue.
//Listen to Push from service worker file
self.addEventListener('push', (e) => {
let data
if (e.data) {
data = e.data.json()
}
const options = {
body: data.body,
icon: '/images/fav/android-icon-192x192.png',
image: '/storage/users'+data.image||'/images/profiles/profile.png',
badge: '/images/fav/android-icon-96x96.png',
actions:data.actions,
data:data.data
}
e.waitUntil(self.registration.showNotification(data.title, options))
});
self.addEventListener('notificationclick', function(event) {
var url = event.notification.data.location;
event.waitUntil(
clients.matchAll({type: 'window'}).then( windowClients => {
for (var i = 0; i < windowClients.length; i++) {
var client = windowClients[i];
if (client.url === url && 'focus' in client) {
return client.focus();
}
}
if (clients.openWindow) {
return clients.openWindow(url);
}
})
);
});
//User model
<?php
namespace App;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
use Tymon\JWTAuth\Contracts\JWTSubject;
use NotificationChannels\WebPush\HasPushSubscriptions;
class User extends Authenticatable implements JWTSubject
{
use Notifiable;
use HasPushSubscriptions;
/**
* The attributes that are mass assignable.
*
* #var array
*/
protected $fillable = [
'fname','lname',"username", 'email', 'password',"code","active"
];
protected $guard_name = 'api';
/**
* The attributes that should be hidden for arrays.
*
* #var array
*/
protected $hidden = [
'password', 'remember_token',
];
// Rest omitted for brevity
/**
* Get the identifier that will be stored in the subject claim of the JWT.
*
* #return mixed
*/
public function getJWTIdentifier()
{
return $this->getKey();
}
/**
* Return a key value array, containing any custom claims to be added to the JWT.
*
* #return array
*/
public function getJWTCustomClaims()
{
return [];
}
}
//example for notification class
<?php
namespace App\Notifications;
use App\PostEvent;
use App\User;
use Illuminate\Bus\Queueable;
use Illuminate\Notifications\Notification;
use Illuminate\Contracts\Queue\ShouldQueue;
use NotificationChannels\WebPush\WebPushChannel;
use NotificationChannels\WebPush\WebPushMessage;
class interestEvent extends Notification implements ShouldQueue
{
use Queueable;
/**
* Create a new notification instance.
*
* #return void
*/
public $event;
public $user;
public function __construct(PostEvent $event,User $user)
{
$this->event=$event;
$this->user=$user;
}
/**
* Get the notification's delivery channels.
*
* #param mixed $notifiable
* #return array
*/
public function via($notifiable)
{
return ['database','broadcast',WebPushChannel::class];
}
public function toDatabase($notifiable)
{
$message="event you are interested in will begin tomorrow";
$name=$this->user->fname;
if($name){
$name .=" ".$this->user->lname;
}
else
{
$name=$this->user->username;
}
return [
'user_id' => $this->user->id,
"name"=>$name,
'message' => $message,
'image'=>$this->user->image,
'post_id'=>$this->event->post_id,
'eventName'=>$this->event->name,
];
}
/**
* Get the array representation of the notification.
*
* #param mixed $notifiable
* #return array
*/
public function toArray($notifiable)
{
$message="event you are interested in will begin tomorrow";
$name=$this->user->fname;
if($name){
$name .=" ".$this->user->lname;
}
else
{
$name=$this->user->username;
}
return [
'id' => $this->id,
'read_at' => null,
'data' => [
'user_id' => $this->user->id,
'message' => $message,
"name"=>$name,
'image'=>$this->user->image,
'post_id'=>$this->event->post_id,
'eventName'=>$this->event->name,
'location'=>"/home/posts/".$this->event->post_id
],
];
}
public function toWebPush($notifiable, $notification)
{
$message="event you are interested in will begin tomorrow";
$name=$this->user->fname;
if($name){
$name .=" ".$this->user->lname;
}
else
{
$name=$this->user->username;
}
$message="(".$this->event->name.") ".$message;
return (new WebPushMessage)
->title('Ajwbtcom')
->body($message)
->action('See Event', "/home/posts/".$this->event->post_id)
->image($this->user->image)
->data( [
'user_id' => $this->user->id,
'message' => $message,
"name"=>$name,
'image'=>$this->user->image,
'post_id'=>$this->event->post_id,
'eventName'=>$this->event->name,
'location'=>"/home/posts/".$this->event->post_id
]);
}
}
You can use the tag option when you call showNotification in order to display only the last notification:
https://notifications.spec.whatwg.org/#using-the-tag-member-for-a-single-instance

Limit sending email Laravel in once schedule task

I have problem with limit email exchange from SMTP. I have counting table with specific column. total is 201. that total will send email automatic with schedule task on the server.
Counting TOTAL
can I send email per batch using laravel as much as 201 email in once send email?
cronEmail
/**
* The name and signature of the console command.
*
* #var string
*/
protected $signature = 'email:reminder';
/**
* The console command description.
*
* #var string
*/
protected $description = 'Command description';
/**
* Create a new command instance.
*
* #return void
*/
public function __construct()
{
parent::__construct();
}
/**
* Execute the console command.
*
* #return mixed
*/
public function handle()
{
$this->updateMailConfig();
$check = DB::table('a_kpi')->join('d_mem','k_created_by','m_id')
->leftjoin('a_kpid','kd_kpi_id','k_id')
->where('k_status_id',1)
->where(function($query){
$query->where('kd_status_id','=','In Progress')
->orwhere('kd_status_id','=',null)
->orwhere('kd_status_id','=')
->orwhere('kd_status_id','=','null')
->orwhere('kd_status_id','=',"null");
})
->get();
$dt = date("Y-m-d");
$dtdt = date( "Y-m-d", strtotime( "$dt +10 day" ) );
for ($i=0; $i <count($check); $i++) {
if ($check[$i]->kd_duedate == $dtdt) {
$mail = $check[$i]->m_email;
Mail::send('mail.tes',
['pesan' => 'KPI INFORMATION',
'k_label' => $check[$i]->k_label,
'kd_tacticalstep' => $check[$i]->kd_tacticalstep,
'kd_duedate' => $check[$i]->kd_duedate],
function ($message) use ($mail)
{
$message->subject('REMINDER');
$message->to($mail);
});
$data = DB::table('d_log_reminder')
->insert([
'dlr_id'=>$check[$i]->k_id,
'dlr_kpi_id'=>$check[$i]->k_id,
'dlr_kpid_id'=>$check[$i]->kd_id,
'dlr_tacticalstep'=>$check[$i]->kd_tacticalstep,
'dlr_label'=>$check[$i]->k_label,
'dlr_duedate'=>$check[$i]->kd_duedate,
'dlr_created_by'=>$check[$i]->k_created_by,
'dlr_send_to'=>$mail
]);
}
}
// $check = DB::table('d_mem')->where('m_username','admin')->update(['m_code'=>'cor'.date('d-m-y h:i:s')]);
}
}
Kernel.php
<?php
namespace App\Console;
use Illuminate\Console\Scheduling\Schedule;
use App\Helper\ConfigUpdater;
use Mail;
use DB;
use Illuminate\Foundation\Console\Kernel as ConsoleKernel;
class Kernel extends ConsoleKernel
{
use ConfigUpdater;
/**
* The Artisan commands provided by your application.
*
* #var array
*/
protected $commands = [
'App\Console\Commands\cronEmail'
//
];
/**
* Define the application's command schedule.
*
* #param \Illuminate\Console\Scheduling\Schedule $schedule
* #return void
*/
protected function schedule(Schedule $schedule)
{
$schedule->command('email:reminder')
->everyMinute();
}
/**
* Register the Closure based commands for the application.
*
* #return void
*/
protected function commands()
{
require base_path('routes/console.php');
}
}

Resources