今日を含む直近7日間のアクセス数をカウントするアクセスカウンターを作りました。「最近読まれているリスト」ページは、このアクセス数の多い順に並んでいます。
概要
今日を含む直近の7日間分のアクセス履歴とアクセス数の合計を保存する。
アクセス履歴は日付をキー、アクセス数を値に持つ連想配列とし、投稿メタ(カスタムフィールド)に保存する。
アクセス数の合計も別の投稿メタとして保存する。これを降順にソートして投稿を取り出すことで「最近読まれているリスト」を表示できるようにする。
クローラーのアクセスは簡易ロジックによって除外する。ただしアクセス履歴の更新だけを行わせてメンテナンスを手伝ってもらう。
2022/1/7、未アクセス時
Array (
[20211230] => 10
[20220101] => 20
[20220105] => 30
)
アクセスカウンター: 60
2022/1/7、1アクセス後
Array (
[20220101] => 20
[20220105] => 30
[20220107] => 1
)
アクセスカウンター: 51
2022/1/7、1アクセス後(botによるアクセス)
Array (
[20220101] => 20
[20220105] => 30
)
アクセスカウンター: 50
コード
add_action( 'wp_footer', 'LF_Access_Count::access_count', 30 );
class LF_Access_Count {
public static function access_count() {
// 管理者からのアクセス、およびlistカテゴリ以外へのアクセスを除外
if ( current_user_can( 'administrator' ) ||
! has_category( 'list' )
) {
return;
}
// カスタムフィールドからカウント履歴を取得
$count_history = get_post_meta( get_the_ID(), 'count_history', true );
// 7日前の YYYYMMDD を取得
$expdate = (int)wp_date( 'Ymd', strtotime( '-7 days' ) );
// 7日前の日付以前の記録を削除(全削除なら空配列が返る)
$count_history = array_filter(
// アクセス履歴が無ければget_post_meta()が空文字を返すのでarrayにキャスト
(array)$count_history,
function( $k ) use( $expdate ) {
return ( $expdate < $k ) ? true : false;
},
ARRAY_FILTER_USE_KEY
);
// ユーザーエージェントを取得(未設定なら空文字)
$ua = $_SERVER['HTTP_USER_AGENT'] ?? '';
// 簡易クローラー判定。bot、bots、spiderで終わる単語が含まれる
// 場合はクローラーと見なす。クローラーでなければカウントアップ
if ( 1 !== preg_match( '/.*(bots?|spider)\b/i', $ua ) ) {
// 今日の日付をYYYYMMDD形式の整数として取得
$today = (int)wp_date( 'Ymd' );
// 今日の日付をキーに持つ要素がアクセス履歴に存在すれば
// 値をインクリメント、なければ1
isset( $count_history[$today] ) ? $count_history[$today]++ : $count_history[$today] = 1;
}
// アクセス履歴を投稿メタに保存
update_post_meta( get_the_ID(), 'count_history', $count_history );
// アクセス履歴の値の合計を投稿メタに保存
update_post_meta( get_the_ID(), 'lf_counter', array_sum( $count_history ) );
}
}