ランキングの表示を評価順に並び替える方法

Cocoonカスタマイズ集
この記事は約12分で読めます。
記事内に広告が含まれています。

拡張:ランキング作成画面にソート設定を追加する方法

Cocoonの設定→ランキングに、評価数順でソートできる設定項目を追加します。

完成イメージ

実装手順

以下のコードをfunctions.phpに追加します。

// ランキングに入力フォームを追加
add_filter('admin_input_form_tag', function ($res, $name = null) {
  $page = isset($_GET['page']) ? $_GET['page'] : '';
  $id = isset($_GET['id']) ? intval($_GET['id']) : null;

  // 対象外は終了
  if ($page !== 'theme-ranking' || $name !== 'visible') {
    return $res;
  }

  // 設定値を取得
  $is_checked = 0;

  if ($id) {
    $ranking_sort = get_option('my_ranking_sort', []);
    $is_checked = isset($ranking_sort[$id]) ? $ranking_sort[$id] : 0;
  }

  // POST値を取得
  if (isset($_POST['title'])) {
    $is_checked = isset($_POST['my_custom_check']) ? 1 : 0;
  }

  // チェックボックスと説明文を出力
  ob_start();
  generate_checkbox_tag('my_custom_check', $is_checked, 'ソートを有効にする');
  generate_tips_tag('評価数順で表示する場合は、有効にしてください。');
  $new_html = ob_get_clean();

  return $new_html . $res;
}, 10, 2);


// 管理画面からの設定データ更新
add_action('admin_init', function () {
  $page = $_GET['page'] ?? '';
  $action = $_POST['action'] ?? '';

  // 対象外は終了
  if ($page !== 'theme-ranking' || !$action) {
    return;
  }

  switch ($action) {
    case 'new':
    case 'edit':
      // nonceチェック
      if (isset($_POST[HIDDEN_FIELD_NAME]) && wp_verify_nonce($_POST[HIDDEN_FIELD_NAME], 'item-ranking')) {
        $target_id_raw = $_POST['id'] ?? null;
        $check_val = isset($_POST['my_custom_check']) ? 1 : 0;

        // ID確定後に設定
        add_action('shutdown', function () use ($target_id_raw, $check_val) {
          global $wpdb;

          // IDを取得
          $id = $target_id_raw ?: ($wpdb->insert_id ?: $wpdb->get_var("SELECT MAX(id) FROM " . ITEM_RANKINGS_TABLE_NAME));

          // 設定を変更
          if ($id) {
            $ranking_sort = get_option('my_ranking_sort', []);

            if ($check_val) {
              $ranking_sort[$id] = 1;
            } else {
              unset($ranking_sort[$id]);
            }

            update_option('my_ranking_sort', $ranking_sort);
          }
        });
      }
      break;

    case 'delete':
      // nonceチェック
      if (isset($_POST[HIDDEN_DELETE_FIELD_NAME]) && wp_verify_nonce($_POST[HIDDEN_DELETE_FIELD_NAME], 'delete-item-ranking')
      ) {
        $id = intval($_POST['id'] ?? 0);

        // 設定を削除
        if ($id) {
          $ranking_sort = get_option('my_ranking_sort', []);

          if (isset($ranking_sort[$id])) {
            unset($ranking_sort[$id]);
            update_option('my_ranking_sort', $ranking_sort);
          }
        }
      }
      break;
  }
});


// ランキングアイテムの順序を変更
add_filter('cocoon_get_item_ranking', function ($record, $id) {
  // 対象外は終了
  if (empty($record) || is_admin()) {
    return $record;
  }

  // ソート設定を取得
  $ranking_sort = get_option('my_ranking_sort', []);

  // ソート対象外は終了
  if (empty($ranking_sort[$id])) {
    return $record;
  }

  // 評価を基準に変更
  uasort($record->item_ranking, function ($a, $b) {
    $ra = (isset($a['rating']) && $a['rating'] !== 'none') ? floatval($a['rating']) : 0;
    $rb = (isset($b['rating']) && $b['rating'] !== 'none') ? floatval($b['rating']) : 0;

    // 両方とも評価なしは順序を維持
    if ($ra === 0.0 && $rb === 0.0) {
      return 0;
    }

    // aの評価なしを後方へ変更
    if ($ra === 0.0) {
      return 1;
    }

    // bの評価なしを後方へ変更
    if ($rb === 0.0) {
      return -1;
    }

    // 評価の高い順に変更
    return $rb <=> $ra;
  });

  // 配列のキーを変更
  $record->item_ranking = array_values($record->item_ranking);

  // 1始まりの形式に設定
  array_unshift($record->item_ranking, null);

  return $record;
}, 10, 2);

さいごに

今回紹介した方法を使えば、ランキング機能で手動並び替えに時間を取られず、評価値に応じて自動で順位を調整できるようになります。
アイテム数が多くても管理が楽になり、より正確で信頼性のあるランキング表示を実現できます。

タイトルとURLをコピーしました