ICONS['SEARCH'], 'delete' => ICONS['DELETE']]; private array $_batchjobButtons = ['batchjob' => '일괄처리', 'batchjob_delete' => '일괄삭제']; protected function __construct() {} final public function setAttributes(array $attributes): void { $this->_attributes = $attributes; } final public function getAttribute(string $key): string { if (!array_key_exists($key, $this->_attributes)) { throw new RuntimeException(static::class . '->' . __FUNCTION__ . "에서 오류발생: {$key}에 해당하는 속성이 정의되지 않았습니다."); } return $this->_attributes[$key]; } final public function setFormFields(array $fields): void { foreach ($fields as $field) { $this->_formFields[$field] = $this->getFormFieldLabel($field); } } //$fields 매치된것만 반환, []->전체 final public function getFormFields(array $fields = []): array { if (empty($fields)) { return $this->_formFields; } // _formFields와 키를 비교하여 교집합을 반환합니다. $fields에 지정된 필드 정의만 추출됩니다. return array_intersect_key($this->_formFields, array_flip($fields)); } final public function setFormRules(string $action, array $fields, $formRules = []): void { foreach ($fields as $field) { $formRules[$field] = $formRules[$field] ?? $this->getFormRule($action, $field); } $this->_formRules = $formRules; } final public function getFormRules(array $fields = []): array { if (empty($fields)) { return $this->_formRules; } return array_intersect_key($this->_formRules, array_flip($fields)); } final public function setFormOptions(string $action, array $fields, array $formDatas = [], $formOptions = []): void { foreach ($fields as $field) { $formOptions[$field] = $formOptions[$field] ?? $this->getFormOption($action, $field, $formDatas); } $this->_formOptions = $formOptions; } //$fields 매치된것만 반환, []->전체 final public function getFormOptions(array $fields = []): array { if (empty($fields)) { return $this->_formOptions; } return array_intersect_key($this->_formOptions, array_flip($fields)); } final public function setFormFilters(array $fields): void { $this->_formFilters = $fields; } final public function getFormFilters(): array { return $this->_formFilters; } final public function setIndexFilters(array $fields): void { $this->_indexFilters = $fields;; } final public function getIndexFilters(): array { return $this->_indexFilters; } final public function setBatchjobFilters(array $fields): void { $this->_batchjobFilters = $fields;; } final public function getBatchjobFilters(): array { return $this->_batchjobFilters; } final public function setActionButtons(array $buttons): array { return $this->_actionButtons = $buttons; } final public function getActionButtons(): array { return $this->_actionButtons; } final public function setBatchjobButtons(array $buttons): array { return $this->_batchjobButtons = $buttons; } final public function getBatchjobButtons(): array { return $this->_batchjobButtons; } //Validation용 // final public function validate(array $formDatas): bool // { // $validation = service('validation'); // $dynamicRules = []; // foreach ($this->getFormRules() as $field => $rule) { // //field별 추가 커스텀 룰 적용 // list($field, $rule) = $this->getValidationRule($field, $rule); // $dynamicRules[$field] = ['rules' => $rule, 'label' => $this->getFormFields()[$field]]; // } // $validation->setRules($dynamicRules); // return $validation->run($formDatas); // } final public function validate(array $formDatas): bool { $validation = service('validation'); $dynamicRules = []; $dynamicLabels = []; // 레이블 배열 추가 if (!count($this->getFormRules())) { throw new RuntimeException(static::class . '->' . __FUNCTION__ . "에서 오류발생: 지정된 Form RULE이 없습니다."); } foreach ($this->getFormRules() as $field => $rule) { list($field, $rule) = $this->getValidationRule($field, $rule); $dynamicRules[$field] = $rule; // 규칙만 저장 $dynamicLabels[$field] = $this->getFormFields()[$field]; } log_message('debug', 'Fields: ' . var_export($this->getFormFields(), true)); log_message('debug', 'Rules: ' . var_export($dynamicRules, true)); log_message('debug', 'Data: ' . var_export($formDatas, true)); // setRules의 세 번째 인자로 레이블 전달 $validation->setRules($dynamicRules, [], $dynamicLabels); // run()에는 데이터만 전달 (setRules에서 이미 설정됨) $result = $validation->run($formDatas); if ($result === false) { $message = __METHOD__ . "에서 데이터 검증 오류발생: " . var_export($validation->getErrors(), true); log_message('debug', $message); throw new RuntimeException($message); } else { log_message('debug', 'Validate Run Succeeded.'); } return $result; } //필수함수 //사용자정의 함수 protected function getValidationRule(string $field, string $rule): array { return array($field, $rule); } public function getFormFieldLabel(string $field, ?string $label = null): string { switch ($field) { default: $label = $label ?? lang("{$this->getAttribute('class_path')}.label.{$field}"); break; } return $label; } public function getFormRule(string $action, string $field): string { switch ($field) { case $this->getAttribute('pk_field'): if (!$this->getAttribute('useAutoIncrement')) { $rule = sprintf("required|regex_match[/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}/]%s", in_array($action, ["create"]) ? "|is_unique[{$this->getAttribute('table')}.{$field}]" : ""); } else { $rule = "required|numeric"; } break; case $this->getAttribute('title_field'): $rule = sprintf("required|trim|string%s", in_array($action, ["create", "create_form"]) ? "|is_unique[{$this->getAttribute('table')}.{$field}]" : ""); break; case "code": // a-zA-Z → 영문 대소문자,0-9 → 숫자,가-힣 → 한글 완성형,\- → 하이픈 $rule = sprintf("required|regex_match[/^[a-zA-Z0-9가-힣\-]+$/]|min_length[4]|max_length[20]%s", in_array($action, ["create"]) ? "|is_unique[{$this->getAttribute('table')}.{$field}]" : ""); break; case "user_uid": $rule = "required|numeric"; break; case "clientinfo_uid": case "serviceinfo_uid": case "serverinfo_uid": $rule = "permit_empty|numeric"; break; case 'picture': $rule = "is_image[{$field}]|mime_in[{$field},image/jpg,image/jpeg,image/gif,image/png,image/webp]|max_size[{$field},300]|max_dims[{$field},2048,768]"; break; case "updated_at": case "created_at": case "deleted_at": $rule = "permit_empty|trim|valid_date"; break; default: $rule = "permit_empty|trim|string"; break; } return $rule; } protected function getFormOption_process($service, string $action, string $field, array $formDatas = []): array { $entities = []; switch ($field) { default: if (in_array($action, ['create_form', 'modify_form', 'alternative_create_form'])) { if (array_key_exists($field, $formDatas)) { $where = sprintf("status = '%s' OR %s='%s'", STATUS['AVAILABLE'], $this->getAttribute('pk_field'), $formDatas[$field]); } else { $where = sprintf("status = '%s'", STATUS['AVAILABLE']); } $entities = $service->getEntities([$where => null]); } else { $entities = $service->getEntities(); } break; } return $entities; } public function getFormOption(string $action, string $field, array $formDatas = [], array $options = ['options' => [], 'atttributes' => []]): array { $tempOptions = ['' => lang("{$this->getAttribute('class_path')}.label.{$field}") . " 선택"]; switch ($field) { case 'user_uid': foreach ($this->getFormOption_process(service('userservice'), $action, $field, $formDatas) as $entity) { $tempOptions[$entity->getPK()] = $entity->getTitle(); // $options['attributes'][$entity->getPK()] = ['data-role' => implode(DEFAULTS['DELIMITER_ROLE'], $entity->getRole())]; } $options['options'] = $tempOptions; break; case 'clientinfo_uid': foreach ($this->getFormOption_process(service('customer_clientservice'), $action, $field, $formDatas) as $entity) { $tempOptions[$entity->getPK()] = $entity->getTitle(); // $options['attributes'][$entity->getPK()] = ['data-role' => implode(DEFAULTS['DELIMITER_ROLE'], $entity->getRole())]; } $options['options'] = $tempOptions; break; default: $optionDatas = lang($this->getAttribute('class_path') . "." . strtoupper($field)); if (!is_array($optionDatas)) { throw new RuntimeException(static::class . '->' . __FUNCTION__ . "에서 오류발생:{$field}가 배열값이 아닙니다."); } foreach ($optionDatas as $key => $label) { $tempOptions[$key] = $label; } $options['options'] = $tempOptions; break; } return $options; } }