Making WordPress.org

Changeset 13033


Ignore:
Timestamp:
12/08/2023 03:47:14 AM (3 months ago)
Author:
dd32
Message:

Plugin Directory: Record the reason a plugin is rejected.

See #5653.
Closes https://github.com/WordPress/wordpress.org/pull/107.

Location:
sites/trunk/wordpress.org/public_html/wp-content/plugins/plugin-directory
Files:
7 edited

Legend:

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

    r13024 r13033  
    475475        }
    476476
    477         if ( 'disabled' == $post->post_status && 'disabled' != $post_status ) {
     477        if ( 'disabled' == $post->post_status ) {
    478478            $post_states['disabled'] = _x( 'Disabled', 'plugin status', 'wporg-plugins' );
    479479            // Affix the reason it's disabled.
     
    483483            }
    484484        }
    485         if ( 'closed' == $post->post_status && 'closed' != $post_status ) {
     485
     486        if ( 'closed' == $post->post_status ) {
    486487            $post_states['closed'] = _x( 'Closed', 'plugin status', 'wporg-plugins' );
    487488            // Affix the reason it's closed.
     
    491492            }
    492493        }
    493         if ( 'rejected' == $post->post_status && 'rejected' != $post_status ) {
     494
     495        if ( 'rejected' == $post->post_status ) {
    494496            $post_states['rejected'] = _x( 'Rejected', 'plugin status', 'wporg-plugins' );
     497
     498            if ( $post->_rejection_reason ) {
     499                $post_states['reason'] = Template::get_rejection_reasons()[ $post->_rejection_reason ] ?? '';
     500            }
     501
    495502        }
    496503        if ( 'approved' == $post->post_status && 'approved' != $post_status ) {
  • sites/trunk/wordpress.org/public_html/wp-content/plugins/plugin-directory/admin/class-status-transitions.php

    r12991 r13033  
    142142
    143143            case 'rejected':
     144                $this->save_rejected_reason( $post->ID );
    144145                $this->rejected( $post->ID, $post );
    145146                $this->clear_reviewer( $post );
     
    271272                'slug'            => $original_permalink,
    272273                'submission_date' => $submission_date,
     274                'reason'          => sanitize_key( $_POST['rejection_reason'] ?? '' )
    273275            ]
    274276        );
    275         // ..and log rejection.
    276         if ( $email->send() ) {
    277             Tools::audit_log( 'Plugin rejected.', $post_id );
    278         } else {
    279             Tools::audit_log( 'Plugin rejected. Email not sent.', $post_id );
    280         }
     277
     278        $email->send();
    281279    }
    282280
     
    331329        }
    332330
    333         if ( ! current_user_can( 'plugin_approve', $post_id ) ) {
     331        if ( ! current_user_can( 'plugin_close', $post_id ) ) {
    334332            return;
    335333        }
     
    341339
    342340        Tools::audit_log( sprintf( 'Plugin closed. Reason: %s', $close_reason ), $post_id );
     341    }
     342
     343    /**
     344     * Save the reason for rejecting a plugin.
     345     *
     346     * @param int $post_id Post ID.
     347     */
     348    public function save_rejected_reason( $post_id ) {
     349        if ( ! isset( $_REQUEST['rejection_reason'] ) ) {
     350            return;
     351        }
     352
     353        if ( ! current_user_can( 'plugin_reject', $post_id ) ) {
     354            return;
     355        }
     356
     357        $rejection_reason = sanitize_key( $_REQUEST['rejection_reason'] );
     358
     359        update_post_meta( $post_id, '_rejection_reason', $rejection_reason );
     360        update_post_meta( $post_id, 'plugin_rejected_date', current_time( 'mysql' ) );
     361
     362        Tools::audit_log( sprintf( 'Plugin rejected. Reason: %s', $rejection_reason ), $post_id );
    343363    }
    344364
  • sites/trunk/wordpress.org/public_html/wp-content/plugins/plugin-directory/admin/list-table/class-plugin-posts.php

    r13024 r13033  
    606606            </select>
    607607        </fieldset>
     608
     609        <fieldset class="alignleft actions hide-if-js bulk-plugin_reject" disabled="disabled">
     610            <select name="rejection_reason" id="rejection_reason">
     611                <option disabled="disabled" value='' selected="selected"><?php esc_html_e( 'Rejection Reason:', 'wporg-plugins' ); ?></option>
     612                <?php foreach ( Template::get_rejection_reasons() as $key => $label ) : ?>
     613                    <option value="<?php echo esc_attr( $key ); ?>"><?php echo esc_html( $label ); ?></option>
     614                <?php endforeach; ?>
     615            </select>
     616        </fieldset>
     617
    608618        <?php
    609619
  • sites/trunk/wordpress.org/public_html/wp-content/plugins/plugin-directory/admin/metabox/class-controls.php

    r12610 r13033  
    8686        }
    8787
    88         $close_reasons   = Template::get_close_reasons();
    89         $close_reason    = (string) get_post_meta( $post->ID, '_close_reason', true );
    90         $active_installs = (int) get_post_meta( $post->ID, 'active_installs', true );
    91 
    92         $reason_label   = Template::get_close_reason();
    93         $reason_unknown = ( _x( 'Unknown', 'unknown close reason', 'wporg-plugins' ) === $reason_label );
     88        $close_reasons     = Template::get_close_reasons();
     89        $close_reason      = (string) get_post_meta( $post->ID, '_close_reason', true );
     90        $rejection_reasons = Template::get_rejection_reasons();
     91        $rejection_reason  = (string) get_post_meta( $post->ID, '_rejection_reason', true );
     92        $active_installs   = (int) get_post_meta( $post->ID, 'active_installs', true );
     93
     94        $close_reason_label     = Template::get_close_reason();
     95        $close_reason_unknown   = ( _x( 'Unknown', 'unknown close reason', 'wporg-plugins' ) === $reason_label );
     96        $rejection_reason_label = $rejection_reasons[ $rejection_reason ] ?? $rejection_reasons[ 'other' ];
    9497        ?>
    9598        <div class="misc-pub-section misc-pub-plugin-status">
     
    97100            <?php if ( 'closed' === $post->post_status ) : ?>
    98101
    99                 <p><?php printf( __( 'Close Reason: %s', 'wporg-plugins' ), '<strong>' . $reason_label . '</strong>' ); ?></p>
     102                <p><?php printf( __( 'Close Reason: %s', 'wporg-plugins' ), '<strong>' . $close_reason_label . '</strong>' ); ?></p>
    100103
    101104            <?php elseif ( 'disabled' === $post->post_status ) : ?>
    102105
    103                 <p><?php printf( __( 'Disable Reason: %s', 'wporg-plugins' ), '<strong>' . $reason_label . '</strong>' ); ?></p>
     106                <p><?php printf( __( 'Disable Reason: %s', 'wporg-plugins' ), '<strong>' . $close_reason_label . '</strong>' ); ?></p>
     107
     108            <?php elseif ( 'rejected' === $post->post_status ) : ?>
     109
     110                <p><?php printf(
     111                        __( 'Rejection Reason: %s', 'wporg-plugins' ),
     112                        '<strong>' . $rejection_reason_label . '</strong>'
     113                ); ?></p>
    104114
    105115            <?php elseif ( 'publish' === $post->post_status ) : ?>
     
    108118                    <p><strong><?php _e( 'Notice:', 'wporg-plugins' ); ?></strong> <?php _e( 'Due to the large volume of active users, the developers should be warned and their plugin remain open save under extreme circumstances.', 'wporg-plugins' ); ?>.</p>
    109119                <?php endif; ?>
    110 
    111             <?php endif; ?>
    112 
    113             <?php
    114             if (
    115                     ( in_array( 'closed', $statuses, true ) || in_array( 'disabled', $statuses, true ) )
    116                 &&
    117                     ( ! in_array( $post->post_status, array( 'closed', 'disabled' ) ) || $reason_unknown )
    118                 ) :
    119                 ?>
    120 
    121                 <p>
    122                     <label for="close_reason"><?php _e( 'Close/Disable Reason:', 'wporg-plugins' ); ?></label>
    123                     <select name="close_reason" id="close_reason">
    124                         <?php foreach ( $close_reasons as $key => $label ) : ?>
    125                             <option value="<?php echo esc_attr( $key ); ?>"<?php selected( $key, $close_reason ); ?>><?php echo esc_html( $label ); ?></option>
    126                         <?php endforeach; ?>
    127                     </select>
    128                 </p>
    129120
    130121            <?php endif; ?>
     
    142133                }
    143134
     135                if ( 'closed' === $status || 'disabled' === $status ) { ?>
     136                    <p>
     137                        <label for="close_reason"><?php _e( 'Close/Disable Reason:', 'wporg-plugins' ); ?></label>
     138                        <select name="close_reason" id="close_reason">
     139                            <?php foreach ( $close_reasons as $key => $label ) : ?>
     140                                <option value="<?php echo esc_attr( $key ); ?>"<?php selected( $key, $close_reason ); ?>><?php echo esc_html( $label ); ?></option>
     141                            <?php endforeach; ?>
     142                        </select>
     143                    </p>
     144                <?php }
     145
     146                if ( 'rejected' === $status ) { ?>
     147                    <p>
     148                        <label for="rejection_reason"><?php _e( 'Rejection Reason:', 'wporg-plugins' ); ?></label>
     149                        <select name="rejection_reason" id="rejection_reason">
     150                            <?php foreach ( $rejection_reasons as $key => $label ) : ?>
     151                                <option value="<?php echo esc_attr( $key ); ?>"<?php selected( $key, $rejection_reason ); ?>><?php echo esc_html( $label ); ?></option>
     152                            <?php endforeach; ?>
     153                        </select>
     154                    </p>
     155                <?php }
     156
    144157                printf(
    145158                    '<button type="submit" name="post_status" value="%s" class="button set-plugin-status">%s</button>',
  • sites/trunk/wordpress.org/public_html/wp-content/plugins/plugin-directory/admin/tools/class-stats-report.php

    r13009 r13033  
    277277                AND `comment_agent` = ''
    278278                AND (
    279                     `comment_content` IN( 'Plugin Approved.', 'Plugin Rejected.', 'Unassigned.' )
     279                    `comment_content` IN( 'Plugin Approved.', 'Unassigned.' )
    280280                    OR `comment_content` LIKE 'Assigned TO%'
     281                    OR `comment_content` LIKE 'Plugin rejected.%'
    281282                    OR (
    282283                        `comment_content` LIKE 'Plugin closed.%'
     
    653654                echo '</td>';
    654655
    655                 // Plugins Approved, Rejected.
     656                // Plugins Approved.
    656657                echo '<td>', number_format_i18n( $user_stat[ 'Plugin approved.' ] ?? 0 ), '</td>';
    657                 echo '<td>', number_format_i18n( $user_stat[ 'Plugin rejected.' ] ?? 0 ), '</td>';
     658
     659                // Plugins Rejected.
     660                $user_rejected_breakdown = '';
     661                $user_rejected_count     = 0;
     662                foreach ( $user_stat as $key => $count ) {
     663                    if ( ! preg_match( '/^Plugin rejected\./', $key ) ) {
     664                        continue;
     665                    }
     666                    $user_rejected_count += $count;
     667                    $reason               = trim( explode( ':', $key )[1] ?? '' );
     668
     669                    if ( ! $reason ) {
     670                        continue;
     671                    }
     672
     673                    $user_rejected_breakdown .= sprintf(
     674                        "%s: %s\n",
     675                        Template::get_rejection_reasons()[ $reason ],
     676                        number_format_i18n( $count )
     677                    );
     678                }
     679                $user_rejected_breakdown = trim( $user_rejected_breakdown );
     680
     681                echo '<td class="breakdown">', '<span title="', esc_attr( $user_rejected_breakdown ), '">', number_format_i18n( $user_rejected_count ), '</span>';
     682                if ( $user_rejected_breakdown ) {
     683                    echo '<div class="hidden">', nl2br( $user_rejected_breakdown ), '</div>';
     684                }
     685                echo '</td>';
    658686
    659687                // Plugins Closed.
     
    693721                    $(this).children().length > 1 && $(this).children().toggleClass("hidden");
    694722                } );
    695             } );</script>'
     723            } );</script>';
    696724
    697725            ?>
  • sites/trunk/wordpress.org/public_html/wp-content/plugins/plugin-directory/class-template.php

    r12999 r13033  
    908908            'merged-into-core'              => __( 'Merged into Core', 'wporg-plugins' ),
    909909            'unused'                        => __( 'Unused', 'wporg-plugins' ),
     910        );
     911    }
     912
     913    /**
     914     * Returns the reasons for rejecting a plugin.
     915     *
     916     * @return array Rejection reason labels.
     917     */
     918    public static function get_rejection_reasons() {
     919        return array(
     920            '3-month'              => '3 months without completion',
     921            'core-supports'        => 'Code is already in core',
     922            'duplicate-copy'       => 'Duplicate (copy) of another Plugin',
     923            'library-or-framework' => 'Framework or Library Plugin',
     924            'generic'              => "Something we're just not hosting",
     925            'duplicate'            => 'New/renamed version of their own plugin',
     926            'wp-cli'               => 'WP-CLI Only Plugins',
     927            'storefront'           => 'Storefront',
     928            'not-owner'            => 'Not the submitters plugin',
     929            'script-insertion'     => 'Script Insertion Plugins are Dangerous',
     930            'demo'                 => 'Test/Demo plugin (non functional)',
     931            'translation'          => 'Translation of existing plugin',
     932            'banned'               => 'Banned developer trying to sneak back in',
     933            'author-request'       => 'Author requested not to continue',
     934            'other'                => 'OTHER: See notes',
    910935        );
    911936    }
  • sites/trunk/wordpress.org/public_html/wp-content/plugins/plugin-directory/email/class-plugin-rejected.php

    r11438 r13033  
    1919
    2020    function body() {
     21        // NOTE: $this->args['reason'] has rejection reason if applicable.
     22
    2123        /* translators: 1: plugin name, 2: plugin permalink, 3: date of submission, 4: plugins@wordpress.org */
    2224        $email_text = __(
Note: See TracChangeset for help on using the changeset viewer.