키워드: 확장 함수, my_posts, 카테고리, 인기글, 정렬, 기간, 조회수, 좋아요 표기: (소스)=코드 확인·실행 검증, (README)=README 기재, (일반)=일반 지식
dx_board_posts 에 없는 조건(카테고리, 인기순, 기간, 비밀글 제외)이 필요하면 같은 반환 형식의 함수를 만듭니다. 반환 형식을 같게 두면 기존 스킨을 그대로 쓸 수 있습니다.
function my_posts($boardKey, $o = array())
{
$o = array_merge(array('limit' => 5, 'category' => '', 'order' => 'new', 'days' => 0, 'secret' => false), $o);
$db = Database::getInstance();
$b = $db->row("SELECT id FROM `{$db->table('boards')}` WHERE board_key=? AND status=1", array($boardKey));
if (!$b || !my_can_read($boardKey)) return array();
$w = 'p.board_id=? AND p.status=1 AND p.is_notice=0';
$a = array($b['id']);
if (!$o['secret']) $w .= ' AND p.is_secret=0';
if ($o['category'] !== '') {
$w .= ' AND (p.category_slug=? OR (p.category_slug IS NULL AND p.category=?))';
$a[] = $o['category']; $a[] = $o['category'];
}
if ((int)$o['days'] > 0) {
$w .= ' AND p.created_at >= ?';
$a[] = date('Y-m-d H:i:s', time() - 86400 * (int)$o['days']);
}
$orders = array(
'new' => 'p.created_at DESC, p.id DESC',
'hot' => 'p.popular_score DESC, p.id DESC',
'views' => 'p.view_count DESC, p.id DESC',
'likes' => 'p.like_count DESC, p.id DESC',
);
$ord = isset($orders[$o['order']]) ? $orders[$o['order']] : $orders['new'];
$lim = max(1, min(50, (int)$o['limit']));
$rows = $db->rows(
"SELECT p.id, p.title, p.content, p.created_at, p.view_count, p.comment_count, p.is_secret,
COALESCE(m.name, p.author_name, '익명') AS author
FROM `{$db->table('posts')}` p
LEFT JOIN `{$db->table('members')}` m ON m.id = p.member_id
WHERE $w ORDER BY $ord LIMIT $lim", $a);
return my_format_rows($rows, $boardKey);
}
옵션 (실행 검증)
- limit: 1~50 (기본 5), 범위를 벗어나면 보정
- order: new(최신), hot(popular_score), views(조회수), likes(좋아요). 그 외 값은 new
- category: 카테고리 slug. slug 가 없는 예전 글에 한해 이름으로도 일치 (게시판 목록과 같은 규칙)
- days: 최근 N일, secret: true 면 비밀글 포함 (기본 제외)
- 권한은 my_can_read (6/13), 결과 변환은 my_format_rows (10/13) 가 필요하므로 먼저 정의되어 있어야 합니다.
- SQL 값은 모두 바인딩 처리, order 는 허용 목록만 사용해 주입을 막습니다. 테스트에서 order 에 'x; DROP' 을 넣어도 정상 동작.
사용 예
$hot = my_posts('free', array('order' => 'hot', 'limit' => 5, 'days' => 30));
$qna = my_posts('free', array('category' => 'qna'));
- 결과의 excerpt 는 빈 값이고 썸네일은 본문의 첫
만 사용합니다. (10/13)
다음: 12/13 확장 결과 출력과 파일 배치
@디엑스