<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[BuddyPress][13873] trunk: Groups: improve group membership management functions</title>
</head>
<body>

<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt;  }
#msg dl a { font-weight: bold}
#msg dl a:link    { color:#fc3; }
#msg dl a:active  { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { white-space: pre-line; overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff  {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta" style="font-size: 105%">
<dt style="float: left; width: 6em; font-weight: bold">Revision</dt> <dd><a style="font-weight: bold" href="http://buddypress.trac.wordpress.org/changeset/13873">13873</a><script type="application/ld+json">{"@context":"http://schema.org","@type":"EmailMessage","description":"Review this Commit","action":{"@type":"ViewAction","url":"http://buddypress.trac.wordpress.org/changeset/13873","name":"Review Commit"}}</script></dd>
<dt style="float: left; width: 6em; font-weight: bold">Author</dt> <dd>imath</dd>
<dt style="float: left; width: 6em; font-weight: bold">Date</dt> <dd>2024-05-25 04:47:42 +0000 (Sat, 25 May 2024)</dd>
</dl>

<pre style='padding-left: 1em; margin: 2em 0; border-left: 2px solid #ccc; line-height: 1.25; font-size: 105%; font-family: sans-serif'>Groups: improve group membership management functions

- Make the functions handling the 5 available group membership actions (promote, demote, ban, unban, remove) usable outside of the BuddyPress Web version. Doing so, the BP REST API will be able to use them so that current hooks used to perform custom code/clear group cache are still fired within this specific context.
- In BP Nouveau, the group members management interface (which is using the BP REST API) will soon benefit from this work once the BP REST API has been updated.  The hook used to notify a group member has been promoted will then be fired and BP Nouveau behavior will be consistent with the BP Legacy one about group membership management.
- Deprecate some misleading hooks, which were firing even if the group membership action had failed, in favor of new ones which do fire at the right "place".

Props needle

