bp_moderate, or being an admin of the group named in the call, so a team captain can manage their own team. BuddyPress re-checks the same thing itself on remove, ban, promote and demote.not_site_member.install_plugins are unrestricted: the site member requirement, site rules and the unloaded-plugin refusal are skipped for them, with a warning when site plugins were not loaded.A site’s own plugins can refuse any change through the lh_mcp_buddypress_actions_refuse_change filter: return a non-empty reason to refuse. It runs on dry runs too, so a dry run shows what a real run would refuse. Princes Park Touch uses it (in ppt-buddypress-extender) for its one team per format per night rule.
Because those rules live in plugins active on that site only, a site_id call from another site’s connector would skip them. A real change is therefore refused when the target site has plugins this call did not load, and a dry run only warns: use the site’s own connector for such changes.
lh_mcp_buddypress_actions_refuse_change ( $reason, $action, $user_id, $group_id, $role ): $action is add, remove, ban or set_role; return a reason string to refuse.lh_mcp_buddypress_actions_is_site_member ( $is_member, $user_id, $site_id ): whether a user counts as a member of the site.groups_join_group, groups_accept_membership_request, groups_accept_invite, groups_remove_member, groups_ban_member, groups_promote_member and groups_demote_member. The caller is passed as the group admin, as BuddyPress’s REST API does.refused.note is set with lh_audit_trail_set_note() just before each change and cleared after, so it attaches only to that change’s LH Audit Trail entry.site_id to site-scoped abilities and returns site_notice