allowedFields = [...$this->allowedFields, "grpno", "grporder", "grpdepth"]; $this->validationRules = [...$this->validationRules,]; } abstract public function getContentField(); abstract public function reply($parent_entity, array $formDatas): BaseEntity; protected function getFieldRule(string $field, array $rules, string $action = ""): array { switch ($field) { case "grpno": case "grporder": case "grpdepth": $rules[$field] = "if_exist|numeric"; //반드시숫자여야함 break; default: $rules = parent::getFieldRule($field, $rules, $action); break; } return $rules; } final protected function create_process($entity, array $formDatas) { //생성시는 grpno의 max값을 구해서 넣는다. $entity->grpno = $this->selectMax("grpno")->get()->getResult()[0]->grpno + 1; if (!$entity->grpno) { throw new \Exception("grpno는 {$entity->grpno}의 값을 가질수 없습니다."); } return parent::create_process($entity, $formDatas); } final protected function reply_process($parent_entity, $entity, array $formDatas) { //부모의 그룹과 grpno가 같고, 부모의 grporder보다 1 큰것을 grporder+1을 해서 update //escape -> false옵션 반드시 있어야함 $this->set("grporder", "grporder+1", false); $this->where([ "grpno" => $parent_entity->grpno, "grporder >" => $parent_entity->grporder ]); $this->update(); //reply용 설정 $entity->grpno = $parent_entity->grpno; $entity->grporder = $parent_entity->grporder + 1; $entity->grpdepth = $parent_entity->grpdepth + 1; return parent::create_process($entity, $formDatas); } public function setIndexOrderBy(?string $field, ?string $order) { //계단식의 경우는 먼저 다른것보다 먼저 orderBy가 수행되어야 하므로 $this->orderBy("grpno", "DESC"); $this->orderBy("grporder", "ASC"); parent::setIndexOrderBy($field, $order); } }