Mantis 와 DokuWiki 연동하기

저는 원래 지금까지 프로젝트 관리툴로 Redmine 을 사용해 왔습니다. Redmine은 다양한 기능과 Git 과의 연동, 특히 정갈한 인터페이스가 딱 제가 추구하는 관리툴이였습니다. 하지만 이렇게 좋은 Redmine 에 딱 한가지 단점이 있으니 그건 제작 언어가 Ruby라는 점입니다. 이게 단점인 이유는 일반적인 웹호스팅에서는 사용 할 수 없기 때문입니다. 정말 이거 때문에 서버호스팅을 몇번이나 고민했지만 일단 없는 살림에 다른 방법을 강구하기로 했습니다.

Mantis

ㅠㅠ 이름부터 맘에 들지 않아요. 사마귀라니 사.마.귀. 단순 버그이슈용이라는 점도 아쉽습니다. 그리고 정말 센스없는 디자인.

엑셀돋네.jpg

그런 Mantis 이지만 PHP와 MySQL 을 사용하다는 점 때문에 웹호스팅에서도 맘껏 사용 할 수 있는 장점이 있습니다. 또 제가 개인적으로 싫어해서 그렇지 이미 많은 분들이 사용해서 기능은 인정받고 있습니다.

DokuWiki

Mantis 는 사실 버그트래킹외에는 거의 기능이 전무합니다. 전 Gantt 도 쓰고 싶고 저장소도 쓰고 싶고 달력, 게시판 등등 쓰고 싶지만 없습니다. 뭐 다른건 포기 할 수 있지만 딱 하나 포기할 수 없는게 바로 Wiki 입니다. 물론 프로젝트에서 생성되는 문서들은 파일로 저장되지만 레퍼런스라든가 관련 링크들은 Wiki에 남겨두는게 훨씬 빠르게 확인 할 수 있어서 좋습니다. DokuWiki 를 선택한 이유는 딱히 없습니다. 사실 심지어 처음 본 Wiki 입니다.ㅋㅋㅋ 여튼 이 DokuWiki 와 Mantis 를 연동해서 앞으로 프로젝트 관리를 할 예정입니다.

설치

Download Mantis

Download DokuWiki

위의 링크를 통해 최신버전을 받아서 설치 합니다. 설치법은 간단하므로 특별히 설명 하지 않겠습니다. 제가 사용한 버전은 MantisBT 1.2.12 와 dokuwiki-2012-10-13 입니다.

연동하기

Mantis 와 Wiki 연동을 검색해보면 대부분 아래의 문서를 참고합니다. 저도 처음에 이 문서를 참고했는데 2007년 문서에 업데이트도 안되서 현재 상황과는 조금 다릅니다. http://www.mantisbt.org/wiki/doku.php/mantisbt:issue:7075:integration_with_dokuwiki 괜히 고생만 합니다.

환경

Mantis 는 /서버/manits 그리고 DokuWiki는 /서버/dokuwiki 에 설치 되어 있습니다.

Mantis 설정

1. config_inc.php 수정

<br />
	# Wiki Integration Enabled?<br />
	$g_wiki_enable = ON;</p>
<p>	# Wiki Engine<br />
	$g_wiki_engine = 'dokuwiki';</p>
<p>	# Wiki namespace to be used as root for all pages relating to this mantis installation.<br />
	$g_wiki_root_namespace = 'mantis';</p>
<p>	# URL under which the wiki engine is hosted.  Must be on the same server.<br />
	$g_wiki_engine_url = $t_protocol . '://' . $t_host . '/%wiki_engine%/';<br />

Mantis가 업데이트 되면서 이미 Wiki 설정을 위한 준비가 다 되어 있습니다. config_inc.php 에 위의 코드만 추가해주면 끝입니다. $g_wiki_engine 의 값은 DokuWiki가 설치 된 폴더명입니다.

DokuWiki 설정

DokuWiki 와 Mantis 의 연동은 사실 Mantis 의 계정인증을 DokuWiki에서 사용 할 수 있게 하는게 주 입니다. DokuWiki 에서 Mantis 의 계정을 사용 할 수 있도록 아래와 같이 수정합니다.

1. /서버/dokuwiki/conf/dokuwiki.php 수정

<br />
$conf['useacl'] = 1;<br />
$conf['authtype'] = 'mantis';<br />
$conf['defaultgroup'] = 'VIEWER';<br />

2. /서버/dokuwiki/conf/acl.auth.php 추가

<br />
*	@VIEWER		1<br />
*	@REPORTER	2<br />
*	@UPDATER	4<br />
*	@DEVELOPER	8<br />
*	@MANAGER	16<br />
*	@ADMINISTRATOR	16<br />

3. /서버/dokuwiki/conf/local.php 추가

<br />
define( 'MANTIS_ROOT', '/서버 내 절대경로/mantis/' );  // file path to Mantis, must terminate with /<br />
define( 'MANTIS_URL', 'http://도메인/mantis/' );     // url to Mantis, must terminate with /</p>
<p>require_once( MANTIS_ROOT . 'core.php' );<br />

