【スポンサーリンク】

[WordPress] 投稿月でグループ分けした月別PV集計表を見るためのプラグインを作った【ChatGPTと】

一ヶ月分のブログ公開がどれぐらいのページビューにつながっているのか、集計する自分用のWordPressプラグインを作成しました。

自分にとっては未経験の分野でしたが、対話型AI「ChatGPT」に相談してみると、使える叩き台を用意してくれました。

WordPressプラグインづくりははじめてでしたが、かなりの時間短縮。
無事に完成しました。

\記事が役に立ったらシェアしてね/
【スポンサーリンク】

アクセス集計プラグイン

一ヶ月分のブログ公開が、どれぐらいの成果になっているのか知りたいことがあります。

これまでは、Google Analyticsで見ていました。
しかし、UAが廃止されてGA4に移行するので、別の集計方法が必要になりました。

そこで、今回は WordPressの管理画面で確認できるように、プラグインを作成することにしてみました。

結果的には、ブログで使っている「Cocoonテーマ」のアクセス集計データベースを利用して、なんとか各記事の期間ごとのPVを投稿月でグループ化して分析することができました。

このように分析すると、1ヶ月分の記事の閲覧がどのように推移しているのか、わかりやすいです。

だいたい 2ヶ月ほどで安定しているようですね。

完成したコードは以下です。

<?php
/**
 * Plugin Name: 月別集計
 * Plugin URI: chiilabo.com
 * Author: chiilabo
 * Author URI: chiilabo.com
 * Description: 投稿月ごとの月別ページビュー集計表を表示する。
 * Version: 1.0.0
 */

// Exit if accessed directly.
if ( ! defined( 'ABSPATH' ) ) {
    exit;
}

define( 'ACCESSES_TABLE_NAME', $wpdb->prefix . 'cocoon' . '_accesses' );

// Register the admin menu for the plugin
function monthly_pageview_totals_admin_menu() {
    add_menu_page(
        '月別集計',
        '月別集計',
        'edit_posts',
        'monthly-pageview-totals',
        'monthly_pageview_totals_display',
        'dashicons-chart-line',
        20
    );
}
add_action( 'admin_menu', 'monthly_pageview_totals_admin_menu' );

// Callback to display the page content
function monthly_pageview_totals_display() {
    global $wpdb;
    
    // Use the Transients API to cache the page view data for 12 hours

        // Retrieve all the posts and their permalinks
        $posts = get_posts( array(
            'post_type' => 'post',
            'post_status' => 'publish',
            'numberposts' => -1
        ) );
        
        $urls = array();
        $post_ms = array();
        $results = array();
        foreach ( $posts as $post ) {
            $url = parse_url( get_permalink( $post ) );
            $urls[$post->ID] = substr( $url['path'], 1 );
            $post_m = substr($urls[$post->ID], 0,7);
            $post_ms[$post_m]=$post_m;
            $results[$post_m]=array();
        }
        
        
        $table_name = ACCESSES_TABLE_NAME;
        $query = "
            SELECT post_id, SUM(count) as pv, YEAR(date) as year, MONTH(date) as month, date
            FROM $table_name 
            GROUP BY post_id, year, month
            ORDER BY date DESC  
        ";  
        
        // Retrieve the access logs
        $logs = $wpdb->get_results($query);

    $months = array();
    foreach ( $logs as $log ) {
        $post_m = substr($urls[$log->post_id], 0,7);
        $access_m = $log->year.sprintf('%02d', $log->month);
        
        $pv = $results[$post_m][$access_m];
        if (!$pv) {
            $pv =0;
        }
        $results[$post_m][$access_m] = $pv + $log->pv;
        $months[ $access_m ] = $log->year.'年'.$log->month.'月';
    }    
    
    // Initialize the table
    echo '<table class="widefat">';
    echo '<thead><tr>';
    echo '<th width="40%">投稿月</th>';
    
    foreach ( $months as $month ) {
        echo '<th>' . esc_html( $month ) . '</th>';
    }
    echo '</tr></thead>';
    
    // Populate the table
    echo '<tbody>';
    foreach ( $results as $m => $row ) {
        echo '<tr>';
        echo '<td>' . $m  . '</td>';
        foreach ( $months as $key => $month ) {
            $pv = 0;
            foreach ( $row as $mm => $mpv ) {
                if ( $mm == $key ) {
                    $pv = $mpv;
                    break;
                }
            }
            echo '<td align="right">' . ( $pv ? number_format_i18n( $pv ) : '' ) . '</td>';
        }
        echo '</tr>';
    }
    

    echo '</tbody>';
    echo '</table>';
}

