'Digest period: daily, weekly, or monthly (default: daily)', ]; public function run(array $params = []) { $period = $params[0] ?? 'daily'; if (!in_array($period, ['daily', 'weekly', 'monthly'])) { CLI::error('Invalid period. Use: daily, weekly, or monthly'); return; } $activityModel = new ActivityLogModel(); $userModel = new UserModel(); // Determine date range $startDate = match($period) { 'daily' => date('Y-m-d H:i:s', strtotime('-1 day')), 'weekly' => date('Y-m-d H:i:s', strtotime('-7 days')), 'monthly' => date('Y-m-d H:i:s', strtotime('-30 days')), default => date('Y-m-d H:i:s', strtotime('-1 day')), }; // Get activity summary for the period $db = \Config\Database::connect(); $logs = $db->table('activity_logs') ->where('activity_at >=', $startDate) ->orderBy('activity_at', 'DESC') ->get() ->getResultArray(); if (empty($logs)) { CLI::write('No activity found for ' . $period . ' digest', 'yellow'); return; } // Get admin users $admins = $userModel->where('role', 'admin')->findAll(); if (empty($admins)) { CLI::error('No admin users found to send digest to'); return; } // Send email to each admin $email = service('email'); $emailConfig = config('Email'); $successCount = 0; $failCount = 0; foreach ($admins as $admin) { $html = $this->generateDigestHTML($logs, $period, $admin); $email->setFrom($emailConfig->fromEmail, $emailConfig->fromName) ->setTo($admin['email']) ->setSubject(ucfirst($period) . ' Activity Digest - ' . date('Y-m-d')) ->setMessage($html); if ($email->send(false)) { $successCount++; CLI::write('Email sent to: ' . $admin['email'], 'green'); } else { $failCount++; CLI::error('Failed to send email to: ' . $admin['email']); } $email->clear(); } CLI::write("\nDigest email summary:", 'cyan'); CLI::write('Sent: ' . $successCount, 'green'); CLI::write('Failed: ' . $failCount, 'red'); } protected function generateDigestHTML($logs, $period, $admin) { $totalActions = count($logs); // Group by action $byAction = []; foreach ($logs as $log) { $action = $log['action']; $byAction[$action] = ($byAction[$action] ?? 0) + 1; } // Get critical actions $criticalActions = array_filter($logs, function($log) { return stripos($log['action'], 'delete') !== false; }); $actionTypeCount = count($byAction); $criticalActionCount = count($criticalActions); $html = <<

Activity Digest Report

Dear {$admin['first_name']}, here is your {$period} activity summary

{$totalActions}
Total Actions
{$actionTypeCount}
Action Types
{$criticalActionCount}
Critical Actions

Top Actions

HTML; arsort($byAction); foreach (array_slice($byAction, 0, 10) as $action => $count) { $isCritical = stripos($action, 'delete') !== false ? 'class="critical"' : ''; $html .= ""; } $html .= <<
Action Count
{$action}{$count}

Critical Actions (Deletions)

HTML; if (!empty($criticalActions)) { $html .= ''; foreach (array_slice($criticalActions, 0, 20) as $log) { $userId = $log['activity_user_id'] ?? 'System'; $targetType = $log['target_user_type'] ?? '-'; $html .= ""; $html .= ""; $html .= ""; $html .= ""; $html .= ""; $html .= ""; } $html .= '
TimeUserActionTarget
" . date('Y-m-d H:i', strtotime($log['activity_at'])) . "{$userId}{$log['action']}{$targetType}
'; } else { $html .= '

No critical actions detected.

'; } $html .= <<

This is an automated email. Please do not reply to this message.

Generated on {date('Y-m-d H:i:s')}

HTML; return $html; } }