Mantis 와 DokuWiki 의 UTF8 처리 함수가 충돌이 나므로 Mantis의 core.php 를 여기서 한번 불러옵니다.

4. /서버/dokuwiki/inc/auth/mantis.class.php 생성

<br />
&lt;?php<br />
/**<br />
 * Mantis auth backend<br />
 *<br />
 * Uses external Trust mechanism to check against Mantis'<br />
 * user cookie.<br />
 * 13/12/2009 ~ @Tiago Gomes:<br />
 * added modifications to make possible to set project related user rights.(http://www.mantisbt.org/bugs/view.php?id=8249)<br />
 * added modifications so that mantis support logging in/out from DokuWiki’s login page (http://www.mantisbt.org/bugs/view.php?id=8277)<br />
 *<br />
 *<br />
 * @author    Victor Boctor (http://www.futureware.biz)<br />
 *<br />
 */<br />
require_once( MANTIS_ROOT . 'core.php' );</p>
<p>#dbg($GLOBALS);</p>
<p>class auth_mantis extends auth_basic {<br />
    /**<br />
     * Constructor.<br />
     *<br />
     * Sets additional capabilities and config strings<br />
     */<br />
    function auth_mantis(){<br />
        $this-&gt;cando['external'] = true;</p>
<p>        $this-&gt;cando['logoff' ] = true; // module has a logoff method<br />
    }</p>
<p>    /**<br />
     * Authenticates the user using Mantis APIs.<br />
     */<br />
    function trustExternal($user,$pass,$sticky=false){<br />
        global $USERINFO;<br />
        global $conf;</p>
<p>        $ValidUser = false;</p>
<p>        // Manage HTTP authentication with Negotiate protocol enabled<br />
        $user = auth_prepare_username($user);<br />
	$pass = auth_prepare_password($pass);<br />
        // This is necessary in all cases where Authorization HTTP header is always set<br />
	if(auth_is_user_authenticated())<br />
	{<br />
	    $user='';<br />
	}</p>
<p>        // Has a user name been provided?<br />
        if ( !empty ( $user ) )<br />
        {<br />
            // User name provided, so login via form in progress...<br />
            // Are the specified user name and password valid?<br />
            if ( auth_attempt_login ( $user, $pass, $sticky ) )<br />
            {<br />
                // Credential accepted...<br />
                $_SERVER['REMOTE_USER'] = $user; // Set the user name (makes things work...)<br />
                $ValidUser = true; // Report success.<br />
            }<br />
            else<br />
            {<br />
                // Invalid credentials<br />
                        if ( !$silent )<br />
                {<br />
                    msg ( $lang [ 'badlogin' ], -1 );<br />
                }</p>
<p>                $ValidUser = false;<br />
            }<br />
        }<br />
        else<br />
        {<br />
            // No user name provided.<br />
            // Is a user already logged in?<br />
            if ( auth_is_user_authenticated ( ) )<br />
            {<br />
                // Yes, a user is logged in, so set the globals...<br />
                // is it a media display or a page?<br />
                if (isset($_REQUEST['media'])) {<br />
                    //media<br />
                    $t_project_name = explode( ':', getNS( getID(&quot;media&quot;,false) ) );<br />
                } else {<br />
                    // normal page<br />
                    $t_project_name = explode( ':', getNS( getID() ) );<br />
                }<br />
                $t_project_id = project_get_id_by_name( $t_project_name[1] );<br />
                $t_access_level = access_get_project_level( $t_project_id );<br />
                $t_access_level_string = strtoupper( MantisEnum::getLabel( config_get( 'access_levels_enum_string' ),  $t_access_level ) ); // mantis 1.2.0rc<br />
                // $t_access_level_string = strtoupper( get_enum_to_string( config_get( 'access_levels_enum_string' ),  $t_access_level ) );<br />
                $t_access_level_string_ex = strtoupper( $t_project_name[1] ) . '_' . $t_access_level_string;</p>
<p>                $USERINFO['grps'] = array( $t_access_level_string, $t_access_level_string_ex );<br />
                $USERINFO[ 'pass' ] = current_user_get_field ( 'password' );<br />
                $USERINFO[ 'name' ] = current_user_get_field ( 'username' );<br />
                $USERINFO[ 'mail' ] = current_user_get_field ( 'email' );</p>
<p>                $_SERVER[ 'REMOTE_USER' ] = $USERINFO[ 'name' ];<br />
                $_SESSION[ $conf[ 'title' ]][ 'auth' ][ 'user' ] = $USERINFO[ 'name' ];<br />
                $_SESSION[ $conf[ 'title' ]][ 'auth' ][ 'info' ] = $USERINFO;</p>
<p>                $ValidUser = true;<br />
            }<br />
            else<br />
            {<br />
                $ValidUser = false;<br />
            }<br />
        }</p>
<p>        // Is there a valid user login?<br />
        if ( true != $ValidUser )<br />
        {<br />
            // No, so make sure any existing authentication is revoked.<br />
            auth_logoff ( );<br />
        }</p>
<p>        return $ValidUser;<br />
    }<br />
    /**<br />
     * Logout from Mantis<br />
     */<br />
    function logOff(){<br />
        auth_logout();<br />
    }</p>
<p>    /**<br />
     * Get user data<br />
     * (needed for e-mail subscriptions)<br />
     *<br />
     * @author Martin Arends http://www.web-gestaltung.de<br />
     */<br />
    function getUserData($user)<br />
    {<br />
      $data = array();</p>
<p>      $t_user_id = user_get_id_by_name( $user );</p>
<p>      if (isset($_REQUEST['media'])) {<br />
          //media<br />
          $t_project_name = explode( ':', getNS( getID(&quot;media&quot;,false) ) );<br />
      } else {<br />
          // normal page<br />
          $t_project_name = explode( ':', getNS( getID() ) );<br />
      }</p>
<p>      $t_project_id   = project_get_id_by_name( $t_project_name[1] );<br />
      $t_access_level = access_get_project_level( $t_project_id, $t_user_id );<br />
      $t_access_level_string    = strtoupper( MantisEnum::getLabel( config_get( 'access_levels_enum_string' ),  $t_access_level ) );<br />
      $t_access_level_string_ex = strtoupper( $t_project_name[1] ) . '_' . $t_access_level_string;</p>
<p>      $data['name'] = $user;<br />
      $data['grps'] = array( $t_access_level_string, $t_access_level_string_ex );<br />
      $data['mail'] = user_get_email( $t_user_id );<br />
      return $data;<br />
    }<br />
}<br />

