dbmsv4 init...3

This commit is contained in:
최준흠 2025-12-19 10:38:48 +09:00
parent 3021f39177
commit a2d07c384b
3 changed files with 77 additions and 54 deletions

View File

@ -117,46 +117,77 @@ abstract class CommonForm
return $this->_batchjobButtons; return $this->_batchjobButtons;
} }
//Validation용 //Validation용
/**
* 데이터를 검증하고 유효하지 않을 경우 예외를 발생시킵니다.
* 2025 CI4 표준: 규칙 배열 내에 label을 포함하여 한글 메시지 출력을 보장합니다.
*
* @param array $formDatas 검증할 데이터
* @throws RuntimeException
*/
final public function validate(array $formDatas): void final public function validate(array $formDatas): void
{ {
if ($this->_validation === null) { if ($this->_validation === null) {
throw new RuntimeException(static::class . '->' . __FUNCTION__ . "에서 오류발생: Validation 서비스가 초기화되지 않았습니다."); 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 체크를 합니다. $dynamicRules = [];
$formFields = $this->getFormFields();
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])) { if (isset($formFields[$field])) {
$dynamicLabels[$field] = $formFields[$field]; $label = $formFields[$field];
} elseif (str_contains($field, '.*')) { } elseif (str_contains($field, '.*')) {
// role.* 형태라면 부모인 'role'의 레이블을 가져오거나 직접 명시 // 배열 검증(role.* 등)의 경우 부모 필드의 라벨을 활용
$parentField = str_replace('.*', '', $field); $parentField = str_replace('.*', '', $field);
$dynamicLabels[$field] = ($formFields[$parentField] ?? $field) . " 항목"; $label = ($formFields[$parentField] ?? $field) . " 항목";
} else { } 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이 없습니다."); // 5. 검증 규칙 설정 (인자를 하나만 전달하여 설정 충돌 방지)
} $this->_validation->setRules($dynamicRules);
// setRules의 세 번째 인자로 레이블 전달
$this->_validation->setRules($dynamicRules, [], $dynamicLabels); // 6. 검증 실행
if (!$this->_validation->run($formDatas)) { 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) { } 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', '--- Validation Error Detail ---');
log_message('debug', 'Validate Data: ' . var_export($formDatas, true)); 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()); throw new RuntimeException($e->getMessage());
} }
} }
//필수함수 //필수함수
//사용자정의 함수 //사용자정의 함수
protected function getValidationRule(string $field, string $rule): array protected function getValidationRule(string $field, string $rule): array

View File

