diff --git a/app/Forms/CommonForm.php b/app/Forms/CommonForm.php index 7ebf17a..20c7d65 100644 --- a/app/Forms/CommonForm.php +++ b/app/Forms/CommonForm.php @@ -168,16 +168,60 @@ abstract class CommonForm * - 실패 시 FormValidationException(errors 배열)을 throw * (AJAX에서 422로 내려보내기 위함) */ - final public function validate(array &$formDatas): void + final public function validate(string $action, array &$formDatas): void { try { - $formFields = $this->getFormFields(); - $formRules = $this->getFormRules(); + // 1) 전체 룰/필드 + $allFormFields = $this->getFormFields(); + $allFormRules = $this->getFormRules(); - if (empty($formRules)) { + if (empty($allFormRules)) { throw new RuntimeException(static::class . '->' . __FUNCTION__ . "에서 오류발생: 지정된 Form RULE이 없습니다."); } + // 2) 검증 대상 필드 결정 + // - create 계열: 전체 룰 + // - modify 계열: 전달받은 formDatas 키에 해당하는 룰만 + $targetFields = []; + + if (in_array($action, ['modify', 'modify_form'], true)) { + // 전달받은 필드만 검증 + $targetFields = array_keys($formDatas); + + // 검증 대상에서 제외할 내부/제어용 키(프로젝트에 맞게 추가/삭제) + $exclude = ['_method', 'csrf_test_name', 'submit', 'token']; + $targetFields = array_values(array_diff($targetFields, $exclude)); + + // role.* 같은 규칙이 있을 수 있으니 "부모 배열" 보정 + // - formRules에 role.*가 존재하고 + // - formDatas에 role(배열)이 있다면 + // label/ruleset 구성 안정성을 위해 parent도 targetFields에 포함 + foreach ($allFormRules as $ruleField => $_ruleStr) { + $ruleField = (string) $ruleField; + if (str_contains($ruleField, '.*')) { + $parent = str_replace('.*', '', $ruleField); + if (array_key_exists($parent, $formDatas) && !in_array($parent, $targetFields, true)) { + $targetFields[] = $parent; + } + } + } + + // 실제 정의된 룰이 있는 필드만 남김 + $targetFields = array_values(array_intersect($targetFields, array_keys($allFormRules))); + } else { + // create/create_form/alternative_create_form 등은 전체 룰 검증 + $targetFields = array_keys($allFormRules); + } + + // 3) 대상 필드의 rules/fields만 취득 + $formFields = $this->getFormFields($targetFields); + $formRules = $this->getFormRules($targetFields); + + if (empty($formRules)) { + throw new RuntimeException(static::class . '->' . __FUNCTION__ . "에서 오류발생: 검증할 대상 RULE이 없습니다."); + } + + // 4) dynamic ruleset 생성 $dynamicRules = []; foreach ($formRules as $field => $rule) { [$fieldName, $ruleStr] = $this->getValidationRule((string) $field, (string) $rule); @@ -190,18 +234,21 @@ abstract class CommonForm } else { $label = $fieldName; } + $dynamicRules[$fieldName] = [ 'label' => $label, 'rules' => $ruleStr, ]; } + + // 5) run $this->validation->setRules($dynamicRules); if (!$this->validation->run($formDatas)) { throw new FormValidationException($this->validation->getErrors()); } } catch (FormValidationException $e) { - throw $e; // ✅ 필드별 errors 유지 + throw $e; } catch (\TypeError $e) { throw new RuntimeException('검증 도중 타입 오류 발생: ' . $e->getMessage()); } catch (\Throwable $e) { @@ -209,6 +256,7 @@ abstract class CommonForm } } + /* --------------------------------------------------------------------- * Overridable hooks * --------------------------------------------------------------------- */ diff --git a/app/Services/Auth/GoogleService.php b/app/Services/Auth/GoogleService.php index 1f7db7b..36cf03c 100644 --- a/app/Services/Auth/GoogleService.php +++ b/app/Services/Auth/GoogleService.php @@ -26,7 +26,7 @@ class GoogleService extends AuthService { try { //입력값 검증 - $this->getActionForm()->validate($formDatas); + $this->getActionForm()->validate('login', $formDatas); $this->socket->setToken($formDatas['access_code']); $sns_entity = $this->socket->signup(); // local db 사용와의 연결 확인 diff --git a/app/Services/Auth/LocalService.php b/app/Services/Auth/LocalService.php index 9eff5f4..f416fb2 100644 --- a/app/Services/Auth/LocalService.php +++ b/app/Services/Auth/LocalService.php @@ -24,7 +24,7 @@ class LocalService extends AuthService { $this->getActionForm()->action_init_process('login', $formDatas); //입력값 검증 - $this->getActionForm()->validate($formDatas); + $this->getActionForm()->validate('login', $formDatas); //로그인 정보확인 $entity = $this->getEntity(['id' => $formDatas['id'], 'status' => 'AVAILABLE']); if (!$entity instanceof UserEntity) { diff --git a/app/Services/CommonService.php b/app/Services/CommonService.php index 2d921ee..cce6523 100644 --- a/app/Services/CommonService.php +++ b/app/Services/CommonService.php @@ -267,7 +267,7 @@ abstract class CommonService $formDatas = $this->actionForm_fieldhook_process($field, $value, $formDatas); } // log_message('debug', 'AFTER hook CREATE FORMDATA:' . print_r($formDatas ?? null, true)); - $actionForm->validate($formDatas); // ✅ 여기서 검증 + $actionForm->validate('create', $formDatas); // ✅ 여기서 검증 } $entityClass = $this->getEntityClass(); @@ -307,7 +307,7 @@ abstract class CommonService $formDatas = $this->actionForm_fieldhook_process($field, $value, $formDatas); } // log_message('debug', 'AFTER hook MODIFY FORMDATA:' . print_r($formDatas ?? null, true)); - $actionForm->validate($formDatas); // ✅ 여기서 검증 + $actionForm->validate('modify', $formDatas); // ✅ 여기서 검증 } // 검증 통과 후 엔티티 반영 $formDatas = $this->save_before_fill($formDatas);