• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

Freegle / Iznik / 11342

08 May 2026 02:47PM UTC coverage: 68.97% (-3.8%) from 72.761%
11342

push

circleci

web-flow
Merge pull request #403 from Freegle/feature/exports-migration

feat(batch): migrate exports.php to users:process-exports

9127 of 10554 branches covered (86.48%)

Branch coverage included in aggregate %.

400 of 452 new or added lines in 2 files covered. (88.5%)

12172 existing lines in 167 files now uncovered.

100855 of 148909 relevant lines covered (67.73%)

19.62 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

84.09
/iznik-batch/app/Services/UserModMailsService.php
1
<?php
2

3
namespace App\Services;
4

5
use Illuminate\Support\Facades\DB;
6
use Illuminate\Support\Facades\Log;
7

8
/**
9
 * Maintains the users_modmails table by scanning recent logs for mod actions.
10
 *
11
 * Mirrors V1 cron/users_modmails.php:
12
 * - Scan logs from the last 10 minutes for mod actions on users (Rejected, Deleted, Replied, Mailed).
13
 * - Only records where byuser != user (mod acting on someone else).
14
 * - Prune entries older than 30 days.
15
 */
16
class UserModMailsService
17
{
18
    private const SCAN_MINUTES = 10;
19

20
    private const PRUNE_DAYS = 30;
21

22
    private const MOD_ACTION_TYPES = [
23
        ['type' => 'Message', 'subtypes' => ['Rejected', 'Deleted', 'Replied']],
24
        ['type' => 'User', 'subtypes' => ['Mailed', 'Rejected', 'Deleted']],
25
    ];
26

27
    /**
28
     * Insert recent mod-action log entries into users_modmails.
29
     *
30
     * @return int Number of new entries inserted
31
     */
32
    public function updateModMails(bool $dryRun = false): int
8✔
33
    {
34
        $since = now()->subMinutes(self::SCAN_MINUTES);
8✔
35
        $inserted = 0;
8✔
36

37
        $logs = DB::table('logs')
8✔
38
            ->where('timestamp', '>', $since)
8✔
39
            ->where(function ($q) {
8✔
40
                foreach (self::MOD_ACTION_TYPES as $group) {
8✔
41
                    $q->orWhere(function ($inner) use ($group) {
8✔
42
                        $inner->where('type', $group['type'])
8✔
43
                            ->whereIn('subtype', $group['subtypes']);
8✔
44
                    });
8✔
45
                }
46
            })
8✔
47
            ->whereColumn('byuser', '!=', 'user')
8✔
48
            ->whereNotNull('byuser')
8✔
49
            ->whereNotNull('user')
8✔
50
            ->get();
8✔
51

52
        foreach ($logs as $log) {
8✔
53
            if ($dryRun) {
8✔
UNCOV
54
                $exists = DB::table('users_modmails')->where('logid', $log->id)->exists();
×
UNCOV
55
                if (!$exists) {
×
UNCOV
56
                    $inserted++;
×
57
                }
UNCOV
58
                continue;
×
59
            }
60

61
            $affected = DB::table('users_modmails')->insertOrIgnore([
8✔
62
                'userid' => $log->user,
8✔
63
                'logid' => $log->id,
8✔
64
                'timestamp' => $log->timestamp,
8✔
65
                'groupid' => $log->groupid ?? 0,
8✔
66
            ]);
8✔
67

68
            if ($affected > 0) {
8✔
69
                $inserted++;
8✔
70
            }
71
        }
72

73
        Log::info('users_modmails ' . ($dryRun ? 'would update' : 'updated'), ['inserted' => $inserted, 'logs_scanned' => count($logs)]);
8✔
74

75
        return $inserted;
8✔
76
    }
77

78
    /**
79
     * Prune users_modmails entries older than 30 days.
80
     *
81
     * @return int Number of entries deleted
82
     */
83
    public function pruneOldEntries(bool $dryRun = false): int
2✔
84
    {
85
        $cutoff = now()->subDays(self::PRUNE_DAYS)->startOfDay();
2✔
86

87
        if ($dryRun) {
2✔
UNCOV
88
            return DB::table('users_modmails')
×
UNCOV
89
                ->where('timestamp', '<', $cutoff)
×
UNCOV
90
                ->count();
×
91
        }
92

93
        $deleted = DB::table('users_modmails')
2✔
94
            ->where('timestamp', '<', $cutoff)
2✔
95
            ->delete();
2✔
96

97
        if ($deleted > 0) {
2✔
98
            Log::info('users_modmails pruned', ['deleted' => $deleted]);
1✔
99
        }
100

101
        return $deleted;
2✔
102
    }
103
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc