Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
92.00% covered (success)
92.00%
46 / 50
75.00% covered (warning)
75.00%
3 / 4
CRAP
0.00% covered (danger)
0.00%
0 / 1
NotificationSettingsController
92.00% covered (success)
92.00%
46 / 50
75.00% covered (warning)
75.00%
3 / 4
9.04
0.00% covered (danger)
0.00%
0 / 1
 index
100.00% covered (success)
100.00%
24 / 24
100.00% covered (success)
100.00%
1 / 1
1
 updateChannel
100.00% covered (success)
100.00%
11 / 11
100.00% covered (success)
100.00%
1 / 1
4
 updateEvent
100.00% covered (success)
100.00%
11 / 11
100.00% covered (success)
100.00%
1 / 1
1
 sendTest
0.00% covered (danger)
0.00%
0 / 4
0.00% covered (danger)
0.00%
0 / 1
12
1<?php
2
3namespace App\Http\Controllers\admin;
4
5use App\Http\Controllers\Controller;
6use App\Models\NotificationLog;
7use App\Services\Notification\NotificationManager;
8use Illuminate\Http\RedirectResponse;
9use Illuminate\Http\Request;
10use Illuminate\View\View;
11
12/**
13 * Settings → Notification Settings. Two things live here:
14 *  - channel cards (enable toggle + credentials), same pattern as
15 *    Settings → Payment Gateways (PaymentGatewayController);
16 *  - the event × channel matrix + per-event subject/body templates
17 *    (config/notification_events.php rows).
18 * A fresh install sends nothing: every channel starts off, and every
19 * event's channel list starts empty even once a channel is configured.
20 */
21class NotificationSettingsController extends Controller
22{
23    public function index(NotificationManager $manager): View
24    {
25        $channels = collect($manager->keys())->map(function ($key) use ($manager) {
26            $driver = $manager->driver($key);
27            $entry = config("notification_channels.{$key}");
28
29            return [
30                'key' => $key,
31                'label' => $driver->label(),
32                'schema' => $driver->configSchema(),
33                'group' => $entry['group'],
34                'feature' => $entry['feature'],
35                'isImplemented' => $driver->isImplemented(),
36                'enabled' => settings("notification_channels.{$key}.enabled", $entry['default_enabled'] ?? false),
37                'config' => $manager->config($key),
38            ];
39        })->groupBy('group');
40
41        $events = collect(config('notification_events'))->map(function ($event, $key) {
42            return array_merge($event, [
43                'key' => $key,
44                'channels' => (array) settings("notifications.{$key}.channels", []),
45                'subject' => settings("notifications.{$key}.subject", $event['default_subject']),
46                'body' => settings("notifications.{$key}.body", $event['default_body']),
47            ]);
48        });
49
50        $recentLog = NotificationLog::query()->latest()->limit(20)->get();
51
52        return view('admin.notification-settings.index', compact('channels', 'events', 'recentLog'));
53    }
54
55    public function updateChannel(Request $request, string $key, NotificationManager $manager): RedirectResponse
56    {
57        abort_unless($manager->has($key), 404);
58
59        $driver = $manager->driver($key);
60        $schema = $driver->configSchema();
61        $enabled = $request->boolean('enabled');
62
63        $rules = [];
64        foreach ($schema as $field => $def) {
65            $rules["config.{$field}"] = $enabled && ($def['required'] ?? false) ? 'required' : 'nullable';
66        }
67        $data = $request->validate($rules);
68
69        settings()->set("notification_channels.{$key}.enabled", $enabled);
70        settings()->set("notification_channels.{$key}.config", $data['config'] ?? []);
71
72        return redirect()->route('admin.notification-settings.index')->with('success', $driver->label() . ' settings saved.');
73    }
74
75    /** One event's channel toggles + templates, saved together. */
76    public function updateEvent(Request $request, string $event): RedirectResponse
77    {
78        abort_unless(config("notification_events.{$event}") !== null, 404);
79
80        $data = $request->validate([
81            'channels' => 'nullable|array',
82            'channels.*' => 'string',
83            'subject' => 'required|string|max:200',
84            'body' => 'required|string|max:2000',
85        ]);
86
87        settings()->set("notifications.{$event}.channels", $data['channels'] ?? []);
88        settings()->set("notifications.{$event}.subject", $data['subject']);
89        settings()->set("notifications.{$event}.body", $data['body']);
90
91        return redirect()->route('admin.notification-settings.index')->with('success', 'Notification settings saved.');
92    }
93
94    /** "Send test" — fires immediately (not queued), so the admin sees the real result right away. */
95    public function sendTest(Request $request, string $key, NotificationManager $manager): RedirectResponse
96    {
97        abort_unless($manager->has($key), 404);
98
99        $data = $request->validate(['to' => 'required|string|max:255']);
100
101        $result = $manager->send($key, $data['to'], 'Test notification', 'This is a test message from your store\'s Notification Settings.');
102
103        return back()->with($result['ok'] ? 'success' : 'error', $result['ok'] ? 'Test sent.' : ('Test failed: ' . $result['response']));
104    }
105}