5. /서버/dokuwiki/lib/plugins/mantis/syntax.php 생성

<br />
&lt;?php<br />
/**<br />
 * Mantis Plugin: Hyperlinks references to Mantis Issues<br />
 *<br />
 * @license    GPL 2 (http://www.gnu.org/licenses/gpl.html)<br />
 * @author     Victor Boctor (http://www.futureware.biz)<br />
 */</p>
<p>if(!defined('DOKU_INC')) define('DOKU_INC',realpath(dirname(__FILE__).'/../../').'/');<br />
if(!defined('DOKU_PLUGIN')) define('DOKU_PLUGIN',DOKU_INC.'lib/plugins/');<br />
require_once(DOKU_PLUGIN.'syntax.php');</p>
<p>/**<br />
 * A plug-in that hyper links references to Mantis issues.  References<br />
 * to Mantis issues should use the following format: ~~Mantis:123~~.<br />
 *<br />
 * All DokuWiki plugins to extend the parser/rendering mechanism<br />
 * need to inherit from this class<br />
 */<br />
class syntax_plugin_mantis extends DokuWiki_Syntax_Plugin {</p>
<p>    /**<br />
     * return some info<br />
     */<br />
    function getInfo(){<br />
        return array(<br />
            'author' =&gt; 'Victor Boctor',<br />
            'email'  =&gt; 'vboctor at users . sourceforge . net',<br />
            'date'   =&gt; '2006-05-18',<br />
            'name'   =&gt; 'Mantis Issues Plugin',<br />
            'desc'   =&gt; 'Support References to Mantis Issues',<br />
            'url'    =&gt; 'http://www.futureware.biz',<br />
        );<br />
    }</p>
<p>    /**<br />
     * What kind of syntax are we?<br />
     */<br />
    function getType(){<br />
        return 'substition';  # typo is intentional<br />
    }</p>
<p>    /**<br />
     * What about paragraphs?<br />
     */<br />
    function getPType(){<br />
        return 'normal';<br />
    }</p>
<p>    /**<br />
     * Where to sort in?<br />
     */<br />
    function getSort(){<br />
        return 156;<br />
    }</p>
<p>    /**<br />
     * Connect pattern to lexer<br />
     */<br />
    function connectTo($mode) {<br />
        $this-&gt;Lexer-&gt;addSpecialPattern('~~Mantis:[0-9]+~~', $mode, 'plugin_mantis');<br />
    }</p>
<p>    /**<br />
     * Handle the match<br />
     */<br />
    function handle($match, $state, $pos, &amp;$handler){<br />
        $match = substr( $match, 9, -2 ); // strip &quot;~~Mantis:&quot; from start and &quot;~~&quot; from end<br />
        return array( strtolower( $match ) );<br />
    }</p>
<p>    /**<br />
     * Create output<br />
     */<br />
    function render($format, &amp;$renderer, $data) {<br />
        if ( $format == 'xhtml' ) {<br />
			$renderer-&gt;externallink( MANTIS_URL . 'view.php?id=' . $data[0], $data[0] );<br />
            return true;<br />
        }<br />
        return false;<br />
    }<br />
}<br />

Source

mantis_dokuwiki

위에서 언급한 수정된 파일들만 첨부합니다. 몇몇 설정 파일들은 본인의 서버설정에 맞게 수정해 줘야 하는 점 잊지마시기 바랍니다. 이제 버그트래커와 위키로 프로젝트 잘 관리하세요~!

Comments (1)

Leave a Comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.