サイト全体でタグを管理するため、pico のタグを letag でも管理する

letagによるpicoのタグ管理はワンファイルハックでOKだった

picoは独自のタグ管理の仕組みを持っています。しかしサイト横断で使えるタグシステムがあればすばらしいと思い、調べてみました。

XCL2.2の互換モジュール(legacy)では、タグ管理のインターフェースのみが定められています。

XOOPS_ROOT_PATH/modules/legacy/class/interface/TagDelegateInterface.class.php
XOOPS_ROOT_PATH/modules/legacy/class/interface/TagClientDelegateInterface.class.php

このインターフェースを実装したモジュールの代表格が、letagです。何とよむのかな。「る・たぐ」?XCLの開発を担っているkilicaさんという方の作品なので、XCLのアーキテクチャを学ぶのにもちょうどよいと思い、使わせていただくことにしました。

letagはもちろんのこと、picoもデリゲートによってソースコードに手を入れることなく処理を追加できるポイントをいくつか提供してくれています。

試行錯誤の結果、いわゆる「ワンファイルハック」(ファイルを1つ追加するだけのカスタマイズ)によって、picoのタグ管理をletagで行うことができました。picoのソースコードには手を加えないことが前提なので、picoのタグ管理をやめるのではなく、letagでも管理をするという感じです。

その詳細

デリゲートをソースコードの改変無しに組み込むには、プリロードという機能を使います。具体的には以下のようなファイルをXOOPS_ROOT_PATH/modules/docs/preload/に置きます(当サイトではpicoの1つをdocsという名前で複製しています)。
※ picoは複製可能モジュールですのでロジックの大部分はXOOPS_TRUST_PATHにあります。もしすべてのpicoモジュールに同様の変更を加える場合にはXOOPS_TRUST_PATH/modules/pico/preload/に置けばいいはずです。


class Docs_TagsPreload extends XCube_ActionFilter
{
  function 
preBlockFilter()
  {
    
$this->mRoot->mDelegateManager->add'ModuleClass.Pico.Contentman.InsertSuccess' , array( &$this 'hook' ) ) ;
    
$this->mRoot->mDelegateManager->add'ModuleClass.Pico.Contentman.UpdateSuccess' , array( &$this 'hook' ) ) ;
  }

  function 
hook$mydirname $content_id $cat_data $ret_uri4html )
  {
    
// Get tags from docs(pico) module
    
$contentObj = new PicoContent$mydirname $content_id ) ;
    
$tagArr explode' ' $contentObj->data['tags'] ) ;

preBlockFilter()の中身、つまりpicoへの挿入/修正を検知してhook()を呼び出すところは、「Xoops Users Group Japan - Re: picoでxpWikiへの外部Autoリンク」をそのままお借りしました。

タグのデータは、hook()の引数としては渡されません。上のソースコードでは、PicoContentのオブジェクトを生成しています。実はここで他の処理も行っているためにこのようなオーバーヘッドの大きい方法を選択しましたが、ただタグ情報だけを取得するのであれば、$_POST['tags']でユーザーが入力した情報がそのまま取得できます。

ただし、これをそのままletagに渡すわけにはいきません。picoでは全角スペースを半角スペースに置き換えたり、カンマやピリオドを取り去ったり、タグをきれいにする処理を行ってからテーブルに格納しています。$_POST経由でタグを取得する場合には、最後の2行を次のように置き換えればよいと思います。


    
// Convert "zen-kaku" alphabets and numbers(a) and space(s) to "han-kaku"
    
if( function_exists'mb_convert_kana' ) ) {
      
$tags mb_convert_kana$_POST['tags'] , 'as' ) ;
    }

    
// Allow [0-9A-Za-z] only
    
$tagArr array_uniqueexplode' ' preg_replace'/[\x00-\x2f\x3a-\x40\x5b-\x60\x7b-\x7f]/' ' ' $tags ) ) ) ;

そのようにして得られたタグ($tagArr)を、デリゲート機構を使ってletagに渡します。


    
// Set tags to tags(letag) module
    
$result null;
    
$tagdirname 'tags';
    
XCube_DelegateUtils::call("Legacy_Tag.$tagdirname.SetTags"$result$tagdirname$mydirname'content'$content_idtime(), $tagArr);
  }
}

$result には呼び出すメソッド(Letag_TagDelegate::setTags())の返り値がセットされるはずなのですが、なぜかsetTags()が第一引数の$resultをリファレンスで受け取っていないので null のままです。


友達に伝える
タグ: XOOPS pico letag
作成: 2013/9/3 by:koji
更新: 2013/10/9 by:koji


pico に amazon.co.jp からの書影イメージを表示

Tech

picoの特定カテゴリをxoopsfaq化する

新規ユーザー登録(無料)

  • メールニュース[週刊起-動線]の購読
  • コメントなどの投稿
  • ココロミの利用
  • 一部コンテンツの購読

ログイン

コメント

タグ(キーワード)