[buddypress-trac] [BuddyPress Trac] #8728: Group Moderator Unable Delete Group Posts

buddypress-trac noreply at wordpress.org
Mon Apr 15 12:18:36 UTC 2024


#8728: Group Moderator Unable Delete Group Posts
--------------------------------------+------------------------
 Reporter:  kainelabsteam             |       Owner:  emaralive
     Type:  enhancement               |      Status:  assigned
 Priority:  normal                    |   Milestone:  14.0.0
Component:  Groups                    |     Version:  10.3.0
 Severity:  normal                    |  Resolution:
 Keywords:  needs-patch dev-feedback  |
--------------------------------------+------------------------
Changes (by emaralive):

 * keywords:  needs-patch => needs-patch dev-feedback


Comment:

 In alphabetical order, @dcavins, @espellcaste, @imath, @vapvarun; perhaps
 the following will satisfy most of what was stipulated during the
 [https://wordpress.slack.com/archives/C02RQBYUG/p1712170856525779 BP Dev
 Chat] on April 3, 2024 and reiterated within the
 [https://bpdevel.wordpress.com/2024/04/13/bp-dev-chat-summary-
 april-3-2024/ BP Dev-Chat Summary April 3, 2024].

 The reason why the the
 **[https://github.com/buddypress/buddypress/blob/master/src/bp-groups/bp-
 groups-activity.php#L652%7CL675 callback]**
 (**{{{bp_groups_filter_activity_user_can_delete}}}**) for the
 **[https://github.com/buddypress/buddypress/blob/master/src/bp-groups/bp-
 groups-activity.php#L675C14-L675C41 filter]**
 (**{{{bp_activity_user_can_delete}}}**) does not work is due to the
 **conditional** starting on
 **[https://github.com/buddypress/buddypress/blob/master/src/bp-groups/bp-
 groups-activity.php#L658%7CL660 line 658]**, for example:
 {{{
         if ( isset( $activity->component ) || 'groups' !==
 $activity->component ) {
                 return $retval;
         }
 }}}

 The conditional contains a logical **OR** operator and since **{{{isset(
 $activity->component )}}}** will, **in all likelihood**, be **true**, the
 variable **{{{$retval}}}** will be the the **parameter** value that was
 initially passed to the **callback**. IOW, the function ends at this point
 and never reaches any of the downstream conditionals that would determine
 a different outcome, e.g., the determination of whether group admins or
 group mods can delete activity posts. The fix is to change the logical
 **OR** to a logical **AND**, for example:
 {{{
         if ( isset( $activity->component ) && 'groups' !==
 $activity->component ) {
                 return $retval;
         }
 }}}

 In retrospect, was this intentional or an oversight as to how the
 **callback** was written/coded for release? And, since the **callback**
 existed since version **6.0.0**; why was this not recognized as a bug
 before and after this ticket was submitted? However, with the fix, there
 are a couple of undesirable consequences, as I see it, that allow for
 group admins and group mods to:

 * Delete site admin activity posts (within the confines of a respective
 group and if the group is public within sitewide or user activity streams)
 * Delete group members (group admin, group mods & group members) activity
 posts if the group is public within sitewide or user activity streams.

 To avert the aforementioned undesirable consequences, I propose the
 callback to be initially rewritten/recoded as, which serves as POC:
 {{{
 function bp_groups_filter_activity_user_can_delete( $retval, $activity ) {
         // Bail if no current user.
         // Todo: add second conditional statement to check the state to
 allow group activity deletions.
         // e.g., "|| ! bp_enable_group_activity_deletions()".
         if ( ! is_user_logged_in() ) {
                 return $retval;
         }

         // The second conditional statement does not allow "site admin"
 activity posts to be deleted by "non site admins".
         if ( bp_current_user_can( 'bp_moderate' ) || bp_user_can(
 $activity->user_id, 'bp_moderate' ) ) {
                 return $retval;
         }

         $bp = buddypress();

         // Confine group activity deletion to the confines of the
 respective group where it is allowed.
         if ( ! empty( $bp->groups->current_group->id ) ) {
                 $group_id = $bp->groups->current_group->id;

                 // Todo: break this out into additional conditionals that
 provide granularity as to who can to what, when.
                 if ( groups_is_user_creator( bp_loggedin_user_id(),
 $group_id ) || groups_is_user_admin( bp_loggedin_user_id(), $group_id ) ||
 groups_is_user_mod( bp_loggedin_user_id(), $group_id ) ) {
                         $retval = true;
                 }
         }

         return $retval;
 }
 }}}

 Later I plan to add granularity of control to the proposed **callback**
 that will delineate who can delete activity posts as well as when, for
 example:
 * group creator only
 * group creator and group admins
 * group creator, group admins and group mods

 At least, that would be the plan. Currently, I have the site admin control
 as to whether group activity deletions are allowed, in which the default
 state is **not enabled** or **disabled** (see screenshots **screenshot-
 win10-me-2024.04.14-08_10_55.png** & **screenshot-
 win10-me-2024.04.14-08_17_41.png**).

 == **Role Capabilities**
  NOTE:: **1.** By default a **group creator** is a **group admin**. [[BR]]
 **2.** **X** is default capability. [[BR]] **3.** **Z** is new capability
 based on parameters of proposed change to **callback**.

 ||                           ||= **site admin** =||= **group admin** =||=
 **group mod** =||
 ||   **mark/unmark user as spammer**||  X        ||                   ||
 ||
 ||  **mark/unmark activity as spam**||  X        ||                   ||
 ||
 ||    **delete group activity post**||  X        ||   Z               ||
 Z              ||
 ||   **ban/unban any group member**||  X         ||   X               ||
 ||
 || **remove any group member**||  X               ||   X               ||
 ||
 || **promote/demote any group member**||  X       ||   X               ||
 ||
 [[BR]]
 == **Group Roles**
 ||= **ID** =||= **Name** =||= **Note** =||
 ||admin ||  Administrator|| As noted earlier **group creator** by default
 is a **group admin** ||
 ||mod       ||   Moderator||
 ||member    ||       Member||
 ||banned    ||      Banned||
 [[BR]]
 == **Mark/Unmark User as Spammer**
 Only available to **site admin** via various locations
 * Backend - [All] Users screen/page.
 * Backend - Individual User's **Extended Profile** screen/page - Status
 metabox.
 * Frontend - Individual User's **Members Capabilities** screen/page, e.g.
 site.url//members/{user}/settings/capabilities/

  Note:: **1.** **user_status** is a field in the **users** table.[[BR]]
 **2.** **hide_sitewide** is a field in the **bp_activity** table, visible
 from backend - activity page/screen.[[BR]] **3.** **is_spam** is a field
 in the **bp_activity** table, visible from backend - activity page/screen
 - spam tab.

 ||= **state** =||= **user_status** =||= **hide_sitewide** =||= **is_spam**
 =||= **Note** =||
 || Normal ||  0  ||  0  ||  0  ||
 || Spammed ||  1  ||  1  ||  1  ||Kicked from site unable to log back in
 until unspammed.  ||
 || Unspammed ||  0  ||  1  ||  0  ||Able to log in, but previous activity
 post are hidden  ||
 [[BR]]
 == **Mark/Unmark Activity as Spam**
 Only available to **site admin** via backend Activity page/screen. Toggle
 **is_spam** field from **0** to **1** or **1** to **0**.

 == **Delete Group Activity Post**
 Currently, only available to **site admin** via delete button on activity
 post (or backend activity page/screen) or **group member** who created the
 activity post via delete button visible on activity post. Proposed to be
 available to **group creator**, **group admin** or **group mod** depending
 on configuration defined by the code implemented by this ticket or as
 defined by a 3rd party plugin.

 == **Ban/Unban Any Group Member**
 Only available to **site admin** or **group admin** via **Manage Group
 Members** page/screen. The banned member's activity posts remain visible
 and cannot rejoin group until unbanned.

 == **Remove Any Group Member**
 Only available to **site admin** or **group admin** via **Manage Group
 Members** page/screen. The removed member's activity posts remain visible
 and can rejoin group at any time.

 == **Promote/Demote Any Group Member**
 Only available to **site admin** or **group admin** via **Manage Group
 Members** page/screen with the exception that they cannot promote/demote
 themselves. What I find odd is that a **group creator** (by default
 **group role** is a **group admin**) can be demoted from **group admin**
 status (which also means, if a **site admin** creates a group, the same
 applies).

-- 
Ticket URL: <https://buddypress.trac.wordpress.org/ticket/8728#comment:8>
BuddyPress Trac <http://buddypress.org/>
BuddyPress Trac


More information about the buddypress-trac mailing list