diff --git a/app/Controllers/Admin/UserController.php b/app/Controllers/Admin/UserController.php index e1d78f8..12b63f4 100644 --- a/app/Controllers/Admin/UserController.php +++ b/app/Controllers/Admin/UserController.php @@ -14,10 +14,6 @@ use App\Services\UserService; class UserController extends AdminController { - /** - * @property UserService $service - * IDE에게 protected $service 속성이 LocalService 타입임을 알려줍니다. - */ public const PATH = 'user'; public function initController(RequestInterface $request, ResponseInterface $response, LoggerInterface $logger) { @@ -42,7 +38,7 @@ class UserController extends AdminController //요청 데이터를 DTO 객체로 변환 $dto = new UserDTO($this->request->getPost()); $entity = $this->service->create($dto); - $redirect_url = $this->authService->popPreviousUrl() ?? implode(DIRECTORY_SEPARATOR, $this->getActionPaths()); + $redirect_url = $this->getAuthContext()->popPreviousUrl() ?? implode(DIRECTORY_SEPARATOR, $this->getActionPaths()); return redirect()->to($redirect_url)->with('success', "{$entity->getTitle()} 계정 생성이 완료되었습니다."); } protected function modify_form_process($uid): void @@ -68,7 +64,7 @@ class UserController extends AdminController //요청 데이터를 DTO 객체로 변환 $dto = new UserDTO($this->request->getPost()); $entity = $this->service->modify($dto); - $redirect_url = $this->authService->popPreviousUrl() ?? implode(DIRECTORY_SEPARATOR, $this->getActionPaths()); + $redirect_url = $this->getAuthContext()->popPreviousUrl() ?? implode(DIRECTORY_SEPARATOR, $this->getActionPaths()); return redirect()->to($redirect_url)->with('success', "{$entity->getTitle()} 계정 수정이 완료되었습니다."); } } diff --git a/app/Controllers/Auth/AuthController.php b/app/Controllers/Auth/AuthController.php index 6a85c91..8cd4e81 100644 --- a/app/Controllers/Auth/AuthController.php +++ b/app/Controllers/Auth/AuthController.php @@ -32,7 +32,6 @@ abstract class AuthController extends CommonController $this->action_init_process($action); $this->login_form_process(); $this->action_render_process($action); - // dd($this->getViewDatas()); } catch (\Exception $e) { $this->addViewDatas(self::ACTION_RESULT, 'error'); $this->addViewDatas(self::ACTION_MESSAGE, $e->getMessage()); @@ -51,12 +50,12 @@ abstract class AuthController extends CommonController try { $this->action_init_process($action); $this->login_process(); - $redirect_url = $this->authService->popPreviousUrl() ?? implode(DIRECTORY_SEPARATOR, $this->getActionPaths()); + $redirect_url = $this->getAuthContext()->popPreviousUrl() ?? implode(DIRECTORY_SEPARATOR, $this->getActionPaths()); return redirect()->to($redirect_url)->with('success', MESSAGES['LOGIN']); } catch (ValidationException $e) { // 검증 실패 시 폼으로 돌아가서 오류 메시지 표시 log_message('error', $e->getMessage()); - return redirect()->back()->withInput()->with('errors', $e->getMessage()); + return redirect()->back()->withInput()->with('error', $e->getMessage()); } catch (\Exception $e) { log_message('error', $e->getMessage()); return redirect()->back()->withInput()->with('error', $e->getMessage()); @@ -69,7 +68,7 @@ abstract class AuthController extends CommonController try { $this->logout_process(); // 홈페이지로 리다이렉트 - $redirect_url = $this->authService->popPreviousUrl() ?? "/"; + $redirect_url = $this->getAuthContext()->popPreviousUrl() ?? "/"; return redirect()->route($redirect_url)->with('error', MESSAGES['LOGOUT']); } catch (\Exception $e) { log_message("error", $e->getMessage()); diff --git a/app/Controllers/CommonController.php b/app/Controllers/CommonController.php index 0efaf09..be18ada 100644 --- a/app/Controllers/CommonController.php +++ b/app/Controllers/CommonController.php @@ -4,6 +4,7 @@ namespace App\Controllers; use App\Controllers\BaseController; use App\DTOs\CertificationDTO; +use App\Libraries\AuthContext; use App\Traits\LogTrait; use CodeIgniter\HTTP\DownloadResponse; use CodeIgniter\HTTP\RedirectResponse; @@ -27,11 +28,11 @@ abstract class CommonController extends BaseController public function initController(RequestInterface $request, ResponseInterface $response, LoggerInterface $logger) { parent::initController($request, $response, $logger); - $this->myCertification = CertificationDTO::byAuthContext(service('myauth')->getAuthContext()); + $this->myCertification = CertificationDTO::byAuthContext($this->getAuthContext()); } - protected function getLayout(): string + final protected function getAuthContext(): AuthContext { - return 'empty'; + return service('myauth')->getAuthContext(); } final public function addActionPaths(string $path) { @@ -53,6 +54,10 @@ abstract class CommonController extends BaseController return $this->_viewDatas[$key] ?? null; } //공통 필수기능 + protected function getLayout(): string + { + return 'empty'; + } protected function doValidation(string $action): array { $dynamicRules = []; @@ -146,7 +151,7 @@ abstract class CommonController extends BaseController } catch (ValidationException $e) { // 검증 실패 시 폼으로 돌아가서 오류 메시지 표시 log_message('error', $e->getMessage()); - return redirect()->back()->withInput()->with('errors', $e->getMessage()); + return redirect()->back()->withInput()->with('error', $e->getMessage()); } catch (\Exception $e) { log_message('error', $e->getMessage()); return redirect()->back()->withInput()->with('error', $e->getMessage()); @@ -185,7 +190,7 @@ abstract class CommonController extends BaseController } catch (ValidationException $e) { // 검증 실패 시 폼으로 돌아가서 오류 메시지 표시 log_message('error', $e->getMessage()); - return redirect()->back()->withInput()->with('errors', $e->getMessage()); + return redirect()->back()->withInput()->with('error', $e->getMessage()); } catch (\Exception $e) { log_message('error', $e->getMessage()); return redirect()->back()->withInput()->with('error', $e->getMessage()); diff --git a/app/DTOs/Auth/AuthDTO.php b/app/DTOs/Auth/AuthDTO.php index dc318c8..c3fc649 100644 --- a/app/DTOs/Auth/AuthDTO.php +++ b/app/DTOs/Auth/AuthDTO.php @@ -4,7 +4,7 @@ namespace App\DTOs\Auth; use App\DTOs\CommonDTO; -abstract class AuthDTO extends CommonDTO +class AuthDTO extends CommonDTO { public function __construct() { diff --git a/app/Forms/Auth/LocalForm.php b/app/Forms/Auth/LocalForm.php index 338b545..d4a77d1 100644 --- a/app/Forms/Auth/LocalForm.php +++ b/app/Forms/Auth/LocalForm.php @@ -25,18 +25,34 @@ class LocalForm extends CommonForm } public function getFormRule(string $action, string $field, array $rules = []): array { - $rules = parent::getFormRule($action, $field, $rules); + // 부모 클래스의 기본 규칙을 먼저 가져옵니다. + $rules = parent::getFormRule($action, $field, $rules); + switch ($field) { case "id": - $rule = "required|trim|min_length[4]|max_length[20]"; - $rule .= in_array($action, ["create", "create_form"]) ? "|is_unique[{$this->getAttribute('table')}.{$field}]" : ""; - $rules[$field] = $rule; + // 💡 배열을 사용하여 규칙 목록을 안전하게 만듭니다. + $ruleList = [ + "required", + "trim", + "min_length[4]", + "max_length[20]", + ]; + // 'create' 액션에만 is_unique 규칙을 추가합니다. + if (in_array($action, ["create", "create_form"])) { + // $this->getAttribute('table') 대신 $this->model->getTable()를 사용하거나, + // 해당 Form 클래스가 $this->model을 가지고 있다면 그것을 사용해야 합니다. + $ruleList[] = "is_unique[{$this->getAttribute('table')}.{$field}]"; + } + // 배열 요소를 '|'로 안전하게 연결하여 최종 Rule 문자열을 생성합니다. + $rules[$field] = implode('|', $ruleList); break; case "passwd": - $rules[$field] = in_array($action, ["create", "create_form"]) ? "required|trim|string" : "permit_empty|trim|string"; + $rules[$field] = in_array($action, ["create", "create_form"]) + ? "required|trim|string" + : "permit_empty|trim|string"; break; default: - $rules = parent::getFormRule($action, $field, $rules); + $rules = parent::getFormRule($action, $field, $rules); break; } return $rules; diff --git a/app/Services/Auth/AuthService.php b/app/Services/Auth/AuthService.php index 07bd173..aa3e312 100644 --- a/app/Services/Auth/AuthService.php +++ b/app/Services/Auth/AuthService.php @@ -2,10 +2,11 @@ namespace App\Services\Auth; +use App\DTOs\Auth\AuthDTO; use App\Entities\UserEntity; use App\Helpers\AuthHelper; -use App\Models\CommonModel; use App\Libraries\AuthContext; +use App\Models\CommonModel; use CodeIgniter\Validation\Exceptions\ValidationException; /** @@ -92,7 +93,7 @@ abstract class AuthService { switch ($field) { default: - $rules[$field] = $this->getFormService()->getValidationRule($action, $field); + $rules = $this->getFormService()->getFormRule($action, $field); break; } return $rules; @@ -100,12 +101,13 @@ abstract class AuthService //로그인 abstract protected function login_process(array $formDatas): UserEntity; - public function login(object $dto): UserEntity + public function login(AuthDTO $dto): UserEntity { + $formDatas = (array)$dto; //입력값 검증 - $formDatas = (array) $dto; - if (!service('validation')->setRules($this->getValidationRules(__FUNCTION__))->run($formDatas)) { - throw new ValidationException(implode("\n", service('validation')->getErrors())); + $validation = service('validation')->setRules($this->getValidationRules(__FUNCTION__)); + if (!$validation->run($formDatas)) { + throw new ValidationException(implode("\n", $validation->getErrors())); } //인증처리 $entity = $this->login_process($formDatas); diff --git a/app/Services/Auth/GoogleService.php b/app/Services/Auth/GoogleService.php index d32962e..f6f3784 100644 --- a/app/Services/Auth/GoogleService.php +++ b/app/Services/Auth/GoogleService.php @@ -3,13 +3,12 @@ namespace App\Services\Auth; use App\DTOs\Auth\GoogleDTO; -use App\DTOs\AuthDTO; +use App\DTOs\Auth\AuthDTO; use App\Entities\UserEntity; use App\Forms\Auth\GoogleForm; use App\Libraries\MySocket\GoogleSocket\CURL; use App\Models\UserModel; use CodeIgniter\Exceptions\PageNotFoundException; -use CodeIgniter\Validation\Exceptions\ValidationException; use RuntimeException; class GoogleService extends AuthService @@ -53,13 +52,11 @@ class GoogleService extends AuthService throw new PageNotFoundException("관리자에게 문의하시기 바랍니다.\n{$e->getMessage()}"); } } - public function login(mixed $dto): UserEntity + public function login(AuthDTO $dto): UserEntity { if (!$dto instanceof GoogleDTO) { - throw new RuntimeException(__METHOD__ . "에서 오류발생: GoogleDTO만 사용하실수 있습니다"); + throw new RuntimeException(__METHOD__ . "에서 오류발생: " . get_class($dto) . " DTO는 사용할 수 없습니다. LocalDTO만 허용됩니다."); } return parent::login($dto); - // DTO 객체를 배열로 변환하여 검증기에 전달 - $formDatas = (array) $dto; } } diff --git a/app/Services/Auth/LocalService.php b/app/Services/Auth/LocalService.php index f8f5809..3ebeefc 100644 --- a/app/Services/Auth/LocalService.php +++ b/app/Services/Auth/LocalService.php @@ -2,12 +2,14 @@ namespace App\Services\Auth; -use App\DTOs\Auth\LocalDTO; +use App\DTOs\Auth\AuthDTO; // 부모 클래스의 타입 힌트를 위해 사용 (알리아스 아님) +use App\DTOs\Auth\LocalDTO; // LocalDTO를 직접 사용 use App\Entities\UserEntity; use App\Forms\Auth\LocalForm; use App\Models\UserModel; use RuntimeException; + class LocalService extends AuthService { public function __construct(UserModel $model) @@ -42,10 +44,10 @@ class LocalService extends AuthService return $entity; } - public function login(object $dto): UserEntity + public function login(AuthDTO $dto): UserEntity { if (!$dto instanceof LocalDTO) { - throw new RuntimeException(__METHOD__ . "에서 오류발생:" . get_class($dto) . "는 사용할수 없습니다."); + throw new RuntimeException(__METHOD__ . "에서 오류발생: " . get_class($dto) . " DTO는 사용할 수 없습니다. LocalDTO만 허용됩니다."); } return parent::login($dto); } diff --git a/app/Services/CommonService.php b/app/Services/CommonService.php index 237111b..78b2e01 100644 --- a/app/Services/CommonService.php +++ b/app/Services/CommonService.php @@ -94,7 +94,7 @@ abstract class CommonService { switch ($field) { default: - $rules[$field] = $this->getFormService()->getValidationRule($action, $field); + $rules = $this->getFormService()->getFormRule($action, $field); break; } return $rules; @@ -127,8 +127,10 @@ abstract class CommonService public function create(object $dto): CommonEntity { $formDatas = (array) $dto; - if (!service('validation')->setRules($this->getValidationRules(__FUNCTION__))->run($formDatas)) { - throw new ValidationException(implode("\n", service('validation')->getErrors())); + //입력값 검증 + $validation = service('validation')->setRules($this->getValidationRules(__FUNCTION__)); + if (!$validation->run($formDatas)) { + throw new ValidationException(implode("\n", $validation->getErrors())); } $entity = $this->create_process($formDatas); $result = $this->model->insert($entity, $this->model->useAutoIncrement()); @@ -139,8 +141,10 @@ abstract class CommonService public function modify(object $dto): CommonEntity { $formDatas = (array) $dto; - if (!service('validation')->setRules($this->getValidationRules(__FUNCTION__))->run($formDatas)) { - throw new ValidationException(implode("\n", service('validation')->getErrors())); + //입력값 검증 + $validation = service('validation')->setRules($this->getValidationRules(__FUNCTION__)); + if (!$validation->run($formDatas)) { + throw new ValidationException(implode("\n", $validation->getErrors())); } list($pk, $updateData) = $this->modify_process($formDatas); $entity = new ($this->model->returnType)($updateData); // 재조회에 필요한 PK를 얻기 위함