動作無保証】montyly_pageview_totals.zipのダウンロード

自分用なので動作は全く保証しませんが、「monthly_pageview_totals.php」を「monthly_pageview_totals」フォルダに入れて圧縮したら「monthly_pageview_totals.zip」になります。あとは、WordPressの「プラグイン追加」からインストールできます。

動作には Cocoonテーマのアクセスログが必要です。

ChatGPTとやり取りして作った

たまに「function.php」をいじってサイト上でページを生成することはあるのですが、WordPressプラグインでははじめてです。どこから手を付けたらいいのか、検討がつきませんでした。
そこで、話題の対話型AIの「ChatGPT」に相談しながら、作っていくことにしました。

ChatGPTには、はじめ以下のような質問をしました。

WordPressで投稿月別の合計アクセス数を月別に集計するプラグインを作ってください。

集計表は列は集計月別、行は投稿月別、各セルにはページビューの合計を入力します。

すると、PHPコードを返してくれました。

申し訳ありませんが、… WordPressプラグインの作成に関する十分な情報を持っていません。ただし、一般的なアプローチとして、…カスタムPHPスクリプトを作成することができます。

ちょっと意図とは違いますが、各投稿の月ごとのPVを集計するコードのようです。

<?php
global $wpdb;

// Get all published posts
$posts = $wpdb->get_results("SELECT ID, post_date, post_title FROM $wpdb->posts WHERE post_status = 'publish'");

// Initialize array to hold monthly pageview totals
$pageviews_by_month = array();

// Loop through each post and calculate its pageview total
foreach ($posts as $post) {
    $post_id = $post->ID;
    $post_date = $post->post_date;
    $post_title = $post->post_title;

    // Get monthly pageview total for this post
    $pageviews = $wpdb->get_var("SELECT SUM(views) FROM $wpdb->post_views WHERE id = $post_id AND type = 'post' AND MONTH(date) = MONTH('$post_date') AND YEAR(date) = YEAR('$post_date')");

    // Add pageview total to monthly total for this month
    $month = date('Y-m', strtotime($post_date));
    if (!isset($pageviews_by_month[$month])) {
        $pageviews_by_month[$month] = array();
    }
    $pageviews_by_month[$month][$post_date] = $pageviews;
}

// Print monthly pageview totals as a table
echo "<table>";
echo "<thead><tr><th>Month</th>";
foreach ($posts as $post) {
    echo "<th>" . $post->post_title . "</th>";
}
echo "</tr></thead>";
echo "<tbody>";
foreach ($pageviews_by_month as $month => $totals) {
    echo "<tr><td>" . $month . "</td>";
    foreach ($posts as $post) {
        $post_date = $post->post_date;
        $pageviews = isset($totals[$post_date]) ? $totals[$post_date] : 0;
        echo "<td>" . $pageviews . "</td>";
    }
    echo "</tr>";
}
echo "</tbody>";
echo "</table>";
?>

このスクリプトでは、まずすべての公開された投稿を取得します。次に、各投稿のページビューの合計を計算し、各月の集計表に追加します。最後に、集計表をHTMLテーブルとして出力します。

このスクリプトを、WordPressプラグインとして実装するためには、必要なWordPress関数やフックを利用して、データベースアクセスや出力方法を調整する必要があります

ChatGPTによるコードの説明

PHPスクリプトからWordPressプラグインに

とりあえず、「WordPressプラグイン」として動作させてみましょう。
PHPスクリプトを「WordPressプラグイン」として入れる方法も聞いてみました。

zip形式のWordPressプラグインファイルが必要なんだけど、さっきのPHPファイルを圧縮するだけでよいですか?

いろいろ教えてくれます。
ただし、後々やってみると、今回のようなシンプルなプラグインならもっと簡単。
phpファイルを プラグイン名のフォルダに入れてから zip形式で圧縮するだけでよかったみたいです。

ここに admin-page.php やreadme.txt を作っていれていますが、結果的には省いても動作しました。

なにはともあれ、自作プラグインをWordPressにインストールして、管理メニューが追加されました。

意外とやってみるとできるもんだね。

ChatGPTが生成したページの修正作業

表示されたプラグインの管理ページはこちら。
行列の並びが逆ですし、結果の数値もありませんでした。

とはいえ、最低限のひな形があるので、データベースの取得と画面への表示に関係する箇所を集中的に見ればよいので、これでもだいぶ助かるんです。

サイト読み込みエラーを乗り越えて

