if ( ! function_exists( 'kc_recommend_get_similar_manga_v2tax' ) ) { function kc_recommend_get_similar_manga_v2tax( int $manga_id, array $tax_term_ids_map = array() ): array { if ( $manga_id <= 0 ) { return array(); } $cache_key = 'kagari_similar_reco_v2tax_' . (int) $manga_id; $cached = get_transient( $cache_key ); if ( is_array( $cached ) && ! empty( $cached ) ) { return $cached; } // tax名 $tax_play = function_exists('kc_tax') ? kc_tax('play') : 'kc_play'; $tax_look = function_exists('kc_tax') ? kc_tax('look') : 'kc_look'; $tax_scenario = function_exists('kc_tax') ? kc_tax('scenario') : 'kc_scenario'; $tax_feature = function_exists('kc_tax') ? kc_tax('feature') : 'kc_feature'; $tax_author = function_exists('kc_tax') ? kc_tax('author') : 'kc_author'; // 入力term map 正規化 $play_ids = isset( $tax_term_ids_map[ $tax_play ] ) && is_array( $tax_term_ids_map[ $tax_play ] ) ? array_values(array_unique(array_filter(array_map('intval',$tax_term_ids_map[$tax_play])))) : array(); $look_ids = isset( $tax_term_ids_map[ $tax_look ] ) && is_array( $tax_term_ids_map[ $tax_look ] ) ? array_values(array_unique(array_filter(array_map('intval',$tax_term_ids_map[$tax_look])))) : array(); $scenario_ids = isset( $tax_term_ids_map[ $tax_scenario ] ) && is_array( $tax_term_ids_map[ $tax_scenario ] ) ? array_values(array_unique(array_filter(array_map('intval',$tax_term_ids_map[$tax_scenario])))) : array(); $feature_ids = isset( $tax_term_ids_map[ $tax_feature ] ) && is_array( $tax_term_ids_map[ $tax_feature ] ) ? array_values(array_unique(array_filter(array_map('intval',$tax_term_ids_map[$tax_feature])))) : array(); // 4タクソが全部空なら検索不能 if ( empty($play_ids) && empty($look_ids) && empty($scenario_ids) && empty($feature_ids) ) { return array(); } // 同一作者を除外(Similar枠から排除) $exclude_author_ids = array(); $cur_author_terms = get_the_terms( $manga_id, $tax_author ); if ( $cur_author_terms && ! is_wp_error( $cur_author_terms ) ) { $exclude_author_ids = array_values(array_unique(array_filter(array_map('intval', wp_list_pluck($cur_author_terms,'term_id'))))); } $post_types = function_exists('kc_manga_post_types') ? kc_manga_post_types() : array('kc_manga'); // 候補取得:OR(どれか一致)→ 後段で「2カテゴリ以上一致」にフィルタ $or_group = array( 'relation' => 'OR' ); if ( !empty($play_ids) ) { $or_group[] = array('taxonomy'=>$tax_play, 'field'=>'term_id','terms'=>$play_ids); } if ( !empty($look_ids) ) { $or_group[] = array('taxonomy'=>$tax_look, 'field'=>'term_id','terms'=>$look_ids); } if ( !empty($scenario_ids) ) { $or_group[] = array('taxonomy'=>$tax_scenario, 'field'=>'term_id','terms'=>$scenario_ids); } if ( !empty($feature_ids) ) { $or_group[] = array('taxonomy'=>$tax_feature, 'field'=>'term_id','terms'=>$feature_ids); } $tax_query = array( 'relation' => 'AND', $or_group ); if ( !empty($exclude_author_ids) ) { $tax_query[] = array( 'taxonomy' => $tax_author, 'field' => 'term_id', 'terms' => $exclude_author_ids, 'operator' => 'NOT IN', ); } // ✅ 取りこぼし対策:20 → 200(増やしすぎたくなければ100でもOK) $candidate_query = new WP_Query(array( 'post_type' => $post_types, 'post_status' => 'publish', 'posts_per_page' => 200, 'post__not_in' => array($manga_id), 'tax_query' => $tax_query, 'no_found_rows' => true, )); $items = array(); // ✅ “似てる”定義:最低「2カテゴリ以上一致」 $MIN_CATEGORY_HITS = 2; // 強めたいなら 3 にする if ( $candidate_query->have_posts() ) { while ( $candidate_query->have_posts() ) { $candidate_query->the_post(); $pid = get_the_ID(); $c_play = get_the_terms( $pid, $tax_play ); $c_look = get_the_terms( $pid, $tax_look ); $c_scenario = get_the_terms( $pid, $tax_scenario ); $c_feature = get_the_terms( $pid, $tax_feature ); $c_play_ids = ($c_play && !is_wp_error($c_play)) ? wp_list_pluck($c_play,'term_id') : array(); $c_look_ids = ($c_look && !is_wp_error($c_look)) ? wp_list_pluck($c_look,'term_id') : array(); $c_scenario_ids = ($c_scenario && !is_wp_error($c_scenario)) ? wp_list_pluck($c_scenario,'term_id') : array(); $c_feature_ids = ($c_feature && !is_wp_error($c_feature)) ? wp_list_pluck($c_feature,'term_id') : array(); $shared_play = (!empty($play_ids) && !empty($c_play_ids)) ? array_intersect($play_ids, $c_play_ids) : array(); $shared_look = (!empty($look_ids) && !empty($c_look_ids)) ? array_intersect($look_ids, $c_look_ids) : array(); $shared_scenario = (!empty($scenario_ids) && !empty($c_scenario_ids)) ? array_intersect($scenario_ids, $c_scenario_ids) : array(); $shared_feature = (!empty($feature_ids) && !empty($c_feature_ids)) ? array_intersect($feature_ids, $c_feature_ids) : array(); $category_hits = 0; if (!empty($shared_play)) $category_hits++; if (!empty($shared_look)) $category_hits++; if (!empty($shared_scenario)) $category_hits++; if (!empty($shared_feature)) $category_hits++; // ❌ 1カテゴリ一致は“似てる”扱いにしない if ( $category_hits < $MIN_CATEGORY_HITS ) { continue; } $similarity = count($shared_play) + count($shared_look) + count($shared_scenario) + count($shared_feature); // 人気スコア $pop = 0; if ( function_exists('kagari_status_get_views') ) { $v = (int) kagari_status_get_views($pid); if ($v > 0) $pop += (int) floor(log(1 + $v)); } $likes = function_exists('kc_get_manga_like_count') ? (int) kc_get_manga_like_count($pid) : (int) get_post_meta($pid, '_kc_like_count', true); if ($likes > 0) $pop += min(10, $likes); $items[] = array( 'post' => get_post($pid), 'category_hits' => (int) $category_hits, 'similarity' => (int) $similarity, 'popularity' => (int) $pop, 'date' => (int) get_post_time('U', true, $pid), ); } wp_reset_postdata(); } // 並び:一致カテゴリ数 → 一致term総数 → 品質 → 新しさ usort($items, function($a,$b){ if ($a['category_hits'] !== $b['category_hits']) return $b['category_hits'] - $a['category_hits']; if ($a['similarity'] !== $b['similarity']) return $b['similarity'] - $a['similarity']; if ($a['popularity'] !== $b['popularity']) return $b['popularity'] - $a['popularity']; return $b['date'] - $a['date']; }); // ✅ 埋めない:似てるものだけ最大10件(足りなければ少ないまま) $top = array_slice($items, 0, 10); if ( !empty($top) ) { set_transient($cache_key, $top, 20 * MINUTE_IN_SECONDS); } // 返却形式を既存に合わせる(viewer側が similarity_score を見てる可能性があるため) $out = array(); foreach ($top as $x) { $out[] = array( 'post' => $x['post'], 'similarity_score' => $x['similarity'], 'popularity_score' => $x['popularity'], 'date' => $x['date'], ); } return $out; } }
Warning: Cannot modify header information - headers already sent by (output started at /var/www/kagari/wp-content/themes/blocksy-child/inc/core/viewer/kc-recommend-helpers.php:1) in /var/www/kagari/wp-content/plugins/paid-memberships-pro/adminpages/reports/logins.php on line 458

Warning: Cannot modify header information - headers already sent by (output started at /var/www/kagari/wp-content/themes/blocksy-child/inc/core/viewer/kc-recommend-helpers.php:1) in /var/www/kagari/wp-includes/pluggable.php on line 1531

Warning: Cannot modify header information - headers already sent by (output started at /var/www/kagari/wp-content/themes/blocksy-child/inc/core/viewer/kc-recommend-helpers.php:1) in /var/www/kagari/wp-includes/pluggable.php on line 1534