166 lines
4.8 KiB
PHP
166 lines
4.8 KiB
PHP
<?php
|
|
|
|
namespace App\Services;
|
|
|
|
use App\Jobs\LogActivityJob;
|
|
use Illuminate\Database\Eloquent\Model;
|
|
use Illuminate\Support\Facades\Log;
|
|
|
|
class ActivityLogger
|
|
{
|
|
private array $hiddenFields = [
|
|
'password',
|
|
'remember_token',
|
|
'plain_password',
|
|
'token',
|
|
'secret',
|
|
'api_key',
|
|
'updated_at',
|
|
];
|
|
|
|
public function log(
|
|
string $event,
|
|
string $logName,
|
|
string $description,
|
|
?Model $subject = null,
|
|
array $oldValues = [],
|
|
array $newValues = [],
|
|
): void {
|
|
try {
|
|
[$causerType, $causerId, $causerName] = $this->resolveCauser();
|
|
|
|
LogActivityJob::dispatch([
|
|
'log_name' => $logName,
|
|
'event' => $event,
|
|
'description' => $description,
|
|
'subject_type' => $subject ? get_class($subject) : null,
|
|
'subject_id' => $subject?->getKey(),
|
|
'causer_type' => $causerType,
|
|
'causer_id' => $causerId,
|
|
'causer_name' => $causerName,
|
|
'old_values' => $oldValues ?: null,
|
|
'new_values' => $newValues ?: null,
|
|
'ip_address' => request()->getClientIp(),
|
|
'user_agent' => request()->userAgent(),
|
|
]);
|
|
} catch (\Throwable $e) {
|
|
Log::warning('[ActivityLogger] Failed to dispatch log job', [
|
|
'error' => $e->getMessage(),
|
|
'event' => $event,
|
|
'log_name' => $logName,
|
|
]);
|
|
}
|
|
}
|
|
|
|
public function logCreated(Model $model, string $logName): void
|
|
{
|
|
$causer = $this->getCauserName();
|
|
$id = $model->getKey();
|
|
|
|
$this->log(
|
|
event: 'created',
|
|
logName: $logName,
|
|
description: "$causer tạo mới $logName" . ($id ? " #$id" : ''),
|
|
subject: $model,
|
|
newValues: $this->filterValues($model->getAttributes()),
|
|
);
|
|
}
|
|
|
|
public function logUpdated(Model $model, string $logName): void
|
|
{
|
|
$dirty = $model->getDirty();
|
|
if (empty($dirty)) {
|
|
return;
|
|
}
|
|
|
|
$dirty = $this->filterValues($dirty);
|
|
$original = $this->filterValues(array_intersect_key($model->getOriginal(), $dirty));
|
|
|
|
if (empty($dirty)) {
|
|
return;
|
|
}
|
|
|
|
$causer = $this->getCauserName();
|
|
$id = $model->getKey();
|
|
$fields = implode(', ', array_keys($dirty));
|
|
|
|
$this->log(
|
|
event: 'updated',
|
|
logName: $logName,
|
|
description: "$causer cập nhật $logName" . ($id ? " #$id" : '') . " [$fields]",
|
|
subject: $model,
|
|
oldValues: $original,
|
|
newValues: $dirty,
|
|
);
|
|
}
|
|
|
|
public function logDeleted(Model $model, string $logName): void
|
|
{
|
|
$causer = $this->getCauserName();
|
|
$id = $model->getOriginal($model->getKeyName()) ?? $model->getKey();
|
|
|
|
$this->log(
|
|
event: 'deleted',
|
|
logName: $logName,
|
|
description: "$causer xóa $logName" . ($id ? " #$id" : ''),
|
|
subject: $model,
|
|
);
|
|
}
|
|
|
|
public function logRestored(Model $model, string $logName): void
|
|
{
|
|
$causer = $this->getCauserName();
|
|
$id = $model->getKey();
|
|
|
|
$this->log(
|
|
event: 'restored',
|
|
logName: $logName,
|
|
description: "$causer khôi phục $logName" . ($id ? " #$id" : ''),
|
|
subject: $model,
|
|
);
|
|
}
|
|
|
|
public function logAuth(string $event, string $causerType, $causerId, string $causerName): void
|
|
{
|
|
$action = match ($event) {
|
|
'login' => 'đăng nhập',
|
|
'logout' => 'đăng xuất',
|
|
'register' => 'đăng ký tài khoản',
|
|
default => $event,
|
|
};
|
|
|
|
$this->log(
|
|
event: $event,
|
|
logName: 'auth',
|
|
description: "[$causerType] $causerName $action",
|
|
subject: null,
|
|
oldValues: [],
|
|
newValues: ['causer_type' => $causerType, 'causer_id' => $causerId, 'causer_name' => $causerName],
|
|
);
|
|
}
|
|
|
|
private function resolveCauser(): array
|
|
{
|
|
if ($admin = auth()->guard('admin')->user()) {
|
|
return ['admin', $admin->id, $admin->username ?? $admin->email];
|
|
}
|
|
|
|
if ($customer = auth()->guard('client')->user()) {
|
|
return ['customer', $customer->id, $customer->email ?? $customer->name];
|
|
}
|
|
|
|
return ['system', null, 'System'];
|
|
}
|
|
|
|
public function getCauserName(): string
|
|
{
|
|
[, , $name] = $this->resolveCauser();
|
|
return $name;
|
|
}
|
|
|
|
private function filterValues(array $values): array
|
|
{
|
|
return array_diff_key($values, array_flip($this->hiddenFields));
|
|
}
|
|
}
|