<?php

/*
 * elasticsearch を利用し
 * 全レス検索を実現するモジュール
 *
**/

if(!defined("_ADD_LOCAL_PEAR_PATH_")) {
 define("_ADD_LOCAL_PEAR_PATH_", true);
 set_include_path(get_include_path() . PATH_SEPARATOR . dirname(__FILE__) . "/pear");
}

require_once 'Request.php';
require_once 'const.php';
//-----------------------------------------------------------------------------------
//

class ElasticSearchClient
{
  var $apiserver = "";
  var $apitype   = "ressearch";
  
  function _get_contents($url, $method=HTTP_REQUEST_METHOD_GET, $body=false)
  {
    //http オプション
    $option = array(
      "timeout" => "10",
      "allowRedirects" => true,
      "maxRedirects" => 3,
    );
    
    $req = new HTTP_Request($url, $option);
    
    $req->setMethod($method);
    $req->addHeader("Content-Type", "application/json"); 
    
    if($body){
      $req->setBody($body);
    }
    
    $res = $req->sendRequest(); //HTTPリクエストの実行
    
    if (PEAR::isError($res)){
      //エラー文出力
      $body = $res->getMessage();
      log2file(__FILE__.":".__LINE__." response error ".$body);
    }else{
      $resCode = $req->getResponseCode();
      $length  = $req->getResponseHeader("Content-Length");
      $encode  = $req->getResponseHeader("content-encoding");
      $body    = $req->getResponseBody();
      
      if( $resCode >= 200 && $resCode < 300
      && ($length == false || $encode != false || strlen( $body ) == $length ) )
      {
        return $body;
      }
    }
    
    return FALSE;
  }
  
  
  /*constructor
   *
   * $server elasticsearchのサーバーとインデックスを指定する
   *         例:"http://localhost:9200/myindex/"
  */
  function ElasticSearchClient( $server )
  {
    $this->apiserver = $server;
  }
  
  /**
   * ドキュメントを更新する
   * $url     取得スレッドの元URL
   * $restext 検索対象テキスト
   * $id      elasticsearchの登録ID(２回め以降の更新のため)
   * 
   * result   elasticsearchの登録ID
   */
  function Put( $url, $restext, $id=false)
  {
    if($id){
      $apiurl = $this->apiserver . $this->apitype . "/" . $id;
      $body = json_encode(array("url" => $url, "restext" => $restext));
      $resp = $this->_get_contents($apiurl, HTTP_REQUEST_METHOD_PUT, $body);
    }else{
      $apiurl = $this->apiserver . $this->apitype ;
      $body = json_encode(array("url" => $url, "restext" => $restext));
      $resp = $this->_get_contents($apiurl, HTTP_REQUEST_METHOD_POST, $body);
    }
    
    if($resp && $respj = json_decode($resp, true))
    {
      return $respj["_id"];
    }
    return false;
  }
  
  /**
   * ドキュメントを破棄する
   *
   * $id elasticsearchの登録ID
  **/
  function Del( $id )
  {
    $url = $this->apiserver . $this->apitype . "/" . $id;
    
    $body = json_encode( array() );
    
    $resp = $this->_get_contents($url, HTTP_REQUEST_METHOD_DELETE, $body);
    if($resp && $respj = json_decode($resp, true))
    {
      return $respj;
    }
    return false;
  }
  
  /*
   * ドキュメントを検索する
   *
   * result マッチしたドキュメントのurlリスト
   */
  function Search( $query )
  {
    $url = $this->apiserver . $this->apitype . "/_search" ;
/*
    $query =array(
       "size"  => 10000,
       "query" => array(
        "simple_query_string" => array(
          "fields" => array("restext"),
          "query" => $query,
          "default_operator" => "and"
        )));
*/
    $query =array(
       "size"  => 10000,
       "fields" => array("url"),
       "filter" => array(
        "query" => array(
         "simple_query_string" => array(
          "fields" => array("restext"),
          "query" => $query,
          "default_operator" => "and"
         )
        )
       )
      );
    $query = json_encode($query);
    
    $resp = $this->_get_contents($url, HTTP_REQUEST_METHOD_GET,$query);
    $result = array();
    if($resp && $respj = json_decode($resp, true))
    {
      foreach($respj["hits"]["hits"] as $hit) {
        $result[] = $hit["fields"]["url"][0];
      }
    }
    return $result;
  }
}

//-----------------------------------------------------------------------------------
//インデックス更新

function UpdateSearchIndex($meta, $search_id) {
  if(readConfig("USESEARCHSV")) {
    $basenames = urlToBasename( $meta['url'] );
    $filepath = readConfig("CONTDIR") . $basenames["CONT"] . _PGET_INDEX_PAGE_;
    
    //ギャラザのようなことをする
    $textutf8 = mb_convert_encoding(file_get_contents($filepath), "UTF8", "SJIS");
    $fixtext = "";
    
    //レスを抽出
    if(preg_match_all( '/<blockquote[^>]*>(.*?)<\/blockquote>/i', $textutf8, $matches, PREG_PATTERN_ORDER) )
    {
      foreach($matches[1] as $restext) {
      
        $restext = preg_replace('/<[^>]+>/i','',$restext);
        
        $fixtext .= $restext; 
      }
    }
    //タグを検索対象に追加
    /*
    if( is_array($meta['tags']) ){
      foreach($meta['tags'] as $item) {
        $fixtext .= $item[0];
      }
    }
    */
    
    //サーバーに登録
    $sv = new ElasticSearchClient(readConfig("SEARCHSVADDR"));
    return $sv->Put( $meta['url'],  $fixtext, $search_id);
  }
  return false;
}



