Cocoonテーマのコードを利用して、自前の「注目記事ランキング」を作っていたのですが、更新によってエラーになってしまいました。
改めて、コードを修正して直すことができました。
1. サイトのPHPにエラーがある
教室ホームページを見たら、ページにエラーが表示されて、レイアウトが崩れていることに気づきました。(2022年10月17日)。
このサイトで重大なエラーが発生しました。
WordPressのトラブルシューティングについては、こちらをご覧ください。
このエラーは、WordPressサイトのPHPコードに、エラーがある場合に表示されます。
処理がエラー箇所で止まってしまうため、それ以降のページ要素やスタイルが全て出力されません。
1-1. Cocoonテーマの更新で自前コードが不整合
エラー箇所を調べてみると、「注目記事ランキング」でした。
このランキングは、Cocoonテーマの「人気記事ショートコード」のソースコードをもとに、私が改造して作っていたものです。
どうも、Cocoonのアップデートで、人気記事ショートコード関数の内部処理が修正され、分岐していた自前のコードが整合性が取れなくなってしまったようです。
ちょうど WordPressが 6.0.2、Cocoonが2.5.0 に更新されたタイミングでした。
Cocoon 2.5は、WordPress 6.0のメジャーアップデートに合わせるため、変更箇所が多かったのだとも思います。
ソースコードからコピーして改造しているので、更新があれば修正が必要になるのは仕方がないです。
2. 更新に合うように自前のコードを作り直す
久々にするコードの修正は集中力が必要なので、後回しにしていました。
ようやく時間が作れたので、コードを修正していきます。
ランキング集計用に別のSQLクエリを渡したいだけなのですが、関数呼び出しの深い部分に書かれているため、直接変更できません。ショートコードの関数の呼び出し元から順に、全て複製して修正しています。
まずは、関係するコードをもう一度洗い出していきます。
GitHubにあるCocoonのソースコードを、前回の修正時の記録をたよりに見ていきます。
ざっと見て、人気記事ショートコードの関数呼び出しはそのままだったので、該当する部分のコードをテキストエディタにコピーします。
//人気記事ショートコード関数
/** lib/shortcodes.php */
if (!shortcode_exists('popular_list')) {
add_shortcode('popular_list', 'popular_entries_shortcode');
}
if ( !function_exists( 'popular_entries_shortcode' ) ):
function popular_entries_shortcode($atts) {
extract(shortcode_atts(array(
'days' => 'all',
'count' => 5,
'type' => 'default',
'rank' => 0,
'pv' => 0,
'cats' => 'all',
'children' => 0,
'bold' => 0,
'arrow' => 0,
'class' => null,
'author' => null,
'post_type' => 'post',
'horizontal' => 0,
), $atts, 'popular_list'));
$cat_ids = array();
if ($cats && $cats != 'all') {
$cat_ids = explode(',', $cats);
}
$atts = array(
'days' => $days,
'entry_count' => $count,
'entry_type' => $type,
'ranking_visible' => $rank,
'pv_visible' => $pv,
'cat_ids' => $cat_ids,
'children' => $children,
'bold' => $bold,
'arrow' => $arrow,
'class' => $class,
'author' => $author,
'post_type' => $post_type,
'horizontal' => $horizontal,
);
ob_start();
generate_popular_entries_tag($atts);
$res = ob_get_clean();
return $res;
}
endif;
//人気ランキングリストの取得
/** lib/html-forms.php */
if ( !function_exists( 'generate_popular_entries_tag' ) ):
function generate_popular_entries_tag($atts){
extract(shortcode_atts(array(
'days' => 'all',
'entry_count' => 5,
'entry_type' => ET_DEFAULT,
'ranking_visible' => 0,
'pv_visible' => 0,
'cat_ids' => array(),
'children' => 0,
'exclude_post_ids' => array(),
'exclude_cat_ids' => array(),
'bold' => 0,
'arrow' => 0,
'class' => null,
'author' => null,
'post_type' => 'post',
'horizontal' => 0,
), $atts));
$records = get_access_ranking_records($days, $entry_count, $entry_type, $cat_ids, $exclude_post_ids, $exclude_cat_ids, $children, $author, $post_type);
$thumb_size = get_popular_entries_thumbnail_size($entry_type);
$atts = array(
'type' => $entry_type,
'ranking_visible' => $ranking_visible,
'pv_visible' => $pv_visible,
'bold' => $bold,
'arrow' => $arrow,
'class' => $class,
'horizontal' => $horizontal,
);
$cards_classes = get_additional_widget_entry_cards_classes($atts);
?>
<div class="popular-entry-cards widget-entry-cards no-icon cf<?php echo $cards_classes; ?>">
<?php if ( $records ) :
$i = 1;
foreach ($records as $post):
$permalink = get_permalink( $post->ID );
$title = $post->post_title;
$no_thumbnail_url = ($entry_type == ET_DEFAULT) ? get_no_image_120x68_url($post->ID) : get_no_image_320x180_url($post->ID);
$w = ($entry_type == ET_DEFAULT) ? THUMB120WIDTH : THUMB320WIDTH;
$h = ($entry_type == ET_DEFAULT) ? THUMB120HEIGHT : THUMB320HEIGHT;
$post_thumbnail = get_the_post_thumbnail( $post->ID, $thumb_size, array('alt' => '', 'loading' => 'lazy', 'decoding' => 'async') );
$pv = $post->sum_count;
if ($post_thumbnail) {
$post_thumbnail_img = $post_thumbnail;
} else {
$post_thumbnail_img = get_original_image_tag($no_thumbnail_url, $w, $h, 'no-image popular-entry-card-thumb-no-image widget-entry-card-thumb-no-image', '');
}
$pv_tag = null;
if ($pv_visible){
$pv_text = $pv == '1' ? $pv.' view' : $pv.' views';
$pv_tag = '<span class="popular-entry-card-pv widget-entry-card-pv">'.$pv_text.'</span>';
}
?>
<a href="<?php echo $permalink; ?>" class="popular-entry-card-link widget-entry-card-link a-wrap no-<?php echo $i; ?>" title="<?php echo esc_attr($title); ?>">
<div class="popular-entry-card widget-entry-card e-card cf">
<figure class="popular-entry-card-thumb widget-entry-card-thumb card-thumb">
<?php echo $post_thumbnail_img; ?>
<?php
$is_visible = apply_filters('is_popular_entry_card_category_label_visible', false);
$is_visible = apply_filters('is_widget_entry_card_category_label_visible', $is_visible);
the_nolink_category($post->ID, $is_visible); //カテゴリラベルの取得 ?>
</figure><!-- /.popular-entry-card-thumb -->
<div class="popular-entry-card-content widget-entry-card-content card-content">
<span class="popular-entry-card-title widget-entry-card-title card-title"><?php echo $title;?></span>
<?php if ($entry_type != ET_LARGE_THUMB_ON): ?>
<?php echo $pv_tag; ?>
<?php endif ?>
<?php generate_widget_entry_card_date('popular', $post->ID); ?>
</div><!-- /.popular-entry-content -->
<?php if ($entry_type == ET_LARGE_THUMB_ON): ?>
<?php echo $pv_tag; ?>
<?php endif ?>
</div><!-- /.popular-entry-card -->
</a><!-- /.popular-entry-card-link -->
<?php
$i++;
endforeach;
else :
echo '<p>'.__( '人気記事は見つかりませんでした。', THEME_NAME ).'</p>';//見つからない時のメッセージ
endif; ?>
</div>
<?php
}
endif;
/** lib/page-access/access-func.php */
//アクセスランキングを取得
if ( !function_exists( 'get_access_ranking_records' ) ):
function get_access_ranking_records($days = 'all', $limit = 5, $type = ET_DEFAULT, $cat_ids = array(), $exclude_post_ids = array(), $exclude_cat_ids = array(), $children = 0, $author = null, $post_type = 'post'){
//カテゴリー配列を文字列に変換
$cat_ids = is_array($cat_ids) ? $cat_ids : array();
$cats = implode(',', $cat_ids);
//アクセスキャッシュを有効にしている場合
if (is_access_count_cache_enable()) {
if ($cat_ids) {
//子孫カテゴリも含める場合
if ($children) {
$categories = $cat_ids;
$res = $categories;
foreach ($categories as $category) {
$res = array_merge($res, get_term_children( $category, 'category' ));
}
$cat_ids = $res;
$cats = implode(',', $res);
}
}
//除外投稿
$archive_exclude_post_ids = get_archive_exclude_post_ids();
if ($archive_exclude_post_ids && is_array($archive_exclude_post_ids)) {
$exclude_post_ids = array_unique(array_merge($exclude_post_ids, $archive_exclude_post_ids));
}
$exclude_post_ids = is_array($exclude_post_ids) ? $exclude_post_ids : array();
$expids = implode(',', $exclude_post_ids);
$exclude_cat_ids = is_array($exclude_cat_ids) ? $exclude_cat_ids : array();
$excats = implode(',', $exclude_cat_ids);
$type = get_accesses_post_type();
$transient_id = TRANSIENT_POPULAR_PREFIX.'?days='.$days.'&limit='.$limit.'&type='.$type.'&cats='.$cats.'&children='.$children.'&expids='.$expids.'&excats='.$excats.'&author='.$author.'&post_type='.$post_type;
$cache = get_transient( $transient_id );
if ($cache) {
if (DEBUG_MODE && is_user_administrator()) {
// echo('<pre>');
// echo $transient_id;
// echo('</pre>');
} elseif (is_user_administrator()){
} else {
return $cache;
}
}
}
global $wpdb;
$access_table = ACCESSES_TABLE_NAME;
// $post_type = 'post';
$date = get_current_db_date();
$where = " WHERE {$access_table}.post_type = '$post_type' ".PHP_EOL;
// _v($where);
if ($days != 'all') {
$date_before = get_current_db_date_before($days);
$where .= " AND {$access_table}.date BETWEEN '$date_before' AND '$date' ".PHP_EOL;
}
if (is_ids_exist($exclude_post_ids)) {
$where .= " AND {$access_table}.post_id NOT IN(".implode(',', $exclude_post_ids).") ".PHP_EOL;
}
//3180, 3234
if (!is_numeric($limit)) {
$limit = 5;
}
//カテゴリを指定する場合
if (is_ids_exist($cat_ids) || is_ids_exist($exclude_cat_ids)) {
global $post;
$term_relationships = $wpdb->term_relationships;
$term_taxonomy = $wpdb->term_taxonomy;
$joined_table = 'terms_accesses';
//カテゴリー指定
if (is_ids_exist($cat_ids)) {
$cat_ids = implode(',', $cat_ids);
//$where .= " AND {$term_relationships}.term_taxonomy_id IN ({$cat_ids}) ".PHP_EOL;
$where .= " AND {$term_taxonomy}.term_id IN ({$cat_ids}) ".PHP_EOL;
}
//除外カテゴリー指定
if (is_ids_exist($exclude_cat_ids)) {
//空の配列を取り除く
$exclude_cat_ids = array_filter($exclude_cat_ids, "strlen");
//カンマ区切りにする
$ex_cat_ids = implode(',', $exclude_cat_ids);
$ex_cat_ids = preg_replace('/,$/', '', $ex_cat_ids);
$where .= " AND {$term_relationships}.term_taxonomy_id NOT IN ({$ex_cat_ids}) ".PHP_EOL;
}
$where .= " AND {$term_taxonomy}.taxonomy = 'category' ".PHP_EOL;
// //テーブル結合するクエリの場合はWHEREに付け加えるのでANDに変更する
// $where = str_replace('WHERE', 'AND', $where);
$query = "
SELECT {$joined_table}.post_id, SUM({$joined_table}.count) AS sum_count, {$joined_table}.term_taxonomy_id, {$joined_table}.taxonomy
FROM (
#カテゴリとアクセステーブルを内部結合してグルーピングし並び替えた結果
SELECT {$access_table}.post_id, {$access_table}.count, {$term_relationships}.term_taxonomy_id, {$term_taxonomy}.taxonomy
FROM {$term_relationships}
INNER JOIN {$access_table} ON {$term_relationships}.object_id = {$access_table}.post_id
INNER JOIN {$term_taxonomy} ON {$term_relationships}.term_taxonomy_id = {$term_taxonomy}.term_taxonomy_id
$where #WHERE句
GROUP BY {$access_table}.id
) AS {$joined_table} #カテゴリとアクセステーブルを内部結合した仮の名前
GROUP BY {$joined_table}.post_id
ORDER BY sum_count DESC
";
//_v($query);
//1回のクエリで投稿データを取り出せるようにテーブル結合クエリを追加
$query = wrap_joined_wp_posts_query($query, $limit, $author, $post_type);
} else {
$query = "
SELECT {$access_table}.post_id, SUM({$access_table}.count) AS sum_count
FROM {$access_table} $where
GROUP BY {$access_table}.post_id
ORDER BY sum_count DESC
";
//1回のクエリで投稿データを取り出せるようにテーブル結合クエリを追加
$query = wrap_joined_wp_posts_query($query, $limit, $author, $post_type);
}
$records = $wpdb->get_results( $query );
if (is_access_count_cache_enable() && $records) {
set_transient( $transient_id, $records, 60 * get_access_count_cache_interval() );
}
return $records;
}
endif;
3. 改造したポイント
人気記事ショートコードを生成するコードをもとに、急上昇記事ランキングになるようにSQLクエリの部分を改造しました。
//急上昇ランキングリストの取得
/** lib/html-forms.php */
if ( !function_exists( 'generate_trend_entries_tag' ) ):
function generate_trend_entries_tag($atts){
extract(shortcode_atts(array(
'days' => 'all',
'entry_count' => 5,
'entry_type' => ET_DEFAULT,
'ranking_visible' => 0,
'pv_visible' => 0,
'cat_ids' => array(),
'children' => 0,
'exclude_post_ids' => array(),
'exclude_cat_ids' => array(),
'bold' => 0,
'arrow' => 0,
'class' => null,
'author' => null,
'post_type' => 'post',
'horizontal' => 0,
), $atts));
$records = get_trend_ranking_records($days, $entry_count, $entry_type, $cat_ids, $exclude_post_ids, $exclude_cat_ids, $children, $author, $post_type);
$thumb_size = get_popular_entries_thumbnail_size($entry_type);
$atts = array(
'type' => $entry_type,
'ranking_visible' => $ranking_visible,
'pv_visible' => $pv_visible,
'bold' => $bold,
'arrow' => $arrow,
'class' => $class,
'horizontal' => $horizontal,
);
$cards_classes = get_additional_widget_entry_cards_classes($atts);
?>
<div class="popular-entry-cards widget-entry-cards no-icon cf<?php echo $cards_classes; ?>">
<?php if ( $records ) :
$i = 1;
foreach ($records as $post):
$permalink = get_permalink( $post->ID );
$title = $post->post_title;
$no_thumbnail_url = ($entry_type == ET_DEFAULT) ? get_no_image_120x68_url($post->ID) : get_no_image_320x180_url($post->ID);
$w = ($entry_type == ET_DEFAULT) ? THUMB120WIDTH : THUMB320WIDTH;
$h = ($entry_type == ET_DEFAULT) ? THUMB120HEIGHT : THUMB320HEIGHT;
$post_thumbnail = get_the_post_thumbnail( $post->ID, $thumb_size, array('alt' => '', 'loading' => 'lazy', 'decoding' => 'async') );
$pv = $post->sum_count;
if ($post_thumbnail) {
$post_thumbnail_img = $post_thumbnail;
} else {
$post_thumbnail_img = get_original_image_tag($no_thumbnail_url, $w, $h, 'no-image popular-entry-card-thumb-no-image widget-entry-card-thumb-no-image', '');
}
$pv_tag = null;
if ($pv_visible){
$pv_text = $pv == '1' ? $pv.' view' : $pv.' views';
$pv_tag = '<span class="popular-entry-card-pv widget-entry-card-pv">'.$pv_text.'</span>';
}
?>
<a href="<?php echo $permalink; ?>" class="popular-entry-card-link widget-entry-card-link a-wrap no-<?php echo $i; ?>" title="<?php echo esc_attr($title); ?>">
<div class="popular-entry-card widget-entry-card e-card cf">
<figure class="popular-entry-card-thumb widget-entry-card-thumb card-thumb">
<?php echo $post_thumbnail_img; ?>
<?php
$is_visible = apply_filters('is_popular_entry_card_category_label_visible', false);
$is_visible = apply_filters('is_widget_entry_card_category_label_visible', $is_visible);
the_nolink_category($post->ID, $is_visible); //カテゴリラベルの取得 ?>
</figure><!-- /.popular-entry-card-thumb -->
<div class="popular-entry-card-content widget-entry-card-content card-content">
<span class="popular-entry-card-title widget-entry-card-title card-title"><?php echo $title;?></span>
<?php if ($entry_type != ET_LARGE_THUMB_ON): ?>
<?php echo $pv_tag; ?>
<?php endif ?>
<?php generate_widget_entry_card_date('popular', $post->ID); ?>
</div><!-- /.popular-entry-content -->
<?php if ($entry_type == ET_LARGE_THUMB_ON): ?>
<?php echo $pv_tag; ?>
<?php endif ?>
</div><!-- /.popular-entry-card -->
</a><!-- /.popular-entry-card-link -->
<?php
$i++;
endforeach;
else :
echo '<p>'.__( '人気記事は見つかりませんでした。', THEME_NAME ).'</p>';//見つからない時のメッセージ
endif; ?>
</div>
<?php
}
endif;
/** lib/page-access/access-func.php */
//アクセスランキングを取得
if ( !function_exists( 'get_trend_ranking_records' ) ):
function get_trend_ranking_records($days = 'all', $limit = 5, $type = ET_DEFAULT, $cat_ids = array(), $exclude_post_ids = array(), $exclude_cat_ids = array(), $children = 0, $author = null, $post_type = 'post'){
//カテゴリー配列を文字列に変換
$cat_ids = is_array($cat_ids) ? $cat_ids : array();
$cats = implode(',', $cat_ids);
//アクセスキャッシュを有効にしている場合
if (is_access_count_cache_enable()) {
if ($cat_ids) {
//子孫カテゴリも含める場合
if ($children) {
$categories = $cat_ids;
$res = $categories;
foreach ($categories as $category) {
$res = array_merge($res, get_term_children( $category, 'category' ));
}
$cat_ids = $res;
$cats = implode(',', $res);
}
}
//除外投稿
$archive_exclude_post_ids = get_archive_exclude_post_ids();
if ($archive_exclude_post_ids && is_array($archive_exclude_post_ids)) {
$exclude_post_ids = array_unique(array_merge($exclude_post_ids, $archive_exclude_post_ids));
}
$exclude_post_ids = is_array($exclude_post_ids) ? $exclude_post_ids : array();
$expids = implode(',', $exclude_post_ids);
$exclude_cat_ids = is_array($exclude_cat_ids) ? $exclude_cat_ids : array();
$excats = implode(',', $exclude_cat_ids);
$type = get_accesses_post_type();
$transient_id = TRANSIENT_POPULAR_PREFIX.'?days='.$days.'&limit='.$limit.'&type='.$type.'&cats='.$cats.'&children='.$children.'&expids='.$expids.'&excats='.$excats.'&author='.$author.'&post_type='.$post_type;
$cache = get_transient( $transient_id );
if ($cache) {
if (DEBUG_MODE && is_user_administrator()) {
// echo('<pre>');
// echo $transient_id;
// echo('</pre>');
} elseif (is_user_administrator()){
} else {
return $cache;
}
}
}
global $wpdb;
$trend_table = ACCESSES_TABLE_NAME;
// $post_type = 'post';
$date = get_current_db_date();
$date_yesterday = get_current_db_date_before(1);
$where = " WHERE {$trend_table}.post_type = '$post_type' ".PHP_EOL;
// _v($where);
if ($days != 'all') {
$date_before = get_current_db_date_before($days);
$where .= " AND {$trend_table}.date BETWEEN '$date_before' AND '$date' ".PHP_EOL;
}
if (is_ids_exist($exclude_post_ids)) {
$where .= " AND {$trend_table}.post_id NOT IN(".implode(',', $exclude_post_ids).") ".PHP_EOL;
}
//3180, 3234
if (!is_numeric($limit)) {
$limit = 5;
}
//カテゴリを指定する場合
if (is_ids_exist($cat_ids) || is_ids_exist($exclude_cat_ids)) {
global $post;
$term_relationships = $wpdb->term_relationships;
$term_taxonomy = $wpdb->term_taxonomy;
$joined_table = 'terms_accesses';
//カテゴリー指定
if (is_ids_exist($cat_ids)) {
$cat_ids = implode(',', $cat_ids);
//$where .= " AND {$term_relationships}.term_taxonomy_id IN ({$cat_ids}) ".PHP_EOL;
$where .= " AND {$term_taxonomy}.term_id IN ({$cat_ids}) ".PHP_EOL;
}
//除外カテゴリー指定
if (is_ids_exist($exclude_cat_ids)) {
//空の配列を取り除く
$exclude_cat_ids = array_filter($exclude_cat_ids, "strlen");
//カンマ区切りにする
$ex_cat_ids = implode(',', $exclude_cat_ids);
$ex_cat_ids = preg_replace('/,$/', '', $ex_cat_ids);
$where .= " AND {$term_relationships}.term_taxonomy_id NOT IN ({$ex_cat_ids}) ".PHP_EOL;
}
$where .= " AND {$term_taxonomy}.taxonomy = 'category' ".PHP_EOL;
// //テーブル結合するクエリの場合はWHEREに付け加えるのでANDに変更する
// $where = str_replace('WHERE', 'AND', $where);
$query = "
SELECT {$joined_table}.post_id, SUM({$joined_table}.count) AS sum_count, {$joined_table}.term_taxonomy_id, {$joined_table}.taxonomy
FROM (
#カテゴリとアクセステーブルを内部結合してグルーピングし並び替えた結果
SELECT {$trend_table}.post_id, {$trend_table}.count, {$term_relationships}.term_taxonomy_id, {$term_taxonomy}.taxonomy
FROM {$term_relationships}
INNER JOIN {$trend_table} ON {$term_relationships}.object_id = {$trend_table}.post_id
INNER JOIN {$term_taxonomy} ON {$term_relationships}.term_taxonomy_id = {$term_taxonomy}.term_taxonomy_id
$where #WHERE句
GROUP BY {$trend_table}.id
) AS {$joined_table} #カテゴリとアクセステーブルを内部結合した仮の名前
GROUP BY {$joined_table}.post_id
ORDER BY sum_count DESC
";
//_v($query);
//1回のクエリで投稿データを取り出せるようにテーブル結合クエリを追加
$query = wrap_joined_wp_posts_query($query, $limit, $author, $post_type);
} else {
$query = "
SELECT t1.post_id,
ROUND((t2.today) / 1.5 - (t1.latest - t2.today) / ($days - 2)) AS sum_count
FROM (
SELECT {$trend_table}.post_id,
SUM({$trend_table}.count) AS latest
FROM {$trend_table}
WHERE {$trend_table}.post_type = '$post_type'
AND {$trend_table}.date BETWEEN '$date_before' AND '$date'
GROUP BY {$trend_table}.post_id
) t1 INNER JOIN (
SELECT {$trend_table}.post_id,
SUM({$trend_table}.count) AS today
FROM {$trend_table}
WHERE {$trend_table}.post_type = '$post_type'
AND {$trend_table}.date BETWEEN '$date_yesterday' AND '$date'
GROUP BY {$trend_table}.post_id
) t2
ON t1.post_id = t2.post_id
ORDER BY sum_count DESC
";
//1回のクエリで投稿データを取り出せるようにテーブル結合クエリを追加
$query = wrap_joined_wp_posts_query($query, $limit, $author, $post_type);
}
$records = $wpdb->get_results( $query );
if (is_access_count_cache_enable() && $records) {
set_transient( $transient_id, $records, 60 * get_access_count_cache_interval() );
}
return $records;
}
endif;
SQLの部分だけを変更できればよいのですが、関数パラメータになっているわけではないので、まるごとコピーしてから、別の関数にしました。
その分、保守性は悪くなってしまいますね。
今後のために、改造した箇所(主に3つ)をメモしておきます。
3-1. 関数・変数名の変更
既存のコードは衝突しないように、複製したコードの変更名を変更しました。
(popular_list → trend_list、access_table → trend_table など)。
単純な検索・置換だと、呼び出している関数がおかしくなることがあるので、確認しながら操作しました。
3-2. クエリ用に変数を追加した
急上昇ランキングでは、直近のアクセスと最近のアクセスの平均を比べて、増えているページを上位にしています。
安定してアクセスが多いページではなく、急にアクセスが増えたページを見たいからです。
急にアクセス数が増えたページは、検索エンジンに評価されたか、検索数が増えたか、しているので、なんらかの需要があります。検索理由に合っているか検証して、優先的にページ内容を見直しています。
直近のアクセスを集計するために、get_trend_ranking_records関数に、変数$day_yesterdayを追加しました。
$date_yesterday = get_current_db_date_before(1);
$day_beforeがある辺りです。
3-3. 集計クエリを変更する
get_trend_ranking_records関数の$queryの中身を変更しました。
これがメインの部分です。
この際、最近1週間(期間は変更可能)の平均よりどれぐらいアクセスが増えているかに対応するように計算式を改めました。
カウント = 前日・当日のアクセス / 1.5 – (最近のアクセス – 前日・当日のアクセス) / (集計期間 – 2)
当日のアクセスは、時間によって重み付けが変わる必要がありますが、0.5日分として決め打ちしています。
$query = "
SELECT t1.post_id,
ROUND((t2.today) / 1.5 - (t1.latest - t2.today) / ($days - 2)) AS sum_count
FROM (
SELECT {$trend_table}.post_id,
SUM({$trend_table}.count) AS latest
FROM {$trend_table}
WHERE {$trend_table}.post_type = '$post_type'
AND {$trend_table}.date BETWEEN '$date_before' AND '$date'
GROUP BY {$trend_table}.post_id
) t1 INNER JOIN (
SELECT {$trend_table}.post_id,
SUM({$trend_table}.count) AS today
FROM {$trend_table}
WHERE {$trend_table}.post_type = '$post_type'
AND {$trend_table}.date BETWEEN '$date_yesterday' AND '$date'
GROUP BY {$trend_table}.post_id
) t2
ON t1.post_id = t2.post_id
ORDER BY sum_count DESC
";
最近の集計(t2)と、当日・前日の集計(t1)を結合して、sum_countを集計しています。
無事に修正できました。
こちらもどうぞ。