Browse Source

Message notification design

moell 11 months ago
parent
commit
6befacefb3

+ 46 - 0
app/Events/ObjectActionCreate.php

@@ -0,0 +1,46 @@
+<?php
+
+namespace App\Events;
+
+use App\Models\Action;
+use App\Models\Config;
+use App\Models\Enums\ConfigGroup;
+use Illuminate\Broadcasting\Channel;
+use Illuminate\Broadcasting\InteractsWithSockets;
+use Illuminate\Broadcasting\PresenceChannel;
+use Illuminate\Broadcasting\PrivateChannel;
+use Illuminate\Contracts\Broadcasting\ShouldBroadcast;
+use Illuminate\Foundation\Events\Dispatchable;
+use Illuminate\Queue\SerializesModels;
+
+class ObjectActionCreate
+{
+    use Dispatchable, InteractsWithSockets, SerializesModels;
+
+    public array $notificationSetting = [];
+
+    /**
+     * Create a new event instance.
+     */
+    public function __construct(public Action $action)
+    {
+        $settingResult = Config::query()
+            ->where("group", ConfigGroup::MESSAGE_NOTIFICATION)
+            ->where("key", "setting")
+            ->first();
+
+        $this->notificationSetting = $settingResult ? json_decode($settingResult->value, true) : [];
+    }
+
+    /**
+     * Get the channels the event should broadcast on.
+     *
+     * @return array<int, \Illuminate\Broadcasting\Channel>
+     */
+    public function broadcastOn(): array
+    {
+        return [
+            new PrivateChannel('channel-name'),
+        ];
+    }
+}

+ 39 - 0
app/Listeners/SendActionBrowserNotification.php

@@ -0,0 +1,39 @@
+<?php
+
+namespace App\Listeners;
+
+use App\Events\ObjectActionCreate;
+use App\Models\Enums\ActionObjectType;
+use App\Models\Enums\ObjectAction;
+use Illuminate\Contracts\Queue\ShouldQueue;
+use Illuminate\Queue\InteractsWithQueue;
+
+class SendActionBrowserNotification implements ShouldQueue
+{
+    /**
+     * Create the event listener.
+     */
+    public function __construct()
+    {
+        //
+    }
+
+    /**
+     * Handle the event.
+     */
+    public function handle(ObjectActionCreate $event): void
+    {
+
+    }
+
+    public function shouldQueue(ObjectActionCreate $event): bool
+    {
+        $actionObjectType = ActionObjectType::tryFrom($event->action->object_type);
+        $objectAction = ObjectAction::tryFrom($event->action->action);
+        if (! $actionObjectType || !$objectAction) {
+            return false;
+        }
+
+        return in_array($objectAction->value, $event->notificationSetting[$actionObjectType->value]['email'] ?? []);
+    }
+}

+ 39 - 0
app/Listeners/SendActionEmailNotification.php

@@ -0,0 +1,39 @@
+<?php
+
+namespace App\Listeners;
+
+use App\Events\ObjectActionCreate;
+use App\Models\Enums\ActionObjectType;
+use App\Models\Enums\ObjectAction;
+use Illuminate\Contracts\Queue\ShouldQueue;
+use Illuminate\Queue\InteractsWithQueue;
+
+class SendActionEmailNotification implements ShouldQueue
+{
+    /**
+     * Create the event listener.
+     */
+    public function __construct()
+    {
+        //
+    }
+
+    /**
+     * Handle the event.
+     */
+    public function handle(ObjectActionCreate $event): void
+    {
+
+    }
+
+    public function shouldQueue(ObjectActionCreate $event): bool
+    {
+        $actionObjectType = ActionObjectType::tryFrom($event->action->object_type);
+        $objectAction = ObjectAction::tryFrom($event->action->action);
+        if (! $actionObjectType || !$objectAction) {
+            return false;
+        }
+
+        return in_array($objectAction->value, $event->notificationSetting[$actionObjectType->value]['email'] ?? []);
+    }
+}

