Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
100.00% covered (success)
100.00%
32 / 32
100.00% covered (success)
100.00%
4 / 4
CRAP
100.00% covered (success)
100.00%
1 / 1
NotificationController
100.00% covered (success)
100.00%
32 / 32
100.00% covered (success)
100.00%
4 / 4
4
100.00% covered (success)
100.00%
1 / 1
 index
100.00% covered (success)
100.00%
16 / 16
100.00% covered (success)
100.00%
1 / 1
1
 show
100.00% covered (success)
100.00%
6 / 6
100.00% covered (success)
100.00%
1 / 1
1
 download
100.00% covered (success)
100.00%
9 / 9
100.00% covered (success)
100.00%
1 / 1
1
 ensureRecipientBelongsToInfluencer
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
1<?php
2
3namespace App\Http\Controllers\Influencer;
4
5use App\Http\Controllers\Controller;
6use App\Models\NotificationAttachment;
7use App\Models\NotificationRecipient;
8use Illuminate\Http\Request;
9use Illuminate\Support\Facades\Storage;
10use Illuminate\View\View;
11
12class NotificationController extends Controller
13{
14    public function index(Request $request): View
15    {
16        $influencer = $request->user()->influencer;
17        abort_unless($influencer, 403);
18
19        $notifications = NotificationRecipient::query()
20            ->with(['message.attachments'])
21            ->where('tenant_id', $influencer->tenant_id)
22            ->where('store_id', $influencer->store_id)
23            ->where('influencer_id', $influencer->id)
24            ->latest()
25            ->paginate(15);
26
27        return view('influencer.notifications.index', [
28            'notifications' => $notifications,
29            'unreadCount' => NotificationRecipient::query()
30                ->where('influencer_id', $influencer->id)
31                ->whereNull('read_at')
32                ->count(),
33        ]);
34    }
35
36    public function show(Request $request, NotificationRecipient $notification): View
37    {
38        $influencer = $request->user()->influencer;
39        abort_unless($influencer, 403);
40        $this->ensureRecipientBelongsToInfluencer($notification, $influencer->id);
41
42        $notification->load(['message.attachments', 'message.createdBy']);
43        $notification->markAsRead($request);
44
45        return view('influencer.notifications.show', compact('notification'));
46    }
47
48    public function download(Request $request, NotificationAttachment $attachment)
49    {
50        $influencer = $request->user()->influencer;
51        abort_unless($influencer, 403);
52
53        $allowed = NotificationRecipient::query()
54            ->where('notification_message_id', $attachment->notification_message_id)
55            ->where('influencer_id', $influencer->id)
56            ->exists();
57
58        abort_unless($allowed, 404);
59        abort_unless(Storage::disk($attachment->disk)->exists($attachment->path), 404);
60
61        return Storage::disk($attachment->disk)->download($attachment->path, $attachment->original_name);
62    }
63
64    private function ensureRecipientBelongsToInfluencer(NotificationRecipient $recipient, int $influencerId): void
65    {
66        abort_unless((int) $recipient->influencer_id === $influencerId, 404);
67    }
68}