TIP게시판

제목 ci 답변형 게시판입니다.
글쓴이 개발사랑 작성시각 2013/02/06 14:14:42
댓글 : 20 추천 : 0 스크랩 : 0 조회수 : 18516   RSS
제가 이해한 로직이 맞는지도 점검할겸 글을 올립니다.
잘못되었으면 말씀해주세요.
일전에 다른분이 올려주신 소스에 답글과 spac_editor 등을 추가했습니다.
아 코드이그나이터를 이용해서 만들었습니다.
액티브레코드도 부분 부분 사용했습니다.

먼저 4가지의 필드가 필요합니다.
no = int로서 순차적으로 증가되는 각 필드의 고유값
list_number = 실제 정렬된 순서를 지정하는 필드
depth = 답글의 깊이를 정함
parent = 원본글의 no 값(저도 다른곳의 포스트를 보고 만들었는데 실제로서는 이 필드는 거의 필요가 없는듯 합니다.)

일단 리스트 출력상에서는 list_number asc로 출력합니다.

새글 기입시
등록된 글이 없이 처음일시 list_number에 무조건 1을 기입하도록 합니다.
새글등록시 이미 등록된 글에 가장 최신 list_number에 -1을 해 list_number를 등록하게 되어 있습니다.
이때 로직상 -1 이거나 0으로 되면 1로 세팅해서 업데이트 시킵니다.
그 이외에는 새 글 기입시 등록된 글보다 no값이 작은 경우 무조건 list_number를 +1시키고
새글은 등록된 글 중 가장 작은 list_number 값을 추출해 그 값에 -1을 해 입력시킵니다.
이때 parent_id는 원본글의 값 depth는 1로 세팅합니다.

답변글 등록시
parent_id는 원본글의 값 depth는 원본글의 depth에서 +1를 해 처리합니다.
list_number는 원본글의 list_number보다 큰 경우 전부 +1을 해주고 새글의 list_number는 원본글의 list_number에서
+1을 해 처리합니다. 그러면 원본글의 list_number보다 큰 경우와 원본글 사이에 숫자가 하나남는 상황이 생기고
그 숫자로 답글이 처리되어 list_number asc를 하면 답글이 원본글의 바로 밑에 출력됩니다.
아래는 소스입니다. 저도 정리한다고 남기는글인데 두서 없네요 혹시 의문사항이 생기시면 답글 바랍니다.


새글 기입시 (주석참고)
$this->title = $_POST['title'];
$this->memo = $_POST['memo'];
$this->name = $_POST['name'];
$this->img01 = $_FILES['userfile']['name'];
$this->ip = $_SERVER["REMOTE_ADDR"];
$this->date = date("Y-m-d H:i:s",time());

/*
$this->db->select_max('thread');
$result_set = $this->db->get('board');

$thread_array = $result_set->result_array();

print_r($thread_array);
exit;
*/
$this->db->insert('board', $this);

// 핵심은 list_number 필드에 있다.
// 그런데 데이터 많으면 부하걸리겠다. list_number를 계속 업데이트 해주어야 한다.

// 삽입된 원글의 아이디값을 추출한다.
$id = $this->db->insert_id();

// 원글보다 먼저 등록된 글들의 list_number를 다 1씩 증가시킨다.
// 왜냐하면 답글이 아니고 신규글이기 때문에 제일 위에 정렬된다.
$this->db->query("update board set list_number=list_number+1 where no <".$id);

// 가장작은 리스트 넘버의 값을 추출해서 거기에 -1를 한 값이 최종글의 번호가 된다.
// 게시판 리스트 정렬시에는 가장 작은 값이 위에 오게된다.
$res = $this->db->query("select min(list_number) as list_number_min from board");

$board_array = $res->result_array();

$num_rows = $res->num_rows();

$set_list_number = $board_array[0]['list_number_min'] - 1;

if($set_list_number == -1 || $set_list_number == 0)
{
$set_list_number = 1;
}

$data = array(
'list_number' => $set_list_number,
'depth' => 1,
'parent' => $id
);

