2014年8月22日 星期五

[PHP] 擴充 Mantis SOAP API 、處理 DB Query 心得

前置準備:
  • soap api source code 就擺在 mantis/api/soap 中
  • 記得清掉 SoapServer 跟 SoapClient 的 cache 資料,可以用 ini_set("soap.wsdl_cache_enabled", 0); 或是在 new SoapServer 或 SoapClient 時,指定 'cache_wsdl' => WSDL_CACHE_NONE 資訊
預計新增一個 api 名為 mc_user_group ,需要做的動作:
  • 規劃 mc_user_group 的 input 跟 output 資訊,此例 input 為 username, password,而 output 是 ObjectRefArray,由於都是既定 type ,所以不需額外定義
  • 更新 WSDL 定義,可以從已存在的 mc_enum_access_levels api 來仿照
    • <message name="mc_enum_groupRequest">
      <part name="username" type="xsd:string" />
      <part name="password" type="xsd:string" /></message>
      <message name="mc_enum_groupResponse">
      <part name="return" type="tns:ObjectRefArray" /></message>
    • <operation name="mc_enum_group">
      <documentation>Get the enumeration for group</documentation>
      <input message="tns:mc_enum_groupRequest"/>
      <output message="tns:mc_enum_groupResponse"/>
      </operation>
    • <operation name="mc_enum_group">
      <soap:operation soapAction="http://www.mantisbt.org/bugs/api/soap/mantisconnect.php/mc_enum_group" style="rpc"/>
      <input><soap:body use="encoded" namespace="http://futureware.biz/mantisconnect" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/></input>
      <output><soap:body use="encoded" namespace="http://futureware.biz/mantisconnect" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/></output>
      </operation>
  • 實作 function mc_enum_group( $p_username, $p_password ),若此 function 定義在其他檔案內,記得要更新 mantis/api/soap/mc_core.php 即可
如此一來,就完成擴充 Mantis SOAP api 的任務了,記得要把 Server 跟 Client 的 SOAP Cache 都必須清掉才會正常,不然 client site 會看到類似的訊息(扣除還沒實作的情況):

PHP Fatal error:  Uncaught SoapFault exception: [SOAP-ENV:Server] Procedure 'your_func' not present

以下是片段程式碼:

// Client
$TARGET_API='https://host/mantis/api/soap/mantisconnect.php?wsdl';
ini_set("soap.wsdl_cache_enabled","0");
$c = new SoapClient($TARGET_API);

// debug
// print_r($c->__getFunctions ());

print_r( $c->mc_enum_group($user, $pass) );


// Server
        require_once( 'mc_core.php' );
        ini_set("soap.wsdl_cache_enabled","0");
        $server = new SoapServer("mantisconnect.wsdl",
                        array('features' => SOAP_USE_XSI_ARRAY_TYPE + SOAP_SINGLE_ELEMENT_ARRAYS)
        );
        $server->addFunction(SOAP_FUNCTIONS_ALL);
        $server->handle();


其他心得:

  • 自定 Mantis SOAP API 時,需要留意 input, output 的地方,假設 output 的是 ObjectRefArray 形態,那輸出只能有 id, name ,其他欄位都會被濾掉
  • Mantis SOAP API 使用上要留意權限問題,例如發 issue 用的帳號,若是 repoter 的等級,不能去做 assign monitors 的行為,會有權限問題,有問題時,可以試著用 mc_issue_add 跟 mc_issue_update 交叉測試。

最後,再補一個 DB 操作方式,output 仍以 ObjectRefArray 為例:

function mc_enum_group( $p_username, $p_password ) {
        $t_user_id = mci_check_login( $p_username, $p_password );
        if ( $t_user_id === false ) {
                return mci_soap_fault_login_failed();
        }
         
        $t_result = array();
         
        $query = "SELECT * FROM mantis_user_table";
     
        $result = db_query( $query );
        //file_put_contents('/tmp/debug', print_r($result, true) );

// 此例把 username 充當回傳的 name 資訊、user id 當作回傳 id 資訊
        for( $i=0, $cnt=db_num_rows($result) ; $i<$cnt; ++$i ) {
                $row = db_fetch_array( $result );
                $obj = new stdClass();
                $obj->id = $row['id'];
                $obj->name = $row['username'];
                array_push( $t_result, $obj );
        }    
        return $t_result;
}

沒有留言:

張貼留言