Files
2026-06-08 19:58:50 +07:00

126 lines
3.9 KiB
PHP

<?php
namespace App\Services;
use App\Models\Log;
use Illuminate\Support\Facades\Log as LogFacade;
use Illuminate\Database\Eloquent\Builder;
class LogActionService{
const MAX_PER_PAGE = 50;
const DEFAULT_PER_PAGE = 10;
public static function logAction(int $userId,
string $action,
?string $model = null,
?int $modelId = null,
?array $changes = null,
?string $description = null,
$success)
{
try {
Log::create([
'user_id' => $userId,
'action' => $action,
'model' => $model,
'model_id' => $modelId,
'changes' => $changes ? json_encode($changes) : null,
'description' => $description,
'timestamp' => now(),
'is_success' => $success,
]);
} catch (\Exception $e) {
LogFacade::info('Error inserting log: ' . $e->getMessage());
throw $e; // or handle it gracefully
}
}
public function getLogs(array $filters = []): array
{
try {
$query = Log::query();
$query->with(['user:id,name,role,email']);
$this->applyLogFilters($query, $filters);
$paginatedData = $this->paginateResults($query, $filters, 'logs');
return [true, 'Logs retrieved successfully.', $paginatedData];
} catch (\Throwable $exception) {
return [false, 'Failed to retrieve logs: ' . $exception->getMessage(), []];
}
}
private function applyLogFilters(Builder $query, array $filters): void
{
if (!empty($filters['user_id'])) {
$query->where('user_id', $filters['user_id']);
}
if (!empty($filters['action'])) {
$query->where('action', $filters['action']);
}
if (!empty($filters['model'])) {
$query->where('model', $filters['model']);
}
if (!empty($filters['date_from'])) {
$query->whereDate('timestamp', '>=', $filters['date_from']);
}
if (!empty($filters['date_to'])) {
$query->whereDate('timestamp', '<=', $filters['date_to']);
}
if (isset($filters['is_success'])) {
$query->where('is_success', $filters['is_success']);
// $successFilter = filter_var($filters['is_success'], FILTER_VALIDATE_BOOLEAN, FILTER_NULL_ON_FAILURE);
// if (!is_null($successFilter)) {
// $query->where('is_success', $successFilter);
// }
}
// Default sorting by timestamp
$query->orderBy('timestamp', 'desc');
}
private function paginateResults(Builder $query, array $filters, string $itemsKey): array
{
$perPage = isset($filters['per_page']) &&
is_numeric($filters['per_page']) &&
$filters['per_page'] > 0 &&
$filters['per_page'] <= self::MAX_PER_PAGE
? (int)$filters['per_page']
: self::DEFAULT_PER_PAGE;
$page = isset($filters['page']) &&
is_numeric($filters['page']) &&
$filters['page'] > 0
? (int)$filters['page']
: 1;
$results = $query->paginate($perPage, ['*'], 'page', $page);
if ($results->isEmpty() && $results->currentPage() > 1) {
$results = $query->paginate($perPage, ['*'], 'page', $results->lastPage());
}
return [
$itemsKey => $results->items(),
'pagination' => [
'current_page' => $results->currentPage(),
'last_page' => $results->lastPage(),
'per_page' => (int)$results->perPage(),
'total' => $results->total(),
'from' => $results->firstItem(),
'to' => $results->lastItem(),
'has_more_pages' => $results->hasMorePages(),
]
];
}
}