'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 = <<
{$totalActions}
Total Actions
{$actionTypeCount}
Action Types
{$criticalActionCount}
Critical Actions
Top Actions
| Action |
Count |
HTML;
arsort($byAction);
foreach (array_slice($byAction, 0, 10) as $action => $count) {
$isCritical = stripos($action, 'delete') !== false ? 'class="critical"' : '';
$html .= "| {$action} | {$count} |
";
}
$html .= <<
Critical Actions (Deletions)
HTML;
if (!empty($criticalActions)) {
$html .= '
| Time | User | Action | Target |
';
foreach (array_slice($criticalActions, 0, 20) as $log) {
$userId = $log['activity_user_id'] ?? 'System';
$targetType = $log['target_user_type'] ?? '-';
$html .= "";
$html .= "| " . date('Y-m-d H:i', strtotime($log['activity_at'])) . " | ";
$html .= "{$userId} | ";
$html .= "{$log['action']} | ";
$html .= "{$targetType} | ";
$html .= "
";
}
$html .= '
';
} 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;
}
}