setFields($fields); } abstract public function getTitleField(): string; public function getPKField(): string { return $this->primaryKey; } final public function getFields(array $options = []): array //options=>except or only { if (isset($options['except'])) { return array_diff_key($this->allowedFields, array_flip($options['except'])); } elseif (isset($options['only'])) { return array_intersect_key($this->allowedFields, array_flip($options['only'])); } return $this->allowedFields; } final public function setFields(array $fields): void { $this->allowedFields = $fields; $this->setRules($this->allowedFields); } final public function getRules(array $options): array //options=>except or only { return $this->getValidationRules($options); } final public function setRules(array $fields, $rules = [], $isCreate = true): void { foreach ($fields as $field) { $rules = $this->getFieldRule($field, $rules, $isCreate); } $this->setValidationRules($rules); } protected function getFieldRule(string $field, array $rules, $isCreate = true): array { switch ($field) { case $this->getPKField(): //수동입력인경우 if (!$this->useAutoIncrement) { $rules[$field] = "required|regex_match[/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}/]"; $rules[$field] = $isCreate ? "|is_unique[{$this->table}.{$field}]" : ""; } else { $rules[$field] = "required|numeric"; }; break; case $this->getTitleField(): $rules[$field] = "required|string"; break; case "passwd": $rules[$field] = $isCreate ? "required|trim|string" : "if_exist|trim|string"; $rules["confirmpassword"] = $isCreate ? "required|trim|string|matches[passwd]" : "if_exist|trim|string|matches[passwd]"; break; case "email": $rules[$field] = "if_exist|trim|valid_email"; break; case 'image': $rules[$field] = "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": $rules[$field] = "if_exist|valid_date"; break; default: $rules[$field] = "if_exist|string"; break; } return $rules; } final public function getEntity(): array|object|null { return $this->asObject($this->returnType)->first(); } final public function getEntitys(): array { return $this->asObject($this->returnType)->findAll(); } //create , modify 직전 작업용 작업 protected function setEntityData($entity, $field): mixed { switch ($field) { case $this->getPKField(): if ($$entity->$field === null) { $randomBytes = bin2hex(random_bytes(32)); $entity->$field = 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 "passwd": $entity->$field = password_hash($entity->$field, PASSWORD_DEFAULT); break; case "content": if ($entity->$field !== null) { $entity->$field = htmlentities($entity->$field, ENT_QUOTES); } break; } return $entity; } private function save_process($entity): mixed { foreach ($this->getFields() as $field) { $entity = $this->setEntityData($entity, $field); } 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_dump($this->errors(), true)); } } else { throw new \Exception(__FUNCTION__ . " 오류 발생.\n 기존정보와 동일하여 수정되지 않았습니다."); } return $entity; } final protected function create_process($entity): mixed { //primaryKey가 수동입력이면 $pkField = $this->getPKField(); if (!$this->useAutoIncrement && $entity->$pkField === null) { //PrimayKey Field를 allowedFields의 맨앞에 넣기 -> array_unshif array_unshift($this->allowedFields, $this->getPKField()); $entity = $this->setEntityData($entity, $this->getPKField()); //Create용 Rule다시적용 $this->setRules($this->getFields(), [], true); } $entity = $this->save_process($entity); //primaryKey가 자동입력이면 if ($this->useAutoIncrement) { $entity->$pkField = $this->getInsertID(); } return $entity; } final protected function modify_process($entity): mixed { //Create용 Rule다시적용 $this->setRules($this->getFields(), [], false); return $this->save_process($entity); } }