그누보드 Hook 사용법

최근 그누보드 업데이트 스크립트를 만들면서, 코어 코드가 수정되었을때 자동으로 업데이트 해주는 기능 구현에 애를 먹고 있다.
하지만 그누보드 5.4부터 새로 추가된 hook을 사용하면 코어코드에 대한 수정을 최소한으로 하거나 혹은 코어 수정없이 진행가능하기에 업데이트가 용이하다.

Hook

Hook은 단어 그대로 갈고리처럼 코드 중간에 갈고리를 걸어, 코드를 실행시켜주는 기능을 한다.
혹은 이벤트-리스너와 같은 기능을 한다고 생각해도 좋다.

그누보드가 Hook을 어떻게 구현 했는지 궁금하면, https://github.com/Josantonius/PHP-Hook 의 코드를 가져다 썻다고 하니 보도록 하고 사용 방법만 간단히 익혀보자.

구현 내용 및 분석

간단히 1대1 문의가 왓을 때 slack이나 기타 메신저로 알려주는 부분을 구현해보자.

먼저 그누보드에선 1대1문의를 작성할 때 /bbs/qawrite.php에서 작성을 한 뒤 /bbs/qawrite_update.php로 데이터를 전송해 DB에 저장한다.

이때 /bbs/qawrite_update.php파일 321줄에

<?php
# ...
run_event('qawrite_update', $qa_id, $write, $w, $qaconfig);
# ...

run_event 함수에서 qawrite_update 라는 이벤트를 $qa_id, $write, $w, $qaconfig 변수 4개와 함께 실행하고(일으키고)있다.

하지만 현재는 qawrite_update라는 이벤트에 아무런 내용이 없으므로 아무런 기능을 하지 않는다.
이제 바깥(코어 파일이 아닌 곳)에서 qawrite_update 이벤트가 실행될 때 slack 메시지를 보내는 기능을 추가해보자.

구현

그누보드는 기본적으로 /extend 폴더에 있는 파일은 외부 플러그인 취급하며, 따로 include('common.php');해주지 않아도 자동으로 .php로 끝나는 파일은 common.php가 로딩된 후 실행시켜준다. (common.php 659~667번째줄)

/extend/slack.notice.php

<?php
if (!defined('_GNUBOARD_')) exit; // 개별 페이지 접근 불가

add_event('qawrite_update', 'slack_notice', G5_HOOK_DEFAULT_PRIORITY, 4);

function slack_notice($qa_id, $write, $w, $qaconfig)
{
    global $g5;

    if($w == '' || $w == 'r') {
        $text = "";
        $qa = sql_fetch("SELECT * FROM `{$g5['qa_content_table']}` WHERE `qa_id` = {$qa_id}");
        $text .= "[{$qa['qa_category']}] {$qa['qa_subject']}\n\t=> {$qa['qa_content']}";

        $slack = new Slack();
        $slack = $slack->sendMessage($text);
    }
}

위 코드를 간략히 분석해보면
add_event >
1. qawrite_update 이벤트가 실행될 때, ‘slack_notice‘ 라는 함수를 실행해라. (Variable function)
2. qawrite_update이벤트가 실행될 때 등록된 함수들 중에서 G5_HOOK_DEFAULT_PRIORITY(8) 번째로 실행 해라. (이를 이용하면 순서의 의존적인 여러 함수를 순차적으로 실행 할 수 있다.)
3. 전달되는 파라미터는 총4개 이다.

function slack_notice >
1. 인자로 $qa_id, $write, $w, $qaconfig를 전달받고,
2. 만약 새로운 등록($w == '')이거나, 재문의($w == 'r') 일경우
3. 문의 카테고리(qa_category), 제목(qa_subject), 내용(qa_content)을 담아 slack으로 전송한다.

정리

이 처럼 미리 run_event 가 들어 있는 곳에 내용을 보고 코어 파일에 수정없이 기능을 추가할 수 있어서, 이후 업데이트할 때 변경된 파일을 일일히 신경쓰지 않고 바로바로 엎을 수 있다.

또한, 원하는 위치에 내용이 없다고 하더라고 해당부분에 run_event('원하는_이벤트_이름', $arg1, $arg2) 이렇게 한 줄만 추가해 주고 extend 같은 외부 파일에서 add_event()함수를 통해 실행해주면 코어 코드에 대한 수정을 최소화 할 수 있다.

마지막으로 위에서본 add_event ( 이벤트 추가 )와 run_event ( 이벤트 실행 )말고도

add_replace ( 내용 변경 )
run_replace ( 내용 변경 적용 )
delete_event ( 이벤트 추가된 것을 취소함 )
delete_replace ( 내용 변경된 것을 취소함 )와 같은 함수들이 있으니 그누보드 메뉴얼에서 내용을 확인하고 다양하게 사용해볼 수 있다.

마무리

곧 훈련소 가는데(크흡..) 가기전에 블로그 업데이트 한번 해고 싶어서 최근 유용하게 쓰고있는 그누보드 hook에 대한 내용을 정리해 봤습니다.
기분이 싱숭생숭하다보니 내용이 중구난방일 것같은데 잘못된 것이 있다면 댓글로 남겨주시면 훈련소 다녀와서(ㅎ) 수정하겠습니다.

글의 문제가 있다면 댓글을 달아 주세요.

이 사이트는 스팸을 줄이는 아키스밋을 사용합니다. 댓글이 어떻게 처리되는지 알아보십시오.