Fixes <a href="http://buddypress.trac.wordpress.org/ticket/9158">#9158</a></pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunksrcbpgroupsbpgroupsfunctionsphp">trunk/src/bp-groups/bp-groups-functions.php</a></li>
<li><a href="#trunksrcbpgroupsbpgroupsnotificationsphp">trunk/src/bp-groups/bp-groups-notifications.php</a></li>
<li><a href="#trunksrcbpgroupsscreenssingleadminmanagemembersphp">trunk/src/bp-groups/screens/single/admin/manage-members.php</a></li>
<li><a href="#trunktestsphpunittestcasesgroupsnotificationsphp">trunk/tests/phpunit/testcases/groups/notifications.php</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunksrcbpgroupsbpgroupsfunctionsphp"></a>
<div class="modfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Modified: trunk/src/bp-groups/bp-groups-functions.php</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- trunk/src/bp-groups/bp-groups-functions.php       2024-05-24 14:13:15 UTC (rev 13872)
+++ trunk/src/bp-groups/bp-groups-functions.php 2024-05-25 04:47:42 UTC (rev 13873)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -2006,21 +2006,32 @@
</span><span class="cx" style="display: block; padding: 0 10px">  * Promote a member to a new status within a group.
</span><span class="cx" style="display: block; padding: 0 10px">  *
</span><span class="cx" style="display: block; padding: 0 10px">  * @since 1.0.0
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ * @since 14.0.0 Adds the `$group_admin_id` parameter.
</ins><span class="cx" style="display: block; padding: 0 10px">  *
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- * @param int    $user_id  ID of the user.
- * @param int    $group_id ID of the group.
- * @param string $status   The new status. 'mod' or 'admin'.
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ * @param int    $user_id        ID of the user.
+ * @param int    $group_id       ID of the group.
+ * @param string $status         The new status. 'mod' or 'admin'.
+ * @param int    $group_admin_id Optional. The group admin user ID.
</ins><span class="cx" style="display: block; padding: 0 10px">  * @return bool True on success, false on failure.
</span><span class="cx" style="display: block; padding: 0 10px">  */
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-function groups_promote_member( $user_id, $group_id, $status ) {
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+function groups_promote_member( $user_id, $group_id, $status, $group_admin_id = 0 ) {
+       // Carry on using the item admin set by the Web version.
+       if ( ! $group_admin_id ) {
+               $user_can = bp_is_item_admin();
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-        if ( ! bp_is_item_admin() )
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+         // Use the provided Group Admin ID (eg: during a REST API request).
+       } else {
+               $user_can = bp_current_user_can( 'bp_moderate' ) || groups_is_user_admin( $group_admin_id, $group_id );
+       }
+
+       if ( ! $user_can ) {
</ins><span class="cx" style="display: block; padding: 0 10px">                 return false;
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+        }
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px">        $member = new BP_Groups_Member( $user_id, $group_id );
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px">        // Don't use this action. It's deprecated as of BuddyPress 1.6.
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-        do_action( 'groups_premote_member', $group_id, $user_id, $status );
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ do_action_deprecated( 'groups_premote_member', array( $group_id, $user_id, $status ), '1.6' );
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px">        /**
</span><span class="cx" style="display: block; padding: 0 10px">         * Fires before the promotion of a user to a new status.
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -2033,7 +2044,21 @@
</span><span class="cx" style="display: block; padding: 0 10px">         */
</span><span class="cx" style="display: block; padding: 0 10px">        do_action( 'groups_promote_member', $group_id, $user_id, $status );
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-        return $member->promote( $status );
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ if ( ! $member->promote( $status ) ) {
+               return false;
+       }
+
+       /**
+        * Fires once the group member has been successfully promoted.
+        *
+        * @since 14.0.0
+        *
+        * @param int $user_id  ID of the user being promoted.
+        * @param int $group_id ID of the group being promoted in.
+        */
+       do_action( 'group_member_promoted', $user_id, $group_id );
+
+       return true;
</ins><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px"> /**
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -2040,14 +2065,24 @@
</span><span class="cx" style="display: block; padding: 0 10px">  * Demote a user to 'member' status within a group.
</span><span class="cx" style="display: block; padding: 0 10px">  *
</span><span class="cx" style="display: block; padding: 0 10px">  * @since 1.0.0
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ * @since 14.0.0 Adds the `$group_admin_id` parameter.
</ins><span class="cx" style="display: block; padding: 0 10px">  *
</span><span class="cx" style="display: block; padding: 0 10px">  * @param int $user_id  ID of the user.
</span><span class="cx" style="display: block; padding: 0 10px">  * @param int $group_id ID of the group.
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ * @param int $group_admin_id Optional. The group admin user ID.
</ins><span class="cx" style="display: block; padding: 0 10px">  * @return bool True on success, false on failure.
</span><span class="cx" style="display: block; padding: 0 10px">  */
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-function groups_demote_member( $user_id, $group_id ) {
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+function groups_demote_member( $user_id, $group_id, $group_admin_id = 0 ) {
+       // Carry on using the item admin set by the Web version.
+       if ( ! $group_admin_id ) {
+               $user_can = bp_is_item_admin();
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-        if ( ! bp_is_item_admin() ) {
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+         // Use the provided Group Admin ID (eg: during a REST API request).
+       } else {
+               $user_can = bp_current_user_can( 'bp_moderate' ) || groups_is_user_admin( $group_admin_id, $group_id );
+       }
+
+       if ( ! $user_can ) {
</ins><span class="cx" style="display: block; padding: 0 10px">                 return false;
</span><span class="cx" style="display: block; padding: 0 10px">        }
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -2063,7 +2098,21 @@
</span><span class="cx" style="display: block; padding: 0 10px">         */
</span><span class="cx" style="display: block; padding: 0 10px">        do_action( 'groups_demote_member', $group_id, $user_id );
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-        return $member->demote();
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ if ( ! $member->demote() ) {
+               return false;
+       }
+
+       /**
+        * Fires once the group member has been successfully demoted.
+        *
+        * @since 14.0.0
+        *
+        * @param int $user_id  ID of the user being demoted.
+        * @param int $group_id ID of the group being demoted in.
+        */
+       do_action( 'group_member_demoted', $user_id, $group_id );
+
+       return true;
</ins><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px"> /**
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -2070,14 +2119,24 @@
</span><span class="cx" style="display: block; padding: 0 10px">  * Ban a member from a group.
</span><span class="cx" style="display: block; padding: 0 10px">  *
</span><span class="cx" style="display: block; padding: 0 10px">  * @since 1.0.0
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ * @since 14.0.0 Adds the `$group_admin_id` parameter.
</ins><span class="cx" style="display: block; padding: 0 10px">  *
</span><span class="cx" style="display: block; padding: 0 10px">  * @param int $user_id  ID of the user.
</span><span class="cx" style="display: block; padding: 0 10px">  * @param int $group_id ID of the group.
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ * @param int $group_admin_id Optional. The group admin user ID.
</ins><span class="cx" style="display: block; padding: 0 10px">  * @return bool True on success, false on failure.
</span><span class="cx" style="display: block; padding: 0 10px">  */
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-function groups_ban_member( $user_id, $group_id ) {
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+function groups_ban_member( $user_id, $group_id, $group_admin_id = 0 ) {
+       // Carry on using the item admin set by the Web version.
+       if ( ! $group_admin_id ) {
+               $user_can = bp_is_item_admin();
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-        if ( ! bp_is_item_admin() ) {
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+         // Use the provided Group Admin ID (eg: during a REST API request).
+       } else {
+               $user_can = bp_current_user_can( 'bp_moderate' ) || groups_is_user_admin( $group_admin_id, $group_id );
+       }
+
+       if ( ! $user_can ) {
</ins><span class="cx" style="display: block; padding: 0 10px">                 return false;
</span><span class="cx" style="display: block; padding: 0 10px">        }
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -2093,7 +2152,21 @@
</span><span class="cx" style="display: block; padding: 0 10px">         */
</span><span class="cx" style="display: block; padding: 0 10px">        do_action( 'groups_ban_member', $group_id, $user_id );
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-        return $member->ban();
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ if ( ! $member->ban() ) {
+               return false;
+       }
+
+       /**
+        * Fires once the group member has been successfully banned.
+        *
+        * @since 14.0.0
+        *
+        * @param int $user_id  ID of the user being banned.
+        * @param int $group_id ID of the group being banned from.
+        */
+       do_action( 'group_member_banned', $user_id, $group_id );
+
+       return true;
</ins><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px"> /**
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -2100,14 +2173,24 @@
</span><span class="cx" style="display: block; padding: 0 10px">  * Unban a member from a group.
</span><span class="cx" style="display: block; padding: 0 10px">  *
</span><span class="cx" style="display: block; padding: 0 10px">  * @since 1.0.0
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ * @since 14.0.0 Adds the `$group_admin_id` parameter.
</ins><span class="cx" style="display: block; padding: 0 10px">  *
</span><span class="cx" style="display: block; padding: 0 10px">  * @param int $user_id  ID of the user.
</span><span class="cx" style="display: block; padding: 0 10px">  * @param int $group_id ID of the group.
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ * @param int $group_admin_id Optional. The group admin user ID.
</ins><span class="cx" style="display: block; padding: 0 10px">  * @return bool True on success, false on failure.
</span><span class="cx" style="display: block; padding: 0 10px">  */
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-function groups_unban_member( $user_id, $group_id ) {
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+function groups_unban_member( $user_id, $group_id, $group_admin_id = 0 ) {
+       // Carry on using the item admin set by the Web version.
+       if ( ! $group_admin_id ) {
+               $user_can = bp_is_item_admin();
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-        if ( ! bp_is_item_admin() ) {
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+         // Use the provided Group Admin ID (eg: during a REST API request).
+       } else {
+               $user_can = bp_current_user_can( 'bp_moderate' ) || groups_is_user_admin( $group_admin_id, $group_id );
+       }
+
+       if ( ! $user_can ) {
</ins><span class="cx" style="display: block; padding: 0 10px">                 return false;
</span><span class="cx" style="display: block; padding: 0 10px">        }
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -2123,7 +2206,21 @@
</span><span class="cx" style="display: block; padding: 0 10px">         */
</span><span class="cx" style="display: block; padding: 0 10px">        do_action( 'groups_unban_member', $group_id, $user_id );
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-        return $member->unban();
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ if ( ! $member->unban() ) {
+               return false;
+       }
+
+       /**
+        * Fires once the group member has been successfully unbanned.
+        *
+        * @since 14.0.0
+        *
+        * @param int $user_id  ID of the user being unbanned.
+        * @param int $group_id ID of the group being unbanned from.
+        */
+       do_action( 'group_member_unbanned', $user_id, $group_id );
+
+       return true;
</ins><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px"> /** Group Removal *************************************************************/
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -2132,14 +2229,24 @@
</span><span class="cx" style="display: block; padding: 0 10px">  * Remove a member from a group.
</span><span class="cx" style="display: block; padding: 0 10px">  *
</span><span class="cx" style="display: block; padding: 0 10px">  * @since 1.2.6
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ * @since 14.0.0 Adds the `$group_admin_id` parameter.
</ins><span class="cx" style="display: block; padding: 0 10px">  *
</span><span class="cx" style="display: block; padding: 0 10px">  * @param int $user_id  ID of the user.
</span><span class="cx" style="display: block; padding: 0 10px">  * @param int $group_id ID of the group.
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ * @param int $group_admin_id Optional. The group admin user ID.
</ins><span class="cx" style="display: block; padding: 0 10px">  * @return bool True on success, false on failure.
</span><span class="cx" style="display: block; padding: 0 10px">  */
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-function groups_remove_member( $user_id, $group_id ) {
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+function groups_remove_member( $user_id, $group_id, $group_admin_id = 0 ) {
+       // Carry on using the item admin set by the Web version.
+       if ( ! $group_admin_id ) {
+               $user_can = bp_is_item_admin();
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-        if ( ! bp_is_item_admin() ) {
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+         // Use the provided Group Admin ID (eg: during a REST API request).
+       } else {
+               $user_can = bp_current_user_can( 'bp_moderate' ) || groups_is_user_admin( $group_admin_id, $group_id );
+       }
+
+       if ( ! $user_can ) {
</ins><span class="cx" style="display: block; padding: 0 10px">                 return false;
</span><span class="cx" style="display: block; padding: 0 10px">        }
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -2155,7 +2262,19 @@
</span><span class="cx" style="display: block; padding: 0 10px">         */
</span><span class="cx" style="display: block; padding: 0 10px">        do_action( 'groups_remove_member', $group_id, $user_id );
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-        return $member->remove();
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ if ( ! $member->remove() ) {
+               return false;
+       }
+
+       /**
+        * Fires once the group member has been successfully removed.
+        *
+        * @since 14.0.0
+        *
+        * @param int $user_id  ID of the user being unbanned.
+        * @param int $group_id ID of the group being removed from.
+        */
+       do_action( 'group_member_removed', $user_id, $group_id );
</ins><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px"> /** Group Membership **********************************************************/
</span></span></pre></div>
<a id="trunksrcbpgroupsbpgroupsnotificationsphp"></a>
<div class="modfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Modified: trunk/src/bp-groups/bp-groups-notifications.php</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- trunk/src/bp-groups/bp-groups-notifications.php   2024-05-24 14:13:15 UTC (rev 13872)
+++ trunk/src/bp-groups/bp-groups-notifications.php     2024-05-25 04:47:42 UTC (rev 13873)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -300,7 +300,7 @@
</span><span class="cx" style="display: block; padding: 0 10px">        );
</span><span class="cx" style="display: block; padding: 0 10px">        bp_send_email( 'groups-member-promoted', (int) $user_id, $args );
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-add_action( 'groups_promoted_member', 'groups_notification_promoted_member', 10, 2 );
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+add_action( 'group_member_promoted', 'groups_notification_promoted_member', 10, 2 );
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px"> /**
</span><span class="cx" style="display: block; padding: 0 10px">  * Notify a member they have been invited to a group.
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -1055,7 +1055,7 @@
</span><span class="cx" style="display: block; padding: 0 10px">                bp_notifications_delete_notifications_by_item_id( $user_id, $group_id, buddypress()->groups->id, 'member_promoted_to_mod' );
</span><span class="cx" style="display: block; padding: 0 10px">        }
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-add_action( 'groups_demoted_member', 'bp_groups_delete_promotion_notifications', 10, 2 );
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+add_action( 'group_member_demoted', 'bp_groups_delete_promotion_notifications', 10, 2 );
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px"> /**
</span><span class="cx" style="display: block; padding: 0 10px">  * Mark notifications read when a member accepts a group invitation.
</span></span></pre></div>
<a id="trunksrcbpgroupsscreenssingleadminmanagemembersphp"></a>
<div class="modfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Modified: trunk/src/bp-groups/screens/single/admin/manage-members.php</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- trunk/src/bp-groups/screens/single/admin/manage-members.php       2024-05-24 14:13:15 UTC (rev 13872)
+++ trunk/src/bp-groups/screens/single/admin/manage-members.php 2024-05-25 04:47:42 UTC (rev 13873)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -48,14 +48,15 @@
</span><span class="cx" style="display: block; padding: 0 10px">                        }
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px">                        /**
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                         * Fires before the redirect after a group member has been promoted.
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                  * Fires before the redirect.
</ins><span class="cx" style="display: block; padding: 0 10px">                          *
</span><span class="cx" style="display: block; padding: 0 10px">                         * @since 1.0.0
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                         * @deprecated 14.0.0
</ins><span class="cx" style="display: block; padding: 0 10px">                          *
</span><span class="cx" style="display: block; padding: 0 10px">                         * @param int $user_id ID of the user being promoted.
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                         * @param int $id      ID of the group user is promoted within.
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                  * @param int $id      ID of the group is promoted within.
</ins><span class="cx" style="display: block; padding: 0 10px">                          */
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                        do_action( 'groups_promoted_member', $user_id, $bp->groups->current_group->id );
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                 do_action_deprecated( 'groups_promoted_member', array( $user_id, $bp->groups->current_group->id ), '14.0.0', 'group_member_promoted' );
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px">                        bp_core_redirect( $redirect );
</span><span class="cx" style="display: block; padding: 0 10px">                }
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -86,11 +87,12 @@
</span><span class="cx" style="display: block; padding: 0 10px">                         * Fires before the redirect after a group member has been demoted.
</span><span class="cx" style="display: block; padding: 0 10px">                         *
</span><span class="cx" style="display: block; padding: 0 10px">                         * @since 1.0.0
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                         * @deprecated 14.0.0
</ins><span class="cx" style="display: block; padding: 0 10px">                          *
</span><span class="cx" style="display: block; padding: 0 10px">                         * @param int $user_id ID of the user being demoted.
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                         * @param int $id      ID of the group user is demoted within.
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                  * @param int $id      ID of the group is demoted within.
</ins><span class="cx" style="display: block; padding: 0 10px">                          */
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                        do_action( 'groups_demoted_member', $user_id, $bp->groups->current_group->id );
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                 do_action_deprecated( 'groups_demoted_member', array( $user_id, $bp->groups->current_group->id ), '14.0.0', 'group_member_demoted' );
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px">                        bp_core_redirect( $redirect );
</span><span class="cx" style="display: block; padding: 0 10px">                }
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -114,11 +116,12 @@
</span><span class="cx" style="display: block; padding: 0 10px">                         * Fires before the redirect after a group member has been banned.
</span><span class="cx" style="display: block; padding: 0 10px">                         *
</span><span class="cx" style="display: block; padding: 0 10px">                         * @since 1.0.0
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                         * @deprecated 14.0.0
</ins><span class="cx" style="display: block; padding: 0 10px">                          *
</span><span class="cx" style="display: block; padding: 0 10px">                         * @param int $user_id ID of the user being banned.
</span><span class="cx" style="display: block; padding: 0 10px">                         * @param int $id      ID of the group user is banned from.
</span><span class="cx" style="display: block; padding: 0 10px">                         */
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                        do_action( 'groups_banned_member', $user_id, $bp->groups->current_group->id );
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                 do_action_deprecated( 'groups_banned_member', array( $user_id, $bp->groups->current_group->id ), '14.0.0', 'group_member_banned' );
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px">                        bp_core_redirect( $redirect );
</span><span class="cx" style="display: block; padding: 0 10px">                }
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -142,11 +145,12 @@
</span><span class="cx" style="display: block; padding: 0 10px">                         * Fires before the redirect after a group member has been unbanned.
</span><span class="cx" style="display: block; padding: 0 10px">                         *
</span><span class="cx" style="display: block; padding: 0 10px">                         * @since 1.0.0
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                         * @deprecated 14.0.0
</ins><span class="cx" style="display: block; padding: 0 10px">                          *
</span><span class="cx" style="display: block; padding: 0 10px">                         * @param int $user_id ID of the user being unbanned.
</span><span class="cx" style="display: block; padding: 0 10px">                         * @param int $id      ID of the group user is unbanned from.
</span><span class="cx" style="display: block; padding: 0 10px">                         */
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                        do_action( 'groups_unbanned_member', $user_id, $bp->groups->current_group->id );
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                 do_action_deprecated( 'groups_unbanned_member', array( $user_id, $bp->groups->current_group->id ), '14.0.0', 'group_member_unbanned' );
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px">                        bp_core_redirect( $redirect );
</span><span class="cx" style="display: block; padding: 0 10px">                }
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -170,11 +174,12 @@
</span><span class="cx" style="display: block; padding: 0 10px">                         * Fires before the redirect after a group member has been removed.
</span><span class="cx" style="display: block; padding: 0 10px">                         *
</span><span class="cx" style="display: block; padding: 0 10px">                         * @since 1.2.6
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                         * @deprecated 14.0.0
</ins><span class="cx" style="display: block; padding: 0 10px">                          *
</span><span class="cx" style="display: block; padding: 0 10px">                         * @param int $user_id ID of the user being removed.
</span><span class="cx" style="display: block; padding: 0 10px">                         * @param int $id      ID of the group the user is removed from.
</span><span class="cx" style="display: block; padding: 0 10px">                         */
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                        do_action( 'groups_removed_member', $user_id, $bp->groups->current_group->id );
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                 do_action_deprecated( 'groups_removed_member', array( $user_id, $bp->groups->current_group->id ), '14.0.0', 'group_member_removed' );
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px">                        bp_core_redirect( $redirect );
</span><span class="cx" style="display: block; padding: 0 10px">                }
</span></span></pre></div>
<a id="trunktestsphpunittestcasesgroupsnotificationsphp"></a>
<div class="modfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Modified: trunk/tests/phpunit/testcases/groups/notifications.php</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- trunk/tests/phpunit/testcases/groups/notifications.php    2024-05-24 14:13:15 UTC (rev 13872)
+++ trunk/tests/phpunit/testcases/groups/notifications.php      2024-05-25 04:47:42 UTC (rev 13873)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -181,7 +181,7 @@
</span><span class="cx" style="display: block; padding: 0 10px">                $this->assertEquals( array( $n ), wp_list_pluck( $notifications, 'id' ) );
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px">                // fire the hook
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                do_action( 'groups_demoted_member', $u, $g );
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+         do_action( 'group_member_demoted', $u, $g );
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px">                $notifications = BP_Notifications_Notification::get( array(
</span><span class="cx" style="display: block; padding: 0 10px">                        'user_id' => $u,
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -205,7 +205,7 @@
</span><span class="cx" style="display: block; padding: 0 10px">                $this->assertEquals( array( $n ), wp_list_pluck( $notifications, 'id' ) );
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px">                // fire the hook
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                do_action( 'groups_demoted_member', $u, $g );
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+         do_action( 'group_member_demoted', $u, $g );
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px">                $notifications = BP_Notifications_Notification::get( array(
</span><span class="cx" style="display: block; padding: 0 10px">                        'user_id' => $u,
</span></span></pre>
</div>
</div>

</body>
</html>