NotificationPreferenceController::__construct()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 0

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 0
c 0
b 0
f 0
dl 0
loc 3
rs 10
cc 1
nc 1
nop 1
1
<?php
2
3
namespace Usamamuneerchaudhary\Notifier\Http\Controllers;
4
5
use Illuminate\Http\JsonResponse;
6
use Illuminate\Routing\Controller;
7
use Illuminate\Support\Facades\Auth;
8
use Usamamuneerchaudhary\Notifier\Http\Requests\UpdatePreferenceRequest;
9
use Usamamuneerchaudhary\Notifier\Models\NotificationChannel;
10
use Usamamuneerchaudhary\Notifier\Models\NotificationEvent;
11
use Usamamuneerchaudhary\Notifier\Models\NotificationPreference;
12
use Usamamuneerchaudhary\Notifier\Models\NotificationSetting;
13
use Usamamuneerchaudhary\Notifier\Services\PreferenceService;
14
15
class NotificationPreferenceController extends Controller
16
{
17
    public function __construct(
18
        protected PreferenceService $preferenceService
19
    ) {}
20
21
    /**
22
     * Get all notification preferences for the authenticated user
23
     */
24
    public function index(): JsonResponse
25
    {
26
        $user = Auth::user();
27
        $events = NotificationEvent::where('is_active', true)->get();
28
        $preferences = [];
29
30
        foreach ($events as $event) {
31
            $preference = NotificationPreference::where('user_id', $user->id)
0 ignored issues
show
Bug introduced by
Accessing id on the interface Illuminate\Contracts\Auth\Authenticatable suggest that you code against a concrete implementation. How about adding an instanceof check?
Loading history...
32
                ->where('notification_event_id', $event->id)
33
                ->first();
34
35
            $channels = $this->preferenceService->getChannelsForEvent($event, $preference);
36
37
            $preferences[] = [
38
                'event_key' => $event->key,
39
                'event_name' => $event->name,
40
                'event_group' => $event->group,
41
                'description' => $event->description,
42
                'channels' => $channels,
43
            ];
44
        }
45
46
        return response()->json(['data' => $preferences]);
47
    }
48
49
    /**
50
     * Get available events and channels for building UI
51
     */
52
    public function available(): JsonResponse
53
    {
54
        $events = NotificationEvent::where('is_active', true)
55
            ->select('id', 'key', 'name', 'group', 'description', 'settings')
56
            ->get()
57
            ->map(function ($event) {
58
                return [
59
                    'key' => $event->key,
60
                    'name' => $event->name,
61
                    'group' => $event->group,
62
                    'description' => $event->description,
63
                    'default_channels' => $event->settings['channels'] ?? [],
64
                ];
65
            });
66
67
        $channels = NotificationChannel::where('is_active', true)
68
            ->select('type', 'title', 'icon')
69
            ->get()
70
            ->map(function ($channel) {
71
                return [
72
                    'type' => $channel->type,
73
                    'title' => $channel->title,
74
                    'icon' => $channel->icon,
75
                ];
76
            });
77
78
        return response()->json([
79
            'data' => [
80
                'events' => $events,
81
                'channels' => $channels,
82
            ],
83
        ]);
84
    }
85
86
    /**
87
     * Get preferences for a specific event
88
     */
89
    public function show(string $eventKey): JsonResponse
90
    {
91
        $user = Auth::user();
92
        $event = NotificationEvent::where('key', $eventKey)
93
            ->where('is_active', true)
94
            ->firstOrFail();
95
96
        $preference = NotificationPreference::where('user_id', $user->id)
0 ignored issues
show
Bug introduced by
Accessing id on the interface Illuminate\Contracts\Auth\Authenticatable suggest that you code against a concrete implementation. How about adding an instanceof check?
Loading history...
97
            ->where('notification_event_id', $event->id)
98
            ->first();
99
100
101
        $channels = $this->preferenceService->getChannelsForEvent($event, $preference);
102
103
        return response()->json([
104
            'data' => [
105
                'event_key' => $event->key,
106
                'event_name' => $event->name,
107
                'event_group' => $event->group,
108
                'description' => $event->description,
109
                'channels' => $channels,
110
            ],
111
        ]);
112
    }
113
114
    /**
115
     * Update preferences for a specific event
116
     */
117
    public function update(UpdatePreferenceRequest $request, string $eventKey): JsonResponse
118
    {
119
        $user = Auth::user();
120
        $event = NotificationEvent::where('key', $eventKey)
121
            ->where('is_active', true)
122
            ->firstOrFail();
123
124
        $preferences = NotificationSetting::getPreferences();
125
        if (!($preferences['allow_override'] ?? config('notifier.settings.preferences.allow_override', true))) {
126
            return response()->json([
127
                'message' => 'User preference override is disabled by administrator.',
128
            ], 403);
129
        }
130
131
        $validatedChannels = $request->validated()['channels'];
132
        $activeChannels = NotificationChannel::where('is_active', true)
133
            ->pluck('type')
134
            ->toArray();
135
136
        foreach (array_keys($validatedChannels) as $channelType) {
137
            if (!in_array($channelType, $activeChannels)) {
138
                return response()->json([
139
                    'message' => "Channel '{$channelType}' is not available or active.",
140
                ], 422);
141
            }
142
        }
143
144
        $preference = NotificationPreference::updateOrCreate(
145
            [
146
                'user_id' => $user->id,
0 ignored issues
show
Bug introduced by
Accessing id on the interface Illuminate\Contracts\Auth\Authenticatable suggest that you code against a concrete implementation. How about adding an instanceof check?
Loading history...
147
                'notification_event_id' => $event->id,
148
            ],
149
            [
150
                'channels' => $validatedChannels,
151
                'settings' => $request->input('settings', []),
152
            ]
153
        );
154
155
        return response()->json([
156
            'data' => [
157
                'event_key' => $event->key,
158
                'event_name' => $event->name,
159
                'channels' => $preference->channels,
0 ignored issues
show
Bug introduced by
The property channels does not seem to exist on Illuminate\Database\Eloq...gHasThroughRelationship.
Loading history...
160
            ],
161
            'message' => 'Preferences updated successfully.',
162
        ]);
163
    }
164
165
}
166
167
168