From a2d07c384b124d9f1ad75d3fe61c4fd9600a0018 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=B5=9C=EC=A4=80=ED=9D=A0?= Date: Fri, 19 Dec 2025 10:38:48 +0900 Subject: [PATCH] dbmsv4 init...3 --- app/Forms/CommonForm.php | 73 +++++++++++++------ app/Language/ko/Validation.php | 50 ++++++------- .../Customer/Wallet/WalletService.php | 8 -- 3 files changed, 77 insertions(+), 54 deletions(-) diff --git a/app/Forms/CommonForm.php b/app/Forms/CommonForm.php index 3d9c789..78cd163 100644 --- a/app/Forms/CommonForm.php +++ b/app/Forms/CommonForm.php @@ -117,46 +117,77 @@ abstract class CommonForm return $this->_batchjobButtons; } //Validation용 + /** + * 데이터를 검증하고 유효하지 않을 경우 예외를 발생시킵니다. + * 2025 CI4 표준: 규칙 배열 내에 label을 포함하여 한글 메시지 출력을 보장합니다. + * + * @param array $formDatas 검증할 데이터 + * @throws RuntimeException + */ final public function validate(array $formDatas): void { if ($this->_validation === null) { throw new RuntimeException(static::class . '->' . __FUNCTION__ . "에서 오류발생: Validation 서비스가 초기화되지 않았습니다."); } - $dynamicRules = []; - $dynamicLabels = []; // 레이블 배열 추가 - try { - foreach ($this->getFormRules() as $field => $rule) { - list($field, $rule) = $this->getValidationRule($field, $rule); - $dynamicRules[$field] = $rule; // 규칙만 저장 - // role.* 키가 getFormFields()에 없을 확률이 99%이므로 isset 체크를 합니다. - $formFields = $this->getFormFields(); + $dynamicRules = []; + + try { + // 1. 현재 서비스의 필드 라벨 정보 로드 (언어 파일 기반) + $formFields = $this->getFormFields(); + $formRules = $this->getFormRules(); + + if (empty($formRules)) { + throw new RuntimeException(static::class . '->' . __FUNCTION__ . "에서 오류발생: 지정된 Form RULE이 없습니다."); + } + + foreach ($formRules as $field => $rule) { + // 2. 필드명과 규칙 추출 + list($field, $rule) = $this->getValidationRule($field, $rule); + + // 3. 라벨 결정 로직 (한글 라벨 매핑) if (isset($formFields[$field])) { - $dynamicLabels[$field] = $formFields[$field]; + $label = $formFields[$field]; } elseif (str_contains($field, '.*')) { - // role.* 형태라면 부모인 'role'의 레이블을 가져오거나 직접 명시 + // 배열 검증(role.* 등)의 경우 부모 필드의 라벨을 활용 $parentField = str_replace('.*', '', $field); - $dynamicLabels[$field] = ($formFields[$parentField] ?? $field) . " 항목"; + $label = ($formFields[$parentField] ?? $field) . " 항목"; } else { - $dynamicLabels[$field] = $field; // 기본값 + $label = $field; // 언어 파일에 정의가 없는 경우 필드명 유지 } + + // 4. [핵심 해결책] 규칙 배열 자체에 label을 포함시킴 + // 이렇게 하면 CI4 엔진이 {field} 자리에 이 label 값을 최우선으로 사용합니다. + $dynamicRules[$field] = [ + 'label' => $label, + 'rules' => $rule + ]; } - if (!count($dynamicRules)) { - throw new RuntimeException(static::class . '->' . __FUNCTION__ . "에서 오류발생: 지정된 Form RULE이 없습니다."); - } - // setRules의 세 번째 인자로 레이블 전달 - $this->_validation->setRules($dynamicRules, [], $dynamicLabels); + + // 5. 검증 규칙 설정 (인자를 하나만 전달하여 설정 충돌 방지) + $this->_validation->setRules($dynamicRules); + + // 6. 검증 실행 if (!$this->_validation->run($formDatas)) { - throw new RuntimeException(static::class . '->' . __FUNCTION__ . "에서 데이터 검증 오류발생: " . var_export($this->_validation->getErrors(), true)); + // 한글 라벨이 적용된 에러 메시지들을 배열로 가져와 한 줄씩 합침 + $errors = $this->_validation->getErrors(); + throw new RuntimeException(implode("\n", $errors)); } + + // 검증 성공 시 추가 로직 없이 종료 + } catch (\Throwable $e) { - log_message('debug', 'Validate Rules: ' . var_export($this->getFormRules(), true)); - log_message('debug', 'Validate Dynamic Rules: ' . var_export($dynamicRules, true)); - log_message('debug', 'Validate Data: ' . var_export($formDatas, true)); + // 오류 발생 시 디버깅을 위해 로그 기록 + log_message('debug', '--- Validation Error Detail ---'); + log_message('debug', 'Rules: ' . var_export($this->getFormRules(), true)); + log_message('debug', 'Data: ' . var_export($formDatas, true)); + log_message('debug', 'Message: ' . $e->getMessage()); + throw new RuntimeException($e->getMessage()); } } + //필수함수 //사용자정의 함수 protected function getValidationRule(string $field, string $rule): array diff --git a/app/Language/ko/Validation.php b/app/Language/ko/Validation.php index 6e23f60..9bb1dc1 100644 --- a/app/Language/ko/Validation.php +++ b/app/Language/ko/Validation.php @@ -5,34 +5,34 @@ return [ // 여기서부터 각 Validation rule에 대한 메시지를 정의합니다. // {field}나 {param} 같은 플레이스홀더는 그대로 유지해야 합니다. - 'required' => '{field} 필드는 필수 입력 항목입니다.', - 'isset' => '{field} 필드는 값이 반드시 있어야 합니다.', - 'valid_email' => '{field} 필드는 유효한 이메일 주소여야 합니다.', - 'valid_url' => '{field} 필드는 유효한 URL이어야 합니다.', - 'valid_date' => '{field} 필드는 유효한 날짜여야 합니다.', - 'valid_dates' => '{field} 필드는 유효한 날짜여야 합니다.', - 'valid_ip' => '{field} 필드는 유효한 IP 주소여야 합니다.', - 'valid_mac' => '{field} 필드는 유효한 MAC 주소여야 합니다.', - 'numeric' => '{field} 필드는 숫자만 포함해야 합니다.', - 'integer' => '{field} 필드는 정수여야 합니다.', - 'decimal' => '{field} 필드는 소수점 숫자여야 합니다.', - 'is_numeric' => '{field} 필드는 숫자 문자만 포함해야 합니다.', - 'regex_match' => '{field} 필드는 올바른 형식이어야 합니다.', + 'required' => '[{field}] 필수 입력 항목입니다.', + 'isset' => '[{field}] 값이 반드시 있어야 합니다.', + 'valid_email' => '[{field}] 유효한 이메일 주소여야 합니다.', + 'valid_url' => '[{field}] 유효한 URL이어야 합니다.', + 'valid_date' => '[{field}] 유효한 날짜여야 합니다.', + 'valid_dates' => '[{field}] 유효한 날짜여야 합니다.', + 'valid_ip' => '[{field}] 유효한 IP 주소여야 합니다.', + 'valid_mac' => '[{field}] 유효한 MAC 주소여야 합니다.', + 'numeric' => '[{field}] 숫자만 포함해야 합니다.', + 'integer' => '[{field}] 정수여야 합니다.', + 'decimal' => '[{field}] 소수점 숫자여야 합니다.', + 'is_numeric' => '[{field}] 숫자 문자만 포함해야 합니다.', + 'regex_match' => '[{field}] 올바른 형식이어야 합니다.', 'matches' => '{field} 필드가 {param} 필드와 일치하지 않습니다.', - 'differs' => '{field} 필드는 {param} 필드와 달라야 합니다.', - 'is_unique' => '{field} 필드는 고유한 값이어야 합니다.', - 'is_natural' => '{field} 필드는 숫자여야 합니다.', - 'is_natural_no_zero' => '{field} 필드는 0보다 큰 숫자여야 합니다.', - 'less_than' => '{field} 필드는 {param}보다 작아야 합니다.', - 'less_than_equal_to' => '{field} 필드는 {param}보다 작거나 같아야 합니다.', - 'greater_than' => '{field} 필드는 {param}보다 커야 합니다.', - 'greater_than_equal_to' => '{field} 필드는 {param}보다 크거나 같아야 합니다.', + 'differs' => '[{field}] {param} 필드와 달라야 합니다.', + 'is_unique' => '[{field}] 고유한 값이어야 합니다.', + 'is_natural' => '[{field}] 숫자여야 합니다.', + 'is_natural_no_zero' => '[{field}] 0보다 큰 숫자여야 합니다.', + 'less_than' => '[{field}] {param}보다 작아야 합니다.', + 'less_than_equal_to' => '[{field}] {param}보다 작거나 같아야 합니다.', + 'greater_than' => '[{field}] {param}보다 커야 합니다.', + 'greater_than_equal_to' => '[{field}] {param}보다 크거나 같아야 합니다.', 'error_prefix' => '', 'error_suffix' => '', // 길이(Length) 관련 rule 메시지 - 'min_length' => '{field} 필드는 최소 {param}자 이상이어야 합니다.', - 'max_length' => '{field} 필드는 최대 {param}자 이하여야 합니다.', - 'exact_length' => '{field} 필드는 정확히 {param}자여야 합니다.', - 'in_list' => '{field} 필드는 다음 중 하나여야 합니다: {param}.', + 'min_length' => '[{field}] 최소 {param}자 이상이어야 합니다.', + 'max_length' => '[{field}] 최대 {param}자 이하여야 합니다.', + 'exact_length' => '[{field}] 정확히 {param}자여야 합니다.', + 'in_list' => '[{field}] 다음 중 하나여야 합니다: {param}.', ]; diff --git a/app/Services/Customer/Wallet/WalletService.php b/app/Services/Customer/Wallet/WalletService.php index bc1f66f..c9dd6cd 100644 --- a/app/Services/Customer/Wallet/WalletService.php +++ b/app/Services/Customer/Wallet/WalletService.php @@ -20,12 +20,6 @@ abstract class WalletService extends CustomerService //생성 protected function create_process(array $formDatas): CommonEntity { - if (!array_key_exists('clientinfo_uid', $formDatas)) { - throw new RuntimeException(static::class . '->' . __FUNCTION__ . "에서 오류발생: 고객정보가 정의되지 않았습니다."); - } - if (!array_key_exists('status', $formDatas)) { - throw new RuntimeException(static::class . '->' . __FUNCTION__ . "에서 오류발생: 상태정보가 정의되지 않았습니다."); - } //고객 정보 $clientEntity = service('customer_clientservice')->getEntity($formDatas['clientinfo_uid']); if (!$clientEntity instanceof ClientEntity) { @@ -38,8 +32,6 @@ abstract class WalletService extends CustomerService case STATUS['WITHDRAWAL']: $formDatas = $this->withdrawal_process($clientEntity, $formDatas); break; - default: - throw new RuntimeException(static::class . '->' . __FUNCTION__ . "에서 오류발생: 상태정보{$formDatas['status']}가 정의되지 않았습니다."); } $entity = parent::create_process($formDatas); if (!$entity) {