WordPressのコメント機能は使えない→だったら自作プラグインで拡張してみたら?

2016/08/06

Doyin Faith Kasumu

2

Articles in this issue reproduced from SitePoint
Copyright © 2016, All rights reserved. SitePoint Pty Ltd. www.sitepoint.com. Translation copyright © 2016, KADOKAWA ASCII Research Laboratories, Inc. Japanese syndication rights arranged with SitePoint Pty Ltd, Collingwood, Victoria,Australia through Tuttle-Mori Agency, Inc., Tokyo

「WordPressのコメント欄って、ちょっと使いにくいんだよね」。だったら自作プラグインで機能を拡張してみましょう。手始めに、メンション機能から。

WordPressのWebサイトの多くでは、Web訪問者はブログの記事ページ上でコメントを共有できます。Web訪問者がコメントに返信できるWordPressのプラグインもいくつかあります。しかし、書いた人が複数だと、コメント欄で返信、参照されても誰に向けたものか分かりにくくなってしまいます。

この記事では、Twitterのようなメンション機能をWordPressのWebサイトに組み込める、便利なWordPressプラグインのコーディング方法を紹介します。この方法を使えば読者同士がコメント欄でつながりやすくなります。

記事の最後では、いくつかの追加機能を備えたプラグインをダウンロードできるリンクや、プラグインを閲覧できるGitHubのリンクも紹介します。

mention feature comments

プラグインのコーディング

WordPressプラグインは、すべて/wp-content/plugins/ディレクトリにあるPHPファイルです。最初にwp-mention-plugin.phpを作成します。

wp-mention-plugin.phpにプラグインヘッダーを追加します。そうしないとWordPressがプラグインを認識しません。

<?php
/**
 * Plugin Name: WP Mention Plugin
 * Plugin URI: https://sitepoint.com
 * Description: Mention both registered and non registered @comment__author in comments
 * Version: 1.0.0
 * Author: Doyin Faith Kasumu
 * Author URI: http://t2techblog.com
 * License: GPL2
 */

プラグインのクラスを以下のように作成します。

class wp_mention_plugin {

//codes

アクションフックやフィルターフックは、すべてinitialize()メソッドに入ります。アクションフックやフィルターフックがコンストラクタになるため、クラスのインスタンスが生成されたら、最初のメソッドがコールされます。

    public static function initialize() {

        add_filter( 'comment_text', array ( 'wp_mention_plugin', 'wpmp_mod_comment' ) );

        add_action( 'wp_set_comment_status', array ( 'wp_mention_plugin', 'wpmp_approved' ), 10, 2 );

        add_action( 'wp_insert_comment', array ( 'wp_mention_plugin', 'wpmp_no_approve' ), 10, 2 );
    }

コード解説

comment_textフィルターフックは表示されるコメントのテキストにフィルターをかけます。コメントが変化するとwp_set_comment_statusアクションフックが即座にトリガーされます。さらに、コメントが送信されるとwp_insert_commentアクションフックが即座にトリガーされます。

@で始まる名称はすべて引用符なしでスタイリングします。そのためcomment_textフィルターフックが必要になります。

コメントが承認される前に検閲されるWordPressのWebサイトは、メンションしたコメント作成者による新たに承認されたコメントを追跡するためにwp_set_comment_statusアクションフックが必要です。

コメントが検閲されることなく自動で承認される場合、メンションしたコメント作成者のコメントを追跡するにはwp_insert_commentが必要です。

次にinitialize()メソッドと呼ばれる関数を作成します。まず、wpmp_mod_comment()から始めます。

    public static function wpmp_mod_comment( $comment ) {

        // we set our preferred @mention text color here
        $color_code  = '#00BFFF';

        $pattern     = "/(^|\s)@(\w+)/";
        $replacement = "<span style='color: $color_code;'>$0</span>";
        $mod_comment = preg_replace( $pattern, $replacement, $comment );

        return $mod_comment;
    }

ここでWP Mention Plugin Modify Commentを意味するwpmp_mod_comment()メソッドを作成します。この関数は1つの引数のみを受け付けます。この引数は修正中のコメントです。この引数について心配する必要はありません。WordPressが処理してくれます。

$pattern変数はシンプルな正規の表現パターンを作成します。コメント欄で@any__comment__author__nameがメンションされているかを判断します。コメントにadmin@sitepointのようなものが含まれている場合、有効なメンションとして記録されません。有効なメンションは濃い目のスカイブルーに色付けされます。

@mentionテキストの色を変更したいなら、$color_code変数の値を変更します。

次の手順に進む前に、コメント作成者に送られる通知メールを処理するメソッドを作成します。