@ -5,34 +5,34 @@ return [
// 여기서부터 각 Validation rule에 대한 메시지를 정의합니다. // 여기서부터 각 Validation rule에 대한 메시지를 정의합니다.
// {field}나 {param} 같은 플레이스홀더는 그대로 유지해야 합니다. // {field}나 {param} 같은 플레이스홀더는 그대로 유지해야 합니다.
'required' => '{field} 필드는 필수 입력 항목입니다.', 'required' => '[{field}] 필수 입력 항목입니다.',
'isset' => '{field} 필드는 값이 반드시 있어야 합니다.', 'isset' => '[{field}] 값이 반드시 있어야 합니다.',
'valid_email' => '{field} 필드는 유효한 이메일 주소여야 합니다.', 'valid_email' => '[{field}] 유효한 이메일 주소여야 합니다.',
'valid_url' => '{field} 필드는 유효한 URL이어야 합니다.', 'valid_url' => '[{field}] 유효한 URL이어야 합니다.',
'valid_date' => '{field} 필드는 유효한 날짜여야 합니다.', 'valid_date' => '[{field}] 유효한 날짜여야 합니다.',
'valid_dates' => '{field} 필드는 유효한 날짜여야 합니다.', 'valid_dates' => '[{field}] 유효한 날짜여야 합니다.',
'valid_ip' => '{field} 필드는 유효한 IP 주소여야 합니다.', 'valid_ip' => '[{field}] 유효한 IP 주소여야 합니다.',
'valid_mac' => '{field} 필드는 유효한 MAC 주소여야 합니다.', 'valid_mac' => '[{field}] 유효한 MAC 주소여야 합니다.',
'numeric' => '{field} 필드는 숫자만 포함해야 합니다.', 'numeric' => '[{field}] 숫자만 포함해야 합니다.',
'integer' => '{field} 필드는 정수여야 합니다.', 'integer' => '[{field}] 정수여야 합니다.',
'decimal' => '{field} 필드는 소수점 숫자여야 합니다.', 'decimal' => '[{field}] 소수점 숫자여야 합니다.',
'is_numeric' => '{field} 필드는 숫자 문자만 포함해야 합니다.', 'is_numeric' => '[{field}] 숫자 문자만 포함해야 합니다.',
'regex_match' => '{field} 필드는 올바른 형식이어야 합니다.', 'regex_match' => '[{field}] 올바른 형식이어야 합니다.',
'matches' => '{field} 필드가 {param} 필드와 일치하지 않습니다.', 'matches' => '{field} 필드가 {param} 필드와 일치하지 않습니다.',
'differs' => '{field} 필드는 {param} 필드와 달라야 합니다.', 'differs' => '[{field}] {param} 필드와 달라야 합니다.',
'is_unique' => '{field} 필드는 고유한 값이어야 합니다.', 'is_unique' => '[{field}] 고유한 값이어야 합니다.',
'is_natural' => '{field} 필드는 숫자여야 합니다.', 'is_natural' => '[{field}] 숫자여야 합니다.',
'is_natural_no_zero' => '{field} 필드는 0보다 큰 숫자여야 합니다.', 'is_natural_no_zero' => '[{field}] 0보다 큰 숫자여야 합니다.',
'less_than' => '{field} 필드는 {param}보다 작아야 합니다.', 'less_than' => '[{field}] {param}보다 작아야 합니다.',
'less_than_equal_to' => '{field} 필드는 {param}보다 작거나 같아야 합니다.', 'less_than_equal_to' => '[{field}] {param}보다 작거나 같아야 합니다.',
'greater_than' => '{field} 필드는 {param}보다 커야 합니다.', 'greater_than' => '[{field}] {param}보다 커야 합니다.',
'greater_than_equal_to' => '{field} 필드는 {param}보다 크거나 같아야 합니다.', 'greater_than_equal_to' => '[{field}] {param}보다 크거나 같아야 합니다.',
'error_prefix' => '', 'error_prefix' => '',
'error_suffix' => '', 'error_suffix' => '',
// 길이(Length) 관련 rule 메시지 // 길이(Length) 관련 rule 메시지
'min_length' => '{field} 필드는 최소 {param}자 이상이어야 합니다.', 'min_length' => '[{field}] 최소 {param}자 이상이어야 합니다.',
'max_length' => '{field} 필드는 최대 {param}자 이하여야 합니다.', 'max_length' => '[{field}] 최대 {param}자 이하여야 합니다.',
'exact_length' => '{field} 필드는 정확히 {param}자여야 합니다.', 'exact_length' => '[{field}] 정확히 {param}자여야 합니다.',
'in_list' => '{field} 필드는 다음 중 하나여야 합니다: {param}.', 'in_list' => '[{field}] 다음 중 하나여야 합니다: {param}.',
]; ];

View File

@ -20,12 +20,6 @@ abstract class WalletService extends CustomerService
//생성 //생성
protected function create_process(array $formDatas): CommonEntity 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']); $clientEntity = service('customer_clientservice')->getEntity($formDatas['clientinfo_uid']);
if (!$clientEntity instanceof ClientEntity) { if (!$clientEntity instanceof ClientEntity) {
@ -38,8 +32,6 @@ abstract class WalletService extends CustomerService
case STATUS['WITHDRAWAL']: case STATUS['WITHDRAWAL']:
$formDatas = $this->withdrawal_process($clientEntity, $formDatas); $formDatas = $this->withdrawal_process($clientEntity, $formDatas);
break; break;
default:
throw new RuntimeException(static::class . '->' . __FUNCTION__ . "에서 오류발생: 상태정보{$formDatas['status']}가 정의되지 않았습니다.");
} }
$entity = parent::create_process($formDatas); $entity = parent::create_process($formDatas);
if (!$entity) { if (!$entity) {