field가 array 입니다.\n" . var_export($field, true)); } switch ($field) { case $this->getPKField(): // 수동입력인 경우 if (!$this->useAutoIncrement) { $rule = "required|regex_match[/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}/]"; $rule .= in_array($action, ["create", "create_form"]) ? "|is_unique[" . $this->getTable() . "." . $field . "]" : ""; } else { $rule = "required|numeric"; } break; case $this->getTitleField(): $rule = "required|trim|string"; break; case "code": // a-zA-Z → 영문 대소문자,0-9 → 숫자,가-힣 → 한글 완성형,\- → 하이픈 $rule = "required|regex_match[/^[a-zA-Z0-9가-힣\-]+$/]|min_length[4]|max_length[20]"; $rule .= in_array($action, ["create", "create_form"]) ? "|is_unique[" . $this->getTable() . "." . $field . "]" : ""; 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|valid_date"; break; default: $rule = "permit_empty|trim|string"; break; } return $rule; } // create, modify 직전 작업용 작업 protected function convertFormDatas(string $action, string $field, array $formDatas): mixed { // 필드 값 존재 여부 확인 $value = array_key_exists($field, $formDatas) ? $formDatas[$field] : null; switch ($field) { case $this->getPKField(): // 수동입력인 경우 if (!$this->useAutoIncrement) { $randomBytes = bin2hex(random_bytes(32)); $value = sprintf( '%08s-%04s-%04x-%04x-%12s', substr($randomBytes, 0, 8), substr($randomBytes, 8, 4), substr($randomBytes, 12, 4), substr($randomBytes, 16, 4), substr($randomBytes, 20, 12) ); } break; case "editor": case "detail": case "content": case "discription": case "history": // textarea 계열은 XSS 방지 if ($value === '' || $value === null) { //값이 없거나 빈데이터면 아무것도 하지 않음 } elseif ($value === ' ') { $value = ''; // 공백 하나를 넣어서 의도적인 빈칸 저장 } else { $value = htmlentities($value, ENT_QUOTES, 'UTF-8'); } break; } return $value; } public function create(array $formDatas): mixed { // LogCollector::debug("입력내용"); // LogCollector::debug(var_export($formDatas, true)); $convertedFormDatas = []; foreach ($this->allowedFields as $field) { $value = $this->convertFormDatas( __FUNCTION__, $field, $formDatas ); if ($value !== null) { $convertedFormDatas[$field] = $value; } } // 최종 저장 시 오류 발생하면 if (!$this->save($convertedFormDatas)) { $message = sprintf( "\n------%s 오류-----\n%s\n%s\n------------------------------\n", __METHOD__, var_export($this->errors(), true), $this->getLastQuery() ); LogCollector::debug($message); throw new \Exception($message); } //Model별 returntype형의 Entity 호출 if (!class_exists($this->returnType)) { throw new \RuntimeException(__METHOD__ . "에서 returnType: {$this->returnType}이 정의되지 않았습니다."); } $entity = new $this->returnType($convertedFormDatas); // primaryKey가 자동입력이면 if ($this->useAutoIncrement) { $pkField = $this->getPKField(); $entity->$pkField = $this->getInsertID(); } $debug = sprintf("debug.%s.%s", str_replace("\\", ".", get_class($this)), __FUNCTION__); if (env($debug, false)) { echo var_dump($formDatas); dd($entity->toArray()); } return $entity; } public function modify(mixed $entity, array $formDatas): mixed { // 저장하기 전에 데이터 값 변경이 필요한 Field // LogCollector::debug("[{$entity->getPK()}/{$entity->getTitle()}] 변경 전 내용"); // LogCollector::debug(var_export($formDatas, true)); // LogCollector::debug(var_export($entity->toArray(), true)); foreach ($this->allowedFields as $field) { $value = $this->convertFormDatas( __FUNCTION__, $field, $formDatas ); if ($value !== null) { $entity->$field = $value; } } //수정일추가 $entity->setUpdatedAt(date("Y-m-d H:i:s")); // 최종 저장 시 오류 발생하면 if (!$this->save($entity)) { $message = sprintf( "\n------%s 오류-----\n%s\n------------------------------\n", __METHOD__, var_export($this->errors(), true) ); LogCollector::debug($message); throw new \Exception($message); } $debug = sprintf("debug.%s.%s", str_replace("\\", ".", get_class($this)), __FUNCTION__); if (env($debug, false)) { echo var_dump($formDatas); dd($entity->toArray()); } return $entity; } }