Making WordPress.org

Changeset 12591


Ignore:
Timestamp:
05/17/2023 08:38:01 AM (17 months ago)
Author:
dd32
Message:

Plugin Directory: Introduce assigned reviewer functionality.

Previously the group of reviewers was so small that they knew who was handling which submission, now that we have a larger set of reviewers being onboarded we need to keep track of review assignments a bit better.

See #6993.

Location:
sites/trunk/wordpress.org/public_html/wp-content/plugins/plugin-directory/admin
Files:
1 added
2 edited

Legend:

Unmodified
Added
Removed
  • sites/trunk/wordpress.org/public_html/wp-content/plugins/plugin-directory/admin/class-customizations.php

    r12520 r12591  
    6464        add_action( 'wp_ajax_plugin-author-lookup', array( __NAMESPACE__ . '\Metabox\Author', 'lookup_author' ) );
    6565        add_action( 'wp_ajax_plugin-svn-sync', array( __NAMESPACE__ . '\Metabox\Review_Tools', 'svn_sync' ) );
     66        add_action( 'wp_ajax_plugin-set-reviewer', array( __NAMESPACE__ . '\Metabox\Reviewer', 'xhr_set_reviewer' ) );
    6667
    6768        add_action( 'save_post', array( __NAMESPACE__ . '\Metabox\Release_Confirmation', 'save_post' ) );
    6869        add_action( 'save_post', array( __NAMESPACE__ . '\Metabox\Author_Notice', 'save_post' ) );
     70        add_action( 'save_post', array( __NAMESPACE__ . '\Metabox\Reviewer', 'save_post' ) );
     71
     72        // Audit logs
     73        add_action( 'updated_postmeta', array( $this, 'updated_postmeta' ), 10, 4 );
    6974    }
    7075
     
    212217        }
    213218
     219        // Filter by reviewer.
     220        if ( ! empty( $_REQUEST['reviewer'] ) ) {
     221            $meta_query = $query->get( 'meta_query' ) ?: [];
     222            $meta_query[] = [
     223                'key'   => 'assigned_reviewer',
     224                'value' => intval( $_GET['reviewer'] ),
     225            ];
     226
     227            $query->set( 'meta_query', $meta_query );
     228        }
     229
    214230    }
    215231
     
    242258
    243259        $action = array_intersect(
    244             [ 'plugin_open', 'plugin_close', 'plugin_disable', 'plugin_reject' ],
     260            [ 'plugin_open', 'plugin_close', 'plugin_disable', 'plugin_reject', 'plugin_assign' ],
    245261            [ $_REQUEST['action'], $_REQUEST['action2'] ]
    246262        );
     
    251267
    252268        check_admin_referer( 'bulk-posts' );
     269
     270        $new_status = false;
     271        $from_state = false;
     272        $meta_data  = false;
    253273
    254274        switch( $action ) {
     
    277297                $from_state = [ 'new', 'pending' ];
    278298                break;
     299            case 'plugin_assign':
     300                if ( ! isset( $_REQUEST['reviewer'] ) ) {
     301                    return;
     302                }
     303
     304                $capability = 'plugin_review';
     305                $from_state = 'any';
     306                $message    = _n_noop( '%s plugin assigned.', '%s plugins assigned.', 'wporg-plugins' );
     307                $meta_data = array(
     308                    'assigned_reviewer'      => intval( $_REQUEST['reviewer'] ),
     309                    'assigned_reviewer_time' => time(),
     310                );
     311                break;
    279312            default:
    280313                return;
     
    282315
    283316        $closed = 0;
    284         $plugins  = get_posts( array(
     317        $args = array(
    285318            'post_type'      => 'plugin',
    286319            'post__in'       => array_map( 'absint', $_REQUEST['post'] ),
    287             'post_status'    => $from_state,
    288320            'posts_per_page' => count( $_REQUEST['post'] ),
    289         ) );
     321        );
     322        if ( $from_state ) {
     323            $args['post_status'] = $from_state;
     324        }
     325        $plugins  = get_posts( $args );
    290326
    291327        foreach ( $plugins as $plugin ) {
     
    293329                continue;
    294330            }
    295 
    296             $updated = wp_update_post( array(
    297                 'ID'          => $plugin->ID,
    298                 'post_status' => $new_status,
    299             ) );
     331            $updated = false;
     332
     333            if ( $new_status ) {
     334                $updated = wp_update_post( array(
     335                    'ID'          => $plugin->ID,
     336                    'post_status' => $new_status,
     337                ) );
     338            }
     339            if ( $meta_data ) {
     340                foreach ( $meta_data as $key => $value ) {
     341                    $updated = update_post_meta( $plugin->ID, $key, $value );
     342                }
     343            }
    300344
    301345            if ( $updated && ! is_wp_error( $updated ) ) {
     
    545589            __( 'Plugin Controls', 'wporg-plugins' ),
    546590            array( __NAMESPACE__ . '\Metabox\Controls', 'display' ),
     591            'plugin', 'side', 'high'
     592        );
     593
     594        add_meta_box(
     595            'reviewerdiv',
     596            __( 'Reviewer', 'wporg-plugins' ),
     597            array( __NAMESPACE__ . '\Metabox\Reviewer', 'display' ),
    547598            'plugin', 'side', 'high'
    548599        );
     
    807858        return $keys;
    808859    }
     860
     861    /**
     862     * Watch for post_meta updates and log accordingly.
     863     */
     864    public function updated_postmeta( $meta_id, $post_id, $meta_key, $meta_value ) {
     865        if ( 'assigned_reviewer' === $meta_key && $meta_value ) {
     866            $reviewer = get_user_by( 'id', $meta_value );
     867            Tools::audit_log(
     868                sprintf(
     869                    'Assigned to <a href="%s">%s</a>.',
     870                    esc_url( 'https://profiles.wordpress.org/' . $reviewer->user_nicename . '/' ),
     871                    $reviewer->display_name ?: $reviewer->user_login
     872                ),
     873                get_post( $post_id )
     874            );
     875        } elseif ( 'assigned_reviewer' === $meta_key && ! $meta_value ) {
     876            Tools::audit_log( 'Unassigned.', get_post( $post_id ) );
     877        }
     878    }
    809879}
  • sites/trunk/wordpress.org/public_html/wp-content/plugins/plugin-directory/admin/list-table/class-plugin-posts.php

    r12517 r12591  
    9595        }
    9696
     97        if ( current_user_can( 'plugin_review' ) ) {
     98            $actions['plugin_assign'] = __( 'Assign reviewer', 'wporg-plugins' );
     99        }
     100
    97101        return $actions;
    98102    }
     
    105109        $post_type     = $this->screen->post_type;
    106110        $posts_columns = array(
    107             'cb'     => '<input type="checkbox" />',
     111            'cb'       => '<input type="checkbox" />',
    108112            /* translators: manage posts column name */
    109             'title'  => _x( 'Title', 'column name', 'wporg-plugins' ),
    110             'author' => __( 'Submitter', 'wporg-plugins' ),
     113            'title'    => _x( 'Title', 'column name', 'wporg-plugins' ),
     114            'author'   => __( 'Submitter', 'wporg-plugins' ),
     115            'reviewer' => __( 'Assigned Reviewer', 'wporg-plugins' ),
    111116        );
    112117
     
    411416            $mine_inner_html = sprintf(
    412417                _nx(
    413                     'Mine <span class="count">(%s)</span>',
    414                     'Mine <span class="count">(%s)</span>',
     418                    'My Plugins <span class="count">(%s)</span>',
     419                    'My Plugins <span class="count">(%s)</span>',
    415420                    $user_post_count,
    416421                    'posts',
     
    448453
    449454        $status_links['all'] = $this->get_edit_link( $all_args, $all_inner_html, $class );
     455
     456        // Assigned to me.
     457        if ( current_user_can( 'plugin_review' ) ) {
     458            $assigned_count = $wpdb->get_var( $wpdb->prepare(
     459                "SELECT COUNT(p.ID)
     460                FROM $wpdb->posts p
     461                    JOIN $wpdb->postmeta pm ON p.ID = pm.post_id
     462                WHERE pm.meta_key = 'assigned_reviewer' AND pm.meta_value = %d AND p.post_status NOT IN( 'approved', 'publish' )",
     463                get_current_user_id()
     464            ) );
     465
     466            $assigned_args = array(
     467                'post_type' => $post_type,
     468                'reviewer'  => get_current_user_id(),
     469            );
     470
     471            $assigned_label = sprintf(
     472                _nx(
     473                    'Assigned to Me <span class="count">(%s)</span>',
     474                    'Assigned to Me <span class="count">(%s)</span>',
     475                    $assigned_count,
     476                    'posts',
     477                    'wporg-plugins'
     478                ),
     479                number_format_i18n( $assigned_count )
     480            );
     481
     482            $status_links['assigned'] = $this->get_edit_link( $assigned_args, $assigned_label, ( ($_REQUEST['reviewer'] ?? 0) === get_current_user_id() ? 'current' : '' ) );
     483        }
     484
    450485        if ( $mine ) {
    451486            $status_links['mine'] = $mine;
     
    519554        parent::extra_tablenav( $which );
    520555
     556        if ( 'top' === $which ) {
     557            // The first is the reviewer filter, the second is the assign review bulk action.
     558            ?>
     559            <fieldset class="alignleft actions filter-reviewer">
     560                <?php
     561                wp_dropdown_users( [
     562                    'name'              => 'reviewer',
     563                    'selected'          => intval( $_REQUEST['reviewer'] ?? 0 ),
     564                    'show_option_none'  => __( 'All Reviewers', 'wporg-plugins' ),
     565                    'option_none_value' => 0,
     566                    'role__in'          => [ 'plugin_admin', 'plugin_reviewer' ],
     567                ] );
     568                submit_button( __( 'Filter', 'wporg-plugins' ), 'secondary', false, false );
     569                ?>
     570            </fieldset>
     571            <fieldset class="alignleft actions hide-if-js bulk-plugin_assign" disabled="disabled">
     572                <?php
     573                wp_dropdown_users( [
     574                    'name'              => 'reviewer',
     575                    'selected'          => 0,
     576                    'show_option_none'  => __( 'Assign Review to ...', 'wporg-plugins' ),
     577                    'option_none_value' => 0,
     578                    'role__in'          => [ 'plugin_admin', 'plugin_reviewer' ],
     579                ] );
     580                submit_button( __( 'Assign', 'wporg-plugins' ), 'primary', false, false );
     581                ?>
     582            </fieldset>
     583            <?php
     584        }
     585
    521586        // TODO: This shouldn't have inline CSS/JS.
    522587
     
    530595                    <?php endforeach; ?>
    531596                </select>
     597                <span class="actions bulk-plugin_close">
     598                    <?php submit_button( __( 'Close', 'wporg-plugins' ), 'primary', 'bulk_close', false ); ?>
     599                </span>
     600                <span class="actions bulk-plugin_disable">
     601                    <?php submit_button( __( 'Disable', 'wporg-plugins' ), 'primary', 'bulk_close', false ); ?>
     602                </span>
    532603            </fieldset>
    533604            <style>
     
    543614                        $tablenav = $this.parents('form').find( '.tablenav.top' );
    544615
    545                     $tablenav.find( '.actions.bulk-plugin_close, .actions.bulk-plugin_disable' ).prop( 'disabled', true ).hide();
     616                    $tablenav.find( '.actions.bulk-plugin_close, .actions.bulk-plugin_disable, .actions.bulk-plugin_assign' ).prop( 'disabled', true ).hide();
    546617                    $tablenav.find( '.actions.bulk-' + val ).prop( 'disabled', false ).show();
    547618                } );
     
    551622        }
    552623    }
     624
     625    /**
     626     * The custom Assigned Reviewer column.
     627     */
     628    public function column_reviewer( $post ) {
     629        $reviewer_id   = (int) ( $post->assigned_reviewer ?? 0 );
     630        $reviewer      = $reviewer_id ? get_user_by( 'id', $reviewer_id ) : false;
     631        $reviewer_time = (int) ( $post->assigned_reviewer_time ?? 0 );
     632
     633        if ( $reviewer ) {
     634            printf(
     635                "<a href='%s'>%s</a><br><span>%s</span>",
     636                add_query_arg( [ 'reviewer' => $reviewer_id ] ),
     637                $reviewer->display_name ?: $reviewer->user_login,
     638                sprintf(
     639                    /* translators: %s The time/date different, '1 hour' */
     640                    __( '%s ago', 'wporg-plugins' ),
     641                    human_time_diff( $reviewer_time )
     642                )
     643            );
     644        }
     645    }
    553646}
Note: See TracChangeset for help on using the changeset viewer.