WordPress文章校正プラグイン「Japanese Proofreading Preview」を修正して新APIに対応させる

No Image

校正支援機能があると便利ですよね。
APIがバージョンアップして使えない!と嘆いていましたが、やっぱり不便なので「Japanese Proofreading Preview」を新APIへの対応をやってみました。

素人が手探りでやったので、文句は言わないでください。
もっといい記述方法があると思うので、ちゃんとした修正版が出るのを待ちましょう。
動けばいいのです、動けば。

スポンサーリンク

APIにリクエストを投げる部分の修正

APIにリクエストを投げる部分はプラグインのPHPファイル、yproofreading.phpの188行目からの関数に当たります。
ハイライトにしている部分が訂正する箇所です。

//Yahoo APIに文章校正のリクエストを投げて結果をSimpleXMLElementで返す関数
function yproofreading_get_kousei_result($sentence) {
    $api = 'http://jlp.yahooapis.jp/KouseiService/V1/kousei';
    $appid = get_option('yahoo_appid');
    
    $params = array(
        'sentence' => $sentence
    );
    
    // no_filterが設定されている場合はパラメータに追加する
    $nofilter = yproofreading_build_nofilter();
    if ( $nofilter != "" ) {
        $params["no_filter"] = $nofilter ;
    }
    
    $ch = curl_init($api);
    curl_setopt_array($ch, array(
        CURLOPT_POST => true,
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_USERAGENT => "Yahoo AppID: $appid",
        CURLOPT_POSTFIELDS => http_build_query($params),
    ));
    $results = curl_exec($ch);
    //$info = curl_getinfo($ch);
    //echo $info['request_size'] ;
    curl_close($ch);
    if (false === $results) {
        echo "<div class='proofreading-error'>Internal Server Error</div>";
    }
    $results = new \SimpleXMLElement($results);
    if ($results->Message) {
        echo "<div class='proofreading-error'>" . (string)$results->Message . "</div>";
    }
    return $results;
}

APIのリクエストURLの修正

まずリクエストURLがV1からV2に変わります。
189行目を次のように変更します。

修正前
$api = 'http://jlp.yahooapis.jp/KouseiService/V1/kousei';
修正後
$api = 'http://jlp.yahooapis.jp/KouseiService/V2/kousei';

リクエストのパラメータ変更

192行から記述されている、投げるリクエスト用のパラメータもごっそり変わっています。
今までは対象になる文章だけを送っていたようですが、json形式でIDなどを送ってあげます。
追加されるパラメータの値は固定値や任意の指定です。

修正前
$params = array(
    'sentence' => $sentence
);
修正後
$data = array(
  'id'      => '1234-1',
  'jsonrpc' => '2.0',
  'method'  => 'jlp.kouseiservice.kousei',
  'params'  => array(
      'q'  => $sentence
  )
);
$json = json_encode($data);

変数名を$paramsから$dataと$jsonに変えています。
これは中のparamsと被って分かりづらそうだったからです。

フィルタが使えなくなったので削除

指摘除外用のフィルタがあるのですが、これは使えなくなったようです。
別に残としておいてもいいですが、197-200行目はコメントアウトか削除しておきます。

修正前
$nofilter = yproofreading_build_nofilter();
if ( $nofilter != "" ) {
    $params["no_filter"] = $nofilter ;
}

JSON形式で投げる

元のコードでもcURLを使ってPOST送受信をしていますが、今回はjson形式で送るので、そのパラメータを少し変更する必要があります。
これは修正前コードの203行目から始まる部分です。

修正前
curl_setopt_array($ch, array(
    CURLOPT_POST => true,
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_USERAGENT => "Yahoo AppID: $appid",
    CURLOPT_POSTFIELDS => http_build_query($params),
));
修正後
curl_setopt_array($ch, array(
    CURLOPT_HTTPHEADER => array('Content-Type: application/json'),
    CURLOPT_CUSTOMREQUEST => "POST",
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_USERAGENT => "Yahoo AppID: $appid",
    CURLOPT_POSTFIELDS => $json,
));

受信したJSONデータを配列に変換する

JSONで送信したので、当たり前ですがJSONで返ってきます。
今まではXML形式でしたのでSimleXMLElementを使っていましたが、json_decodeで変換します。

修正前
$results = new \SimpleXMLElement($results);
if ($results->Message) {
    echo "<div class='proofreading-error'>" . (string)$results->Message . "</div>";
}
return $results;
修正後
$res_json = json_decode($results);
return $res_json->result;

修正後

これでリクエストを投げる部分の修正は完了です。
最終的にこうなります。

