ListNotifications::getHeaderActions()   C
last analyzed

Complexity

Conditions 14
Paths 1

Size

Total Lines 152
Code Lines 112

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 1
Metric Value
eloc 112
c 1
b 0
f 1
dl 0
loc 152
rs 5.0133
cc 14
nc 1
nop 0

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
namespace Usamamuneerchaudhary\Notifier\Filament\Resources\NotificationResource\Pages;
4
5
use Filament\Actions\Action;
6
use Filament\Forms\Components\KeyValue;
7
use Filament\Forms\Components\Select;
8
use Filament\Forms\Components\Toggle;
9
use Filament\Notifications\Notification;
10
use Filament\Resources\Pages\ListRecords;
11
use Filament\Schemas\Components\Utilities\Get;
12
use Filament\Schemas\Components\Utilities\Set;
13
use Usamamuneerchaudhary\Notifier\Filament\Resources\NotificationResource;
14
use Usamamuneerchaudhary\Notifier\Models\NotificationEvent;
15
use Usamamuneerchaudhary\Notifier\Models\NotificationChannel;
16
use Usamamuneerchaudhary\Notifier\Services\NotifierManager;
17
use Illuminate\Support\Facades\Log;
18
19
class ListNotifications extends ListRecords
20
{
21
    protected static string $resource = NotificationResource::class;
22
23
    protected function getHeaderActions(): array
24
    {
25
        return [
26
            Action::make('send_test')
0 ignored issues
show
Deprecated Code introduced by
The function Filament\Actions\Action::form() has been deprecated: Use `schema() instead. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

26
            /** @scrutinizer ignore-deprecated */ Action::make('send_test')

This function has been deprecated. The supplier of the function has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.

Loading history...
27
                ->label('Send Test Notification')
28
                ->icon('heroicon-o-paper-airplane')
29
                ->color('success')
30
                ->form([
31
                    Select::make('event_key')
32
                        ->label('Event')
33
                        ->helperText('Select the notification event to trigger. Make sure the event has a template linked to it.')
34
                        ->options(function () {
35
                            return NotificationEvent::where('is_active', true)
36
                                ->with('templates')
37
                                ->get()
38
                                ->mapWithKeys(function ($event) {
39
                                    $hasTemplate = $event->templates()->exists();
40
                                    $label = $event->name;
41
                                    if (!$hasTemplate) {
42
                                        $label .= ' (⚠️ No template)';
43
                                    }
44
                                    return [$event->key => $label];
45
                                })
46
                                ->toArray();
47
                        })
48
                        ->required()
49
                        ->searchable()
50
                        ->reactive()
51
                        ->afterStateUpdated(function ($state, Set $set, Get $get) {
0 ignored issues
show
Unused Code introduced by
The parameter $get is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

51
                        ->afterStateUpdated(function ($state, Set $set, /** @scrutinizer ignore-unused */ Get $get) {

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
52
                            // Load template variables for the selected event
53
                            if ($state) {
54
                                $event = NotificationEvent::where('key', $state)->first();
55
                                if ($event) {
56
                                    $template = $event->templates()->first();
57
                                    if ($template && $template->variables) {
58
59
                                        $defaultData = [];
60
                                        foreach ($template->variables as $key => $description) {
61
                                            $defaultData[$key] = '';
62
                                        }
63
                                        $set('data', $defaultData);
64
                                    }
65
                                }
66
                            }
67
                        }),
68
69
                    Select::make('user_id')
70
                        ->label('User')
71
                        ->helperText('Select the user to send the notification to')
72
                        ->options(function () {
73
                            $userModel = config('auth.providers.users.model');
74
                            return $userModel::whereNotNull('email')
75
                                ->get()
76
                                ->mapWithKeys(fn ($user) => [$user->id => "{$user->name} ({$user->email})"])
77
                                ->toArray();
78
                        })
79
                        ->required()
80
                        ->searchable()
81
                        ->preload(),
82
83
                    KeyValue::make('data')
84
                        ->label('Template Data')
85
                        ->helperText('Enter values for template variables. These will replace {{variable}} placeholders in the template.')
86
                        ->keyLabel('Variable Name')
87
                        ->valueLabel('Value')
88
                        ->addable(true)
89
                        ->deletable(true)
90
                        ->reorderable(),
91
92
                    Toggle::make('test_all_channels')
93
                        ->label('Test All Available Channels')
94
                        ->helperText('If enabled, the notification will be sent to all active channels instead of just the event\'s configured channels. Useful for testing channel configurations.')
95
                        ->default(false)
96
                        ->reactive(),
97
98
                    Select::make('channels')
99
                        ->label('Select Channels (if testing all)')
100
                        ->helperText('Select which channels to test. Only shown when "Test All Available Channels" is enabled.')
101
                        ->options(function () {
102
                            return NotificationChannel::where('is_active', true)
103
                                ->pluck('title', 'type')
104
                                ->toArray();
105
                        })
106
                        ->multiple()
107
                        ->searchable()
108
                        ->visible(fn (Get $get) => $get('test_all_channels') === true),
109
                ])
110
                ->action(function (array $data) {
111
                    try {
112
                        $userModel = config('auth.providers.users.model');
113
                        $user = $userModel::find($data['user_id']);
114
115
                        if (!$user) {
116
                            throw new \Exception('User not found');
117
                        }
118
119
                        // Check if event has a template
120
                        $event = NotificationEvent::where('key', $data['event_key'])->first();
121
                        if (!$event) {
122
                            throw new \Exception("Event '{$data['event_key']}' not found");
123
                        }
124
125
                        $template = $event->templates()->first();
126
                        if (!$template) {
127
                            throw new \Exception("Event '{$event->name}' does not have a template linked to it. Please create a template and link it to this event.");
128
                        }
129
130
                        $notifier = app(NotifierManager::class);
131
                        $eventKey = $data['event_key'];
132
                        $templateData = $data['data'] ?? [];
133
134
                        $channelsUsed = [];
135
136
                        // Check if testing all channels
137
                        if (!empty($data['test_all_channels'])) {
138
                            // Get selected channels or all active channels
139
                            $selectedChannels = $data['channels'] ?? [];
140
141
                            if (empty($selectedChannels)) {
142
                                $allChannels = NotificationChannel::where('is_active', true)->pluck('type')->toArray();
143
                                $selectedChannels = $allChannels;
144
                            }
145
146
                            foreach ($selectedChannels as $channelType) {
147
                                $notifier->sendToChannel($user, $eventKey, $channelType, $templateData);
148
                                $channelsUsed[] = $channelType;
149
                            }
150
151
                            $channelsList = implode(', ', $channelsUsed);
152
                            $message = "Test notifications queued for {$user->name} ({$user->email}) using event: {$event->name}. Channels: {$channelsList}";
153
                        } else {
154
                            $notifier->send($user, $eventKey, $templateData);
155
                            $message = "Notification queued for {$user->name} ({$user->email}) using event: {$event->name}";
156
                        }
157
158
                        Notification::make()
159
                            ->title('Test notification sent successfully!')
160
                            ->body($message . ". Check the notifications list below to see the status.")
161
                            ->success()
162
                            ->send();
163
                    } catch (\Exception $e) {
164
                        Log::error('Failed to send test notification: ' . $e->getMessage(), [
165
                            'event_key' => $data['event_key'] ?? null,
166
                            'user_id' => $data['user_id'] ?? null,
167
                            'trace' => $e->getTraceAsString()
168
                        ]);
169
170
                        Notification::make()
171
                            ->title('Failed to send test notification')
172
                            ->body($e->getMessage())
173
                            ->danger()
174
                            ->send();
175
                    }
176
                }),
177
        ];
178
    }
179
}
180