_classPaths[] = $path; } final public function getClassPaths($isArray = true, $delimeter = DIRECTORY_SEPARATOR): array|string { return $isArray ? $this->_classPaths : implode($delimeter, $this->_classPaths); } final public function getEntity(string|int|array $where, ?string $message = null): mixed { try { $entity = is_array($where) ? $this->model->where($where)->first() : $this->model->find($where); if (!$entity) { return null; } if (is_array($entity)) { throw new \Exception(__METHOD__ . "에서 결과값 Array 오류발생:\n" . var_export($entity, true)); } return $this->getEntity_process($entity); } catch (\Exception $e) { $message = sprintf( "\n------%s SQL오류-----
\n%s\n%s\n------------------------------\n", __FUNCTION__, $this->model->getLastQuery(), $e->getMessage() ); throw new \Exception($message); } } final public function getEntities(mixed $where = null, array $columns = ['*']): array { try { return $this->getEntities_process($where, $columns); } catch (\Exception $e) { $message = sprintf( "\n------%s SQL오류-----
\n%s\n%s\n------------------------------\n", __FUNCTION__, $this->model->getLastQuery(), $e->getMessage() ); throw new \Exception($message); } } // final public function getLatestPK(): int { $row = $this->model->selectMax($this->model->getPKField())->get()->getRow(); return isset($row->uid) ? ((int)$row->uid + 1) : 1; } //Entity관련 protected function getEntity_process(mixed $entity): mixed { return $entity; } //entities를 가져오는 조건 protected function getEntities_process(mixed $where = null, array $columns = ['*']): array { if ($where) { $this->model->where($where); } //출력순서 정의 $this->setOrderBy(); $entities = []; foreach ($this->model->select(implode(',', $columns))->findAll() as $entity) { $entities[$entity->getPK()] = $this->getEntity_process($entity); } return $entities; } //Validation용 final protected function getValidationRules(string $action, array $allRules = []): array { foreach ($this->getFormService()->getFormFields($action) as $field) { $allRules = array_merge($allRules, $this->getValidationRule($action, $field, $allRules)); } return $allRules; } protected function getValidationRule(string $action, string $field, array $rules = []): array { switch ($field) { default: $rules[$field] = $this->getFormService()->getValidationRule($action, $field); break; } return $rules; } //CURD 결과처리용 //DB 결과 처리 로직 통합 및 개선 protected function handle_save_result(mixed $result, $entity): CommonEntity { if (!$result) { // static::class는 현재 호출된 자식 클래스 이름 반환 throw new RuntimeException(static::class . "에서 {$entity->getTitle()} 등록/수정 중 DB 오류가 발생하였습니다."); } // 2. 최종 PK 값 결정 (insert/update 공통) $pkValue = $this->model->useAutoIncrement() && is_numeric($result) && (int)$result > 0 ? (int)$result : $entity->{$this->model->primaryKey}; if (empty($pkValue)) { throw new RuntimeException("{$entity->getTitle()} 저장 후 Primary Key를 확인할 수 없습니다."); } // 3. Entity 재조회 (수정 및 생성 모두 최신 DB 상태 반영) $savedEntity = $this->model->find($pkValue); if (!$savedEntity) { throw new RuntimeException("등록/수정된 데이터를 찾을 수 없습니다. (PK: {$pkValue})"); } return $savedEntity; } //생성용 abstract protected function create_process(array $formDatas): CommonEntity; public function create(object $dto): CommonEntity { $formDatas = (array) $dto; if (!service('validation')->setRules($this->getValidationRules(__FUNCTION__))->run($formDatas)) { throw new ValidationException(implode("\n", service('validation')->getErrors())); } $entity = $this->create_process($formDatas); $result = $this->model->insert($entity, $this->model->useAutoIncrement()); return $this->handle_save_result($result, $entity); } //수정용 abstract protected function modify_process(array $formDatas): array; public function modify(object $dto): CommonEntity { $formDatas = (array) $dto; if (!service('validation')->setRules($this->getValidationRules(__FUNCTION__))->run($formDatas)) { throw new ValidationException(implode("\n", service('validation')->getErrors())); } list($pk, $updateData) = $this->modify_process($formDatas); $entity = new ($this->model->returnType)($updateData); // 재조회에 필요한 PK를 얻기 위함 $result = $this->model->update($pk, $updateData); return $this->handle_save_result($result, $entity); } protected function delete_process($uid): bool { return $this->model->delete($uid); } final public function delete($uid): bool { return $this->delete_process($uid); } //Index용 final public function getTotalCount(): int { return $this->model->countAllResults(false); } //Limit처리 final public function setLimit(int $per_page): void { $this->model->limit($per_page); } //Offset처리 final public function setOffset(int $offset): void { $this->model->offset($offset); } public function index_condition_filterField(string $field, mixed $filter_value): void { switch ($field) { default: $this->model->where("{$this->model->getTable()}.{$field}", $filter_value); break; } } //검색어조건절처리 public function index_condition_filterWord(string $word): void { $this->model->orLike($this->model->getTable() . "." . $this->model->getTitleField(), $word, 'both'); } //날자검색 public function index_condition_filterDate(string $start, string $end): void { $this->model->where(sprintf("%s.created_at >= '%s 00:00:00'", $this->model->getTable(), $start)); $this->model->where(sprintf("%s.created_at <= '%s 23:59:59'", $this->model->getTable(), $end)); } //OrderBy 처리 public function setOrderBy(mixed $field = null, mixed $value = null): void { if ($field !== null && $value !== null) { $this->model->orderBy(sprintf("%s.%s %s", $this->model->getTable(), $field, $value)); } } // //단일작업 // protected function toggle_process(mixed $entity, array $formDatas): mixed // { // return $this->model->modify($entity, $formDatas); // } // public function toggle(mixed $entity, array $formDatas): mixed // { // $db = \Config\Database::connect(); // try { // //트랜잭션 도중 DB 오류가 발생하면 DatabaseException을 던지도록 설정 // $db->transException(true)->transStart(); // $entity = $this->toggle_process($entity, $formDatas); // $db->transComplete(); // return $entity; // } catch (DatabaseException $e) { //DB 오류시 발생 // throw new RuntimeException(sprintf( // "\n----[%s]에서 트랜잭션 실패: DB 오류----\n%s\n%s\n------------------------------\n", // __METHOD__, // $this->model->getLastQuery(), // $e->getMessage() // ), $e->getCode(), $e); // } catch (\Throwable $e) { // 그 외 다른 종류의 예외 처리 // $db->transRollback(); // 예외 발생 시 수동으로 롤백 // throw new RuntimeException($e->getMessage(), 0, $e); // } // } // //일괄처리작업 // protected function batchjob_process(mixed $entity, array $formDatas): mixed // { // return $this->model->modify($entity, $formDatas); // } // public function batchjob(mixed $entity, array $formDatas): mixed // { // $db = \Config\Database::connect(); // try { // //트랜잭션 도중 DB 오류가 발생하면 DatabaseException을 던지도록 설정 // $db->transException(true)->transStart(); // $entity = $this->batchjob_process($entity, $formDatas); // $db->transComplete(); // return $entity; // } catch (DatabaseException $e) { //DB 오류시 발생 // throw new RuntimeException(sprintf( // "\n----[%s]에서 트랜잭션 실패: DB 오류----\n%s\n%s\n------------------------------\n", // __METHOD__, // $this->model->getLastQuery(), // $e->getMessage() // ), $e->getCode(), $e); // } catch (\Throwable $e) { // 그 외 다른 종류의 예외 처리 // $db->transRollback(); // 예외 발생 시 수동으로 롤백 // throw new RuntimeException($e->getMessage(), 0, $e); // } // } // //삭제 // protected function delete_process(string $uid): void // { // if (!$this->model->delete($uid)) { // // delete() 메서드 실패 시 모델의 errors()를 통해 상세 정보 확인 // $errors = $this->model->errors(); // throw new RuntimeException("모델 삭제 실패: " . var_export($errors, true)); // } // } // public function delete(mixed $entity): mixed // { // $db = \Config\Database::connect(); // $db->transStart(); // try { // //트랜잭션 도중 DB 오류가 발생하면 DatabaseException을 던지도록 설정 // $db->transException(true)->transStart(); // $this->delete_process($entity->getPK()); // $db->transComplete(); // return $entity; // } catch (DatabaseException $e) { //DB 오류시 발생 // throw new RuntimeException(sprintf( // "\n----[%s]에서 트랜잭션 실패: DB 오류----\n%s\n%s\n------------------------------\n", // __METHOD__, // $this->model->getLastQuery(), // $e->getMessage() // ), $e->getCode(), $e); // } catch (\Throwable $e) { // 그 외 다른 종류의 예외 처리 // $db->transRollback(); // 예외 발생 시 수동으로 롤백 // throw new RuntimeException($e->getMessage(), 0, $e); // } // } }