//Yahoo APIに文章校正のリクエストを投げて結果をSimpleXMLElementで返す関数
function yproofreading_get_kousei_result($sentence) {
    $api = 'http://jlp.yahooapis.jp/KouseiService/V2/kousei';
    $appid = get_option('yahoo_appid');
    
    $data = array(
      'id'      => '1234-1',
      'jsonrpc' => '2.0',
      'method'  => 'jlp.kouseiservice.kousei',
      'params'  => array(
          'q'  => $sentence
      )
    );
    $json = json_encode($data);
    
    $ch = curl_init($api);
    curl_setopt_array($ch, array(
        CURLOPT_HTTPHEADER => array('Content-Type: application/json'),
        CURLOPT_CUSTOMREQUEST => "POST",
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_USERAGENT => "Yahoo AppID: $appid",
        CURLOPT_POSTFIELDS => $json,
    ));
    
    $results = curl_exec($ch);
    curl_close($ch);
    if (false === $results) {
        echo "<div class='proofreading-error'>Internal Server Error</div>";
    }
    $res_json = json_decode($results);
    return $res_json->result;
}

スポンサーリンク

これでとりあえずはリクエストがちゃんと投げられるようになりました。

受け取ったデータの表示する部分の修正

レスポンスフィールド名もごっそり変わっていますので、その部分を変更してあげます。
元のコードのyproofreading_do_proofreadingという関数内にある302行目から始まるforeach文の中にそのフィールド名がありますので、これを新しいバージョン用に変更します。

修正前
foreach ($results->Result as $value) {
    $start = (int)$value->StartPos;
    $len = (int)$value->Length;
    if ("" === (string)$value->Surface) {
        $surface = mb_substr($sentence, $start, $len);
    } else {
        $surface = (string)$value->Surface;
    }
    if ( mb_strlen($surface) == 1 ) {
        $surface = $surface .  mb_substr($sentence,$start + $len , 1,"UTF-8");
    }
    $word = (string)$value->ShitekiWord;
    if ( mb_strlen($word) == 1 ) {
        $word = $word . mb_substr($sentence,$start + $len , 1,"UTF-8");
    }
    
    $r = array(
    //    'start' => $start,
    //    'end' => $start + $len,
        'surface' => $surface,
        'word' => $word,
        'info' => (string)$value->ShitekiInfo
    //    'index' => array_search((string)$value->ShitekiInfo, $group) + 1
    );
    $h = $r["surface"] . "-" . $r["word"] . "-" . $r["info"];
    if (!in_array($h, $hash)) {
        $hash[] = $h;
        $items[] = array("surface" => $r["surface"], "word" => $r["word"], "info" => $r["info"]);
    }
    //$r["item_index"] = array_search($h, $hash) - 1;
    $result[] = $r;
}

何箇所もあるのでここは端折ってまとめて修正コードを見せます。

修正後
foreach ($results->suggestions as $value) {
  $start = (int)$value->offset;
  $len = (int)$value->length;
  if ("" === (string)$value->word) {
      $surface = mb_substr($sentence, $start, $len);
  } else {
      $surface = (string)$value->word;
  }
  if ( mb_strlen($surface) == 1 ) {
      $surface = $surface .  mb_substr($sentence,$start + $len , 1,"UTF-8");
  }
  $word = (string)$value->suggestion;
  if ( mb_strlen($word) == 1 ) {
      $word = $word . mb_substr($sentence,$start + $len , 1,"UTF-8");
  }
  if ($value->suggestion == "") {
    $word .= (string)$value->note;
  } else {
    $word .= "(" . (string)$value->note . ")";
  }
  $r = array(
  //    'start' => $start,
  //    'end' => $start + $len,
      'surface' => $surface,
      'word' => $word,
      'info' => (string)$value->rule
  //    'index' => array_search((string)$value->ShitekiInfo, $group) + 1
  );
  $h = $r["surface"] . "-" . $r["word"] . "-" . $r["info"];
  if (!in_array($h, $hash)) {
      $hash[] = $h;
      $items[] = array("surface" => $r["surface"], "word" => $r["word"], "info" => $r["info"]);
  }
  //$r["item_index"] = array_search($h, $hash) - 1;
  $result[] = $r;
}

新しいAPIでは置換先候補と補足情報が分けられて返ってくるので、途中でカッコ書きで結合している部分を追加しています。
多分もっとスマートに記述する方法があると思います。


これで元通りに校正支援を受けられるようになりました。
こういう情報はもっと収集しておくべきだと実感しました。
「気づいたら使えない!困る!」と嘆く前に気付けたらいいんですけどね。

WordPress文章校正プラグイン「Japanese Proofreading Preview」を修正して新APIに対応させる

スポンサーリンク

Leave a Comment

  • 2022/04/01

    この記事を見ながら必要箇所訂正したところ、無事プラグインが動くようになりました。
    ありがとうございます!

    Reply