Ticket #3029: 3029.patch
File 3029.patch, 36.6 KB (added by , 7 years ago) |
---|
-
wordpress.org/public_html/wp-content/plugins/plugin-directory/admin/class-customizations.php
48 48 add_action( 'add_meta_boxes', array( $this, 'register_admin_metaboxes' ), 10, 2 ); 49 49 add_action( 'do_meta_boxes', array( $this, 'replace_title_global' ) ); 50 50 51 add_filter( 'postbox_classes_plugin_internal-notes', array( __NAMESPACE__ . '\Metabox\Internal_Notes', 'postbox_classes' ) ); 52 add_filter( 'postbox_classes_plugin_plugin-committers', array( __NAMESPACE__ . '\Metabox\Committers', 'postbox_classes' ) ); 53 add_filter( 'wp_ajax_add-committer', array( __NAMESPACE__ . '\Metabox\Committers', 'add_committer' ) ); 54 add_filter( 'wp_ajax_delete-committer', array( __NAMESPACE__ . '\Metabox\Committers', 'remove_committer' ) ); 51 add_filter( 'postbox_classes_plugin_internal-notes', array( __NAMESPACE__ . '\Metabox\Internal_Notes', 'postbox_classes' ) ); 52 add_filter( 'postbox_classes_plugin_plugin-committers', array( __NAMESPACE__ . '\Metabox\Committers', 'postbox_classes' ) ); 53 add_filter( 'postbox_classes_plugin_plugin-support-reps', array( __NAMESPACE__ . '\Metabox\Support_Reps', 'postbox_classes' ) ); 54 add_filter( 'wp_ajax_add-committer', array( __NAMESPACE__ . '\Metabox\Committers', 'add_committer' ) ); 55 add_filter( 'wp_ajax_delete-committer', array( __NAMESPACE__ . '\Metabox\Committers', 'remove_committer' ) ); 56 add_filter( 'wp_ajax_add-support-rep', array( __NAMESPACE__ . '\Metabox\Support_Reps', 'add_support_rep' ) ); 57 add_filter( 'wp_ajax_delete-support-rep', array( __NAMESPACE__ . '\Metabox\Support_Reps', 'remove_support_rep' ) ); 55 58 add_action( 'wp_ajax_plugin-author-lookup', array( __NAMESPACE__ . '\Metabox\Author', 'lookup_author' ) ); 56 59 57 60 } … … 114 117 wp_enqueue_style( 'plugin-admin-post-css', plugins_url( 'css/edit-form.css', Plugin_Directory\PLUGIN_FILE ), array( 'edit' ), 4 ); 115 118 wp_enqueue_script( 'plugin-admin-post-js', plugins_url( 'js/edit-form.js', Plugin_Directory\PLUGIN_FILE ), array( 'wp-util', 'wp-lists' ), 5 ); 116 119 wp_localize_script( 'plugin-admin-post-js', 'pluginDirectory', array( 117 'approvePluginAYS' => __( 'Are you sure you want to approve this plugin?', 'wporg-plugins' ), 118 'rejectPluginAYS' => __( 'Are you sure you want to reject this plugin?', 'wporg-plugins' ), 119 'removeCommitterAYS' => __( 'Are you sure you want to remove this committer?', 'wporg-plugins' ), 120 'approvePluginAYS' => __( 'Are you sure you want to approve this plugin?', 'wporg-plugins' ), 121 'rejectPluginAYS' => __( 'Are you sure you want to reject this plugin?', 'wporg-plugins' ), 122 'removeCommitterAYS' => __( 'Are you sure you want to remove this committer?', 'wporg-plugins' ), 123 'removeSupportRepAYS' => __( 'Are you sure you want to remove this support rep?', 'wporg-plugins' ), 120 124 ) ); 121 125 break; 122 126 … … 436 440 'plugin', 'side' 437 441 ); 438 442 443 add_meta_box( 444 'plugin-support-reps', 445 __( 'Plugin Support Reps', 'wporg-plugins' ), 446 array( __NAMESPACE__ . '\Metabox\Support_Reps', 'display' ), 447 'plugin', 'side' 448 ); 439 449 } 440 450 441 451 // Remove unnecessary metaboxes. -
wordpress.org/public_html/wp-content/plugins/plugin-directory/admin/list-table/class-committers.php
22 22 parent::__construct( array( 23 23 'singular' => 'committer', 24 24 'plural' => 'committers', 25 'screen' => isset( $args['screen'] ) ? $args['screen'] : null,25 'screen' => isset( $args['screen'] ) ? $args['screen'] : 'plugin', 26 26 ) ); 27 27 } 28 28 -
wordpress.org/public_html/wp-content/plugins/plugin-directory/admin/list-table/class-support-reps.php
1 <?php 2 namespace WordPressdotorg\Plugin_Directory\Admin\List_Table; 3 use WordPressdotorg\Plugin_Directory\Tools; 4 5 _get_list_table( 'WP_List_Table' ); 6 7 /** 8 * Comments list table for comments meta box. 9 * 10 * @package WordPressdotorg\Plugin_Directory\Admin\List_Table 11 */ 12 class Support_Reps extends \WP_List_Table { 13 14 /** 15 * Constructor. 16 * 17 * @see WP_List_Table::__construct() for more information on default arguments. 18 * 19 * @param array $args An associative array of arguments. 20 */ 21 public function __construct( $args = array() ) { 22 parent::__construct( array( 23 'singular' => 'support_rep', 24 'plural' => 'support_reps', 25 'screen' => isset( $args['screen'] ) ? $args['screen'] : 'plugin', 26 ) ); 27 } 28 29 /** 30 * Check the current user's permissions. 31 * 32 * @return bool 33 */ 34 public function ajax_user_can() { 35 return current_user_can( 'plugin_remove_support_rep' ); 36 } 37 38 /** 39 * Prepare the users list for display. 40 * 41 * @access public 42 * 43 * @global string $role 44 * @global string $usersearch 45 */ 46 public function prepare_items() { 47 $plugin_slug = get_post()->post_name; 48 if ( ! $plugin_slug ) { 49 return; 50 } 51 $existing_support_reps = Tools::get_plugin_support_reps( $plugin_slug ); 52 $this->items = array_map( function ( $user ) { 53 return new \WP_User( $user ); 54 }, $existing_support_reps ); 55 } 56 57 /** 58 * Output 'no users' message. 59 * 60 * @access public 61 */ 62 public function no_items() { 63 _e( 'No support reps found.', 'wporg-plugins' ); 64 } 65 66 /** 67 * 68 * @return array 69 */ 70 protected function get_table_classes() { 71 $classes = parent::get_table_classes(); 72 $classes[] = 'wp-list-table'; 73 74 unset( $classes[ array_search( 'striped', $classes ) ] ); 75 76 return $classes; 77 } 78 79 /** 80 * 81 * @return array 82 */ 83 protected function get_column_info() { 84 return array( 85 array( 86 'avatar' => __( 'Avatar', 'wporg-plugins' ), 87 'username' => __( 'Username', 'wporg-plugins' ), 88 ), 89 array(), 90 'username', 91 ); 92 } 93 94 /** 95 * 96 */ 97 public function display() { 98 ?> 99 <table class="<?php echo implode( ' ', $this->get_table_classes() ); ?>"> 100 <colgroup> 101 <col width="40px" /> 102 <col /> 103 </colgroup> 104 <tbody id="the-support-rep-list" data-wp-lists="list:support-rep"> 105 <?php $this->display_rows_or_placeholder(); ?> 106 </tbody> 107 </table> 108 <?php 109 } 110 111 /** 112 * Generate the list table rows. 113 * 114 * @access public 115 */ 116 public function display_rows() { 117 foreach ( $this->items as $user_object ) { 118 echo "\n\t" . $this->single_row( $user_object ); 119 } 120 ?> 121 <tr id="add-support-rep" class="add-support-rep wp-hidden-children"> 122 <td colspan="2"> 123 <button type="button" id="add-support-rep-toggle" class="button-link"><?php _e( '+ Add New Support Rep', 'wporg-plugins' ); ?></button> 124 <p class="wp-hidden-child"> 125 <?php wp_nonce_field( 'add-support-rep', '_ajax_nonce', false ); ?> 126 <span id="support-rep-error" class="notice notice-alt notice-error" style="display:none;"></span> 127 <label> 128 <input type="text" name="add_support_rep" class="form-required" value="" aria-required="true" placeholder="<?php esc_attr_e( 'WordPress.org username', 'wporg-plugins' ); ?>"> 129 <span class="screen-reader-text"><?php _e( 'Add a new support rep', 'wporg-plugins' ); ?></span> 130 </label> 131 <input type="button" id="add-support-rep-submit" class="button" data-wp-lists="add:the-support-rep-list:add-support-rep::post_id=<?php echo get_post()->ID; ?>" value="<?php _e( 'Add Support Rep', 'wporg-plugins' ); ?>"> 132 </p> 133 </td> 134 </tr> 135 <?php 136 } 137 138 /** 139 * Generate HTML for a single row on the users.php admin panel. 140 * 141 * @access public 142 * 143 * @param object $user_object The current user object. 144 * @return string Output for a single row. 145 */ 146 public function single_row( $user_object ) { 147 if ( ! ( $user_object instanceof \WP_User ) ) { 148 $user_object = get_userdata( (int) $user_object ); 149 } 150 $user_object->filter = 'display'; 151 list( $columns, $hidden, $primary ) = $this->get_column_info(); 152 153 // Set up the hover actions for this support rep. 154 $actions = array(); 155 156 // Check if the support rep for this row is removable. 157 $post_id = get_post()->ID; 158 if ( current_user_can( 'plugin_remove_support_rep', $post_id ) && $user_object->ID != get_current_user_id() ) { 159 $actions['delete'] = "<a class='submitremove' data-wp-lists='delete:the-support-rep-list:support-rep-{$user_object->ID}:faafaa:post_id={$post_id}' href='" . wp_nonce_url( 'users.php?action=remove&support-rep=' . $user_object->ID, "remove-support-rep-{$user_object->ID}" ) . "'>" . __( 'Remove', 'wporg-plugins' ) . "</a>"; 160 } 161 162 /** 163 * Filter the action links displayed under each support rep in the Support Reps list table. 164 * 165 * @param array $actions An array of action links to be displayed. 166 * @param \WP_User $user_object WP_User object for the currently-listed support rep. 167 */ 168 $actions = apply_filters( 'support_rep_row_actions', $actions, $user_object ); 169 170 $row = "<tr id='support-rep-$user_object->ID'>"; 171 172 foreach ( $columns as $column_name => $column_display_name ) { 173 $data = 'data-colname="' . wp_strip_all_tags( $column_display_name ) . '"'; 174 $classes = "$column_name column-$column_name"; 175 176 if ( $primary === $column_name ) { 177 $classes .= ' has-row-actions column-primary'; 178 } 179 if ( in_array( $column_name, $hidden ) ) { 180 $classes .= ' hidden'; 181 } 182 183 $row .= "<td class='$classes' $data>"; 184 switch ( $column_name ) { 185 case 'avatar': 186 $row .= get_avatar( $user_object->ID, 32 ); 187 break; 188 189 case 'username': 190 $row .= sprintf( '<strong><a href="%s">%s</a></strong><br /><%s>', 191 esc_url( '//profiles.wordpress.org/' . $user_object->user_nicename ), 192 $user_object->user_login, 193 $user_object->user_email 194 ); 195 break; 196 197 default: 198 /** 199 * Filter the display output of custom columns in the Users list table. 200 * 201 * @param string $output Custom column output. Default empty. 202 * @param string $column_name Column name. 203 * @param int $user_id ID of the currently-listed user. 204 */ 205 $row .= apply_filters( 'manage_support_reps_custom_column', '', $column_name, $user_object->ID ); 206 } 207 if ( $primary === $column_name ) { 208 $row .= $this->row_actions( $actions ); 209 } 210 $row .= '</td>'; 211 } 212 $row .= '</tr>'; 213 214 return $row; 215 } 216 217 /** 218 * Gets the name of the default primary column. 219 * 220 * @access protected 221 * 222 * @return string Name of the default primary column, in this case, 'username'. 223 */ 224 protected function get_default_primary_column_name() { 225 return 'username'; 226 } 227 } -
wordpress.org/public_html/wp-content/plugins/plugin-directory/admin/metabox/class-support-reps.php
1 <?php 2 namespace WordPressdotorg\Plugin_Directory\Admin\Metabox; 3 use WordPressdotorg\Plugin_Directory\Admin\List_Table; 4 use WordPressdotorg\Plugin_Directory\Tools; 5 6 /** 7 * The Plugin Support Reps admin metabox. 8 * 9 * @package WordPressdotorg\Plugin_Directory\Admin\Metabox 10 */ 11 class Support_Reps { 12 13 /** 14 * Filters the postbox classes for custom comment meta boxes. 15 * 16 * @param array $classes An array of postbox classes. 17 * @return array 18 */ 19 public static function postbox_classes( $classes ) { 20 $classes[] = 'support-reps-meta-box'; 21 22 return array_filter( $classes ); 23 } 24 25 /** 26 * Displays a list of support reps for the current plugin. 27 */ 28 public static function display() { 29 $list = new List_Table\Support_Reps(); 30 $list->prepare_items(); 31 $list->display(); 32 } 33 34 /** 35 * Ajax handler for adding a new support rep. 36 */ 37 public static function add_support_rep() { 38 $login = isset( $_POST['add_support_rep'] ) ? sanitize_user( $_POST['add_support_rep'] ) : ''; 39 $post_id = isset( $_POST['post_id'] ) ? (int) $_POST['post_id'] : 0; 40 41 check_ajax_referer( 'add-support-rep' ); 42 43 if ( ! current_user_can( 'plugin_add_support_rep', $post_id ) || 'publish' !== get_post_status( $post_id ) ) { 44 wp_die( -1 ); 45 } 46 47 global $post; 48 49 $response = new \WP_Ajax_Response(); 50 $post = get_post( $post_id ); 51 52 if ( ! $support_rep = get_user_by( 'login', $login ) ) { 53 $response->add( array( 54 'what' => 'support_rep', 55 'data' => new \WP_Error( 'error', sprintf( __( 'The user %s does not exist.', 'wporg-plugins' ), '<code>' . $login . '</code>' ) ), 56 ) ); 57 $response->send(); 58 } 59 60 $result = Tools::add_plugin_support_rep( $post->post_name, $support_rep ); 61 62 if ( ! $result ) { 63 $message = __( 'An error has occurred. Please reload the page and try again.', 'wporg-plugins' ); 64 65 $response->add( array( 66 'what' => 'support_rep', 67 'data' => new \WP_Error( 'error', $message ), 68 ) ); 69 $response->send(); 70 } 71 72 $wp_list_table = new List_Table\Support_Reps(); 73 74 $response->add( array( 75 'what' => 'support_rep', 76 'id' => $support_rep->ID, 77 'data' => $wp_list_table->single_row( $support_rep ), 78 'position' => -1, 79 ) ); 80 $response->send(); 81 } 82 83 /** 84 * Ajax handler for removing a support rep. 85 */ 86 public static function remove_support_rep() { 87 $id = isset( $_POST['id'] ) ? (int) $_POST['id'] : 0; 88 $post_id = isset( $_POST['post_id'] ) ? (int) $_POST['post_id'] : 0; 89 90 check_ajax_referer( "remove-support-rep-$id" ); 91 92 if ( ! current_user_can( 'plugin_remove_support_rep', $post_id ) || 'publish' !== get_post_status( $post_id ) ) { 93 wp_die( -1 ); 94 } 95 96 $response = new \WP_Ajax_Response(); 97 $plugin_slug = get_post( $post_id )->post_name; 98 99 if ( ! $support_rep = get_user_by( 'id', $id ) ) { 100 $response->add( array( 101 'what' => 'support_rep', 102 'data' => new \WP_Error( 'error', __( 'The specified user does not exist.', 'wporg-plugins' ) ), 103 ) ); 104 $response->send(); 105 } 106 107 $result = Tools::remove_plugin_support_rep( $plugin_slug, $support_rep ); 108 109 wp_die( $result ); 110 } 111 } -
wordpress.org/public_html/wp-content/plugins/plugin-directory/api/class-base.php
20 20 new Routes\Query_Plugins(); 21 21 new Routes\SVN_Access(); 22 22 new Routes\Plugin_Committers(); 23 new Routes\Plugin_Support_Reps(); 23 24 } 24 25 25 26 /** -
wordpress.org/public_html/wp-content/plugins/plugin-directory/api/routes/class-plugin-support-reps.php
1 <?php 2 namespace WordPressdotorg\Plugin_Directory\API\Routes; 3 use WordPressdotorg\Plugin_Directory\Plugin_Directory; 4 use WordPressdotorg\Plugin_Directory\Template; 5 use WordPressdotorg\Plugin_Directory\Tools; 6 use WordPressdotorg\Plugin_Directory\API\Base; 7 use WP_REST_Server; 8 use WP_Error; 9 use WP_User; 10 11 12 /** 13 * An API Endpoint to manage plugin support reps. 14 * 15 * @package WordPressdotorg_Plugin_Directory 16 */ 17 class Plugin_Support_Reps extends Base { 18 19 function __construct() { 20 register_rest_route( 'plugins/v1', '/plugin/(?P<plugin_slug>[^/]+)/support-reps/?', array( 21 array( 22 'methods' => WP_REST_Server::READABLE, 23 'callback' => array( $this, 'list_support_reps' ), 24 'permission_callback' => function( $request ) { 25 return current_user_can( 26 'plugin_admin_edit', 27 Plugin_Directory::get_plugin_post( $request['plugin_slug'] ) 28 ); 29 }, 30 'args' => array( 31 'plugin_slug' => array( 32 'validate_callback' => array( $this, 'validate_plugin_slug_callback' ), 33 'required' => true, 34 ), 35 ) 36 ), 37 array( 38 'methods' => WP_REST_Server::CREATABLE, 39 'callback' => array( $this, 'add_support_rep' ), 40 'permission_callback' => function( $request ) { 41 return current_user_can( 42 'plugin_add_support_rep', 43 Plugin_Directory::get_plugin_post( $request['plugin_slug'] ) 44 ); 45 }, 46 'args' => array( 47 'plugin_slug' => array( 48 'validate_callback' => array( $this, 'validate_plugin_slug_callback' ), 49 'required' => true, 50 ), 51 ) 52 ) 53 ) ); 54 55 register_rest_route( 'plugins/v1', '/plugin/(?P<plugin_slug>[^/]+)/support-reps/(?P<support_rep>[^/]+)/?', array( 56 'methods' => WP_REST_Server::DELETABLE, 57 'callback' => array( $this, 'remove_support_rep' ), 58 'permission_callback' => function( $request ) { 59 return current_user_can( 60 'plugin_remove_support_rep', 61 Plugin_Directory::get_plugin_post( $request['plugin_slug'] ) 62 ); 63 }, 64 'args' => array( 65 'plugin_slug' => array( 66 'validate_callback' => array( $this, 'validate_plugin_slug_callback' ), 67 'required' => true, 68 ), 69 'support_rep' => array( 70 'validate_callback' => array( $this, 'validate_user_slug_callback' ), 71 'required' => true, 72 ) 73 ) 74 ) ); 75 } 76 77 /** 78 * 79 */ 80 function list_support_reps( $request ) { 81 $plugin_slug = $request['plugin_slug']; 82 83 $support_reps = array(); 84 foreach ( (array) Tools::get_plugin_support_reps( $plugin_slug ) as $user_nicename ) { 85 $user = get_user_by( 'slug', $user_nicename ); 86 $support_reps[] = $this->user_support_rep_details( $user ); 87 } 88 89 return $support_reps; 90 } 91 92 function add_support_rep( $request ) { 93 $user = new WP_User( $request['support_rep'] ); 94 if ( ! $user->exists() ) { 95 return new WP_Error( 'plugin_user_not_found', __( 'The provided user could not be found.', 'wporg-plugins' ) ); 96 } 97 98 $plugin_slug = $request['plugin_slug']; 99 100 if ( ! Tools::add_plugin_support_rep( $plugin_slug, $user ) ) { 101 return new WP_Error( 'failed', __( 'The operation failed. Please try again.', 'wporg-plugins' ) ); 102 } 103 104 return $this->user_support_rep_details( $user ); 105 } 106 107 function remove_support_rep( $request ) { 108 $user = new WP_User( $request['support_rep'] ); 109 if ( ! $user->exists() ) { 110 return new WP_Error( 'plugin_user_not_found', __( 'The provided user could not be found.', 'wporg-plugins' ) ); 111 } 112 113 $plugin_slug = $request['plugin_slug']; 114 115 $result = Tools::remove_plugin_support_rep( $plugin_slug, $user ); 116 if ( ! $result ) { 117 return new WP_Error( 'failed', __( 'The operation failed. Please try again.', 'wporg-plugins' ) ); 118 } 119 120 return true; 121 } 122 123 /** 124 * Validate that a user by the given slug exists. 125 */ 126 function validate_user_slug_callback( $value ) { 127 return (bool) get_user_by( 'slug', $value ); 128 } 129 130 /** 131 * Helper function to return a support rep object 132 */ 133 function user_support_rep_details( $user ) { 134 $data = array( 135 'nicename' => $user->user_nicename, 136 'profile' => esc_url( 'https://profiles.wordpress.org/' . $user->user_nicename ), 137 'avatar' => get_avatar_url( $user->ID, 32 ), 138 'name' => Template::encode( $user->display_name ) 139 ); 140 141 if ( current_user_can( 'plugin_review' ) ) { 142 $data['email'] = $user->user_email; 143 } 144 145 return $data; 146 } 147 148 } 149 150 -
wordpress.org/public_html/wp-content/plugins/plugin-directory/class-capabilities.php
26 26 case 'plugin_admin_edit': 27 27 case 'plugin_add_committer': 28 28 case 'plugin_remove_committer': 29 case 'plugin_add_support_rep': 30 case 'plugin_remove_support_rep': 29 31 $plugin_edit_cap = true; 30 32 // Fall through 31 33 -
wordpress.org/public_html/wp-content/plugins/plugin-directory/class-plugin-directory.php
260 260 ), 261 261 ) ); 262 262 263 register_taxonomy( 'plugin_support_reps', array( 'plugin', 'force-count-to-include-all-post_status' ), array( 264 'hierarchical' => false, 265 'query_var' => 'plugin_support_rep', 266 'rewrite' => false, 267 'labels' => array( 268 'name' => __( 'Support Reps', 'wporg-plugins' ), 269 'singular_name' => __( 'Support Rep', 'wporg-plugins' ), 270 ), 271 'public' => true, 272 'show_ui' => true, 273 'show_admin_column' => true, 274 'capabilities' => array( 275 'assign_terms' => 'do_not_allow', 276 ), 277 ) ); 278 263 279 register_taxonomy( 'plugin_tags', array( 'plugin', 'force-count-to-include-all-post_status' ), array( 264 280 'hierarchical' => false, 265 281 'query_var' => 'plugin_tags', … … 547 563 register_widget( __NAMESPACE__ . '\Widgets\Support' ); 548 564 register_widget( __NAMESPACE__ . '\Widgets\Committers' ); 549 565 register_widget( __NAMESPACE__ . '\Widgets\Contributors' ); 566 register_widget( __NAMESPACE__ . '\Widgets\Support_Reps' ); 550 567 } 551 568 552 569 /** -
wordpress.org/public_html/wp-content/plugins/plugin-directory/class-tools.php
227 227 } 228 228 229 229 /** 230 * Retrieve a list of support reps for a specific plugin. 231 * 232 * @static 233 * 234 * @param string $plugin_slug The plugin slug. 235 * @return array The list of user_nicename's which are support reps. 236 */ 237 public static function get_plugin_support_reps( $plugin_slug ) { 238 if ( ! $plugin_slug ) { 239 return array(); 240 } 241 242 if ( false === ( $support_reps = wp_cache_get( $plugin_slug, 'plugin-support-reps' ) ) ) { 243 $post = Plugin_Directory::get_plugin_post( $plugin_slug ); 244 $support_reps = wp_get_object_terms( $post->ID, 'plugin_support_reps', array( 'fields' => 'names' ) ); 245 246 wp_cache_set( $plugin_slug, $support_reps, 'plugin-support-reps', 12 * HOUR_IN_SECONDS ); 247 } 248 249 return $support_reps; 250 } 251 252 /** 253 * Add a user as a support rep for a plugin. 254 * 255 * @static 256 * 257 * @param string $plugin_slug The plugin slug. 258 * @param string|\WP_User $user The user to add. 259 * @return bool 260 */ 261 public static function add_plugin_support_rep( $plugin_slug, $user ) { 262 if ( ! $user instanceof \WP_User ) { 263 $user = new \WP_User( $user ); 264 } 265 266 if ( ! $user->exists() || ! $plugin_slug ) { 267 return false; 268 } 269 270 $post = Plugin_Directory::get_plugin_post( $plugin_slug ); 271 272 if ( ! $post ) { 273 return false; 274 } 275 276 $result = wp_add_object_terms( $post->ID, $user->user_nicename, 'plugin_support_reps' ); 277 278 return $result; 279 } 280 281 /** 282 * Remove a user as a support rep for a plugin. 283 * 284 * @static 285 * 286 * @param string $plugin_slug The plugin slug. 287 * @param string|\WP_User $user The user to remove. 288 * @return bool 289 */ 290 public static function remove_plugin_support_rep( $plugin_slug, $user ) { 291 if ( ! $user instanceof \WP_User ) { 292 $user = new \WP_User( $user ); 293 } 294 295 if ( ! $user->exists() || ! $plugin_slug ) { 296 return false; 297 } 298 299 $post = Plugin_Directory::get_plugin_post( $plugin_slug ); 300 301 if ( ! $post ) { 302 return false; 303 } 304 305 $result = wp_remove_object_terms( $post->ID, $user->user_nicename, 'plugin_support_reps' ); 306 307 return $result; 308 } 309 310 /** 230 311 * Subscribe/Unsubscribe a user to a plugins commits. 231 312 * 232 313 * Plugin Committers are automatically subscribed to plugin commit -
wordpress.org/public_html/wp-content/plugins/plugin-directory/css/edit-form.css
74 74 75 75 #poststuff .comments-meta-box.postbox .inside, 76 76 #poststuff .committers-meta-box.postbox .inside, 77 #poststuff .support-reps-meta-box.postbox .inside, 77 78 .comments-meta-box .column-comment p { 78 79 margin: 0; 79 80 padding: 0; … … 102 103 } 103 104 104 105 .comments-meta-box .comments-box, 105 .committers-meta-box .wp-list-table { 106 .committers-meta-box .wp-list-table, 107 .support-reps-meta-box .wp-list-table { 106 108 border: 0 none; 107 109 } 108 110 … … 137 139 } 138 140 } 139 141 140 /* Committers meta box */ 141 .add-committer { 142 /* Committers and Support Reps meta boxes */ 143 .add-committer, 144 .add-support-rep { 142 145 padding: 0 12px 12px; 143 146 } 144 147 145 .add-committer .button-link { 148 .add-committer .button-link, 149 .add-support-rep .button-link { 146 150 font-weight: 600; 147 151 margin: 10px 0; 148 152 } 149 153 150 .add-committer input[type="text"] { 154 .add-committer input[type="text"], 155 .add-support-rep input[type="text"] { 151 156 margin: 0 0 1em; 152 157 max-width: 260px; 153 158 vertical-align: baseline; … … 154 159 width: 100%; 155 160 } 156 161 157 .add-committer .notice { 162 .add-committer .notice, 163 .add-support-rep .notice { 158 164 display: block; 159 165 padding: 0.5em 0 0.5em 1em; 160 166 } … … 264 270 background-color: #fde3e3; 265 271 } 266 272 267 .plugin-committers > div { 273 .plugin-committers > div, 274 .plugin-support-reps > div { 268 275 overflow-x: hidden; 269 276 white-space: nowrap; 270 277 } 271 278 272 .plugin-committer-email { 279 .plugin-committer-email, 280 .plugin-support-rep-email { 273 281 font-size: smaller; 274 282 } 275 283 -
wordpress.org/public_html/wp-content/plugins/plugin-directory/js/edit-form.js
29 29 $( 'input[name="add_committer"]', '#add-committer' ).val( '' ).focus(); 30 30 } ); 31 31 32 $( '#add-support-rep-toggle' ).on( 'click', PluginEdit.toggleSupportRepForm ); 33 34 $( '#the-support-rep-list' ).wpList({ 35 alt: false, 36 confirm: function( element, settings, action ) { 37 if ( 'support-rep' === settings.what && 'delete' === action ) { 38 return confirm( pluginDirectory.removeSupportRepAYS ); 39 } 40 return true; 41 }, 42 addAfter: PluginEdit.supportRepRequestAfter, 43 delAfter: PluginEdit.supportRepRequestAfter 44 }).on( 'wpListAddEnd', function() { 45 $( 'input[name="add_support_rep"]', '#add-support-rep' ).val( '' ).focus(); 46 } ); 47 32 48 $( '#contact-author' ).appendTo( '#plugin-review .inside' ); 33 49 }, 34 50 … … 108 124 } else { 109 125 $( '#committer-error' ).empty().hide(); 110 126 } 127 }, 128 129 toggleSupportRepForm: function( event ) { 130 var $form = $( '#add-support-rep' ); 131 132 // Show/hide form. 133 $form.toggleClass( 'wp-hidden-children' ); 134 135 // Focus on the input field, and on enter add the support rep, don't save post. 136 $( 'input[name="add_support_rep"]', $form ).focus().on( 'keydown', function( event ) { 137 if ( 13 === event.which ) { 138 event.preventDefault(); 139 $( '#add-support-rep-submit', $form ).click(); 140 } 141 } ); 142 }, 143 144 supportRepRequestAfter: function( response, data ) { 145 if ( data.parsed.errors ) { 146 $( '#support-rep-error' ).html( data.parsed.responses[0].errors[0].message ).show(); 147 } else { 148 $( '#support-rep-error' ).empty().hide(); 149 } 111 150 } 112 151 113 152 }; -
wordpress.org/public_html/wp-content/plugins/plugin-directory/widgets/class-support-reps.php
1 <?php 2 namespace WordPressdotorg\Plugin_Directory\Widgets; 3 use WordPressdotorg\Plugin_Directory\Template; 4 use WordPressdotorg\Plugin_Directory\Tools; 5 6 /** 7 * A Widget to display support rep information about a plugin. 8 * 9 * @package WordPressdotorg\Plugin_Directory\Widgets 10 */ 11 class Support_Reps extends \WP_Widget { 12 /** 13 * Support Reps constructor. 14 */ 15 public function __construct() { 16 parent::__construct( 'plugin_support_reps', __( 'Plugin Support Reps', 'wporg-plugins' ), array( 17 'classname' => 'plugin-support-reps', 18 'description' => __( 'Displays support rep information.', 'wporg-plugins' ), 19 ) ); 20 } 21 22 /** 23 * Outputs the content of the widget. 24 * 25 * @param array $args 26 * @param array $instance 27 */ 28 public function widget( $args, $instance ) { 29 $post = get_post(); 30 31 $support_reps = Tools::get_plugin_support_reps( $post->post_name ); 32 $support_reps = array_map( function ( $user_login ) { 33 return get_user_by( 'slug', $user_login ); 34 }, $support_reps ); 35 36 if ( current_user_can( 'plugin_add_support_rep', $post ) || current_user_can( 'plugin_remove_support_rep', $post ) ) { 37 wp_enqueue_script( 'wporg-plugins-support-reps', plugins_url( 'js/support-reps.js', __FILE__ ), array( 'wp-util' ), true ); 38 wp_localize_script( 'wporg-plugins-support-reps', 'supportRepsWidget', array( 39 'restUrl' => get_rest_url(), 40 'restNonce' => wp_create_nonce( 'wp_rest' ), 41 'pluginSlug' => $post->post_name, 42 'removeSupportRepAYS' => __( 'Are you sure you want to remove this support rep?', 'wporg-plugins' ), 43 ) ); 44 } 45 46 $title = apply_filters( 'widget_title', empty( $instance['title'] ) ? __( 'Support Reps', 'wporg-plugins' ) : $instance['title'], $instance, $this->id_base ); 47 48 echo $args['before_widget']; 49 echo $args['before_title'] . $title . $args['after_title']; 50 ?> 51 52 <ul id="support-rep-list" class="support-rep-list"> 53 54 <?php foreach ( $support_reps as $support_rep ) : ?> 55 <li data-user="<?php echo esc_attr( $support_rep->user_nicename ); ?>"> 56 <?php echo get_avatar( $support_rep->ID, 32 ); ?> 57 <a href="<?php echo esc_url( 'https://profiles.wordpress.org/' . $support_rep->user_nicename ); ?>"> 58 <?php echo Template::encode( $support_rep->display_name ); ?> 59 </a><br> 60 61 <?php if ( current_user_can( 'plugin_remove_support_rep', $post ) ) : ?> 62 <small> 63 <?php echo current_user_can( 'plugin_review' ) ? esc_html( $support_rep->user_email ) . ' ' : ''; ?> 64 <button class="button-link remove"><?php _e( 'Remove', 'wporg-plugins' ); ?></button> 65 </small> 66 <?php endif; ?> 67 </li> 68 <?php endforeach; ?> 69 70 <?php if ( current_user_can( 'plugin_add_support_rep', $post ) ) : ?> 71 <li class="new"> 72 <form id="add-support-rep" action="POST"> 73 <input type="text" name="support_rep" placeholder="<?php esc_attr_e( 'Login, Slug, or Email.', 'wporg-plugins' ); ?>"> 74 <button type="submit" class="button button-secondary"><?php esc_attr_e( 'Add', 'wporg-plugins' ); ?></button> 75 </form> 76 77 <script id="tmpl-new-support-rep" type="text/template"> 78 <li data-user="{{ data.nicename }}"> 79 <a class="profile" href="{{ data.profile }}"> 80 <img src="{{ data.avatar }}" class="avatar avatar-32 photo" height="32" width="32"> 81 {{ data.name }} 82 </a><br> 83 <small> 84 <# if ( data.email ) { #> 85 <span class="email">{{ data.email }}</span> 86 <# } #> 87 <button class="button-link remove"><?php _e( 'Remove', 'wporg-plugins' ); ?></button> 88 </small> 89 </li> 90 </script> 91 </li> 92 <?php endif; ?> 93 </ul> 94 95 <?php 96 echo $args['after_widget']; 97 } 98 } -
wordpress.org/public_html/wp-content/plugins/plugin-directory/widgets/js/support-reps.js
1 ( 2 /** 3 * @param {Object} $ 4 * @param {Object} wp 5 * @param {Object} pluginDir 6 * @param {String} pluginDir.restUrl 7 * @param {String} pluginDir.restNonce 8 * @param {String} pluginDir.pluginSlug 9 */ 10 function( $, wp, pluginDir ) { 11 var logError = function( result ) { 12 $( '.spinner' ).removeClass( 'spinner' ); 13 result = $.parseJSON( result.responseText ); 14 if ( typeof result.message !== 'undefined' ) { 15 alert( result.message ); 16 } 17 }; 18 19 $( '#support-rep-list' ) 20 .on( 'click', '.remove', function() { 21 if ( ! window.confirm( pluginDir.removeSupportRepAYS ) ) { 22 return; 23 } 24 25 var $row = $( this ).addClass( 'spinner' ).parents( 'li' ), 26 url = pluginDir.restUrl + 'plugins/v1/plugin/' + pluginDir.pluginSlug + '/support-reps/' + $row.data( 'user' ) + '/?_wpnonce=' + pluginDir.restNonce; 27 28 $.post( { 29 url: url, 30 method: 'DELETE', 31 } ).success( function( result ) { 32 if ( true === result ) { 33 $row.slideUp( 500, function() { 34 $row.remove() 35 } ); 36 } 37 } ).fail( logError ); 38 } ) 39 .on( 'submit', '#add-support-rep', function( event ) { 40 event.preventDefault(); 41 42 var $row = $( this ).parents( 'li' ), 43 $newUserInput = $row.find( 'input[name="support_rep"]' ), 44 $button = $row.find( '.button-small' ).addClass( 'spinner' ), 45 url = pluginDir.restUrl + 'plugins/v1/plugin/' + pluginDir.pluginSlug + '/support-reps/?_wpnonce=' + pluginDir.restNonce; 46 47 $.post( { 48 url: url, 49 dataType: 'json', 50 data: { 51 support_rep: $newUserInput.val() 52 } 53 } ).done( function( result ) { 54 if ( typeof result.name !== 'undefined' ) { 55 $row.before( wp.template( 'new-support-rep' )( result ) ); 56 $newUserInput.val( '' ); 57 $button.removeClass( 'spinner' ); 58 } 59 } ).fail( logError ); 60 } ); 61 } )( window.jQuery, window.wp, window.supportRepsWidget ); -
wordpress.org/public_html/wp-content/themes/pub/wporg-plugins/client/components/widget-area/widgets/committers/style.scss
1 .committer-list { 1 .committer-list, 2 .support-rep-list { 2 3 font-size: ms( -2 ); 3 4 list-style: none; 4 5 margin: 0; -
wordpress.org/public_html/wp-content/themes/pub/wporg-plugins/template-parts/plugin-sidebar-advanced.php
21 21 // If the user is not a contributor/committer for the plugin, we'll show the Donate metabox instead of the committer metabox. 22 22 if ( current_user_can( 'plugin_admin_view', $post ) ) { 23 23 the_widget( 'WordPressdotorg\Plugin_Directory\Widgets\Committers', array(), $widget_args ); 24 the_widget( 'WordPressdotorg\Plugin_Directory\Widgets\Support_Reps', array(), $widget_args ); 24 25 } else { 25 26 the_widget( 'WordPressdotorg\Plugin_Directory\Widgets\Donate', array(), $widget_args ); 26 27 }