    private static function wpmp_send_mail( $comment ) {
        $the_related_post        = $comment->comment_post_ID;
        $the_related_comment     = $comment->comment_ID;
        $the_related_post_url    = get_permalink( $the_related_post );
        $the_related_comment_url = get_comment_link( $the_related_comment );

        // we get the mentions here
        $the_comment = $comment->comment_content;
        $pattern     = "/(^|\s)@(\w+)/";

        // if we find a match of the mention pattern
        if ( preg_match_all( $pattern, $the_comment, $match ) ) {

            // remove all @s from comment author names to effectively
            // generate appropriate email addresses of authors mentioned
            foreach ( $match as $m ) {
                $email_owner_name = preg_replace( '/@/', '', $m );
                $email_owner_name = array_map( 'trim', $email_owner_name );
            }

            /**
             * This part is for For full names, make comment authors replace spaces them  with
             * two underscores. e.g, John Doe would be mentioned as @John__Doe
             *
             * PS: Mentions are case insensitive
             */
            if ( preg_match_all( '/\w+__\w+/', implode( '', $email_owner_name ) ) ) {
                $email_owner_name = str_ireplace( '__', ' ', $email_owner_name );
            }

            // we generate all the mentioned comment author(s) email addresses
            $author_emails = array_map( 'self::wpmp_gen_email', $email_owner_name );

            // ensure at least one valid comment author is mentioned before sending email
            if ( ! is_null( $author_emails ) ) {
                $subj = '[' . get_bloginfo( 'name' ) . '] Someone mentioned you in a comment';

                $email_body = "Hello, someone mentioned you in a comment($the_related_comment_url)".
                              " at MyBlog.com. Here is a link to the related post: $the_related_post_url";

                wp_mail( $author_emails, $subj, $email_body );

            }
        }
    }

コード解説

先ほどのwpmp_mod_comment()メソッドを使ってコメントをフィルターし、メンションされている人をチェックします。もしメンションされている人がいれば、コメント作成者名の前にある@を削除します。@を削除すれば、名前を使ってデータベースからコメント作成者の情報を作成できます。

ときにはコメント作成者がフルネームを入力することもあります。たとえば「John Doe」などのようにコメント作成者の名前にスペースを含む文字を記入する場合です。このような場合、名前をメンションする人は名前の間にあるスペースを二重下線に置き換えなければなりません。そのため、if(preg_match_all('/\w+__\w+/',implode('',$email_owner_name)))…のようなコードから始め、@mentionテキストでは必ずすべての二重下線をスペースに変換するようにします。

次にこのあと作成するwpmp_gen_email()メソッドを使って、メンションしたコメント作成者のメールアドレスを作成します。$email_body変数とwp_mail()関数が、対応するコメントや投稿へのリンクを含んだ通知メールを個々に保存し送ります。

注意:コード中でメンションされたコメント作成者や作成者のメールアドレスなどが配列に保存されているのを発見したら注意してください。このように保存されるのは複数のコメント作成者がメンションされている場合にのみです。

$email_bodyの中のMyBlog.comというコードをお好みのWebサイト名に変えることをお忘れなく。

    public static function wpmp_gen_email( $name ) {
        global $wpdb;

        $name  = sanitize_text_field( $name );
        $query = "SELECT comment_author_email FROM {$wpdb->comments} WHERE comment_author = %s ";

        $prepare_email_address = $wpdb->prepare( $query, $name );
        $email_address         = $wpdb->get_var( $prepare_email_address );

        return $email_address;
    }

コード解説

先ほどwpmp_gen_email()メソッドについては詳しく解説しましたが、メンションコメント作成者のメールを生成するだけです。作成したメソッドが受け取った$nameストリング引数はコメント作成者名です。受け取ったコメント作成者名を使ってデータベースからメンションされたコメント作成者の情報を取得します。SQL攻撃を防ぐために、WordPressのprepare()関数を使って必ずクエリが安全に処理されるようにします。

次にコメントが最初に検閲されているかを追跡するメソッドを2つ以上作成します。そのあとに通知メールを送ります。

    public static function wpmp_approved( $comment_id, $status ) {
        $comment = get_comment( $comment_id, OBJECT );
        ( $comment && $status == 'approve' ? self::wpmp_send_mail( $comment ) : null );
    }

    public static function wpmp_no_approve( $comment_id, $comment_object ) {
        ( wp_get_comment_status( $comment_id ) == 'approved' ? self::wpmp_send_mail( $comment_object ) : null );
    }

最初にwpmp_approved()が、$comment_idを持つ検閲されているコメントが承認されているかを確認します。そのあとに、通知メールを送信するwpmp_send_mail()メソッドをコールします。

wpmp_no_approve()はコメントが自動承認されると直ちに通知メールを送信するwpmp_send_mail()メソッドをコールしますが、最初に検閲はしません。

プラグインにコーディングした作業をさせるには、先ほど使ったwp_mention_pluginのクラスのインスタンスを作成し、必要なアクションフックとフィルターフックを登録するinitialize()メソッドをコールする必要があります。

}

$wp_mention_plugin = new wp_mention_plugin;
$wp_mention_plugin->initialize();

?>

plugin notification feature

最後に

記事では、Twitterのようなメンション機能をWordPressのWebサイトに組み込む、便利なWordPressプラグインを作成する方法を紹介しました。

ここからAtmentionをダウンロードできます。Atmentionはメンション機能を組み込む以外にもいくつかの機能を備えたプラグインです。これ以外のプラグインを使いたいのならGitHubWP Mention Pluginコードをチェックしてみてください。

(原文:Enhance Your WordPress Comments with a Mention Feature

[翻訳:中村文也]
[編集:Livit

Copyright © 2016, Doyin Faith Kasumu All Rights Reserved.

Doyin Faith Kasumu

Doyin Faith Kasumu

ナイジェリア出身のWeb開発者、フリーランスのライターです。新しいことを学ぶのが好きで個人ブログでWeb開発のチュートリアルを紹介しています。

Loading...