[WordPress] プラグインなしで記事の閲覧数をカウント・初期化するカスタマイズ方法

記事ページの閲覧数を管理したい

WordPressで管理しているサイトの記事ページの閲覧数をカウントしたいことということはないでしょうか。

閲覧数集計用プラグインの導入や Google Analytics などのアクセス解析サービスを使うことでも対応できますが、閲覧数をWordpressをカスタマイズして自力で集計します。

今回カスタマイズで作る機能は以下の3点です。

  1. 記事ページへの閲覧回数を集計する機能
  2. 管理画面の投稿一覧に閲覧数列の追加・ソート機能
  3. 管理画面の投稿一覧で閲覧数を一括初期化する機能

順番に見ていきます。

アクセス回数の集計機能

ページへのアクセス回数 = 閲覧数として考えます。したがって、ページ表示時のイベントをフックし、DBに回数を集計していきます。

閲覧数当項目はWordpressでは管理されていません。したがってカスタムフィールドとして追加してやる必要があります。update_post_meta という関数を使うことでカスタムフィールドでデータを管理できます。

update_post_meta関数

update_post_meta() は、指定した投稿に存在するカスタムフィールドの値を更新します。add_post_meta() の代わりとしても使うことができます。
この関数はまず、$post_id で ID を指定した投稿に $meta_key を持つカスタムフィールドが存在することを確認します。
もし存在しなければ代わりに add_post_meta( $post_id, $meta_key, $meta_value ) を実行し、その結果を返します。

次のようにして使います。

<?php update_post_meta( $post_id, $meta_key, $meta_value ); ?>

$post_id で更新対象の記事IDを指定し、$meta_key, $meta_value で管理するデータのキーと値を指定します。これで任意の記事に対するカスタムフィールドを更新できます。上述の通り、指定したキーのデータが無い場合は、登録されるので気にしなくても良いです。

get_post_meta関数

カスタムフィールドの値は get_post_meta 関数で取得できます。

<?php $meta_values = get_post_meta($post_id, $key, $single); ?>

$post_id で対象の記事IDを指定し、$meta_key でカスタムフィールドのキーを指定します。$single は真偽値を指定します。trueを指定すると単一の値で取得します。

閲覧数を集計する

update_post_meta 関数と get_post_meta 関数を使って閲覧数を集計します。wp_headイベントをフックして、閲覧する記事に対して、閲覧数のカスタムフィールドを更新します。

以下すべてのコードは functions.php に記述します。

// ボット判定関数
function is_bot() {
    $ua = $_SERVER['HTTP_USER_AGENT'];
    $bots = array(
        "googlebot",
        "bingbot",
        "yahoo", 
    );
    foreach( $bots as $bot ) {
        if (stripos( $ua, $bot ) !== false) {
            return true;
        }
    }
    return false;
}

// 閲覧数集計
add_action( 'wp_head', function() {
    global $post;
    if ( 'publish' === get_post_status( $post ) 
        && is_single() && !is_preview() && !is_bot()) {
        // 公開済、記事ページ、プレビューではない、ボットでない場合
        $views = intval( get_post_meta( $post->ID, 'custom_views', true ) );
        update_post_meta( $post->ID, 'custom_views', ( $views + 1 ) );
    }
} );

何でもかんでも閲覧数としてカウントしていると大変なことになるので、以下の条件で閲覧数をカウントするようにしています。

  • 公開済の記事であること
  • 記事ページであること
  • プレビューではないこと
  • ボットではないこと

‘custom_views’ というキー値でカスタムフィールドに閲覧数を保存しています。これで閲覧数を集計する機能は完成です。次はこれを一覧画面で確認できるようにします。

投稿一覧に閲覧数列の追加

投稿一覧に上の画像のように列を追加して閲覧数を表示します。

// 投稿一覧に[閲覧数]列を追加する
add_filter( 'manage_posts_columns', function( $columns ) {
    $columns['views'] = '閲覧数';
    return $columns;
} );
// カスタムフィールドの値(集計した閲覧数)を表示
add_action( 'manage_posts_custom_column', function( $column_name, $post_id ) {
    if ( $column_name == 'views' ) {
        $views = intval( get_post_meta( $post_id, 'custom_views', true ) );
        echo $views;
    }
}, 10, 2 );

manage_posts_columns イベントをフックして投稿一覧の列を追加します。これだけではヘッダー列が出るだけで値が表示されません。

manage_posts_custom_column イベントをフックして列の値を出力します。引数 $column_name が 追加した列名に一致する場合に、カスタムフィールドから閲覧数を取得して出力します。

これで閲覧数列にデータが表示されます。自分で記事ページを表示してから投稿一覧を確認すると、閲覧数が増えているのが確認できるはずです。

閲覧数で投稿一覧をソートする

ここまでで一覧に閲覧数を表示するところまで確認できました。次は閲覧数の値に基づき一覧をソートする機能を追加します。

// ソート対象の列として追加
add_filter( 'manage_edit-post_sortable_columns', function( $columns ) {
    $columns['views'] = '閲覧数';
    return $columns;
} );
// 数値としてソートするように設定
add_filter( 'request', function( $vars ) {
    if ( isset( $vars['orderby'] ) && '閲覧数' == $vars['orderby'] ) {
        $vars = array_merge( $vars, array(
            'meta_key' => 'custom_views',
            'orderby' => 'meta_value_num'
        ));
    }
    return $vars;
} );

ソート可能にするのは簡単で追加した列と同じ列を、manage_edit-post_sortable_columns イベントをフックして追加します。これだけでソートしてくれるのですが、数値としてソートしてくれないので正しくソートされません。

したがって、数値としてソートするようにパラメータをいじります。

これだけでソート可能になります。

閲覧数を初期化する機能

最後に閲覧数を初期化する(0に戻す)機能を付けておきます。別に必要ないかもしれませんが。

閲覧数初期化機能は投稿一覧の一括処理をカスタマイズして追加します。一括処理のカスタマイズ方法詳細は以下の記事に詳しく書きましたので参照してください。

ここに記事URL

一括処理の方法がわかれば難しくありません。記事のカスタムフィールドで管理している閲覧数に0を設定してやればよいです。

// 一括処理項目追加
add_filter( 'bulk_actions-edit-post', function( $actions ) {
    // 閲覧数クリア項目追加
    $actions += array( 'clear_views' => '閲覧数初期化' );
    return $actions;
} );

// 一括処理部分
add_filter( 'handle_bulk_actions-edit-post', function( $redirect_to, $doaction, $post_ids ) {
    if ( $doaction == 'clear_views' ) {
        foreach ( $post_ids as $post_id ) {
            // チェックされた記事のループ
            update_post_meta( $post_id, 'custom_views', 0 );
        }
    }
    $redirect_to = add_query_arg( 'bulk_views_clear', count( $post_ids ), $redirect_to );
    return $redirect_to;
}, 10, 3 );

// 一括処理結果通知
add_action( 'admin_notices', function () {
    if ( ! empty( $_REQUEST['bulk_views_clear'] ) ) {
        $cleared_count = intval( $_REQUEST['bulk_views_clear'] );
        echo "<div id='message' class='updated fade'>{$cleared_count}件の閲覧数を初期化しました。</div>";
    }
} );

上記コードを追加すると、投稿一覧の一括処理項目に「閲覧数初期化」という項目が追加されます。

実行するとチェックしてある投稿について閲覧数を0にする処理が走ります。処理結果件数はメッセージが表示されます。

閲覧数が0になっていたら成功です。

以上。