<?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;
}