Skip to content

Instantly share code, notes, and snippets.

@mrunknown0001
Last active July 16, 2025 23:18
Show Gist options
  • Select an option

  • Save mrunknown0001/ceafd5c0dbb94ef40f574fd54bcff6a6 to your computer and use it in GitHub Desktop.

Select an option

Save mrunknown0001/ceafd5c0dbb94ef40f574fd54bcff6a6 to your computer and use it in GitHub Desktop.
Laravel Livewire NotificationHelper Trait and NotificationService for php-flasher

Example How to Use

<?php

namespace App\Http\Controllers;

use App\Traits\NotificationHelper;
use App\Services\NotificationService;

class MyController extends Controller
{
    use NotificationHelper;

    public showNotification()
    {
      $this->flashNotification('Notification Message', 'success'); // success, info, error, warning
    }
}
<?php
namespace App\Traits;
use App\Services\NotificationService;
trait NotificationHelper
{
/**
* Send a flasher notification with duplicate prevention
*/
public function flashNotification($message, $type = 'success', $options = [])
{
return NotificationService::flash($message, $type, $options);
}
/**
* Send a browser event notification with duplicate prevention
*/
public function browserNotification($event, $title, $text = '', $icon = 'info')
{
return NotificationService::browserEvent($this, $event, $title, $text, $icon);
}
/**
* Display success notification
*/
public function displaySuccess($title, $text = '', $useFlasher = false)
{
if ($useFlasher) {
$this->flashNotification($text ?: $title, 'success');
} else {
$this->browserNotification('sales-notif', $title, $text, 'success');
}
}
/**
* Display error notification
*/
public function displayError($title, $text = '', $useFlasher = false)
{
if ($useFlasher) {
$this->flashNotification($text ?: $title, 'error');
} else {
$this->browserNotification('sales-notif', $title, $text, 'error');
}
}
/**
* Display warning notification
*/
public function displayWarning($title, $text = '', $useFlasher = false)
{
if ($useFlasher) {
$this->flashNotification($text ?: $title, 'warning');
} else {
$this->browserNotification('sales-notif', $title, $text, 'warning');
}
}
/**
* Display info notification
*/
public function displayInfo($title, $text = '', $useFlasher = false)
{
if ($useFlasher) {
$this->flashNotification($text ?: $title, 'info');
} else {
$this->browserNotification('sales-notif', $title, $text, 'info');
}
}
/**
* Clear notification tracking for current request
*/
public function clearNotificationTracking()
{
self::$shownNotifications = [];
}
/**
* Clean up expired session notifications
*/
public function cleanupExpiredNotifications()
{
$keys = Session::all();
foreach ($keys as $key => $value) {
if (strpos($key, '_expires') !== false) {
if (time() > $value) {
$baseKey = str_replace('_expires', '', $key);
Session::forget($baseKey);
Session::forget($key);
}
}
}
}
}
<?php
namespace App\Services;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\Session;
class NotificationService
{
private static $sessionKey = 'shown_notifications';
private static $cachePrefix = 'notif_';
private static $duplicateWindow = 10; // seconds
/**
* Send flasher notification with duplicate prevention
*/
public static function flash($message, $type = 'success', $options = [])
{
// Create unique identifier
$identifier = self::createIdentifier($message, $type);
// Check if already shown
if (self::isRecentlyShown($identifier)) {
return false;
}
// Mark as shown
self::markAsShown($identifier);
// Default options
$defaultOptions = [
'timeout' => 5000,
'position' => 'top-right',
];
$options = array_merge($defaultOptions, $options);
// Send notification
flasher($message, $type, $options);
return true;
}
/**
* Send browser event notification with duplicate prevention
*/
public static function browserEvent($component, $event, $title, $text = '', $icon = 'info')
{
// Create unique identifier
$identifier = self::createIdentifier($title . $text, $icon);
// Check if already shown
if (self::isRecentlyShown($identifier)) {
return false;
}
// Mark as shown
self::markAsShown($identifier);
// Dispatch event
$component->dispatchBrowserEvent($event, [
'title' => $title,
'text' => $text,
'icon' => $icon,
'timestamp' => time(),
'identifier' => $identifier
]);
return true;
}
/**
* Create unique identifier for notification
*/
private static function createIdentifier($message, $type)
{
return md5($message . $type . auth()->id());
}
/**
* Check if notification was recently shown
*/
private static function isRecentlyShown($identifier)
{
// Check cache first (faster)
$cacheKey = self::$cachePrefix . $identifier;
if (Cache::has($cacheKey)) {
return true;
}
// Check session as fallback
$shown = Session::get(self::$sessionKey, []);
if (isset($shown[$identifier])) {
$timestamp = $shown[$identifier];
if ((time() - $timestamp) < self::$duplicateWindow) {
return true;
} else {
// Remove expired entry
unset($shown[$identifier]);
Session::put(self::$sessionKey, $shown);
}
}
return false;
}
/**
* Mark notification as shown
*/
private static function markAsShown($identifier)
{
$timestamp = time();
// Store in cache (more reliable)
$cacheKey = self::$cachePrefix . $identifier;
Cache::put($cacheKey, $timestamp, self::$duplicateWindow);
// Store in session as backup
$shown = Session::get(self::$sessionKey, []);
$shown[$identifier] = $timestamp;
// Clean old entries (keep only last 10)
if (count($shown) > 10) {
$shown = array_slice($shown, -10, 10, true);
}
Session::put(self::$sessionKey, $shown);
}
/**
* Clear all notification tracking
*/
public static function clearAll()
{
Session::forget(self::$sessionKey);
// Clear cache entries (this is approximate)
$shown = Session::get(self::$sessionKey, []);
foreach (array_keys($shown) as $identifier) {
Cache::forget(self::$cachePrefix . $identifier);
}
}
/**
* Clean up expired entries
*/
public static function cleanup()
{
$shown = Session::get(self::$sessionKey, []);
$currentTime = time();
$cleaned = [];
foreach ($shown as $identifier => $timestamp) {
if (($currentTime - $timestamp) < self::$duplicateWindow) {
$cleaned[$identifier] = $timestamp;
}
}
Session::put(self::$sessionKey, $cleaned);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment