Changeset 60987
- Timestamp:
- 10/20/2025 07:20:17 PM (4 months ago)
- Location:
- trunk
- Files:
-
- 7 edited
-
src/wp-admin/includes/class-wp-comments-list-table.php (modified) (1 diff)
-
src/wp-admin/includes/comment.php (modified) (1 diff)
-
src/wp-includes/comment.php (modified) (3 diffs)
-
src/wp-includes/link-template.php (modified) (1 diff)
-
src/wp-includes/post.php (modified) (3 diffs)
-
src/wp-includes/rest-api/endpoints/class-wp-rest-comments-controller.php (modified) (12 diffs)
-
tests/phpunit/tests/rest-api/rest-comments-controller.php (modified) (7 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/wp-admin/includes/class-wp-comments-list-table.php
r59877 r60987 152 152 'post_type' => $post_type, 153 153 'update_comment_post_cache' => true, 154 'type__not_in' => array( 'note' ), 154 155 ); 155 156 -
trunk/src/wp-admin/includes/comment.php
r60416 r60987 158 158 $post_id_in = "'" . implode( "', '", $post_id_array ) . "'"; 159 159 160 $pending = $wpdb->get_results( "SELECT comment_post_ID, COUNT(comment_ID) as num_comments FROM $wpdb->comments WHERE comment_post_ID IN ( $post_id_in ) AND comment_approved = '0' GROUP BY comment_post_ID", ARRAY_A );160 $pending = $wpdb->get_results( "SELECT comment_post_ID, COUNT(comment_ID) as num_comments FROM $wpdb->comments WHERE comment_post_ID IN ( $post_id_in ) AND comment_approved = '0' AND comment_type != 'note' GROUP BY comment_post_ID", ARRAY_A ); 161 161 162 162 if ( $single ) { -
trunk/src/wp-includes/comment.php
r60406 r60987 418 418 'update_comment_meta_cache' => false, 419 419 'orderby' => 'none', 420 'type__not_in' => array( 'note' ), 420 421 ); 421 422 if ( $post_id > 0 ) { … … 714 715 715 716 $dupe_id = $wpdb->get_var( $dupe ); 717 718 // Allow duplicate notes for resolution purposes. 719 if ( isset( $commentdata['comment_type'] ) && 'note' === $commentdata['comment_type'] ) { 720 $dupe_id = false; 721 } 716 722 717 723 /** … … 4104 4110 } 4105 4111 } 4112 4113 /** 4114 * Register initial note status meta. 4115 * 4116 * @since 6.9.0 4117 */ 4118 function wp_create_initial_comment_meta() { 4119 register_meta( 4120 'comment', 4121 '_wp_note_status', 4122 array( 4123 'type' => 'string', 4124 'description' => __( 'Note resolution status' ), 4125 'single' => true, 4126 'show_in_rest' => array( 4127 'schema' => array( 4128 'type' => 'string', 4129 'enum' => array( 'resolved', 'reopen' ), 4130 ), 4131 ), 4132 ) 4133 ); 4134 } 4135 add_action( 'init', 'wp_create_initial_comment_meta' ); -
trunk/src/wp-includes/link-template.php
r60900 r60987 4344 4344 * @since 3.0.0 4345 4345 * 4346 * @param array $types An array of content types. Default only contains 'comment'. 4347 */ 4348 $allowed_comment_types = apply_filters( 'get_avatar_comment_types', array( 'comment' ) ); 4346 * @since 6.9.0 The 'note' comment type was added. 4347 * 4348 * @param array $types An array of content types. Default contains 'comment' and 'note'. 4349 */ 4350 $allowed_comment_types = apply_filters( 'get_avatar_comment_types', array( 'comment', 'note' ) ); 4349 4351 4350 4352 return in_array( $comment_type, (array) $allowed_comment_types, true ); -
trunk/src/wp-includes/post.php
r60906 r60987 38 38 'query_var' => false, 39 39 'delete_with_user' => true, 40 'supports' => array( 'title', 'editor', 'author', 'thumbnail', 'excerpt', 'trackbacks', 'custom-fields', 'comments', 'revisions', 'post-formats' ), 40 'supports' => array( 41 'title', 42 'editor' => array( 'notes' => true ), 43 'author', 44 'thumbnail', 45 'excerpt', 46 'trackbacks', 47 'custom-fields', 48 'comments', 49 'revisions', 50 'post-formats', 51 ), 41 52 'show_in_rest' => true, 42 53 'rest_base' => 'posts', … … 63 74 'query_var' => false, 64 75 'delete_with_user' => true, 65 'supports' => array( 'title', 'editor', 'author', 'thumbnail', 'page-attributes', 'custom-fields', 'comments', 'revisions' ), 76 'supports' => array( 77 'title', 78 'editor' => array( 'notes' => true ), 79 'author', 80 'thumbnail', 81 'page-attributes', 82 'custom-fields', 83 'comments', 84 'revisions', 85 ), 66 86 'show_in_rest' => true, 67 87 'rest_base' => 'pages', … … 2330 2350 return ( isset( $_wp_post_type_features[ $post_type ][ $feature ] ) ); 2331 2351 } 2332 2333 2352 /** 2334 2353 * Retrieves a list of post type names that support a specific feature. -
trunk/src/wp-includes/rest-api/endpoints/class-wp-rest-comments-controller.php
r60937 r60987 124 124 */ 125 125 public function get_items_permissions_check( $request ) { 126 $is_note = 'note' === $request['type']; 127 $is_edit_context = 'edit' === $request['context']; 126 128 127 129 if ( ! empty( $request['post'] ) ) { 128 130 foreach ( (array) $request['post'] as $post_id ) { 129 131 $post = get_post( $post_id ); 132 133 if ( $post && $is_note && ! $this->check_post_type_supports_notes( $post->post_type ) ) { 134 return new WP_Error( 135 'rest_comment_not_supported_post_type', 136 __( 'Sorry, this post type does not support notes.' ), 137 array( 'status' => 403 ) 138 ); 139 } 130 140 131 141 if ( ! empty( $post_id ) && $post && ! $this->check_read_post_permission( $post, $request ) ) { … … 145 155 } 146 156 147 if ( ! empty( $request['context'] ) && 'edit' === $request['context'] && ! current_user_can( 'moderate_comments' ) ) { 157 // Re-map edit context capabilities when requesting `note` for a post. 158 if ( $is_edit_context && $is_note && ! empty( $request['post'] ) ) { 159 foreach ( (array) $request['post'] as $post_id ) { 160 if ( ! current_user_can( 'edit_post', $post_id ) ) { 161 return new WP_Error( 162 'rest_forbidden_context', 163 __( 'Sorry, you are not allowed to edit comments.' ), 164 array( 'status' => rest_authorization_required_code() ) 165 ); 166 } 167 } 168 } elseif ( $is_edit_context && ! current_user_can( 'moderate_comments' ) ) { 148 169 return new WP_Error( 149 170 'rest_forbidden_context', … … 395 416 } 396 417 397 if ( ! empty( $request['context'] ) && 'edit' === $request['context'] && ! current_user_can( 'moderate_comments' ) ) { 418 // Re-map edit context capabilities when requesting `note` type. 419 $edit_cap = 'note' === $comment->comment_type ? array( 'edit_comment', $comment->comment_ID ) : array( 'moderate_comments' ); 420 if ( ! empty( $request['context'] ) && 'edit' === $request['context'] && ! current_user_can( ...$edit_cap ) ) { 398 421 return new WP_Error( 399 422 'rest_forbidden_context', … … 453 476 */ 454 477 public function create_item_permissions_check( $request ) { 478 $is_note = ! empty( $request['type'] ) && 'note' === $request['type']; 479 480 if ( ! is_user_logged_in() && $is_note ) { 481 return new WP_Error( 482 'rest_comment_login_required', 483 __( 'Sorry, you must be logged in to comment.' ), 484 array( 'status' => 401 ) 485 ); 486 } 487 455 488 if ( ! is_user_logged_in() ) { 456 489 if ( get_option( 'comment_registration' ) ) { … … 506 539 } 507 540 508 if ( isset( $request['status'] ) && ! current_user_can( 'moderate_comments' ) ) { 541 $edit_cap = $is_note ? array( 'edit_post', (int) $request['post'] ) : array( 'moderate_comments' ); 542 if ( isset( $request['status'] ) && ! current_user_can( ...$edit_cap ) ) { 509 543 return new WP_Error( 510 544 'rest_comment_invalid_status', … … 533 567 } 534 568 535 if ( 'draft' === $post->post_status ) { 569 if ( $is_note && ! $this->check_post_type_supports_notes( $post->post_type ) ) { 570 return new WP_Error( 571 'rest_comment_not_supported_post_type', 572 __( 'Sorry, this post type does not support notes.' ), 573 array( 'status' => 403 ) 574 ); 575 } 576 577 if ( 'draft' === $post->post_status && ! $is_note ) { 536 578 return new WP_Error( 537 579 'rest_comment_draft_post', … … 557 599 } 558 600 559 if ( ! comments_open( $post->ID ) ) {601 if ( ! comments_open( $post->ID ) && ! $is_note ) { 560 602 return new WP_Error( 561 603 'rest_comment_closed', … … 585 627 } 586 628 587 // Do not allow comments to be created with a non- defaulttype.588 if ( ! empty( $request['type'] ) && 'comment' !== $request['type']) {629 // Do not allow comments to be created with a non-core type. 630 if ( ! empty( $request['type'] ) && ! in_array( $request['type'], array( 'comment', 'note' ), true ) ) { 589 631 return new WP_Error( 590 632 'rest_invalid_comment_type', … … 599 641 } 600 642 601 $prepared_comment['comment_type'] = 'comment';643 $prepared_comment['comment_type'] = $request['type']; 602 644 603 645 if ( ! isset( $prepared_comment['comment_content'] ) ) { 604 646 $prepared_comment['comment_content'] = ''; 647 } 648 649 // Include note metadata into check_is_comment_content_allowed. 650 if ( isset( $request['meta']['_wp_note_status'] ) ) { 651 $prepared_comment['meta']['_wp_note_status'] = $request['meta']['_wp_note_status']; 605 652 } 606 653 … … 1520 1567 'context' => array( 'view', 'edit', 'embed' ), 1521 1568 'readonly' => true, 1569 'default' => 'comment', 1522 1570 ), 1523 1571 ), … … 1926 1974 } 1927 1975 1976 // Allow empty notes only when resolution metadata is valid. 1977 if ( 1978 isset( $check['comment_type'] ) && 1979 'note' === $check['comment_type'] && 1980 isset( $check['meta']['_wp_note_status'] ) && 1981 in_array( $check['meta']['_wp_note_status'], array( 'resolved', 'reopen' ), true ) 1982 ) { 1983 return true; 1984 } 1985 1928 1986 /* 1929 1987 * Do not allow a comment to be created with missing or empty … … 1932 1990 return '' !== $check['comment_content']; 1933 1991 } 1992 1993 /** 1994 * Check if post type supports notes. 1995 * 1996 * @param string $post_type Post type name. 1997 * @return bool True if post type supports notes, false otherwise. 1998 */ 1999 private function check_post_type_supports_notes( $post_type ) { 2000 $supports = get_all_post_type_supports( $post_type ); 2001 if ( ! isset( $supports['editor'] ) ) { 2002 return false; 2003 } 2004 if ( ! is_array( $supports['editor'] ) ) { 2005 return false; 2006 } 2007 foreach ( $supports['editor'] as $item ) { 2008 if ( ! empty( $item['notes'] ) ) { 2009 return true; 2010 } 2011 } 2012 return false; 2013 } 1934 2014 } -
trunk/tests/phpunit/tests/rest-api/rest-comments-controller.php
r60937 r60987 13 13 protected static $editor_id; 14 14 protected static $moderator_id; 15 protected static $contributor_id; 15 16 protected static $subscriber_id; 16 17 protected static $author_id; 18 protected static $user_ids = array(); 17 19 18 20 protected static $post_id; … … 27 29 protected static $total_comments = 30; 28 30 protected static $per_page = 50; 31 protected static $num_notes = 10; 29 32 30 33 protected $endpoint; … … 40 43 ); 41 44 42 self::$superadmin_id = $factory->user->create(45 self::$superadmin_id = $factory->user->create( 43 46 array( 44 47 'role' => 'administrator', … … 46 49 ) 47 50 ); 48 self::$admin_id = $factory->user->create(51 self::$admin_id = $factory->user->create( 49 52 array( 50 53 'role' => 'administrator', 51 54 ) 52 55 ); 53 self::$editor_id = $factory->user->create(56 self::$editor_id = $factory->user->create( 54 57 array( 55 58 'role' => 'editor', 56 59 ) 57 60 ); 58 self::$moderator_id = $factory->user->create(61 self::$moderator_id = $factory->user->create( 59 62 array( 60 63 'role' => 'comment_moderator', 61 64 ) 62 65 ); 63 self::$subscriber_id = $factory->user->create( 66 self::$contributor_id = $factory->user->create( 67 array( 68 'role' => 'contributor', 69 ) 70 ); 71 self::$subscriber_id = $factory->user->create( 64 72 array( 65 73 'role' => 'subscriber', 66 74 ) 67 75 ); 68 self::$author_id = $factory->user->create(76 self::$author_id = $factory->user->create( 69 77 array( 70 78 'role' => 'author', … … 112 120 'user_id' => self::$subscriber_id, 113 121 ) 122 ); 123 124 self::$user_ids = array( 125 'superadmin' => self::$superadmin_id, 126 'administrator' => self::$admin_id, 127 'editor' => self::$editor_id, 128 'moderator' => self::$moderator_id, 129 'contributor' => self::$contributor_id, 130 'subscriber' => self::$subscriber_id, 131 'author' => self::$author_id, 114 132 ); 115 133 … … 132 150 self::delete_user( self::$editor_id ); 133 151 self::delete_user( self::$moderator_id ); 152 self::delete_user( self::$contributor_id ); 134 153 self::delete_user( self::$subscriber_id ); 135 154 self::delete_user( self::$author_id ); … … 3622 3641 ); 3623 3642 } 3643 3644 /** 3645 * Create a test post with note. 3646 * 3647 * @param int $user_id Post author's user ID. 3648 * @return int Post ID. 3649 */ 3650 protected function create_test_post_with_note( $role ) { 3651 $user_id = self::$user_ids[ $role ]; 3652 $post_id = self::factory()->post->create( 3653 array( 3654 'post_title' => 'Test Post for Notes', 3655 'post_content' => 'This is a test post to check note permissions.', 3656 'post_status' => 'contributor' === $role ? 'draft' : 'publish', 3657 'post_author' => $user_id, 3658 ) 3659 ); 3660 3661 for ( $i = 0; $i < self::$num_notes; $i++ ) { 3662 self::factory()->comment->create( 3663 array( 3664 'comment_post_ID' => $post_id, 3665 'comment_type' => 'note', 3666 'comment_approved' => 0 === $i % 2 ? 1 : 0, 3667 ) 3668 ); 3669 } 3670 3671 return $post_id; 3672 } 3673 3674 /** 3675 * @ticket 64096 3676 */ 3677 public function test_cannot_read_note_without_post_type_support() { 3678 register_post_type( 3679 'no-notes', 3680 array( 3681 'label' => 'No Notes', 3682 'supports' => array( 'title', 'editor', 'author', 'comments' ), 3683 'show_in_rest' => true, 3684 'public' => true, 3685 ) 3686 ); 3687 3688 create_initial_rest_routes(); 3689 wp_set_current_user( self::$admin_id ); 3690 3691 $post_id = self::factory()->post->create( array( 'post_type' => 'no-notes' ) ); 3692 $request = new WP_REST_Request( 'GET', '/wp/v2/comments' ); 3693 $request->set_param( 'post', $post_id ); 3694 $request->set_param( 'type', 'note' ); 3695 $request->set_param( 'context', 'edit' ); 3696 3697 $response = rest_get_server()->dispatch( $request ); 3698 $this->assertErrorResponse( 'rest_comment_not_supported_post_type', $response, 403 ); 3699 3700 _unregister_post_type( 'no-notes' ); 3701 } 3702 3703 /** 3704 * @ticket 64096 3705 */ 3706 public function test_create_note_require_login() { 3707 wp_set_current_user( 0 ); 3708 3709 $post_id = self::factory()->post->create(); 3710 $request = new WP_REST_Request( 'POST', '/wp/v2/comments' ); 3711 $request->set_param( 'post', $post_id ); 3712 $request->set_param( 'type', 'note' ); 3713 $response = rest_get_server()->dispatch( $request ); 3714 3715 $this->assertErrorResponse( 'rest_comment_login_required', $response, 401 ); 3716 } 3717 3718 /** 3719 * @ticket 64096 3720 */ 3721 public function test_cannot_create_note_without_post_type_support() { 3722 register_post_type( 3723 'no-note', 3724 array( 3725 'label' => 'No Notes', 3726 'supports' => array( 'title', 'editor', 'author', 'comments' ), 3727 'show_in_rest' => true, 3728 'public' => true, 3729 ) 3730 ); 3731 3732 wp_set_current_user( self::$admin_id ); 3733 $post_id = self::factory()->post->create( array( 'post_type' => 'no-note' ) ); 3734 $params = array( 3735 'post' => $post_id, 3736 'author_name' => 'Ishmael', 3737 'author_email' => 'herman-melville@earthlink.net', 3738 'author_url' => 'https://en.wikipedia.org/wiki/Herman_Melville', 3739 'content' => 'Call me Ishmael.', 3740 'author' => self::$admin_id, 3741 'type' => 'note', 3742 ); 3743 3744 $request = new WP_REST_Request( 'POST', '/wp/v2/comments' ); 3745 $request->add_header( 'Content-Type', 'application/json' ); 3746 $request->set_body( wp_json_encode( $params ) ); 3747 $response = rest_get_server()->dispatch( $request ); 3748 $this->assertErrorResponse( 'rest_comment_not_supported_post_type', $response, 403 ); 3749 3750 _unregister_post_type( 'no-note' ); 3751 } 3752 3753 /** 3754 * @ticket 64096 3755 */ 3756 public function test_create_note_draft_post() { 3757 wp_set_current_user( self::$editor_id ); 3758 $draft_id = self::factory()->post->create( 3759 array( 3760 'post_status' => 'draft', 3761 ) 3762 ); 3763 $params = array( 3764 'post' => $draft_id, 3765 'author_name' => 'Ishmael', 3766 'author_email' => 'herman-melville@earthlink.net', 3767 'author_url' => 'https://en.wikipedia.org/wiki/Herman_Melville', 3768 'content' => 'Call me Ishmael.', 3769 'author' => self::$editor_id, 3770 'type' => 'note', 3771 ); 3772 3773 $request = new WP_REST_Request( 'POST', '/wp/v2/comments' ); 3774 $request->add_header( 'Content-Type', 'application/json' ); 3775 $request->set_body( wp_json_encode( $params ) ); 3776 3777 $response = rest_get_server()->dispatch( $request ); 3778 $data = $response->get_data(); 3779 $new_comment = get_comment( $data['id'] ); 3780 $this->assertSame( 'Call me Ishmael.', $new_comment->comment_content ); 3781 $this->assertSame( 'note', $new_comment->comment_type ); 3782 } 3783 3784 /** 3785 * @ticket 64096 3786 */ 3787 public function test_create_note_status() { 3788 wp_set_current_user( self::$author_id ); 3789 $post_id = self::factory()->post->create( array( 'post_author' => self::$author_id ) ); 3790 3791 $params = array( 3792 'post' => $post_id, 3793 'author_name' => 'Ishmael', 3794 'author_email' => 'herman-melville@earthlink.net', 3795 'author_url' => 'https://en.wikipedia.org/wiki/Herman_Melville', 3796 'content' => 'Comic Book Guy', 3797 'author' => self::$author_id, 3798 'type' => 'note', 3799 'status' => 'hold', 3800 ); 3801 3802 $request = new WP_REST_Request( 'POST', '/wp/v2/comments' ); 3803 $request->add_header( 'Content-Type', 'application/json' ); 3804 $request->set_body( wp_json_encode( $params ) ); 3805 3806 $response = rest_get_server()->dispatch( $request ); 3807 $data = $response->get_data(); 3808 $new_comment = get_comment( $data['id'] ); 3809 3810 $this->assertSame( '0', $new_comment->comment_approved ); 3811 $this->assertSame( 'note', $new_comment->comment_type ); 3812 } 3813 3814 /** 3815 * @ticket 64096 3816 */ 3817 public function test_cannot_create_with_non_valid_comment_type() { 3818 wp_set_current_user( self::$admin_id ); 3819 $post_id = $this->factory->post->create(); 3820 3821 $params = array( 3822 'post' => $post_id, 3823 'author_name' => 'Ishmael', 3824 'author_email' => 'herman-melville@earthlink.net', 3825 'author_url' => 'https://en.wikipedia.org/wiki/Herman_Melville', 3826 'content' => 'Comic Book Guy', 3827 'author' => self::$admin_id, 3828 'type' => 'review', 3829 ); 3830 3831 $request = new WP_REST_Request( 'POST', '/wp/v2/comments' ); 3832 $request->add_header( 'Content-Type', 'application/json' ); 3833 $request->set_body( wp_json_encode( $params ) ); 3834 $response = rest_get_server()->dispatch( $request ); 3835 3836 $this->assertErrorResponse( 'rest_invalid_comment_type', $response, 400 ); 3837 } 3838 3839 /** 3840 * @ticket 64096 3841 */ 3842 public function test_create_assigns_default_type() { 3843 wp_set_current_user( self::$editor_id ); 3844 $post_id = self::factory()->post->create(); 3845 3846 $params = array( 3847 'post' => $post_id, 3848 'author_name' => 'Ishmael', 3849 'author_email' => 'herman-melville@earthlink.net', 3850 'author_url' => 'https://en.wikipedia.org/wiki/Herman_Melville', 3851 'content' => 'Comic Book Guy', 3852 'author' => self::$editor_id, 3853 ); 3854 3855 $request = new WP_REST_Request( 'POST', '/wp/v2/comments' ); 3856 $request->add_header( 'Content-Type', 'application/json' ); 3857 $request->set_body( wp_json_encode( $params ) ); 3858 3859 $response = rest_get_server()->dispatch( $request ); 3860 $data = $response->get_data(); 3861 $new_comment = get_comment( $data['id'] ); 3862 3863 $this->assertSame( 'comment', $new_comment->comment_type ); 3864 } 3865 3866 /** 3867 * @dataProvider data_note_status_provider 3868 * @ticket 64096 3869 */ 3870 public function test_create_empty_note_with_resolution_meta( $status ) { 3871 wp_set_current_user( self::$editor_id ); 3872 $post_id = self::factory()->post->create(); 3873 $params = array( 3874 'post' => $post_id, 3875 'author_name' => 'Editor', 3876 'author_email' => 'editor@example.com', 3877 'author_url' => 'https://example.com', 3878 'author' => self::$editor_id, 3879 'type' => 'note', 3880 'content' => '', 3881 'meta' => array( 3882 '_wp_note_status' => $status, 3883 ), 3884 ); 3885 $request = new WP_REST_Request( 'POST', '/wp/v2/comments' ); 3886 $request->add_header( 'Content-Type', 'application/json' ); 3887 $request->set_body( wp_json_encode( $params ) ); 3888 3889 $response = rest_get_server()->dispatch( $request ); 3890 $this->assertSame( 201, $response->get_status() ); 3891 } 3892 3893 /** 3894 * @ticket 64096 3895 */ 3896 public function test_cannot_create_empty_note_without_resolution_meta() { 3897 wp_set_current_user( self::$editor_id ); 3898 $post_id = self::factory()->post->create(); 3899 $params = array( 3900 'post' => $post_id, 3901 'author_name' => 'Editor', 3902 'author_email' => 'editor@example.com', 3903 'author_url' => 'https://example.com', 3904 'author' => self::$editor_id, 3905 'type' => 'note', 3906 'content' => '', 3907 ); 3908 $request = new WP_REST_Request( 'POST', '/wp/v2/comments' ); 3909 $request->add_header( 'Content-Type', 'application/json' ); 3910 $request->set_body( wp_json_encode( $params ) ); 3911 $response = rest_get_server()->dispatch( $request ); 3912 $this->assertErrorResponse( 'rest_comment_content_invalid', $response, 400 ); 3913 } 3914 3915 /** 3916 * @ticket 64096 3917 */ 3918 public function test_cannot_create_empty_note_with_invalid_resolution_meta() { 3919 wp_set_current_user( self::$editor_id ); 3920 $post_id = self::factory()->post->create(); 3921 $params = array( 3922 'post' => $post_id, 3923 'author_name' => 'Editor', 3924 'author_email' => 'editor@example.com', 3925 'author_url' => 'https://example.com', 3926 'author' => self::$editor_id, 3927 'type' => 'note', 3928 'content' => '', 3929 'meta' => array( 3930 '_wp_note_status' => 'invalid', 3931 ), 3932 ); 3933 $request = new WP_REST_Request( 'POST', '/wp/v2/comments' ); 3934 $request->add_header( 'Content-Type', 'application/json' ); 3935 $request->set_body( wp_json_encode( $params ) ); 3936 $response = rest_get_server()->dispatch( $request ); 3937 $this->assertErrorResponse( 'rest_comment_content_invalid', $response, 400 ); 3938 } 3939 3940 /** 3941 * @ticket 64096 3942 */ 3943 public function test_create_duplicate_note() { 3944 wp_set_current_user( self::$editor_id ); 3945 $post_id = self::factory()->post->create(); 3946 3947 for ( $i = 0; $i < 2; $i++ ) { 3948 $params = array( 3949 'post' => $post_id, 3950 'author_name' => 'Editor', 3951 'author_email' => 'editor@example.com', 3952 'author_url' => 'https://example.com', 3953 'author' => self::$editor_id, 3954 'type' => 'note', 3955 'content' => 'Doplicated comment', 3956 ); 3957 $request = new WP_REST_Request( 'POST', '/wp/v2/comments' ); 3958 $request->add_header( 'Content-Type', 'application/json' ); 3959 $request->set_body( wp_json_encode( $params ) ); 3960 $response = rest_get_server()->dispatch( $request ); 3961 $this->assertSame( 201, $response->get_status() ); 3962 } 3963 } 3964 3965 /** 3966 * @dataProvider data_note_get_items_permissions_data_provider 3967 * @ticket 64096 3968 */ 3969 public function test_note_get_items_permissions_edit_context( $role, $post_author_role, $can_read ) { 3970 wp_set_current_user( self::$user_ids[ $role ] ); 3971 $post_id = $this->create_test_post_with_note( $post_author_role ); 3972 3973 $request = new WP_REST_Request( 'GET', '/wp/v2/comments' ); 3974 $request->set_param( 'post', $post_id ); 3975 $request->set_param( 'type', 'note' ); 3976 $request->set_param( 'status', 'all' ); 3977 $request->set_param( 'per_page', 100 ); 3978 $request->set_param( 'context', 'edit' ); 3979 $response = rest_get_server()->dispatch( $request ); 3980 3981 if ( $can_read ) { 3982 $comments = $response->get_data(); 3983 $this->assertEquals( self::$num_notes, count( $comments ) ); 3984 } else { 3985 $this->assertErrorResponse( 'rest_forbidden_context', $response, 403 ); 3986 } 3987 3988 wp_delete_post( $post_id, true ); 3989 } 3990 3991 /** 3992 * @ticket 64096 3993 */ 3994 public function test_note_get_items_permissions_mixed_post_authors() { 3995 $author_post_id = $this->create_test_post_with_note( 'author' ); 3996 $editor_post_id = $this->create_test_post_with_note( 'editor' ); 3997 3998 wp_set_current_user( self::$author_id ); 3999 4000 $request = new WP_REST_Request( 'GET', '/wp/v2/comments' ); 4001 $request->set_param( 'post', array( $author_post_id, $editor_post_id ) ); 4002 $request->set_param( 'type', 'note' ); 4003 $request->set_param( 'status', 'all' ); 4004 $request->set_param( 'per_page', 100 ); 4005 $request->set_param( 'context', 'edit' ); 4006 $response = rest_get_server()->dispatch( $request ); 4007 4008 $this->assertErrorResponse( 'rest_forbidden_context', $response, 403 ); 4009 4010 wp_delete_post( $author_post_id, true ); 4011 wp_delete_post( $editor_post_id, true ); 4012 } 4013 4014 /** 4015 * @dataProvider data_note_get_items_permissions_data_provider 4016 * @ticket 64096 4017 */ 4018 public function test_note_get_item_permissions_edit_context( $role, $post_author_role, $can_read ) { 4019 wp_set_current_user( self::$user_ids[ $role ] ); 4020 4021 $post_id = self::factory()->post->create( 4022 array( 4023 'post_title' => 'Test Post for Block Comments', 4024 'post_content' => 'This is a test post to check block comment permissions.', 4025 'post_status' => 'contributor' === $post_author_role ? 'draft' : 'publish', 4026 'post_author' => self::$user_ids[ $post_author_role ], 4027 ) 4028 ); 4029 4030 $comment_id = self::factory()->comment->create( 4031 array( 4032 'comment_post_ID' => $post_id, 4033 'comment_type' => 'note', 4034 // Test with unapproved comment, which is more restrictive. 4035 'comment_approved' => 0, 4036 'user_id' => self::$user_ids[ $post_author_role ], 4037 ) 4038 ); 4039 4040 $request = new WP_REST_Request( 'GET', '/wp/v2/comments/' . $comment_id ); 4041 $request->set_param( 'context', 'edit' ); 4042 $response = rest_get_server()->dispatch( $request ); 4043 4044 if ( $can_read ) { 4045 $comment = $response->get_data(); 4046 $this->assertEquals( $comment_id, $comment['id'] ); 4047 } else { 4048 $this->assertErrorResponse( 'rest_forbidden_context', $response, 403 ); 4049 } 4050 4051 wp_delete_post( $post_id, true ); 4052 } 4053 4054 public function data_note_get_items_permissions_data_provider() { 4055 return array( 4056 'Administrator can see note on other posts' => array( 'administrator', 'author', true ), 4057 'Editor can see note on other posts' => array( 'editor', 'contributor', true ), 4058 'Author cannot see note on other posts' => array( 'author', 'editor', false ), 4059 'Contributor cannot see note on other posts' => array( 'contributor', 'author', false ), 4060 'Subscriber cannot see note' => array( 'subscriber', 'author', false ), 4061 'Author can see note on own post' => array( 'author', 'author', true ), 4062 'Contributor can see note on own post' => array( 'contributor', 'contributor', true ), 4063 ); 4064 } 4065 4066 public function data_note_status_provider() { 4067 return array( 4068 'resolved' => array( 'resolved' ), 4069 'reopen' => array( 'reopen' ), 4070 ); 4071 } 3624 4072 }
Note: See TracChangeset
for help on using the changeset viewer.