giftcon_dev/app/Services/Admin/Log/MemberPasswdModifyLogService.php

163 lines
5.4 KiB
PHP

<?php
namespace App\Services\Admin\Log;
use App\Repositories\Admin\Log\MemberPasswdModifyLogRepository;
final class MemberPasswdModifyLogService
{
public function __construct(
private readonly MemberPasswdModifyLogRepository $repo,
) {}
public function indexData(array $query = []): array
{
$filters = [
'date_from' => $this->safeDate($query['date_from'] ?? ''),
'date_to' => $this->safeDate($query['date_to'] ?? ''),
'state' => $this->safeEnum($query['state'] ?? '', ['S','E']), // S 직접, E 찾기
'mem_no' => $this->safeInt($query['mem_no'] ?? null),
'type' => $this->safeStr($query['type'] ?? '', 40), // 신포맷 type
'email' => $this->safeStr($query['email'] ?? '', 80), // 구포맷 user_email
'ip' => $this->safeIpPrefix($query['ip'] ?? ''), // remote_addr or auth_key contains
'q' => $this->safeStr($query['q'] ?? '', 120), // info 전체 like
];
if ($filters['date_from'] && $filters['date_to']) {
if (strcmp($filters['date_from'], $filters['date_to']) > 0) {
[$filters['date_from'], $filters['date_to']] = [$filters['date_to'], $filters['date_from']];
}
}
$page = $this->repo->paginate($filters, 30);
$items = [];
foreach ($page->items() as $it) {
$r = is_array($it) ? $it : (array)$it;
$infoRaw = (string)($r['info'] ?? '');
$infoArr = $this->decodeJson($infoRaw);
$state = (string)($r['state'] ?? '');
$memNo = (int)($infoArr['mem_no'] ?? 0);
$type = trim((string)($infoArr['type'] ?? ''));
$eventType = $type !== '' ? $type : ($state === 'E' ? '비밀번호찾기 변경' : '비밀번호변경');
$eventTime = trim((string)($infoArr['redate'] ?? ''));
if ($eventTime === '') $eventTime = (string)($r['rgdate'] ?? '');
$ip = trim((string)($infoArr['remote_addr'] ?? ''));
if ($ip === '') {
$ip = $this->extractIpFromAuthKey((string)($infoArr['auth_key'] ?? '')) ?: '';
}
$email = trim((string)($infoArr['user_email'] ?? ''));
if ($email === '') $email = trim((string)($infoArr['email'] ?? ''));
$agent = trim((string)($infoArr['agent'] ?? ''));
$items[] = array_merge($r, [
'info_arr' => $infoArr,
'mem_no_int' => $memNo,
'mem_link' => $memNo > 0 ? ('/members/' . $memNo) : null,
'state_label' => $state === 'E' ? '비번찾기' : '직접변경',
'state_badge' => $state === 'E' ? 'badge--warn' : 'badge--ok',
'event_type' => $eventType,
'event_time' => $eventTime,
'ip_norm' => $ip,
'email_norm' => $email,
'agent_norm' => $agent,
// 펼침용(구포맷 핵심 필드)
'auth_key' => (string)($infoArr['auth_key'] ?? ''),
'auth_effective_time' => (string)($infoArr['auth_effective_time'] ?? ''),
// raw pretty
'info_pretty' => $this->prettyJson($infoArr, $infoRaw),
]);
}
return [
'filters' => $filters,
'page' => $page,
'items' => $items,
'stateMap' => [
'S' => '직접변경',
'E' => '비번찾기',
],
];
}
private function decodeJson(string $raw): array
{
$raw = trim($raw);
if ($raw === '') return [];
$arr = json_decode($raw, true);
return is_array($arr) ? $arr : [];
}
private function prettyJson(array $arr, string $fallbackRaw): string
{
if (!empty($arr)) {
return (string)json_encode($arr, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
}
return $fallbackRaw;
}
private function extractIpFromAuthKey(string $authKey): ?string
{
$authKey = trim($authKey);
if ($authKey === '') return null;
// auth_key 끝에 "1.85.101.111" 같은 IP가 붙는 케이스 대응 (마지막 매치 사용)
if (preg_match_all('/(\d{1,3}(?:\.\d{1,3}){3})/', $authKey, $m) && !empty($m[1])) {
return (string)end($m[1]);
}
return null;
}
private function safeStr(mixed $v, int $max): string
{
$s = trim((string)$v);
if ($s === '') return '';
if (mb_strlen($s) > $max) $s = mb_substr($s, 0, $max);
return $s;
}
private function safeEnum(mixed $v, array $allowed): string
{
$s = trim((string)$v);
return in_array($s, $allowed, true) ? $s : '';
}
private function safeInt(mixed $v): ?int
{
if ($v === null || $v === '') return null;
if (!is_numeric($v)) return null;
$n = (int)$v;
return $n >= 0 ? $n : null;
}
private function safeDate(mixed $v): ?string
{
$s = trim((string)$v);
if ($s === '') return null;
return preg_match('/^\d{4}-\d{2}-\d{2}$/', $s) ? $s : null;
}
private function safeIpPrefix(mixed $v): string
{
$s = trim((string)$v);
if ($s === '') return '';
return preg_match('/^[0-9.]+$/', $s) ? $s : '';
}
}