CleanupAnalyticsCommand   A
last analyzed

Complexity

Total Complexity 5

Size/Duplication

Total Lines 75
Duplicated Lines 0 %

Importance

Changes 2
Bugs 0 Features 2
Metric Value
wmc 5
eloc 48
c 2
b 0
f 2
dl 0
loc 75
rs 10

1 Method

Rating   Name   Duplication   Size   Complexity  
B handle() 0 70 5
1
<?php
2
3
namespace Usamamuneerchaudhary\Notifier\Commands;
4
5
use Illuminate\Console\Command;
6
use Illuminate\Support\Facades\DB;
7
use Usamamuneerchaudhary\Notifier\Models\Notification;
8
use Usamamuneerchaudhary\Notifier\Models\NotificationSetting;
9
10
class CleanupAnalyticsCommand extends Command
11
{
12
    protected $signature = 'notifier:cleanup-analytics {--dry-run : Show what would be cleaned without actually deleting}';
13
    protected $description = 'Clean up old analytics data based on retention settings';
14
15
    public function handle(): int
16
    {
17
        $analytics = NotificationSetting::getAnalytics();
18
19
        if (!($analytics['enabled'] ?? config('notifier.settings.analytics.enabled', true))) {
20
            $this->info('Analytics is disabled. Skipping cleanup.');
21
            return Command::SUCCESS;
22
        }
23
24
        $retentionDays = $analytics['retention_days'] ?? config('notifier.settings.analytics.retention_days', 90);
25
        $cutoffDate = now()->subDays($retentionDays);
26
27
        $this->info("Cleaning up analytics data older than {$retentionDays} days (before {$cutoffDate->format('Y-m-d H:i:s')})...");
28
29
        // Find notifications with analytics data older than retention period
30
        // Must be created before cutoff AND have analytics data
31
        $query = Notification::where('created_at', '<', $cutoffDate)
32
            ->where(function ($q) use ($cutoffDate) {
33
                $q->where(function ($subQ) use ($cutoffDate) {
34
                    $subQ->whereNotNull('opened_at')
35
                         ->where('opened_at', '<', $cutoffDate);
36
                })
37
                ->orWhere(function ($subQ) use ($cutoffDate) {
38
                    $subQ->whereNotNull('clicked_at')
39
                         ->where('clicked_at', '<', $cutoffDate);
40
                })
41
                ->orWhere(function ($subQ) {
42
                    $subQ->where('opens_count', '>', 0)
43
                         ->orWhere('clicks_count', '>', 0);
44
                });
45
            });
46
47
        $count = $query->count();
48
49
        if ($count === 0) {
50
            $this->info('No old analytics data found to clean up.');
51
            return Command::SUCCESS;
52
        }
53
54
        if ($this->option('dry-run')) {
55
            $this->info("Would clean up {$count} notification(s) with old analytics data.");
56
            $this->table(
57
                ['ID', 'User ID', 'Channel', 'Opened At', 'Clicked At', 'Opens Count', 'Clicks Count', 'Created At'],
58
                $query->limit(10)->get()->map(function ($notification) {
59
                    return [
60
                        $notification->id,
61
                        $notification->user_id,
62
                        $notification->channel,
63
                        $notification->opened_at?->format('Y-m-d H:i:s') ?? 'N/A',
64
                        $notification->clicked_at?->format('Y-m-d H:i:s') ?? 'N/A',
65
                        $notification->opens_count,
66
                        $notification->clicks_count,
67
                        $notification->created_at->format('Y-m-d H:i:s'),
68
                    ];
69
                })->toArray()
70
            );
71
            return Command::SUCCESS;
72
        }
73
74
        $updated = 0;
75
        $notifications = $query->get();
76
77
        foreach ($notifications as $notification) {
78
            DB::statement('UPDATE notifier_notifications SET opened_at = NULL, clicked_at = NULL, opens_count = 0, clicks_count = 0 WHERE id = ?', [$notification->id]);
79
            $updated++;
80
        }
81
82
        $this->info("Successfully cleaned up analytics data for {$updated} notification(s).");
83
84
        return Command::SUCCESS;
85
    }
86
}
87
88