2026-05-08 12:22:08 +05:30

111 lines
4.5 KiB
PHP

<?php
namespace App\Controllers;
use App\Models\ActivityLogModel;
class ActivityLog extends BaseController
{
public function index()
{
if ($r = $this->requireRole('admin')) {
return $r;
}
$logModel = new ActivityLogModel();
$summary = $logModel->getActivitySummary();
$availableActions = $logModel->getAvailableActions();
$action = $this->request->getGet('action');
if (is_array($action)) {
$action = array_values(array_filter(array_map('trim', $action)));
} else {
$action = trim((string) $action);
}
$role = $this->request->getGet('role');
if (is_array($role)) {
$role = array_values(array_filter(array_map('trim', $role)));
} else {
$role = trim((string) $role);
}
$filters = [
'action' => $action,
'role' => $role,
'date_from' => trim((string) $this->request->getGet('date_from')),
'date_to' => trim((string) $this->request->getGet('date_to')),
];
return view('admin/activity_log', [
'logs' => $logModel->getFilteredLogs($filters),
'filters' => $filters,
'summary' => $summary,
'availableActions' => $availableActions,
]);
}
public function analytics()
{
if ($r = $this->requireRole('admin')) {
return $r;
}
$period = $this->request->getGet('period') ?? '7_days';
$days = ($period === '30_days') ? 30 : 7;
$dateFrom = date('Y-m-d', strtotime("-$days days"));
$db = \Config\Database::connect();
$summary = [
'total_actions' => $db->table('activity_logs')->where('activity_at >=', $dateFrom)->countAllResults(),
'by_action' => $db->table('activity_logs')->select('action, COUNT(id) as count')->where('activity_at >=', $dateFrom)->groupBy('action')->get()->getResultArray(),
'by_role' => $db->table('activity_logs')->select('activity_user_type as actor_role, COUNT(id) as count')->where('activity_at >=', $dateFrom)->groupBy('activity_user_type')->get()->getResultArray(),
];
$mostActive = $db->table('activity_logs al')
->select("CONCAT(COALESCE(u.first_name, ''), ' ', COALESCE(u.last_name, '')) as name, COUNT(al.id) as count")
->join('users u', 'u.id = al.activity_user_id', 'left')
->where('al.activity_at >=', $dateFrom)
->groupBy('al.activity_user_id')
->orderBy('count', 'DESC')
->limit(10)
->get()
->getResultArray();
$summary['most_active_users'] = $mostActive;
$actionLabels = array_column($summary['by_action'], 'action');
$actionCounts = array_column($summary['by_action'], 'count');
$typeLabels = array_column($summary['by_role'], 'actor_role');
$typeCounts = array_column($summary['by_role'], 'count');
$userLabels = array_map(function($user) { return trim((string) $user['name']) ?: 'System'; }, $mostActive);
$userCounts = array_column($mostActive, 'count');
$uniqueIPs = $db->table('activity_logs')->select('ip as ip, COUNT(id) as count')->where('activity_at >=', $dateFrom)->where('ip IS NOT NULL')->groupBy('ip')->orderBy('count', 'DESC')->get()->getResultArray();
$criticalActions = $db->table('activity_logs al')
->select("al.activity_at as activity_at, CONCAT(COALESCE(u.first_name, ''), ' ', COALESCE(u.last_name, '')) AS actor_name, u.email AS actor_email, al.action, al.target_user_type as target_user_type, al.target_user_id as target_user_id, al.description")
->join('users u', 'u.id = al.activity_user_id', 'left')
->like('al.action', 'delete')
->orderBy('al.activity_at', 'DESC')
->limit(50)
->get()
->getResultArray();
return view('admin/activity_analytics', [
'period' => $period,
'summary' => $summary,
'uniqueIPs' => $uniqueIPs,
'criticalActions' => $criticalActions,
'actionLabels' => json_encode($actionLabels),
'actionCounts' => json_encode($actionCounts),
'typeLabels' => json_encode($typeLabels),
'typeCounts' => json_encode($typeCounts),
'userLabels' => json_encode($userLabels),
'userCounts' => json_encode($userCounts)
]);
}
}