前言
這段程式碼主要解決 LearnDash 後台課程列表無法直接查看每門課程已報名學生數的問題。對於管理大量課程與學員的教學平台管理員來說,快速掌握報名狀況非常重要。本文適合熟悉 WordPress 與 LearnDash 且想自訂後台介面與效能優化的工程師或自學者。
新增自訂欄位到課程列表
透過 WordPress 提供的 manage_edit-{$post_type}_columns 過濾器,我們在 sfwd-courses(LearnDash 課程)後台列表中插入一個「已報名學生」欄位。此欄位被放置在標題欄位後面,方便管理者一目了然。
add_filter('manage_edit-sfwd-courses_columns', function ($columns) {
$new = [];
foreach ($columns as $k => $v) {
$new[$k] = $v;
if ($k === 'title') {
$new['ld_enrolled_count'] = '已報名學生';
}
}
if (!isset($new['ld_enrolled_count'])) {
$new['ld_enrolled_count'] = '已報名學生';
}
return $new;
}, 20);
顯示欄位內容與計數邏輯
使用 manage_sfwd-courses_posts_custom_column 動作鉤子,根據課程 ID 呼叫自訂函式取得報名學生數並輸出。計數邏輯透過 WP_UserQuery 查詢所有有 usermeta 中 `course{course_id}_access_from` 欄位存在的使用者數量,這是 LearnDash 判斷學員是否有課程存取權的標準做法。
add_action('manage_sfwd-courses_posts_custom_column', function ($column, $post_id) {
if ($column !== 'ld_enrolled_count')
return;
$count = vs_ld_get_enrolled_count($post_id);
echo esc_html((string) $count);
}, 10, 2);
快取機制提升效能
為避免課程列表頁面每筆課程都執行重複且昂貴的資料庫查詢,使用 WordPress 內建快取(wp_cache)暫存結果 10 分鐘。這樣可以大幅減少對資料庫的負擔,避免後台卡頓。
function vs_ld_get_enrolled_count($course_id)
{
$course_id = (int) $course_id;
if ($course_id <= 0)
return 0;
$cache_key = 'course_enrolled_' . $course_id;
$cached = wp_cache_get($cache_key, 'ld_course_enroll_count');
if ($cached !== false) {
return (int) $cached;
}
$meta_key = 'course_' . $course_id . '_access_from';
$uq = new WP_User_Query([
'fields' => 'ID',
'number' => 1,
'paged' => 1,
'count_total' => true,
'meta_query' => [
[
'key' => $meta_key,
'compare' => 'EXISTS',
],
],
]);
$count = (int) $uq->get_total();
wp_cache_set($cache_key, $count, 'ld_course_enroll_count', 10 * MINUTE_IN_SECONDS);
return $count;
}
課程更新時清除快取
為確保報名數字不會因快取而過時,當課程內容被更新時,會自動刪除對應快取,讓下一次查詢能取得最新資料。
add_action('save_post_sfwd-courses', function ($post_id) {
if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE)
return;
$post_id = (int) $post_id;
wp_cache_delete('course_enrolled_' . $post_id, 'ld_course_enroll_count');
}, 20);
實務應用與延伸
這種方式適合需要在 LearnDash 後台快速掌握各課程報名狀況的管理者,尤其是課程數量龐大時,快取機制可有效減少資料庫負擔。未來可延伸加入排序功能,或結合 AJAX 即時更新報名數,提升使用體驗。
常見問題與注意事項
- 快取時間設定過短會增加資料庫查詢頻率,過長可能導致數據不即時,需依實際需求調整。
- 使用 WP_User_Query 查詢大量用戶時,仍需注意資料庫效能,建議搭配適當索引。
- 本範例假設 LearnDash 使用標準 usermeta key,若有自訂存取邏輯需調整查詢條件。
完整程式碼
<?php
if (!defined('ABSPATH'))
exit;
/**
* LearnDash:後台課程清單新增「已報名學生數」欄位
* - post_type: sfwd-courses
* - 計數依據:usermeta key = course_{course_id}_access_from EXISTS
* - 有短暫快取,避免清單頁卡爆
*/
/** 1) 加欄位 */
add_filter('manage_edit-sfwd-courses_columns', function ($columns) {
// 插在標題後面(你也可以改位置)
$new = [];
foreach ($columns as $k => $v) {
$new[$k] = $v;
if ($k === 'title') {
$new['ld_enrolled_count'] = '已報名學生';
}
}
if (!isset($new['ld_enrolled_count'])) {
$new['ld_enrolled_count'] = '已報名學生';
}
return $new;
}, 20);
/** 2) 顯示欄位內容 */
add_action('manage_sfwd-courses_posts_custom_column', function ($column, $post_id) {
if ($column !== 'ld_enrolled_count')
return;
$count = vs_ld_get_enrolled_count($post_id);
echo esc_html((string) $count);
}, 10, 2);
/** 3) 計數函式(含快取) */
function vs_ld_get_enrolled_count($course_id)
{
$course_id = (int) $course_id;
if ($course_id <= 0)
return 0;
// 快取 10 分鐘(避免列表頁每一列都打一次 users table)
$cache_key = 'course_enrolled_' . $course_id;
$cached = wp_cache_get($cache_key, 'ld_course_enroll_count');
if ($cached !== false) {
return (int) $cached;
}
// LearnDash 最常用的課程存取 key
$meta_key = 'course_' . $course_id . '_access_from';
// 用 WP_User_Query 計數 meta_key EXISTS 的使用者
$uq = new WP_User_Query([
'fields' => 'ID',
'number' => 1, // 只要 count_total,不要真的撈一堆 ID
'paged' => 1,
'count_total' => true,
'meta_query' => [
[
'key' => $meta_key,
'compare' => 'EXISTS',
],
],
]);
$count = (int) $uq->get_total();
wp_cache_set($cache_key, $count, 'ld_course_enroll_count', 10 * MINUTE_IN_SECONDS);
return $count;
}
/** 4) 當課程更新時,清掉該課程快取(避免顯示太久舊數字) */
add_action('save_post_sfwd-courses', function ($post_id) {
if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE)
return;
$post_id = (int) $post_id;
wp_cache_delete('course_enrolled_' . $post_id, 'ld_course_enroll_count');
}, 20);