ここから延々「あーでもないこーでもない」と、修正のやり取りをしていきます。
ただし、鵜呑みにするのは要注意です。

ChatGPTの提出してきたコードをそのままアップロードしたら、WordPress全体が読み込みエラーになったりもしました。

管理画面にもアクセスできなくなって、ちょっと焦りました。
結局、FTPからプラグインのスクリプトファイルを削除して元に戻しました。

自分で直せることが大事。

頼み方にもコツがある(プロンプト・エンジニアリング)

質問するたびに細部が前回とは違うコードを提出してくるので、ほしい回答を得るには依頼の仕方が大事だと感じました。

いろんな情報源を元に、コードを作るので、辻褄が合わないことがあるのです。

ChatGPTとやり取りしていると、こっちで要望内容を整理してから頼むとスムーズになることがわかってきました。

WordPressのプラグイン「pageview_totals.php」を作成してください。

●コメントは日本語で表記してください。

●プラグインのヘッダーには、以下の情報を含めること
Plugin Name:投稿別アクセス集計
Plugin URI:chiilabo.com
Author:chiilabo
Author URI:chiilabo.com
Descriptionには機能の説明を記述します。

●管理画面の「投稿別アクセス集計」にて、以下の機能を実現してください。
アクセス権限は edit_posts
ページslugは、pageview-totals

投稿ごとのページビュー集計表を表示する

・行は投稿ごとに投稿日の新しい順に並べます。

投稿列の項目はページURLでドメインを削除したものを表示します。
例えば、https://chiilabo.com/2022-02/gmail-unused-account-delete/ なら 2022-02/gmail-unused-account-delete/
投稿列の列幅は全体の40%になるようにしてください。

表の各項目には投稿ごとにページビューを合計してください。
投稿ごとのページビューは、アクセスログから集計して求めます。

結果が0の場合は空欄にしてください。
表は細い枠線で区切り、数値は右揃えにしてください。

コード全体を出力した後に、説明をしてください。

これを「プロンプトの作成」といいます。
人間がどんなプロンプトを作るかで、AIの返す答えの精度が変わってきます。

<?php
/**
 * Plugin Name: 投稿別アクセス集計
 * Plugin URI: chiilabo.com
 * Author: chiilabo
 * Author URI: chiilabo.com
 * Description: 投稿ごとのアクセス数を集計して表示するプラグインです。
 */

defined( 'ABSPATH' ) or die( 'No direct script access allowed' );

add_action( 'admin_menu', 'pageview_totals_menu' );

function pageview_totals_menu() {
    add_submenu_page(
        'edit.php',
        '投稿別アクセス集計',
        '投稿別アクセス集計',
        'edit_posts',
        'pageview-totals',
        'pageview_totals_callback'
    );
}

function pageview_totals_callback() {
    global $wpdb;
    $table_name = $wpdb->prefix . 'access_logs';

    $urls = $wpdb->get_results(
        "SELECT DISTINCT post_id, post_name FROM $wpdb->posts ".
        "INNER JOIN $table_name ON $wpdb->posts.ID = $table_name.post_id ".
        "ORDER BY post_date DESC"
    );

    $logs = $wpdb->get_results(
        "SELECT post_id, COUNT(*) as count ".
        "FROM $table_name ".
        "GROUP BY post_id"
    );

    echo '<div class="wrap">';
    echo '<h1>投稿別アクセス集計</h1>';

    if ( empty( $urls ) ) {
        echo '<p>アクセスログがありません。</p>';
        echo '</div>';
        return;
    }

    echo '<table class="wp-list-table widefat fixed striped">';
    echo '<thead><tr>';
    echo '<th style="width: 40%;">URL</th>';
    echo '<th>アクセス数</th>';
    echo '</tr></thead><tbody>';

    foreach ( $urls as $url ) {
        $count = 0;
        foreach ( $logs as $log ) {
            if ( $log->post_id == $url->post_id ) {
                $count = $log->count;
                break;
            }
        }

        if ( $count > 0 ) {
            $url_name = preg_replace( '#^https?://[^/]+#i', '', get_permalink( $url->post_id ) );
            echo '<tr><td>'.$url_name.'</td><td style="text-align: right;">'.number_format( $count ).'</td></tr>';
        }
    }

    echo '</tbody></table>';
    echo '</div>';
}

このプラグインは、管理画面に「投稿別アクセス集計」というメニューを追加し、投稿ごとのアクセス数を集計して表示します。

