Files
Inventory/app/Services/AuditService.php

201 lines
6.2 KiB
PHP

<?php
namespace App\Services;
use App\Core\Database;
use App\Core\Session;
class AuditService
{
private Database $database;
private Session $session;
public function __construct(Database $database, Session $session)
{
$this->database = $database;
$this->session = $session;
}
public function log(string $action, string $table, int $recordId, array $oldValue = null, array $newValue = null): void
{
$userId = $this->session->getUserId();
if (!$userId) {
return; // Skip logging if no user
}
$data = [
'user_id' => $userId,
'action' => $action,
'table_name' => $table,
'record_id' => $recordId,
'old_value' => $oldValue ? json_encode($oldValue) : null,
'new_value' => $newValue ? json_encode($newValue) : null,
'created_at' => date('Y-m-d H:i:s')
];
try {
$this->database->insert('audit_log', $data);
} catch (\Exception $e) {
error_log('Audit logging failed: ' . $e->getMessage());
}
}
public function getAuditLog(string $table = null, int $recordId = null, int $limit = 100): array
{
$sql = "SELECT al.*, u.name as user_name
FROM audit_log al
LEFT JOIN users u ON al.user_id = u.id
WHERE 1=1";
$params = [];
if ($table) {
$sql .= " AND al.table_name = :table";
$params['table'] = $table;
}
if ($recordId) {
$sql .= " AND al.record_id = :record_id";
$params['record_id'] = $recordId;
}
$sql .= " ORDER BY al.created_at DESC LIMIT :limit";
$params['limit'] = $limit;
return $this->database->fetchAll($sql, $params);
}
public function getAssetHistory(int $assetId): array
{
return $this->getAuditLog('assets', $assetId);
}
public function getUserActivity(int $userId, int $limit = 50): array
{
$sql = "SELECT al.*, u.name as user_name
FROM audit_log al
LEFT JOIN users u ON al.user_id = u.id
WHERE al.user_id = :user_id
ORDER BY al.created_at DESC
LIMIT :limit";
return $this->database->fetchAll($sql, [
'user_id' => $userId,
'limit' => $limit
]);
}
public function getRecentActivity(int $limit = 20): array
{
$sql = "SELECT al.*, u.name as user_name
FROM audit_log al
LEFT JOIN users u ON al.user_id = u.id
ORDER BY al.created_at DESC
LIMIT :limit";
return $this->database->fetchAll($sql, ['limit' => $limit]);
}
public function getActivityByDateRange(string $startDate, string $endDate): array
{
$sql = "SELECT al.*, u.name as user_name
FROM audit_log al
LEFT JOIN users u ON al.user_id = u.id
WHERE DATE(al.created_at) BETWEEN :start_date AND :end_date
ORDER BY al.created_at DESC";
return $this->database->fetchAll($sql, [
'start_date' => $startDate,
'end_date' => $endDate
]);
}
public function getActivityByAction(string $action, int $limit = 100): array
{
$sql = "SELECT al.*, u.name as user_name
FROM audit_log al
LEFT JOIN users u ON al.user_id = u.id
WHERE al.action = :action
ORDER BY al.created_at DESC
LIMIT :limit";
return $this->database->fetchAll($sql, [
'action' => $action,
'limit' => $limit
]);
}
public function getAssetChanges(int $assetId): array
{
$sql = "SELECT al.*, u.name as user_name
FROM audit_log al
LEFT JOIN users u ON al.user_id = u.id
WHERE al.table_name = 'assets'
AND al.record_id = :asset_id
AND al.action IN ('update', 'delete')
ORDER BY al.created_at DESC";
return $this->database->fetchAll($sql, ['asset_id' => $assetId]);
}
public function getInventoryActivity(int $inventoryId): array
{
$sql = "SELECT al.*, u.name as user_name
FROM audit_log al
LEFT JOIN users u ON al.user_id = u.id
WHERE al.table_name = 'inventories'
AND al.record_id = :inventory_id
ORDER BY al.created_at DESC";
return $this->database->fetchAll($sql, ['inventory_id' => $inventoryId]);
}
public function cleanupOldLogs(int $daysToKeep = 365): int
{
$sql = "DELETE FROM audit_log
WHERE created_at < DATE_SUB(NOW(), INTERVAL :days DAY)";
return $this->database->query($sql, ['days' => $daysToKeep])->rowCount();
}
public function getAuditSummary(): array
{
$sql = "SELECT
COUNT(*) as total_entries,
COUNT(DISTINCT user_id) as unique_users,
COUNT(DISTINCT table_name) as tables_affected,
MIN(created_at) as first_entry,
MAX(created_at) as last_entry
FROM audit_log";
return $this->database->fetch($sql) ?: [];
}
public function getTopUsers(int $limit = 10): array
{
$sql = "SELECT
u.name as user_name,
COUNT(*) as activity_count
FROM audit_log al
LEFT JOIN users u ON al.user_id = u.id
GROUP BY al.user_id, u.name
ORDER BY activity_count DESC
LIMIT :limit";
return $this->database->fetchAll($sql, ['limit' => $limit]);
}
public function getMostActiveTables(int $limit = 10): array
{
$sql = "SELECT
table_name,
COUNT(*) as activity_count
FROM audit_log
GROUP BY table_name
ORDER BY activity_count DESC
LIMIT :limit";
return $this->database->fetchAll($sql, ['limit' => $limit]);
}
}