$this->db->where('no', $id);
$this->db->update('board', $data);

답글 기입시(주석참고)
$this->title = $_POST['title'];
$this->memo = $_POST['memo'];
$this->name = $_POST['name'];
$this->img01 = $_FILES['userfile']['name'];
$this->ip = $_SERVER["REMOTE_ADDR"];
$this->date = date("Y-m-d H:i:s",time());
/*
$this->db->select_max('thread');
$result_set = $this->db->get('board');

$thread_array = $result_set->result_array();

print_r($thread_array);
exit;
*/
$this->db->insert('board', $this);

$id = $this->db->insert_id();

// 답글의 원본글의 정보를 추출한다.
$this->db->select('*');
$this->db->from('board');
$this->db->where('no', $_POST['no']);
$query = $this->db->get();

$sel_board_array = $query->result();
$depth = $sel_board_array[0]->depth + 1;

// 원본글의 list_number보다 큰 먼저 정렬된글들의 list_number를 전부더해 답글의 밑에 보이도록 한다.
// 이때 list_number가 작은글들은 업데이트 되지 않는다 왜냐하면 list_number가 큰 글들을 전부 +1 업데이트 시키고
// 원본글과 +1 시킨 글 사이에 답글의 list_number가 위치할것이기 때문이다.
$this->db->query("update board set list_number=list_number+1 where list_number >".$sel_board_array[0]->list_number);

$set_list_number = $sel_board_array[0]->list_number + 1;

if($set_list_number == -1 || $set_list_number == 0)
{
$set_list_number = 1;
}

$data = array(
'list_number' => $set_list_number,
'depth' => $depth,
'parent' => $sel_board_array[0]->no
);

$this->db->where('no', $id);
$this->db->update('board', $data);


// $res_set = $sel_board_array[0]->res + 1;
// $rev_set = $sel_board_array[0]->rev + 1;

// $this->db->set('res', 'res+1');
// $this->db->where('ref', $_POST['ref']);
// $this->db->where('res >', $sel_board_array[0]->res);
// $this->db->update('board');

// $this->db->query("update board set res=res+1 where ref ='".$_POST['ref']."' and res > ".$sel_board_array[0]->res);
// $this->db->query("update board set ref=".$_POST['no'].", rev = ".$rev_set.", res=".$res_set." where no = ".$id);

// $this->db->query();

/*
$data = array(
'ref' => $_POST['no'],
'res' => $res_set,
'rev' => $rev_set
);

$this->db->where('ref', $id);
$this->db->where('res >', $sel_board_array[0]->res);
$this->db->update('board', $data);
*/
첨부파일 board.zip (8.6 KB)
 다음글 ci 1.7 -> ci 2.1.3 업그레이드 방법 (3)
 이전글 HMVC 사용시 Form_validation callb... (1)

댓글

변종원(웅파) / 2013/02/08 16:17:59 / 추천 0
asc 주시면 되구요. 

order by 값 조절하시면 정렬 변경됩니다.
개발사랑 / 2013/02/12 13:44:42 / 추천 0
order by LENGTH(comment_order) asc 하면 나중에 등록된글이 제일 밑으로 가는데요
나중에 등록된글이 위로 올라오게 하는 방법은 없을지요? 제가 잘 모르는듯해 죄송합니다.
좋은 답변부탁드립니다. ㅋ;;;
홍구2 / 2013/02/14 18:39:55 / 추천 0
 변수를 지칭할 때 $_POST와 같이 직접 언급하지 마시고 $this->input->post() 방식을 쓰시는게 어떨런지요.
개발사랑 / 2013/02/15 12:50:21 / 추천 0

예 알겠습니다. 감사합니다. 가능하면 그렇게 하는게 보안적인 측면에도 좋죠

홍구2 / 2013/03/19 13:24:34 / 추천 0
개발사랑// 웅파님의 소스만 보고 댓글을 드리자면, 개발사랑님이 문의하신 나중에 등록된 글이 위로... 의 기준은 `id`,`desc`로 하면 되지 않을까요? 정확하지 않은 댓글이면 죄송합니다.