setFields($fields); $this->setRules($this->getFields()); } 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; } final public function getRules(array $options): array //options=>except or only { return $this->getValidationRules($options); } final public function setRules(array $fields, $rules = []): void { foreach ($fields as $field) { $rules = $this->getFieldRule($field, $rules); } $this->setValidationRules($rules); } protected function getFieldRule(string $field, array $rules): 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}/]|is_unique[{$this->table}.{$field}]"; } else { $rules[$field] = "required|numeric"; }; break; case $this->getTitleField(): $rules[$field] = "required|trim|string"; break; case "passwd": $rules[$field] = "required|trim|string"; break; case "confirmpassword": $rules["confirmpassword"] = "required|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, string $field, $value = null): mixed { switch ($field) { case $this->getPKField(): if ($value === 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) ); } else { $entity->$field = $value; } break; case "passwd": $entity->$field = password_hash($value, PASSWORD_DEFAULT); break; case "content": $entity->$field = htmlspecialchars($value, ENT_QUOTES); //htmlentities($value); break; default: $entity->$field = $value; break; } return $entity; } private function save_process($entity): mixed { 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, array $formDatas = []): mixed { foreach ($this->getFields() as $field) { if (array_key_exists($field, $formDatas) && $formDatas[$field] !== $entity->$field) { $entity = $this->setEntityData($entity, $field, $formDatas[$field]); } } //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()); } $entity = $this->save_process($entity); //primaryKey가 자동입력이면 if ($this->useAutoIncrement) { $entity = $this->setEntityData($entity, $this->getPKField(), $this->getInsertID()); } return $entity; } final protected function modify_process($entity, array $formDatas = []): mixed { foreach ($this->getFields() as $field) { if (array_key_exists($field, $formDatas) && $formDatas[$field] !== $entity->$field) { $entity = $this->setEntityData($entity, $field, $formDatas[$field]); } } return $this->save_process($entity); } }