Ticket #33154: 33154.3.diff
File 33154.3.diff, 10.5 KB (added by , 10 years ago) |
---|
-
src/wp-admin/includes/class-wp-comments-list-table.php
class WP_Comments_List_Table extends WP_ 429 429 * @global WP_Post $post 430 430 * @global object $comment 431 431 * 432 432 * @param object $a_comment 433 433 */ 434 434 public function single_row( $a_comment ) { 435 435 global $post, $comment; 436 436 437 437 $comment = $a_comment; 438 438 $the_comment_class = wp_get_comment_status( $comment->comment_ID ); 439 439 if ( ! $the_comment_class ) { 440 440 $the_comment_class = ''; 441 441 } 442 442 $the_comment_class = join( ' ', get_comment_class( $the_comment_class, $comment->comment_ID, $comment->comment_post_ID ) ); 443 443 444 $post = get_post( $comment->comment_post_ID );445 446 444 $this->user_can = current_user_can( 'edit_comment', $comment->comment_ID ); 447 445 448 446 echo "<tr id='comment-$comment->comment_ID' class='$the_comment_class'>"; 449 447 $this->single_row_columns( $comment ); 450 448 echo "</tr>\n"; 451 449 } 452 450 453 451 /** 454 452 * Generate and display row actions links. 455 453 * 456 454 * @since 4.3.0 457 455 * @access protected 458 456 * 459 457 * @param object $comment Comment being acted upon. 460 458 * @param string $column_name Current column name. 461 459 * @param string $primary Primary column name. 462 460 * @return string|void Comment row actions output. 463 461 */ 464 462 protected function handle_row_actions( $comment, $column_name, $primary ) { 465 463 global $comment_status; 466 464 467 465 if ( $primary !== $column_name ) { 468 466 return ''; 469 467 } 470 468 471 469 if ( ! $this->user_can ) { 472 470 return; 473 471 } 474 472 475 $post = get_post();476 477 473 $the_comment_status = wp_get_comment_status( $comment->comment_ID ); 478 474 479 475 $out = ''; 480 476 481 477 $del_nonce = esc_html( '_wpnonce=' . wp_create_nonce( "delete-comment_$comment->comment_ID" ) ); 482 478 $approve_nonce = esc_html( '_wpnonce=' . wp_create_nonce( "approve-comment_$comment->comment_ID" ) ); 483 479 484 480 $url = "comment.php?c=$comment->comment_ID"; 485 481 486 482 $approve_url = esc_url( $url . "&action=approvecomment&$approve_nonce" ); 487 483 $unapprove_url = esc_url( $url . "&action=unapprovecomment&$approve_nonce" ); 488 484 $spam_url = esc_url( $url . "&action=spamcomment&$del_nonce" ); 489 485 $unspam_url = esc_url( $url . "&action=unspamcomment&$del_nonce" ); 490 486 $trash_url = esc_url( $url . "&action=trashcomment&$del_nonce" ); 491 487 $untrash_url = esc_url( $url . "&action=untrashcomment&$del_nonce" ); … … class WP_Comments_List_Table extends WP_ 522 518 if ( 'trash' == $the_comment_status ) { 523 519 $actions['untrash'] = "<a href='$untrash_url' data-wp-lists='delete:the-comment-list:comment-$comment->comment_ID:66cc66:untrash=1' class='vim-z vim-destructive'>" . __( 'Restore' ) . '</a>'; 524 520 } 525 521 526 522 if ( 'spam' == $the_comment_status || 'trash' == $the_comment_status || !EMPTY_TRASH_DAYS ) { 527 523 $actions['delete'] = "<a href='$delete_url' data-wp-lists='delete:the-comment-list:comment-$comment->comment_ID::delete=1' class='delete vim-d vim-destructive'>" . __( 'Delete Permanently' ) . '</a>'; 528 524 } else { 529 525 $actions['trash'] = "<a href='$trash_url' data-wp-lists='delete:the-comment-list:comment-$comment->comment_ID::trash=1' class='delete vim-d vim-destructive' title='" . esc_attr__( 'Move this comment to the trash' ) . "'>" . _x( 'Trash', 'verb' ) . '</a>'; 530 526 } 531 527 532 528 if ( 'spam' != $the_comment_status && 'trash' != $the_comment_status ) { 533 529 $actions['edit'] = "<a href='comment.php?action=editcomment&c={$comment->comment_ID}' title='" . esc_attr__( 'Edit comment' ) . "'>". __( 'Edit' ) . '</a>'; 534 530 535 531 $format = '<a data-comment-id="%d" data-post-id="%d" data-action="%s" class="%s" title="%s" href="#">%s</a>'; 536 532 537 $actions['quickedit'] = sprintf( $format, $comment->comment_ID, $ post->ID, 'edit', 'vim-q comment-inline',esc_attr__( 'Edit this item inline' ), __( 'Quick Edit' ) );533 $actions['quickedit'] = sprintf( $format, $comment->comment_ID, $comment->comment_post_ID, 'edit', 'vim-q comment-inline',esc_attr__( 'Edit this item inline' ), __( 'Quick Edit' ) ); 538 534 539 $actions['reply'] = sprintf( $format, $comment->comment_ID, $ post->ID, 'replyto', 'vim-r comment-inline', esc_attr__( 'Reply to this comment' ), __( 'Reply' ) );535 $actions['reply'] = sprintf( $format, $comment->comment_ID, $comment->comment_post_ID, 'replyto', 'vim-r comment-inline', esc_attr__( 'Reply to this comment' ), __( 'Reply' ) ); 540 536 } 541 537 542 538 /** This filter is documented in wp-admin/includes/dashboard.php */ 543 539 $actions = apply_filters( 'comment_row_actions', array_filter( $actions ), $comment ); 544 540 545 541 $i = 0; 546 542 $out .= '<div class="row-actions">'; 547 543 foreach ( $actions as $action => $link ) { 548 544 ++$i; 549 545 ( ( ( 'approve' == $action || 'unapprove' == $action ) && 2 === $i ) || 1 === $i ) ? $sep = '' : $sep = ' | '; 550 546 551 547 // Reply and quickedit need a hide-if-no-js span when not added with ajax 552 548 if ( ( 'reply' == $action || 'quickedit' == $action ) && ! defined('DOING_AJAX') ) 553 549 $action .= ' hide-if-no-js'; 554 550 elseif ( ( $action == 'untrash' && $the_comment_status == 'trash' ) || ( $action == 'unspam' && $the_comment_status == 'spam' ) ) { … … class WP_Comments_List_Table extends WP_ 660 656 661 657 /** 662 658 * 663 659 * @return string 664 660 */ 665 661 public function column_date() { 666 662 return get_comment_date( __( 'Y/m/d \a\t g:i a' ) ); 667 663 } 668 664 669 665 /** 670 666 * @access public 671 667 */ 672 668 public function column_response() { 673 669 $post = get_post(); 674 670 671 if ( ! $post ) { 672 return; 673 } 674 675 675 if ( isset( $this->pending_count[$post->ID] ) ) { 676 676 $pending_comments = $this->pending_count[$post->ID]; 677 677 } else { 678 678 $_pending_count_temp = get_pending_comments_num( array( $post->ID ) ); 679 679 $pending_comments = $this->pending_count[$post->ID] = $_pending_count_temp[$post->ID]; 680 680 } 681 681 682 682 if ( current_user_can( 'edit_post', $post->ID ) ) { 683 683 $post_link = "<a href='" . get_edit_post_link( $post->ID ) . "' class='comments-edit-item-link'>"; 684 684 $post_link .= esc_html( get_the_title( $post->ID ) ) . '</a>'; 685 685 } else { 686 686 $post_link = esc_html( get_the_title( $post->ID ) ); 687 687 } 688 688 689 689 echo '<div class="response-links">'; -
src/wp-includes/capabilities.php
function map_meta_cap( $cap, $user_id ) 1293 1293 * @param string $cap Capability name. 1294 1294 * @param array $caps User capabilities. 1295 1295 */ 1296 1296 $allowed = apply_filters( "auth_post_meta_{$meta_key}", false, $meta_key, $post->ID, $user_id, $cap, $caps ); 1297 1297 if ( ! $allowed ) 1298 1298 $caps[] = $cap; 1299 1299 } elseif ( $meta_key && is_protected_meta( $meta_key, 'post' ) ) { 1300 1300 $caps[] = $cap; 1301 1301 } 1302 1302 break; 1303 1303 case 'edit_comment': 1304 1304 $comment = get_comment( $args[0] ); 1305 1305 if ( empty( $comment ) ) 1306 1306 break; 1307 1307 $post = get_post( $comment->comment_post_ID ); 1308 $caps = map_meta_cap( 'edit_post', $user_id, $post->ID ); 1308 1309 /* 1310 * If the post doesn't exist, we have an orphaned comment. 1311 * Fall back to the edit_posts capability, instead. 1312 */ 1313 if ( $post ) { 1314 $caps = map_meta_cap( 'edit_post', $user_id, $post->ID ); 1315 } else { 1316 $caps = map_meta_cap( 'edit_posts', $user_id ); 1317 } 1309 1318 break; 1310 1319 case 'unfiltered_upload': 1311 1320 if ( defined('ALLOW_UNFILTERED_UPLOADS') && ALLOW_UNFILTERED_UPLOADS && ( !is_multisite() || is_super_admin( $user_id ) ) ) 1312 1321 $caps[] = $cap; 1313 1322 else 1314 1323 $caps[] = 'do_not_allow'; 1315 1324 break; 1316 1325 case 'unfiltered_html' : 1317 1326 // Disallow unfiltered_html for all users, even admins and super admins. 1318 1327 if ( defined( 'DISALLOW_UNFILTERED_HTML' ) && DISALLOW_UNFILTERED_HTML ) 1319 1328 $caps[] = 'do_not_allow'; 1320 1329 elseif ( is_multisite() && ! is_super_admin( $user_id ) ) 1321 1330 $caps[] = 'do_not_allow'; 1322 1331 else 1323 1332 $caps[] = $cap; -
tests/phpunit/tests/ajax/EditComment.php
class Tests_Ajax_EditComment extends WP_ 63 63 $xml = simplexml_load_string( $this->_last_response, 'SimpleXMLElement', LIBXML_NOCDATA ); 64 64 65 65 // Check the meta data 66 66 $this->assertEquals( -1, (string) $xml->response[0]->edit_comment['position'] ); 67 67 $this->assertEquals( $comment->comment_ID, (string) $xml->response[0]->edit_comment['id'] ); 68 68 $this->assertEquals( 'edit-comment_' . $comment->comment_ID, (string) $xml->response['action'] ); 69 69 70 70 // Check the payload 71 71 $this->assertNotEmpty( (string) $xml->response[0]->edit_comment[0]->response_data ); 72 72 73 73 // And supplemental is empty 74 74 $this->assertEmpty( (string) $xml->response[0]->edit_comment[0]->supplemental ); 75 75 } 76 76 77 77 /** 78 * @ticket 33154 79 */ 80 function test_editor_can_edit_orphan_comments() { 81 global $wpdb; 82 83 // Become an editor 84 $this->_setRole( 'editor' ); 85 86 // Get a comment 87 $comments = get_comments( array( 88 'post_id' => $this->_comment_post->ID 89 ) ); 90 $comment = array_pop( $comments ); 91 92 // Manually update the comment_post_ID, because wp_update_comment() will prevent it. 93 $wpdb->query( "UPDATE {$wpdb->comments} SET comment_post_ID=0 WHERE comment_ID={$comment->comment_ID}" ); 94 clean_comment_cache( $comment->comment_ID ); 95 96 // Set up a default request 97 $_POST['_ajax_nonce-replyto-comment'] = wp_create_nonce( 'replyto-comment' ); 98 $_POST['comment_ID'] = $comment->comment_ID; 99 $_POST['content'] = 'Lorem ipsum dolor sit amet, consectetur adipiscing elit.'; 100 101 // Make the request 102 try { 103 $this->_handleAjax( 'edit-comment' ); 104 } catch ( WPAjaxDieContinueException $e ) { 105 unset( $e ); 106 } 107 108 // Get the response 109 $xml = simplexml_load_string( $this->_last_response, 'SimpleXMLElement', LIBXML_NOCDATA ); 110 111 // Check the meta data 112 $this->assertEquals( -1, (string) $xml->response[0]->edit_comment['position'] ); 113 $this->assertEquals( $comment->comment_ID, (string) $xml->response[0]->edit_comment['id'] ); 114 $this->assertEquals( 'edit-comment_' . $comment->comment_ID, (string) $xml->response['action'] ); 115 116 // Check the payload 117 $this->assertNotEmpty( (string) $xml->response[0]->edit_comment[0]->response_data ); 118 119 // And supplemental is empty 120 $this->assertEmpty( (string) $xml->response[0]->edit_comment[0]->supplemental ); 121 } 122 123 /** 78 124 * Get comments as a non-privileged user (subscriber) 79 125 * Expects test to fail 80 126 * @return void 81 127 */ 82 128 public function test_as_subscriber() { 83 129 84 130 // Become an administrator 85 131 $this->_setRole( 'subscriber' ); 86 132 87 133 // Get a comment 88 134 $comments = get_comments( array( 89 135 'post_id' => $this->_comment_post->ID 90 136 ) ); 91 137 $comment = array_pop( $comments ); 92 138