2026年8月16日

2026年8月16日

BuddyPressのエラーを解決する方法

はじめに

BuddyPressでメンバープロフィールページが404エラーになる・グループへの参加ボタンが動作しない・アクティビティフィードに投稿が表示されない・メッセージ送信ができないといった問題は、パーマリンク設定・コンポーネントの有効化・テーマとの競合が原因です。

症状・原因

  • /members/{username}/にアクセスすると404エラーになる
  • グループページでメンバー一覧が表示されない
  • アクティビティフィードが空のまま更新されない
  • BuddyPressのページが通常の投稿レイアウトで表示される(専用テンプレートが使われない)

解決手順

ステップ1:BuddyPressの状態を確認する

# BuddyPressのバージョンとコンポーネントを確認
wp eval "
if (function_exists('buddypress')) {
    echo 'BuddyPress version: ' . BP_VERSION . PHP_EOL;
}

// アクティブなコンポーネントを確認
\$components = bp_core_get_components('active');
echo 'Active components: ' . PHP_EOL;
foreach (\$components as \$key => \$comp) {
    echo '  ' . \$key . ': ' . \$comp['title'] . PHP_EOL;
}
"

# BuddyPressのページ設定を確認
wp eval "
\$bp_pages = bp_core_get_directory_page_ids();
echo 'BP Directory pages: ' . PHP_EOL;
foreach (\$bp_pages as \$component => \$page_id) {
    printf('  %s: page_id=%d url=%s' . PHP_EOL,
        \$component,
        \$page_id,
        get_permalink(\$page_id)
    );
}
"

# パーマリンクをリセット
wp rewrite flush --hard
echo "Rewrite rules flushed"

ステップ2:コンポーネントとページ設定を修正する

// functions.php: BuddyPressのコンポーネント設定

// ① 必要なコンポーネントを有効化する確認
add_action('bp_init', function(): void {
    // メンバーコンポーネントが有効かチェック
    if (!bp_is_active('members')) {
        // 管理画面: Settings → BuddyPress → Components から有効化
        error_log('[BP] members component is not active');
    }

    // グループコンポーネントが有効かチェック
    if (!bp_is_active('groups')) {
        error_log('[BP] groups component is not active');
    }
});

// ② BuddyPressのルートページURLをカスタマイズ
add_filter('bp_core_get_user_domain', function(string $domain, int $user_id, string $user_login): string {
    // メンバーURLをカスタムスラッグに変更する場合
    // デフォルト: /members/{username}/
    return $domain;
}, 10, 3);

// ③ BuddyPressページのタイトルを設定
add_filter('bp_page_title', function(string $title): string {
    if (bp_is_user()) {
        return bp_get_displayed_user_fullname() . 'のプロフィール | ' . get_bloginfo('name');
    }
    if (bp_is_group()) {
        return bp_get_current_group_name() . ' | ' . get_bloginfo('name');
    }
    return $title;
});

ステップ3:アクティビティフィードを修正する

// functions.php: BuddyPressアクティビティのカスタマイズ

// ① カスタムアクティビティを投稿する
function bp_post_custom_activity(int $user_id, string $action, string $content = ''): int {
    if (!function_exists('bp_activity_add')) return 0;

    return bp_activity_add([
        'user_id'           => $user_id,
        'component'         => 'custom',
        'type'              => 'custom_action',
        'action'            => $action,
        'content'           => $content,
        'item_id'           => 0,
        'secondary_item_id' => 0,
        'hide_sitewide'     => false,
    ]);
}

// ② アクティビティフィードに表示する内容をフィルタリング
add_filter('bp_activity_get_user_join_filter', function(array $args): array {
    // スパムアクティビティを除外
    $args['spam'] = 'ham_only';
    // 最新50件のみ取得
    $args['per_page'] = 50;
    return $args;
});

// ③ WordPressの投稿をBPアクティビティに自動反映
add_action('publish_post', function(int $post_id): void {
    if (!function_exists('bp_activity_add')) return;

    $post    = get_post($post_id);
    $user_id = (int)$post->post_author;

    bp_activity_add([
        'user_id'   => $user_id,
        'component' => 'blogs',
        'type'      => 'new_blog_post',
        'action'    => sprintf(
            '<a href="%s">%s</a> さんが新しい記事を投稿しました: <a href="%s">%s</a>',
            bp_core_get_user_domain($user_id),
            bp_core_get_user_displayname($user_id),
            get_permalink($post_id),
            esc_html($post->post_title)
        ),
        'item_id'   => get_current_blog_id(),
        'secondary_item_id' => $post_id,
        'recorded_time'     => $post->post_date,
    ]);
});

