_className = $className; parent::__construct(); $this->allowedFields = ["uid", "updated_at", "created_at"]; if (!$this->useAutoIncrement) { array_push($this->allowedFields, $this->primaryKey); } $this->validationRules = []; $this->_session = \Config\Services::session(); $this->_validation = \Config\Services::validation(); } final protected function getClassName() { return $this->_className; } final public function getPrimaryKey(): string { return $this->primaryKey; } abstract public function getTitleField(): string; public function getEntity($conditions): BaseEntity { return $this->where($conditions)->first() ?: throw new \Exception(__FUNCTION__ . "에서 {$this->getClassName()}의 해당 데이터가 없습니다."); } public function getEntitys(array $conditions = array()): array { return $this->where($conditions)->findAll(); } final public function getUUID() { $randomBytes = bin2hex(random_bytes(32)); return 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) ); } final protected function getUUIDFieldRule($condition = 'required'): string { return "{$condition}|regex_match[/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}/]"; } public function getFieldRule(string $field, array $rules, string $action = ""): array { switch ($field) { case $this->primaryKey: //수동입력인경우 if (!$this->useAutoIncrement) { $rules[$field] = $this->getUUIDFieldRule(); $rules[$field] .= $action == "insert" ? "|is_unique[{$this->table}.{$field}]" : ""; } break; case "user_uid": $rules[$field] = $this->getUUIDFieldRule('if_exist'); break; case "passwd": $rules[$field] = "if_exist|trim|string"; if ($action != "") { $rules["confirmpassword"] = "if_exist|trim|string|matches[passwd]"; } break; case "view_cnt": $rules[$field] = "if_exist|numeric"; break; case "updated_at": case "created_at": case "deleted_at": $rules[$field] = "if_exist|valid_date"; break; default: $rules[$field] = "if_exist|string"; break; } return $rules; } final public function getFieldRules(array $fields, string $action = ""): array { $rules = array(); foreach ($fields as $field) { $rules = $this->getFieldRule($field, $rules, $action); } return $rules; } //추후 VersionUP용 final public function getValidation(array $fields, string $action = "") { $this->_validation->reset(); foreach ($fields as $field) { $this->_validation->setRule( $field, lang($this->getClassName() . '.label.' . $field), $this->getValidationFieldRule($field, $action) ); } return $this->_validation; } //Field별 Form Option용 public function getOptions(array $conditions = array(), $options = array()): array { foreach ($this->getEntitys($conditions) as $entity) { $options[$entity->getPrimaryKey()] = $entity->getTitle(); } return $options; } public function getFieldFormOption(string $field): array { switch ($field) { case 'user_uid': if (is_null($this->_user_options)) { $userModel = new UserModel(); $this->_user_options = $userModel->getOptions(); } $options = $this->_user_options; break; default: $options = lang($this->getClassName() . '.' . strtoupper($field)); break; } if (!is_array($options)) { throw new \Exception(__FUNCTION__ . "에서 {$this->getClassName()}의 Field:{$field}의 FormOptionData가 array가 아닙니다.\n" . var_export($options, true)); } return $options; } //Field별 Form Option용 // final public function getFieldFormOptions(array $fields): array // { // $fieldFormOptions = array(); // foreach ($fields as $field) { // if (!is_string($field)) { // throw new \Exception(__FUNCTION__ . "에서 {$this->getClassName()}의 Field:{$field}가 string 아닙니다.\n" . var_export($fields, true)); // } // $fieldFormOptions[$field] = $this->getFieldFormOption($field); // } // return $fieldFormOptions; // } //create , modify 직전 작업용 작업 protected function changeFormData(string $action, string $field, array $formDatas, $entity) { switch ($field) { case $this->primaryKey: //primaryKey가 수동입력이고 추가(Reply도 결국엔 create_process를 상용)시에만 if ($action == 'create' && !$this->useAutoIncrement) { $pk = $this->primaryKey; $entity->$pk = $this->getUUID(); } break; case "user_uid": //입력데이터로 있을시 관리툴에서 (사용자,등)추가, 없을시는 입력의 경우에만 자동(장바구니,등)으로 추가 if (array_key_exists($field, $formDatas) && !is_null($formDatas[$field])) { //관리툴 USERSNS에서 사용자 연동 시 추가기능등에 사용 $entity->$field = $formDatas[$field]; } elseif ($action == 'create' && $this->_session->get(SESSION_NAMES["ISLOGIN"])) { //Front에서 장바구니,게시판등에 추가시 로그온한경우 자동 추가기능등에 사용 $auth = $this->_session->get(SESSION_NAMES["AUTH"]); $entity->$field = $auth[AUTH_FIELDS["ID"]]; } break; case "passwd": if (array_key_exists($field, $formDatas) && $formDatas[$field]) { $entity->$field = password_hash($formDatas[$field], PASSWORD_DEFAULT); } break; case "content": if (array_key_exists($field, $formDatas) && $formDatas[$field]) { $entity->$field = htmlentities($formDatas[$field]); } break; default: if (array_key_exists($field, $formDatas) && $formDatas[$field]) { $entity->$field = $formDatas[$field]; } break; } return $entity; } final protected function save_process($entity) { // echo var_export($entity, true); // exit; if ($entity->hasChanged()) { if (!$this->save($entity)) { log_message("error", __FUNCTION__ . "에서 호출:" . $this->getLastQuery()); log_message("error", implode("\n", $this->errors())); throw new \Exception(__FUNCTION__ . " 오류 발생.\n" . $this->getLastQuery() . "\n" . var_export($this->errors(), true)); } } else { throw new \Exception(__FUNCTION__ . " 오류 발생.\n 기존정보와 동일하여 수정되지 않았습니다."); } return $entity; } protected function create_process($entity, array $formDatas) { foreach ($this->allowedFields as $field) { $entity = $this->changeFormData('create', $field, $formDatas, $entity); } $entity = $this->save_process($entity); //primaryKey가 자동입력이면 if ($this->useAutoIncrement) { $pk = $this->primaryKey; $entity->$pk = $this->insertID(); } return $entity; } final protected function modify_process($entity, array $formDatas) { foreach ($this->allowedFields as $field) { $entity = $this->changeFormData('modify', $field, $formDatas, $entity); } $entity->updated_at = time(); return $this->save_process($entity); } //Index관련 public function setIndexWordFilter(string $word) { } public function setIndexDateFilter($start, $end) { if ($start !== DEFAULTS['EMPTY'] && $end !== DEFAULTS['EMPTY']) { $this->where("created_at >=", $start); $this->where("created_at <=", $end); } } public function setIndexOrderBy(string $field, string $order) { $this->orderBy($field, $order); } final public function setCondition(array $filterFields, $word, $start, $end, $order_field, $order_value) { foreach ($filterFields as $field => $value) { $this->where($field, $value); } if (!is_null($word)) { $this->setIndexWordFilter($word); } if (!is_null($start) && !is_null($end)) { $this->setIndexDateFilter($start, $end); } $this->setIndexOrderBy($order_field, $order_value); } }