trafficmonitor/app/Services/Auth/AuthService.php
2025-11-13 10:24:15 +09:00

121 lines
3.5 KiB
PHP

<?php
namespace App\Services\Auth;
use App\DTOs\Auth\AuthDTO;
use App\Entities\UserEntity;
use App\Helpers\AuthHelper;
use App\Libraries\AuthContext;
use App\Models\CommonModel;
use CodeIgniter\Validation\Exceptions\ValidationException;
/**
* AuthService
* 인증(로그인) 워크플로우를 정의하는 템플릿 클래스입니다.
* CommonService를 상속받지 않아 불필요한 CRUD 구현을 요구하지 않습니다.
*/
abstract class AuthService
{
private $_helper = null;
private ?AuthContext $_authContext = null;
private array $_classPaths = [];
protected ?CommonModel $model = null;
protected function __construct(CommonModel $model)
{
$this->model = $model; // 모델을 직접 주입받아 자식에게 전달
$this->addClassPaths('Auth');
}
abstract public function getFormService(): mixed;
final public function getHelper(): AuthHelper
{
if ($this->_helper === null) {
$this->_helper = new AuthHelper();
// AuthHelper에 필요한 기본 메타데이터만 설정합니다. (CRUD 제거)
$this->_helper->setAttributes([
'pk_field' => $this->model->getPKField(),
'title_field' => $this->model->getTitleField(),
'class_path' => $this->getClassPaths(false)
]);
}
return $this->_helper;
}
//인증세션용
final public function getAuthContext(): AuthContext
{
if ($this->_authContext === null) {
$this->_authContext = new AuthContext();
}
return $this->_authContext;
}
final protected function addClassPaths(string $path): void
{
$this->_classPaths[] = $path;
}
final public function getClassPaths($isArray = true, $delimeter = DIRECTORY_SEPARATOR): array|string
{
return $isArray ? $this->_classPaths : implode($delimeter, $this->_classPaths);
}
protected function getEntity_process(mixed $entity): mixed
{
return $entity;
}
final public function getEntity(string|int|array $where, ?string $message = null): mixed
{
try {
$entity = is_array($where) ? $this->model->where($where)->first() : $this->model->find($where);
if (!$entity) {
return null;
}
if (is_array($entity)) {
throw new \Exception(__METHOD__ . "에서 결과값 Array 오류발생:\n" . var_export($entity, true));
}
return $this->getEntity_process($entity);
} catch (\Exception $e) {
$message = sprintf(
"\n------%s SQL오류-----<BR>\n%s\n%s\n------------------------------\n",
__FUNCTION__,
$this->model->getLastQuery(),
$e->getMessage()
);
throw new \Exception($message);
}
}
final protected function getValidationRules(string $action, array $rules): array
{
$dynamicRules = [];
foreach ($rules as $field => $rule) {
//field별 추가 커스텀 룰 적용
list($field, $rule) = $this->getValidationRule($field, $rule);
$dynamicRules[$field] = $rule;
}
return $dynamicRules;
}
protected function getValidationRule(string $field, string $rule): array
{
return array($field, $rule);
}
//로그인
abstract protected function login_process(array $formDatas): UserEntity;
public function login(AuthDTO $dto): UserEntity
{
$formDatas = (array)$dto;
// dd($formDatas);
//입력값 검증
if (!$this->getFormService()->validate($formDatas)) {
throw new ValidationException(implode("\n", service('validation')->getErrors()));
}
//인증처리
$entity = $this->login_process($formDatas);
//세션처리
$this->getAuthContext()->setAuthSession($entity);
return $entity;
}
//로그아웃
final public function logout(): void
{
$this->getAuthContext()->destroyAuthSession();
}
}