Making WordPress.org

Changeset 12749


Ignore:
Timestamp:
07/20/2023 04:01:22 AM (2 years ago)
Author:
dd32
Message:

Support Forums: Improve the user notes for role changes to include the previous non-participant role, capture moderator/spectator role sets, and generally have cleaner code.

See #5707.

Location:
sites/trunk/wordpress.org/public_html/wp-content/plugins/support-forums/inc
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • sites/trunk/wordpress.org/public_html/wp-content/plugins/support-forums/inc/class-audit-log.php

    r12746 r12749  
    22
    33namespace WordPressdotorg\Forums;
     4use WP_User;
    45
    56class Audit_Log {
     
    1112     */
    1213    var $edited_notes = [];
     14
     15    /**
     16     * Keeps track of the role changes for each user.
     17     *
     18     * @var array
     19     */
     20    var $last_role_change = [];
    1321
    1422    function __construct() {
    1523        // Audit-log entries for Term subscriptions (add/remove)
    16         add_action( 'wporg_bbp_add_user_term_subscription',    array( $this, 'term_subscriptions' ), 10, 2 );
    17         add_action( 'wporg_bbp_remove_user_term_subscription', array( $this, 'term_subscriptions' ), 10, 2 );
     24        add_action( 'wporg_bbp_add_user_term_subscription',    [ $this, 'term_subscriptions' ], 10, 2 );
     25        add_action( 'wporg_bbp_remove_user_term_subscription', [ $this, 'term_subscriptions' ], 10, 2 );
     26
     27        // Add a user note for forum role changes.
     28        add_action( 'add_user_role',     [ $this, 'monitor_role_changes' ], 10, 2 );
     29        add_action( 'remove_user_role',  [ $this, 'monitor_role_changes' ], 10, 2 );
     30        add_filter( 'bbp_set_user_role', [ $this, 'bbp_set_user_role' ],    10, 3 );
     31
     32        // Add a user note when flagging/unflagging a user.
     33        add_action( 'wporg_bbp_flag_user',   [ $this, 'log_user_flag_changes' ], 10, 1 );
     34        add_action( 'wporg_bbp_unflag_user', [ $this, 'log_user_flag_changes' ], 10, 1 );
    1835
    1936        // Slack logs for Moderation notes.
    2037        add_action( 'wporg_bbp_note_added', [ $this, 'forums_notes_added' ], 10, 2 );
     38        add_action( 'shutdown',             [ $this, 'forums_notes_added_shutdown' ] );
    2139    }
    2240
     
    5169    }
    5270
     71
     72    /**
     73     * Keep track of the role changes that happen via bbp_set_user_role.
     74     *
     75     * TODO: Check if this is still needed, bbPress might pass context via bbp_set_user_role.
     76     */
     77    function monitor_role_changes( $user_id, $role ) {
     78        $this->last_role_change[ $user_id ] ??= [];
     79        $this->last_role_change[ $user_id ][ current_filter() ] = $role;
     80    }
     81
     82    /**
     83     * Monitor for role changes, and log as appropriate.
     84     *
     85     * NOTE: This is also triggered on Locale forums. We may need to revisit that at some point.
     86     */
     87    function bbp_set_user_role( $new_role, $user_id, WP_User $user ) {
     88        $previous_role = $this->last_role_change[ $user_id ][ 'remove_user_role' ] ?? false;
     89
     90        // For the purposes of this function, a previous participant role is irrelevant.
     91        if ( bbp_get_participant_role() == $previous_role ) {
     92            $previous_role = false;
     93        }
     94
     95        $monitored_roles = [
     96            bbp_get_keymaster_role(),
     97            bbp_get_moderator_role(),
     98            // bbp_get_participant_role(), // Not monitoring for changes involving only this role.
     99            bbp_get_spectator_role(),
     100            bbp_get_blocked_role()
     101        ];
     102
     103        if (
     104            // If the role change is not one we're monitoring, bail.
     105            ! array_intersect( $monitored_roles, [ $new_role, $previous_role ] ) ||
     106            // If we can't detect any change, bail.
     107            $new_role === $previous_role
     108        ) {
     109            return $new_role; // We're on a filter.
     110        }
     111
     112        // Determine what triggered this change.
     113        $where_from = ! ms_is_switched() ? home_url( '/' ) : $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'];
     114        $where_from = explode( '?', $where_from )[0];
     115        $where_from = preg_replace( '!^(?:https?://)?(.+?)/?[^/]*$!i', '$1', $where_from );
     116
     117        // Add a user note about this action.
     118        $note_text = sprintf(
     119            'Forum role changed to %s%s%s.',
     120            get_role( $new_role )->name,
     121            $previous_role ? sprintf( ' from %s', get_role( $previous_role )->name ) : '',
     122            $where_from ?    sprintf( ' via %s', $where_from ) : ''
     123        );
     124
     125        // Used in wporg-login to add context.
     126        $note_text = apply_filters( 'wporg_bbp_forum_role_changed_note_text', $note_text, $user );
     127
     128        // Add a user note about this action.
     129        Plugin::get_instance()->user_notes->add_user_note_or_update_previous(
     130            $user->ID,
     131            $note_text
     132        );
     133
     134        // It's a filter, so we need to return the value.
     135        return $new_role;
     136    }
     137
     138    /**
     139     * Add a user note when a user is flagged / unflagged.
     140     *
     141     * @param int $user_id
     142     */
     143    function log_user_flag_changes( $user_id ) {
     144        $flag_action = ( 'wporg_bbp_flag_user' === current_action() ) ? 'flagged' : 'unflagged';
     145
     146        $note_text = "User {$flag_action}.";
     147
     148        Plugin::get_instance()->user_notes->add_user_note_or_update_previous(
     149            $user_id,
     150            $note_text
     151        );
     152    }
     153
    53154    /**
    54155     * Record Note changes to Slack.
     
    60161        $this->edited_notes[ $user_id ] ??= [];
    61162        $this->edited_notes[ $user_id ][] = $note_id;
    62 
    63         if ( ! has_action( 'shutdown', [ $this, 'forums_notes_added_shutdown' ] ) ) {
    64             add_action( 'shutdown', [ $this, 'forums_notes_added_shutdown' ] );
    65         }
    66163    }
    67164
     
    70167     */
    71168    function forums_notes_added_shutdown() {
    72         if ( ! function_exists( 'notify_slack' ) || ! defined( 'FORUMS_MODACTIONS_SLACK_CHANNEL' ) ) {
     169        if ( ! $this->edited_notes || ! function_exists( 'notify_slack' ) || ! defined( 'FORUMS_MODACTIONS_SLACK_CHANNEL' ) ) {
    73170            return;
    74171        }
  • sites/trunk/wordpress.org/public_html/wp-content/plugins/support-forums/inc/class-hooks.php

    r12171 r12749  
    136136        add_filter( 'pre_oembed_result', array( $this, 'pre_oembed_result_dont_embed_wordpress_org_anchors' ), 20, 2 );
    137137
    138         // Add a user note when flagging/unflagging a user.
    139         add_filter( 'wporg_bbp_flag_user', array( $this, 'log_user_flag_changes' ) );
    140         add_filter( 'wporg_bbp_unflag_user', array( $this, 'log_user_flag_changes' ) );
    141 
    142138        // Break users sessions / passwords when they get blocked, on the main forums only.
    143139        if ( 'wordpress.org' === get_blog_details()->domain ) {
    144             add_action( 'bbp_set_user_role', array( $this, 'user_blocked_password_handler' ), 10, 3 );
     140            add_filter( 'bbp_set_user_role', array( $this, 'user_blocked_password_handler' ), 10, 3 );
    145141        }
    146142    }
     
    13601356     *
    13611357     * Note: This method is called even when the users role is not changed.
     1358     *
     1359     * See Audit_Log class for where the note is set/updated.
    13621360     */
    13631361    public function user_blocked_password_handler( $new_role, $user_id, \WP_User $user ) {
     
    13661364        // ~~~ is a reset password on WordPress.org. Let's ignore those.
    13671365        if ( '~~~' === $user->user_pass ) {
    1368             return;
     1366            return $new_role;
    13691367        }
    13701368
     
    13741372        $blocked_role    = bbp_get_blocked_role();
    13751373        $password_broken = ( 0 === strpos( $user->user_pass, $blocked_prefix ) );
    1376         $note_text       = false;
    13771374
    13781375        // WP_User::has_role() does not exist, and WP_User::has_cap( 'bbp_blocked' ) will be truthful for super admins.
    13791376        $user_has_blocked_role = ! empty( $user->roles ) && in_array( $blocked_role, $user->roles, true );
    1380 
    1381         // Define what has blocked the user.
    1382         if ( ! ms_is_switched() ) {
    1383             $where_from = preg_replace( '!^https?://!i', '', home_url( is_admin() ? '/wp-admin' : '' ) );
    1384         } else {
    1385             // When we're switched, we can't determine the source of the switch, so we use a bit of URL parsing magic.
    1386             $where_from = $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'];
    1387             if ( str_contains( $where_from, '?' ) ) {
    1388                 list( $where_from, ) = explode( '?', $where_from );
    1389             }
    1390             // Trim actual filename off, just the major path component.
    1391             $where_from = preg_replace( '!/[^/?]+\.[a-z]{3}$!i', '', $where_from  );
    1392         }
    13931377
    13941378        if (
     
    14131397            $manager = \WP_Session_Tokens::get_instance( $user->ID );
    14141398            $manager->destroy_all();
    1415 
    1416             // Add a user note about this action.
    1417             $note_text = sprintf(
    1418                 $where_from ? 'Forum role changed to %s via %s.' : 'Forum role changed to %s.',
    1419                 get_role( $new_role )->name,
    1420                 $where_from
    1421             );
    1422 
    1423             // Used in wporg-login to add context.
    1424             $note_text = apply_filters( 'wporg_bbp_forum_role_changed_note_text', $note_text, $user );
    14251399        } else if (
    14261400            $password_broken &&
     
    14401414
    14411415            clean_user_cache( $user );
    1442 
    1443             // Add a user note about this action.
    1444             $note_text = sprintf(
    1445                 $where_from ? 'Forum role changed to %s via %s.' : 'Forum role changed to %s.',
    1446                 get_role( $new_role )->name,
    1447                 $where_from
    1448             );
    1449 
    1450             // Unused, here for consistency with above.
    1451             $note_text = apply_filters( 'wporg_bbp_forum_role_changed_note_text', $note_text, $user );
    1452         }
    1453 
    1454         if ( $note_text ) {
    1455             // Add a user note about this action.
    1456             Plugin::get_instance()->user_notes->add_user_note_or_update_previous(
    1457                 $user->ID,
    1458                 $note_text
    1459             );
    1460         }
    1461 
    1462     }
    1463 
    1464     /**
    1465      * Add a user note when a user is flagged / unflagged.
    1466      */
    1467     function log_user_flag_changes( $user_id ) {
    1468         $flag_action = ( 'wporg_bbp_flag_user' === current_filter () ) ? 'flagged' : 'unflagged';
    1469 
    1470         $note_text = "User {$flag_action}.";
    1471 
    1472         Plugin::get_instance()->user_notes->add_user_note_or_update_previous(
    1473             $user_id,
    1474             $note_text
    1475         );
    1476     }
     1416        }
     1417
     1418        // It's a filter, return the value.
     1419        return $new_role;
     1420    }
     1421
    14771422}
Note: See TracChangeset for help on using the changeset viewer.