ステップ4:グループとメッセージ機能を修正する

// functions.php: BuddyPressグループ・メッセージのカスタマイズ

// ① グループ作成時にカスタムメタを設定
add_action('groups_group_create_complete', function(int $group_id): void {
    groups_update_groupmeta($group_id, 'group_category', 'general');
    groups_update_groupmeta($group_id, 'max_members', 100);
});

// ② グループ参加時に通知を送る
add_action('groups_join_group', function(int $group_id, int $user_id): void {
    $group    = groups_get_group($group_id);
    $admin_id = bp_get_group_creator_id($group_id);

    // グループ管理者に通知
    bp_notifications_add_notification([
        'user_id'           => $admin_id,
        'item_id'           => $group_id,
        'secondary_item_id' => $user_id,
        'component_name'    => 'groups',
        'component_action'  => 'new_membership_request',
        'date_notified'     => bp_core_current_time(),
        'is_new'            => 1,
    ]);
}, 10, 2);

// ③ メッセージ送信前にレート制限
add_filter('bp_messages_send_message_before_save', function(\BP_Messages_Message $message): \BP_Messages_Message {
    $sender_id  = $message->sender_id;
    $cache_key  = 'bp_msg_rate_' . $sender_id;
    $msg_count  = (int)get_transient($cache_key);

    if ($msg_count >= 20) {
        $message->set_error(new \WP_Error('rate_limit', '1時間に送信できるメッセージは20件までです。'));
        return $message;
    }

    set_transient($cache_key, $msg_count + 1, HOUR_IN_SECONDS);
    return $message;
});

ステップ5:テーマとのテンプレート競合を解決する

// functions.php: BuddyPressテンプレートのカスタマイズ

// ① BuddyPressテンプレートのパスを追加
add_filter('bp_get_template_stack', function(array $stack): array {
    // 子テーマのbuddy-pressディレクトリを優先
    array_unshift($stack, get_stylesheet_directory() . '/buddypress');
    return $stack;
});

// ② BuddyPressページでのみカスタムCSSを読み込む
add_action('wp_enqueue_scripts', function(): void {
    if (!function_exists('is_buddypress') || !is_buddypress()) return;

    wp_enqueue_style(
        'custom-bp-style',
        get_stylesheet_directory_uri() . '/css/buddypress.css',
        ['bp-legacy-css'],
        '1.0.0'
    );
});

// ③ BuddyPressページでサイドバーを非表示にする
add_filter('body_class', function(array $classes): array {
    if (function_exists('is_buddypress') && is_buddypress()) {
        $classes[] = 'full-width-layout';
        $classes[] = 'no-sidebar';
    }
    return $classes;
});
# BuddyPressのデータ整合性を確認
wp eval "
// 孤立したアクティビティを確認
global \$wpdb;
\$orphaned = \$wpdb->get_var(
    \"SELECT COUNT(*) FROM {\$wpdb->prefix}bp_activity
    WHERE user_id NOT IN (SELECT ID FROM {\$wpdb->users})\"
);
echo 'Orphaned activities: ' . \$orphaned . PHP_EOL;

// グループメンバー数を再計算
if (function_exists('bp_total_group_member_count')) {
    \$groups = groups_get_groups(['show_hidden' => true]);
    foreach (\$groups['groups'] as \$group) {
        groups_update_group_meta(\$group->id, 'total_member_count',
            groups_get_total_member_count(\$group->id));
    }
    echo 'Group member counts updated' . PHP_EOL;
}
"

注意事項

  • BuddyPressのメンバーページが404になる場合は「設定→パーマリンク」を保存するだけで解決することが多いです。BuddyPressのリライトルールがWordPressに再登録されます
  • BuddyPressのテンプレートは子テーマ内のbuddypress/ディレクトリに配置します。wp-content/themes/child-theme/buddypress/members/single/profile/のように階層を合わせてください
  • bp_activity_add()で投稿したアクティビティのcomponenttypeは、管理画面の「Settings → BuddyPress → Activity」で有効化されているものと一致させる必要があります

まとめ

BuddyPress修復は①bp_core_get_components('active')でコンポーネント確認・bp_core_get_directory_page_ids()でページ確認・wp rewrite flushでURL再生成、②bp_activity_add()でアクティビティを手動投稿・bp_activity_get_user_join_filterフィルターでフィードを最適化、③groups_update_groupmeta()でグループメタを管理・bp_notifications_add_notification()で通知を送信、④bp_messages_send_message_before_saveフィルターでレート制限を実装、⑤bp_get_template_stackフィルターで子テーマからテンプレートを優先読み込みする手順で解決します。

お気軽にご相談ください

お見積りへ お問い合わせへ