2

I am trying to develop a notification system, but I am not sure if I do certain parts correctly. To simplify the case I will use some generic naming.

How the system should work:

  1. A registered user can subscribe for notifications based on chosen filters from a data table grid. ( for example, notify me when the quantity of an item is X, or have multiple filters set up like set1.slug.quantity > X, some_value = false and some_int = 52)

How I store such preferences:

Example object

"O:8:"stdClass":2:{s:9:"set1.slug";a:1:{s:3:"$eq";s:10:"item_slug1";}s:13:"set1.quantity";a:1:{s:4:"$gte";i:1;}}"

Generation simplified

$object = new \stdClass();
$object->{'set1.slug'} = ['$eq' => 'item_slug1'];
$object->{'set1.quantity'} = ['$gte' => 1];
$object = serialize($object);

It attaches also the user_id and all the data serialized from the form to a partial MongoDB raw query.

Database stored object - predefined filter set for a user. Md is an md5 hash of the object for easier access and edit.

+----+-----------------------------------------------------------------------------------------------------------------+---------+----------------------------------+
| id |                                                     object                                                      | user_id |                md                |
+----+-----------------------------------------------------------------------------------------------------------------+---------+----------------------------------+
|  1 | O:8:"stdClass":2:{s:9:"set1.slug";a:1:{s:3:"$eq";s:10:"item_slug1";}s:13:"set1.quantity";a:1:{s:4:"$gte";i:1;}} |      22 | d5003ba3227c4db3189827329815b053 |
+----+-----------------------------------------------------------------------------------------------------------------+---------+----------------------------------+

This is how I would use it - my vision of how it would work.

I would call findByFilterMD in the API parser in a loop, while the table Items is populated.

// MongoDB query ( items database )
protected function executeUserFilter($array)
{
    $list = Items::raw(function ($collection) use (&$array) {
        return $collection->find(
            $array, ["typeMap" => ['root' => 'array', 'document' => 'array']])
            ->toArray();
    });

    return $list;
}

// MySQL query - stored filters
protected function findByFilterMD($id)
{
    $user = Auth::user();
    $filter = PredefinedFilters::where('md', '=', $id)->first();
    $deserialize = unserialize($filter->object);

    $results = $this->executeUserFilter($deserialize);
    // here would probably be a notification function like pusher or onesignal
}

I am aware that my attempt of achieving this might be totally wrong and I might reinvent the wheel since some tools might do that already.

Here is an example Item MongoDB object

{
    "_id": {
        "$oid": "5c0406abdc04e7007f17f4ef"
    },
    "name": "myObject",
    "inner_ID": "0db0b19a-9c01-4c21-8e10-6879dbcb37f1",
    "some_value": false,
    "some_int": 52,
    "set1": [
        {
            "slug": "item_slug1",
            "quantity": 88,
            "extra": {
                "value": 0
            }
        },
    ],
    "set2": [
        {
            "slug": "item_slug2",
            "quantity": 88,
            "extra": {
                "value": 0
            }
        },
        {
            "slug": "item_slug3",
            "quantity": 88,
            "extra": {
                "value": 0
            }
        }
    ],
    "expires": "2018-12-02 22:21:30"
}

Here comes my questions

  • Is this way of doing it proper?
  • Where should the notification system kick in? I assume it might be in the place where I parse the api of items, then I should loop over the user filter data and run the stored object query - or should it be a separate system called with cron?

I am open to any suggestions, redesigns.

Karl Hill
  • 12,937
  • 5
  • 58
  • 95
Kavvson Empcraft
  • 445
  • 7
  • 32

1 Answers1

0

I developed an app kinda like this. My approach is to make use of Laravel notification found here: https://laravel.com/docs/5.7/notifications#creating-notifications

Let's say, in your case, if someone modify/create data, the other users who subscribe will get notification.

  1. Create notification
php artisan make:notification UserUpdateQuantity
  1. Make User model notifiable, also create scope that subscribe for something
<?php

namespace App;

use Illuminate\Notifications\Notifiable;
use Illuminate\Foundation\Auth\User as Authenticatable;

class User extends Authenticatable
{
    use Notifiable;

    public function scopeSubscribe($query) 
    {
        return $query->where('subscribe', true);
    }
}

the $query in method scopeSubscribe needs to be adjusted based on your business logic

  1. Send notification
$subscriber = User::subscribe()->get();
Notification::send($subscriber, new UserUpdateQuantity());
  1. Create event & listener

You can find the event and listener here https://laravel.com/docs/5.7/events

In the EventServiceProvider

protected $listen = [
    'App\Events\QuantityUpdated' => [
        'App\Listeners\SendUpdateQuantiryNotification',
    ],
];

Then run the command php artisan event:generate

  1. Event listener

In the event listener, we send notification

public function handle(QuantityUpdated $event)
{
    $subscriber = User::subscribe()->get();
    Notification::send($subscriber, new UserUpdateQuantity());
}
  1. Eloquent event

Add event on your eloquent model, so when someone update quantity, it triggers event and the listener will send notification to subscribed users

// In your model
protected $dispatchesEvents = [
    'updated' => App\Events\QuantityUpdated::class
];
louisfischer
  • 1,968
  • 2
  • 20
  • 38
tirta keniten
  • 397
  • 4
  • 13