PowerCMS™
アルファサードのゴールデンウィーク休業について を追加しました。
[ブログ] PowerCMS 6 でのアップデートまとめ を追加しました。
[新着情報] 多要素認証設定画面の QR コードが表示されない問題への対策ファイル を追加しました。
[新着情報] PowerCMSクラウド 月額費用の価格改定に関する追加情報を公開します を追加しました。

PowerCMS ブログ

ホーム > PowerCMS ブログ > ダイナミック検索に特定の記事を含めないようにするカスタマイズ

2015年01月23日

ダイナミック検索に特定の記事を含めないようにするカスタマイズ

PowerCMS では、すべてのエディションに DynamicMTML で動作するダイナミック検索の機能があります。 DynamicMTML では、コールバックプラグインを作るための仕組みが導入されており、これを使ってダイナミック検索が実行する SQL をカスタマイズすることで、特定の記事をダイナミック検索に含めないようにすることができます。

今回は PHP とカスタムフィールドを使ってみます。

カスタムフィールドの作成

  1. まず、カスタムフィールドを作成しましょう。
システムオブジェクト 記事
名前 ダイナミック検索から除外
種別 チェックボックス
ベースネーム exclude_altsearch

他の項目は任意でかまいません。

  1. 次に、記事を二つ作成し、公開しましょう。
タイトル ダイナミック検索から除外
除外する記事 オン
除外しない記事 オフ

※ 公開状態でないと検索対象にならないので注意してください

これで、ダイナミック検索に含まれる記事と含まれない記事の両方ができました。

プラグインの作成

ここから、コールバックを利用して検索 SQL をカスタマイズするプラグインを作成していきます。

  1. $MT_DIR/addons/DynamicMTML.pack/php 内に callbacks ディレクトリを作成します。

  2. callbacks ディレクトリ内にファイル dynamicmtml_pack_pre_altsearch.php を作成します。 ファイル名のルールは [プラグイン名]_[コールバック名].php です。

  3. とりあえず echo 'test'; してみましょう。 関数名のルールはファイル名のルールと同じです。 ダイナミック検索結果の画面にアクセスして「test」文字列が出現したら成功です。

<?php
function dynamicmtml_pack_pre_altsearch ( $mt, &$ctx, &$args, &$params ) {
    echo 'test';
}
?>
4. SQL を探すために、引数の確認をしてみましょう。
<?php
function dynamicmtml_pack_pre_altsearch ( $mt, &$ctx, &$args, &$params ) {
    var_dump( $params );
}
?>

ダイナミック検索結果の画面にアクセスすると、テーマ初期状態であれば

array(5) {
  ["sql"]=>
  string(445) "SELECT mt_entry.entry_id , mt_entry.entry_blog_id, mt_entry.entry_class  FROM mt_entry, mt_author  WHERE  (((entry_title LIKE BINARY '%Lorem%' OR entry_text LIKE BINARY '%Lorem%' OR entry_text_more LIKE BINARY '%Lorem%' OR entry_excerpt LIKE BINARY '%Lorem%' OR entry_ext_datas LIKE BINARY '%Lorem%' OR entry_keywords LIKE BINARY '%Lorem%')))  AND  mt_entry.entry_author_id = mt_author.author_id  AND entry_status = 2 AND ( entry_blog_id = [ブログID] ) "
  ["sort_by"]=>
  string(17) "entry_authored_on"
  ["sort_order"]=>
  string(4) "DESC"
  ["limit"]=>
  string(2) "20"
  ["offset"]=>
  string(1) "1"
}

のような結果が出てきます。お目当ての SQL は $params[ 'sql' ] で取り出せそうですね。 $params[ 'sql' ] の内容をそのまま phpMyAdmin などで実行すれば結果が得られるので、PHP 内で内容を操作する前に SQL をどういう形にするか決めておくとよいでしょう。また、意図通り動作しない場合にデバッグする用途にも使えます。

ポイントとしては、

  1. カスタムフィールドの値を保存している mt_entry_meta に関する条件を追加する

  2. 伴って、FROM に mt_entry_meta を追加する

です。

<?php
function dynamicmtml_pack_pre_altsearch ( $mt, &$ctx, &$args, &$params ) {
    $params[ 'sql' ] .=<<< EOM
    AND (
        mt_entry_meta.entry_meta_entry_id = mt_entry.entry_id
        AND (
            mt_entry_meta.entry_meta_type LIKE 'field.exclude_altsearch'
        )
        AND (
            mt_entry_meta.entry_meta_vinteger_idx NOT LIKE 1
        )
    )
EOM;
    $params[ 'sql' ] = preg_replace( "/\s(WHERE)/", ', mt_entry_meta $1', $params[ 'sql' ] );
}
?>

留意事項

上記ではカスタムフィールドを作成後、新規に記事を2件作成しています。記事を作成した時点で mt_entry_meta テーブルに「ダイナミック検索から除外」カスタムフィールドの値が保存されています(チェックが入っていれば 1、入ってなければ空)。 ですが、これ以前に作成されていた記事は mt_entry_meta テーブルに対応するレコードが作成されていません。そのため、上記の SQL では足らず、もっと複雑な SQL を組み立てる必要があります。 SQL で頑張るよりも、CSV インポート機能を使ってデータをアップデートする方が早いでしょう。

引数の調べ方

今回は pre_altsearch コールバックを使いました。mt ディレクトリ内を pre_altsearch で grep してみると、$MT_DIR/addons/PowerCMS.pack/php/block.mtaltsearchresults.php が引っかかります。 このファイル内の

$app->run_callbacks( 'pre_altsearch', $mt, $ctx, $args, $params );

から引数を判断します。

コールバックの調べ方

mt ディレクトリ内を run_callbacks で grep してみるといろいろ引っかかります。


Recent Entries