예전부터 하려던 것을 이번 모니위키 1.2.0 릴리스를 내놓으면서 이것 저것 정리하면서 시도해보았습니다.

인터넷에 검색해보면 http://www.xpressengine.com/tip/15921874같은 내용처럼 모니위키를 구버전 XE에서 연동시키는 소스를 볼 수 있지만 위의 예에서 연동시키는 방식으로는 모니위키의 ACL 플러그인을 쓰지 못할 뿐만 아니라, XE의 구조가 조금만 바뀌어도 쓸 수 없게 되어버리기때문에 그리 권장할 만한 구현 방식이 아닙니다.

XE의 회원을 연동하기 위해서는 nFORGE 회원과 모니위키를 연동시킨 방식처럼 "회원이 로그인 된 상태인 경우 강제로 모니위키 회원 정보를 생성하는 방식"으로 접근하면 편리합니다. 이 경우에는 Security 플러그인을 확장하는 방식이 아니라 모니위키의 회원 클래스인 WikiUser 클래스를 확장하는 방식을 사용하게 됩니다.

class User_xe17 extends WikiUser {
    function User_xe17($id = '') {
        global $DBInfo;

        define('__XE__', true);

        $zbxe_root_dir = !empty($DBInfo->zbxe_root_dir) ?
                $DBInfo->zbxe_root_dir : __DIR__.'/../../../xe'; // XE root dir

        require_once($zbxe_root_dir."/config/config.inc.php");

        $context = &Context::getInstance();
        $context->init(); // 여기서 매우 느리다.
        ...

(위의 방식은 제가 직접 찾은 방법이나, 이러한 방식으로 할 수 있다는 내용을 블로그를 검색해보니 찾을 수 있더군요)

그러나 위와 같은 방식으로 하면 모니위키가 너무 너무 느려지기때문에 간소화된 init()을 다음과 같은 식으로 호출하는 것이 낫습니다.

    function xe_context_init($xe) {
        //
        // simplified XE context init method to speed up
        //

        // set context variables in $GLOBALS (to use in display handler)
        $xe->context = &$GLOBALS['__Context__'];
        $xe->context->_COOKIE = $_COOKIE;

        $xe->loadDBInfo();

        // set session handler
        if (Context::isInstalled() && $this->db_info->use_db_session == 'Y') {
            $oSessionModel = getModel('session');
            $oSessionController = getController('session');
            session_set_save_handler(
                    array(&$oSessionController, 'open'),
                    array(&$oSessionController, 'close'),
                    array(&$oSessionModel, 'read'),
                    array(&$oSessionController, 'write'),
                    array(&$oSessionController, 'destroy'),
                    array(&$oSessionController, 'gc')
           );
        }
        session_start();

        if ($sess = $_POST[session_name()]) {
            session_id($sess);
        }
    }

    function User_xe17($id = '') {
        global $DBInfo;

        define('__XE__', true);

        $zbxe_root_dir = !empty($DBInfo->zbxe_root_dir) ?
                $DBInfo->zbxe_root_dir : __DIR__.'/../../../xe'; // XE root dir

        require_once($zbxe_root_dir."/config/config.inc.php");

        $context = &Context::getInstance();
        $this->xe_context_init($context); // simplified init context method $context->init(); 대신에 사용.

        $oMemberModel = &getModel('member');
        $oMemberController = &getController('member');

        if ($oMemberModel->isLogged()) {
            ...

참고적으로 위와같이 간소화된 context 초기화 루틴을 사용하는 경우 기존의 context->init()을 사용하는 것보다 거의 20배가 빨랐습니다. (아파치 벤치 ab -n 500 -c 5로 로컬에서 측정한 경우. XE 회원 연동을 아예 하지 않는 경우가 그렇지 않은 경우보다 2.5배 빠름)

이를 좀 더 개선하여 Varnish cache를 사용할 수 있도록 고쳤으며, 최초 접속하는 경우에만 사용자 정보를 DB를 통해 가져오는 절차를 거치고 그 이후에는 세션을 통해서 인증을 하게 되므로 속도 저하가 없어졌습니다.

여기서 사용한 방식을 응용하면 XE1.7의 회원 정보를 보다 빠르게 타 PHP에서 연동시킬 수 있을 것으로 생각됩니다.

완전한 소스는 http://moniwiki.kldp.net/wiki.php/XeUserPlugin 에서 받으실 수 있습니다.

특징 및 기타 변경사항

- 버전 1.5부터는 모니위키 1.2.5에 기본 내장 예정 (2015/04/30)
- XE 1.7, XE 1.8 모두 지원함
- Varnish cache 지원 가능. XE 사용자 모듈을 사용하는데에 따르는 속도 저하가 없음 (2015/4/30 수정)

by dumpcookie 2013. 7. 5. 05:48