+ 1 - 1
app/Models/Enums/ActionObjectType.php

@@ -17,7 +17,7 @@ enum ActionObjectType: string
 
     case PROJECT = "project";
 
-    case REQUIREMENT="requirement";
+    case REQUIREMENT = "requirement";
 
     case TASK = "task";
 

+ 54 - 0
app/Notifications/TaskAction.php

@@ -0,0 +1,54 @@
+<?php
+
+namespace App\Notifications;
+
+use Illuminate\Bus\Queueable;
+use Illuminate\Contracts\Queue\ShouldQueue;
+use Illuminate\Notifications\Messages\MailMessage;
+use Illuminate\Notifications\Notification;
+
+class TaskAction extends Notification
+{
+    use Queueable;
+
+    /**
+     * Create a new notification instance.
+     */
+    public function __construct()
+    {
+        //
+    }
+
+    /**
+     * Get the notification's delivery channels.
+     *
+     * @return array<int, string>
+     */
+    public function via(object $notifiable): array
+    {
+        return ['mail'];
+    }
+
+    /**
+     * Get the mail representation of the notification.
+     */
+    public function toMail(object $notifiable): MailMessage
+    {
+        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.
+     *
+     * @return array<string, mixed>
+     */
+    public function toArray(object $notifiable): array
+    {
+        return [
+            //
+        ];
+    }
+}

+ 6 - 1
app/Providers/EventServiceProvider.php

@@ -2,6 +2,8 @@
 
 namespace App\Providers;
 
+use App\Events\ObjectActionCreate;
+use App\Listeners\SendActionEmailNotification;
 use Illuminate\Auth\Events\Registered;
 use Illuminate\Auth\Listeners\SendEmailVerificationNotification;
 use Illuminate\Foundation\Support\Providers\EventServiceProvider as ServiceProvider;
@@ -25,7 +27,10 @@ class EventServiceProvider extends ServiceProvider
      */
     public function boot(): void
     {
-        //
+        Event::listen(
+            ObjectActionCreate::class,
+            [SendActionEmailNotification::class, 'handle']
+        );
     }
 
     /**

+ 4 - 1
app/Repositories/ActionRepository.php

@@ -2,6 +2,7 @@
 
 namespace App\Repositories;
 
+use App\Events\ObjectActionCreate;
 use App\Models\Action;
 use App\Models\Enums\ActionObjectType;
 use App\Models\Enums\ObjectAction;
@@ -28,7 +29,7 @@ class ActionRepository
         $action = Action::query()->create([
             "object_id" => $objectId,
             "object_type" => $objectType->value,
-            "action" => $action,
+            "action" => $action->value,
             "project_id" => $projectId,
             "comment" => $comment,
             "extra_fields" => $extraFields ?: null,
@@ -39,6 +40,8 @@ class ActionRepository
             History::query()->insert(array_map(fn($change) => [...$change, 'action_id' => $action->id], $objectChanges));
         }
 
+        ObjectActionCreate::dispatch($action);
+
         return $action;
     }
 

+ 34 - 0
database/migrations/2024_04_07_211410_create_notifications_table.php

@@ -0,0 +1,34 @@
+<?php
+
+use Illuminate\Database\Migrations\Migration;
+use Illuminate\Database\Schema\Blueprint;
+use Illuminate\Support\Facades\Schema;
+
+return new class extends Migration
+{
+    /**
+     * Run the migrations.
+     */
+    public function up(): void
+    {
+        Schema::create('notifications', function (Blueprint $table) {
+            $table->id();
+            $table->string('object_type', 30);
+            $table->integer('object_id')->default(0);
+            $table->text('content');
+            $table->timestamp("start_at")->nullable();
+            $table->timestamp("end_at")->nullable();
+            $table->integer("created_by")->nullable();
+            $table->string("announcement_status")->nullable();
+            $table->timestamps();
+        });
+    }
+
+    /**
+     * Reverse the migrations.
+     */
+    public function down(): void
+    {
+        Schema::dropIfExists('notifications');
+    }
+};