001002003004005006007008009010011012013014015016017018019020021022023024025026027028029030031032033034035036037038039040041042043044045046047048049050051052053054055056057058059060061062063064065066067068069070071072073074075076077078079080081082083084085086087088089090091092093094095096097098099100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315
<?php // (2020.11.25, 차재복, Cha Jae Bok, http://www.ktword.co.kr) // id 노드 위 아래로 이동 function id_move_updown($act, $id, $dbi, $table_name) { // 선택 id의 parent,sub_seq 알아보기 $result = mysqli_query($dbi,"select parent,sub_seq from {$table_name} where id=$id"); if (mysqli_errno($dbi)) { $err_msg .= mysqli_errno($dbi)." : ".mysqli_error($dbi)."\n"; } $matched = mysqli_fetch_assoc($result); $parent = $matched[parent]; $sub_seq = $matched[sub_seq]; if ($act == 'id_up') { $near_offset = "(sub_seq+1)"; // 직전 id를 하향 이동 $where_offset = "($sub_seq-1)"; // 직전 id 위치 저장 $self_offset = "($sub_seq-1)"; // 해당 id를 상향 이동 } else if ($act == 'id_down') { $near_offset = "(sub_seq-1)"; // 직후 id를 상향 이동 $where_offset = "($sub_seq+1)"; // 직후 id 위치 저장 $self_offset = "($sub_seq+1)"; // 해당 id를 하향 이동 } // 직전 또는 직후 id를 하향 이동 mysqli_query($dbi,"update {$table_name} set sub_seq={$near_offset} where parent=$parent and sub_seq={$where_offset}"); if (mysqli_errno($dbi)) { $err_msg .= mysqli_errno($dbi)." : ".mysqli_error($dbi)."\n"; } // 해당 id를 상향 또는 하향 이동 if ( mysqli_affected_rows($dbi) > 0 ) { mysqli_query($dbi,"update {$table_name} set sub_seq={$self_offset} where id=$id"); if (mysqli_errno($dbi)) { $err_msg .= mysqli_errno($dbi)." : ".mysqli_error($dbi)."\n"; } } else { $notice = "처음 또는 끝이라서 이동 없음"; } // next parent의 산하 자식 노드들의 정보 $nextParentChilds = nextParentChilds($parent, $dbi); // 결과 리턴 if (empty($err_msg)) { $return = array('notice'=> (empty($notice) ? "상향/하향 이동 성공" : $notice), 'nextParentChilds'=>$nextParentChilds); } else { $return = array('err_msg'=>$err_msg); } echo json_encode($return, JSON_UNESCAPED_UNICODE); } // id 노드 맨 위로 이동 function id_first_last($ch, $id, $dbi, $table_name) { if ($ch != 'id_first' and $ch != 'id_last') return; // 선택 id의 parent,sub_seq 알아보기 $result = mysqli_query($dbi,"select parent,sub_seq from {$table_name} where id=$id"); if (mysqli_errno($dbi)) { $err_msg .= mysqli_errno($dbi)." : ".mysqli_error($dbi)."\n"; } $matched = mysqli_fetch_assoc($result); $parent = $matched[parent]; $sub_seq = $matched[sub_seq]; // 현재 id의 부모 산하 최대 sub_seq 값 $result = mysqli_query($dbi,"select max(sub_seq) as max from {$table_name} where parent=$parent"); if (mysqli_errno($dbi)) { $err_msg .= mysqli_errno($dbi)." : ".mysqli_error($dbi)."\n"; } $matched = mysqli_fetch_assoc($result); $max = $matched[max]; // 맨 앞 여부 체킹 if ( ($ch == 'id_first' and $sub_seq == '1') and ($ch == 'id_last' and $sub_seq == $max) ) { $err_msg .= "현재 맨 앞 또는 맨 뒤이므로 이동 안됨"; $return = array('err_msg'=>$err_msg); echo json_encode($return, JSON_UNESCAPED_UNICODE); return; } if ($ch == 'id_first') { $seq_offset = "(sub_seq+1)"; $reference = "sub_seq<{$sub_seq}"; $first_last = 1; } else if ($ch == 'id_last') { $seq_offset = "(sub_seq-1)"; $reference = "sub_seq>{$sub_seq}"; $first_last = $max; } // 선택된 id의 이전 sub_seq 모두를 (sub_seq+1) 또는 (sub_seq-1) 만큼 앞 또는 뒤로 이동 $query = "update {$table_name} set sub_seq={$seq_offset} where parent=$parent and {$reference}"; //$err_msg .= $query."\n"; mysqli_query($dbi, $query); if (mysqli_errno($dbi)) { $err_msg .= mysqli_errno($dbi)." : ".mysqli_error($dbi)."\n"; } // 선택된 id를 맨 앞으로 이동 $query = "update {$table_name} set sub_seq={$first_last} where id={$id}"; //$err_msg .= $query."\n"; mysqli_query($dbi, $query); if (mysqli_errno($dbi)) { $err_msg .= mysqli_errno($dbi)." : ".mysqli_error($dbi)."\n"; } // next parent의 산하 자식 노드들의 정보 $nextParentChilds = nextParentChilds($parent, $dbi); // 결과 리턴 if (empty($err_msg) and mysqli_affected_rows($dbi) > 0) { $return = array('notice'=>"맨 앞 또는 맨 뒤로 이동 성공",'nextParentChilds'=>$nextParentChilds); } else { $return = array('err_msg'=>$err_msg); } echo json_encode($return, JSON_UNESCAPED_UNICODE); } // id 노드 레벨업 이동 function id_level_up($ch, $id, $dbi, $table_name) { if ($ch != 'id_level_up') return; // (현재 레벨) 선택 id의 parent,sub_seq,$depth,path2node 알아보기 $query = "select parent,sub_seq,depth,path2node from {$table_name} where id=$id"; $result = mysqli_query($dbi, $query); if (mysqli_errno($dbi)) { $err_msg .= mysqli_errno($dbi)." : ".mysqli_error($dbi)."\n"; } $matched = mysqli_fetch_assoc($result); $old_parent = $matched[parent]; $old_sub_seq = $matched[sub_seq]; $old_depth = $matched[depth]; $old_path2node = $matched[path2node]; // 레벨 1 여부 체킹 if ($old_depth == '1') { $err_msg .= "레벨 1 이므로 레벨업 안됨!!!"; $return = array('err_msg'=>$err_msg . '레벨업 실패 에러'); echo json_encode($return, JSON_UNESCAPED_UNICODE); return; } // (현재 레벨) 직후 id들을 하나씩 상향 이동 (-1씩 감소) $query = "update {$table_name} set sub_seq=(sub_seq-1) where parent=$old_parent and sub_seq>($old_sub_seq+1)"; mysqli_query($dbi, $query); if (mysqli_errno($dbi)) { $err_msg .= mysqli_errno($dbi)." : ".mysqli_error($dbi)."\n"; } // (현재 레벨) (자신 포함 모든 자식들의) path2node 변경 및 레벨업(depth-1) $replace = "trim(trailing ',' from replace(concat(path2node,','),concat(',','{$old_parent},{$id}',','),concat(',','{$id}',',')))"; $query = "update {$table_name} set path2node={$replace},depth=depth-1 where concat(path2node,',') like concat('%,','{$old_parent},{$id}',',%')"; $result = mysqli_query($dbi, $query); if (mysqli_errno($dbi)) { $err_msg .= mysqli_errno($dbi)." : ".mysqli_error($dbi)."\n"; } // (상위 레벨) parent의 parent,sub_seq,depth 알아보기 $query = "select parent,sub_seq from {$table_name} where id=$old_parent"; $result = mysqli_query($dbi, $query); if (mysqli_errno($dbi)) { $err_msg .= mysqli_errno($dbi)." : ".mysqli_error($dbi)."\n"; } $matched = mysqli_fetch_assoc($result); $next_parent = $matched[parent]; $next_sub_seq = $matched[sub_seq]; // (상위 레벨) 직후 id들을 하나씩 하향 이동 (+1씩 증가) $query = "update {$table_name} set sub_seq=(sub_seq+1) where parent=$next_parent and sub_seq>$next_sub_seq"; $result = mysqli_query($dbi, $query); if (mysqli_errno($dbi)) { $err_msg .= mysqli_errno($dbi)." : ".mysqli_error($dbi)."\n"; } // (상위 레벨) 해당 id의 레벨업 삽입 $query = "update {$table_name} set parent=$next_parent,sub_seq=($next_sub_seq+1) where id=$id"; $result = mysqli_query($dbi, $query); if (mysqli_errno($dbi)) { $err_msg .= mysqli_errno($dbi)." : ".mysqli_error($dbi)."\n"; } // (하위 레벨) 기존 하위레벨 parent의 child에 자식노드 갯수 업데이트 $query = "UPDATE {$table_name} a LEFT JOIN (SELECT parent,count(*) as cnt FROM {$table_name} GROUP BY parent) b ON a.id=b.parent SET a.child=IFNULL(b.cnt,0) WHERE a.id=$old_parent LIMIT 1"; $result = mysqli_query($dbi, $query); if (mysqli_errno($dbi)) { $err_msg .= mysqli_errno($dbi)." : ".mysqli_error($dbi)."\n"; } // (상위 레벨) 해당 id의 path2node,sub_seq 확인 $query = "select path2node,sub_seq from {$table_name} where id=$id"; $result = mysqli_query($dbi, $query); if (mysqli_errno($dbi)) { $err_msg .= mysqli_errno($dbi)." : ".mysqli_error($dbi)."\n"; } $matched = mysqli_fetch_assoc($result); $path2node = $matched[path2node]; $next_sub_seq = $next_sub_seq + 1; // (상위 레벨) next parent의 산하 자식 노드들의 정보 $nextParentChilds = nextParentChilds($next_parent, $dbi); // 결과 리턴 if (empty($err_msg)){ $return = array('notice'=>'레벨업 성공 !!!', 'path2node'=>$path2node,'next_parent'=>$next_parent,'sub_seq'=>$next_sub_seq,'nextParentChilds'=>$nextParentChilds); } else { $return = array('err_msg'=>$err_msg . '레벨업 실패 에러'); } echo json_encode($return, JSON_UNESCAPED_UNICODE); } // id 노드 레벨다운 이동 function id_level_down($ch, $id, $dbi, $table_name) { if ($ch != 'id_level_down') return; // (현재 레벨) 선택 id의 parent,id,sub_seq,$depth,path2node 알아보기 $query = "select parent,sub_seq,depth,path2node from {$table_name} where id=$id"; $result = mysqli_query($dbi, $query); if (mysqli_errno($dbi)) { $err_msg .= mysqli_errno($dbi)." : ".mysqli_error($dbi)."\n"; } $matched = mysqli_fetch_assoc($result); $parent = $matched[parent]; $sub_seq = $matched[sub_seq]; $depth = $matched[depth]; $path2node = $matched[path2node]; // 현재 id가 처음인지 여부 체킹 if ($sub_seq == '1') { $err_msg .= "처음이므로 레벨다운 안됨!!!"; $return = array('err_msg'=>$err_msg . '레벨다운 실패 에러'); echo json_encode($return, JSON_UNESCAPED_UNICODE); return; } // (현재 레벨) 직전 id 찾음 $query = "select id from {$table_name} where parent=$parent and sub_seq=($sub_seq-1)"; $result = mysqli_query($dbi, $query); if (mysqli_errno($dbi)) { $err_msg .= mysqli_errno($dbi)." : ".mysqli_error($dbi)."\n"; } $matched = mysqli_fetch_assoc($result); $prev_id = $matched[id]; // (현재 레벨) 직후 id들을 하나씩 상향 이동 (-1씩 감소) $query = "update {$table_name} set sub_seq=(sub_seq-1) where parent=$parent and sub_seq>$sub_seq"; mysqli_query($dbi, $query); if (mysqli_errno($dbi)) { $err_msg .= mysqli_errno($dbi)." : ".mysqli_error($dbi)."\n"; } // (자신 포함 모든 자식들) path2node 변경 및 레벨다운(depth+1) $replace = "replace(concat(',',path2node,','),concat(',','{$id}',','),concat(',','{$prev_id},{$id}',','))"; $replace = "trim(both ',' from {$replace})"; $query = "update {$table_name} set path2node={$replace},depth=depth+1 where concat(path2node,',') like concat('%,','{$id}',',%')"; $result = mysqli_query($dbi, $query); if (mysqli_errno($dbi)) { $err_msg .= mysqli_errno($dbi)." : ".mysqli_error($dbi)."\n"; } // (하위 레벨) 현재 parent의 끝 알아보기 (max sub_seq) $query = "select max(sub_seq) as max from {$table_name} where parent=$prev_id"; $result = mysqli_query($dbi, $query); if (mysqli_errno($dbi)) { $err_msg .= mysqli_errno($dbi)." : ".mysqli_error($dbi)."\n"; } $matched = mysqli_fetch_assoc($result); $max_sub_seq = $matched[max]; // (하위 레벨) 해당 id의 레벨다운 끝에 삽입 $query = "update {$table_name} set parent=$prev_id,sub_seq=($max_sub_seq+1) where id=$id"; $result = mysqli_query($dbi, $query); if (mysqli_errno($dbi)) { $err_msg .= mysqli_errno($dbi)." : ".mysqli_error($dbi)."\n"; } // (하위 레벨) 하위레벨 parent의 child에 자식노드 갯수 업데이트 $query = "update {$table_name} set child=($max_sub_seq+1) where id=$prev_id"; $result = mysqli_query($dbi, $query); if (mysqli_errno($dbi)) { $err_msg .= mysqli_errno($dbi)." : ".mysqli_error($dbi)."\n"; } // 해당 id의 path2node,sub_seq 알아보기 $query = "select path2node,sub_seq from {$table_name} where id=$id"; $result = mysqli_query($dbi, $query); if (mysqli_errno($dbi)) { $err_msg .= mysqli_errno($dbi)." : ".mysqli_error($dbi)."\n"; } $matched = mysqli_fetch_assoc($result); $path2node = $matched[path2node]; $sub_seq = $matched[sub_seq]; // next parent의 산하 자식 노드들의 정보 $nextParentChilds = nextParentChilds($prev_id, $dbi); // 결과 리턴 if (empty($err_msg)){ $return = array('notice'=>'레벨다운 성공 !!!', 'path2node'=>$path2node,'next_parent'=>$prev_id,'sub_seq'=>$sub_seq,'nextParentChilds'=>$nextParentChilds); } else { $return = array('err_msg'=>$err_msg . '레벨다운 실패 에러'); } echo json_encode($return, JSON_UNESCAPED_UNICODE); } // path2node, depth 업데이트 함수 function path_depth_update ($id, $dbi, $table_name) { $query = "update {$table_name} set path2node=concat('0,',replace(substring_index(getpath_v2(id),'|',-1),'::',',')), depth=round( ( length(path2node) - length(replace(path2node,';;','')) )/length(';;') ) where id=".$id; $result = mysqli_query($dbi,$query); if (mysqli_errno($dbi)) { echo mysqli_errno($dbi)." : ".mysqli_error($dbi)."\n";} } // function nextParentChilds($id, $dbi) { $query = "select a.id,a.parent,a.sub_seq,a.name,a.name_2nd, a.path2node,a.child,a.yoyak, b.more_type,b.more_subtype,b.more_ptr,b.dir,b.file,b.func from reform a left join reform_more b on a.id=b.id where a.parent={$id} order by a.sub_seq"; $result = mysqli_query($dbi,$query); if (mysqli_errno($dbi)) {echo mysqli_errno($dbi)." : ".mysqli_error($dbi)."\n";} while ($matched = mysqli_fetch_assoc($result)) { $title = ( empty($matched[name_2nd]) ? $matched[name] : $matched[name_2nd] ); $arr[$matched[sub_seq]] = array('id'=>$matched[id], 'parent'=>$matched[parent], 'sub_seq'=>$matched[sub_seq], 'title'=>$title, 'title_orig'=>$matched[name], 'path2node'=>$matched[path2node], 'child'=>$matched[child], 'yoyak'=>$matched[yoyak], 'more_type'=>$matched[more_type], 'more_subtype'=>$matched[more_subtype], 'more_ptr'=>$matched[more_ptr], 'dir'=>$matched[dir], 'file'=>$matched[file], 'func'=>$matched[func] ); } return $arr; }