まず、管理画面にメニューを追加するために、add_actionを使ってadmin_menuフックにpageview_totals_menu関数を登録しています。pageview_totals_menu関数では、add_submenu_pageを使って、WordPressの投稿一覧画面にサブメニューを追加しています。

pageview_totals_callback関数では、アクセスログのテーブル名を取得し、URLとアクセス数の配列を取得します。

Chat GPTによる説明

なるほど「要件定義」みたいな感じ。

プログラミングとは別の仕事になるんだね。

既にこういう仕事を指して「プロンプト・エンジニアリング」と言葉が生まれています。

Cocoonのアクセスログを利用する

結局、アクセスログは、WordPress本体のデータベースには含まれていないようです。
ChatGPTのコードで利用するデータベースは、どこかの見本を参考にしたのでしょうが、自分の環境では使えませんでした。

そこで、以前に利用した Cocoonのアクセス集計を使おうと考えました。

ところが、これは すんなりとはいきませんでした。
というのも、ChatGPTは、「$wpdb->prefix . ‘usapv_total‘」というデータベースから取得できると主張したのですが、実際とは違うようなのです。

「prefix . usapv_total」というテーブルは、私の環境のデータベースにはありません。

最後は自力でソースコード検索

ここから先は自分で検索した方が速そうだね。

ある程度 絞り込んできたら、最後は自分で検索した方が速いです。
GitHubでCocoonのソースコードを調べて、アクセス集計に関わるコード部分を見比べることにしました。

アクセスログを記録している箇所、取得している箇所を探せば、利用しているデータベースがわかるからです。

GitHubのコード検索も便利だよね。

結論としては、「$wpdb->prefix. ‘cocoon’. ‘_accesses‘」というのがデータベースのテーブル名で、そこにアクセスログを記録していることを見つけました。
$wpdbがグローバル変数になっているので、外部スクリプトからも参照できます。

あとは、表示部分のコードを見つつ、呼び出すデータを変更すれば完成です。

なんやかんや半日ほどで完成しました。

取り組む前は数日はかかると見込んでいたので、かなり早く済みました。

ChatGPTはかなり優秀な「助手」だと感じました。

有料版は月に20ドルかぁ……。

でも、月給3000円の助手なんて、十分に価値アリだね。

こちらもどうぞ。

Cocoonで注目記事ランキングのショートコードを作成した【SQLって何?からのデータベース操作】
記事のアクセスランキング(人気記事)は、上位の記事がなかなか変わらないので、あまりおもしろくありません。 WordPressの記事のアクセス数の前週比のランキング(急上昇の記事)を作りたいと思って、Cocoonのコードを読んでみました。 Cocoonのアクセスランキングは、SQLクエリで生成されているので、SQLについてまとめました。 完成したもの Cocoonのget_access_rankin...
[Cocoon] 記事の関連タグをサイドバーに表示した・その2(ショートコードにできた)
結論としては、the_tag_links() ではなく、get_the_tag_links()を呼べばよかっただけでした。 以前の方法の問題点 以前、記事の関連タグをサイドバーに表示するときに、ショートコードにできず、テキストウィジェットでPHPコードを実行する、という方法でむりやり解決していました。 ただし、この方法はウィジェットを確認するたびに、ビジュアル表示になって「コードが評価」されててま...
[Cocoon] ラベルボックスの枠の色を修正した(gutenberg.php)
Cocoon バージョン: 2.5.7.4 に更新したところ、ラベルボックスの枠の色がおかしくなってしまいました。 ラベルボックスの枠を「白」に設定していた箇所が、「黒」に表示されています。 追記 Cocoon バージョン: 2.5.7.5 で修正されました。 (参考) 更新後にラベルボックスの枠の色がおかしい? | 不具合報告 | Cocoon フォーラム ラベルボックスの枠とクラスを検証 Ch...
【人工知能】ChatGPTに質問してみたら、けっこう間違えもあった(アカウント登録の仕方)
話題になっている ChatGPT(chat.openai.com/chat) のアカウントを作成して、試してみました。 まるで人間が答えたような回答を、すぐに出すのでびっくりしました。しかし、いろんな回答をよく読んでみると「滋賀を四国地方」と言ってみたり、あからさまな間違いも少なくありません。 また、こちらから送った文章に機密事項が含まれている場合でも、ChatGPTはそれを学習して、別の人に回答...
QRコードを読み込むと、関連記事を確認できます。
[WordPress] 投稿月でグループ分けした月別PV集計表を見るためのプラグインを作った【ChatGPTと】
【スポンサーリンク】
タイトルとURLをコピーしました