@@ -123,11 +123,21 @@ public function register_routes() {
123123 * @return true|WP_Error True if the request has read access, error object otherwise.
124124 */
125125 public function get_items_permissions_check ( $ request ) {
126+ $ is_note = 'note ' === $ request ['type ' ];
127+ $ is_edit_context = 'edit ' === $ request ['context ' ];
126128
127129 if ( ! empty ( $ request ['post ' ] ) ) {
128130 foreach ( (array ) $ request ['post ' ] as $ post_id ) {
129131 $ post = get_post ( $ post_id );
130132
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+ }
140+
131141 if ( ! empty ( $ post_id ) && $ post && ! $ this ->check_read_post_permission ( $ post , $ request ) ) {
132142 return new WP_Error (
133143 'rest_cannot_read_post ' ,
@@ -144,7 +154,18 @@ public function get_items_permissions_check( $request ) {
144154 }
145155 }
146156
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 ' ) ) {
148169 return new WP_Error (
149170 'rest_forbidden_context ' ,
150171 __ ( 'Sorry, you are not allowed to edit comments. ' ),
@@ -394,7 +415,9 @@ public function get_item_permissions_check( $request ) {
394415 return $ comment ;
395416 }
396417
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 ) ) {
398421 return new WP_Error (
399422 'rest_forbidden_context ' ,
400423 __ ( 'Sorry, you are not allowed to edit comments. ' ),
@@ -452,6 +475,16 @@ public function get_item( $request ) {
452475 * @return true|WP_Error True if the request has access to create items, error object otherwise.
453476 */
454477 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+
455488 if ( ! is_user_logged_in () ) {
456489 if ( get_option ( 'comment_registration ' ) ) {
457490 return new WP_Error (
@@ -505,7 +538,8 @@ public function create_item_permissions_check( $request ) {
505538 }
506539 }
507540
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 ) ) {
509543 return new WP_Error (
510544 'rest_comment_invalid_status ' ,
511545 /* translators: %s: Request parameter. */
@@ -532,7 +566,15 @@ public function create_item_permissions_check( $request ) {
532566 );
533567 }
534568
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 ) {
536578 return new WP_Error (
537579 'rest_comment_draft_post ' ,
538580 __ ( 'Sorry, you are not allowed to create a comment on this post. ' ),
@@ -556,7 +598,7 @@ public function create_item_permissions_check( $request ) {
556598 );
557599 }
558600
559- if ( ! comments_open ( $ post ->ID ) ) {
601+ if ( ! comments_open ( $ post ->ID ) && ! $ is_note ) {
560602 return new WP_Error (
561603 'rest_comment_closed ' ,
562604 __ ( 'Sorry, comments are closed for this item. ' ),
@@ -584,8 +626,8 @@ public function create_item( $request ) {
584626 );
585627 }
586628
587- // Do not allow comments to be created with a non-default type.
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 ) ) {
589631 return new WP_Error (
590632 'rest_invalid_comment_type ' ,
591633 __ ( 'Cannot create a comment with that type. ' ),
@@ -598,12 +640,17 @@ public function create_item( $request ) {
598640 return $ prepared_comment ;
599641 }
600642
601- $ prepared_comment ['comment_type ' ] = ' comment ' ;
643+ $ prepared_comment ['comment_type ' ] = $ request [ ' type ' ] ;
602644
603645 if ( ! isset ( $ prepared_comment ['comment_content ' ] ) ) {
604646 $ prepared_comment ['comment_content ' ] = '' ;
605647 }
606648
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 ' ];
652+ }
653+
607654 if ( ! $ this ->check_is_comment_content_allowed ( $ prepared_comment ) ) {
608655 return new WP_Error (
609656 'rest_comment_content_invalid ' ,
@@ -1519,6 +1566,7 @@ public function get_item_schema() {
15191566 'type ' => 'string ' ,
15201567 'context ' => array ( 'view ' , 'edit ' , 'embed ' ),
15211568 'readonly ' => true ,
1569+ 'default ' => 'comment ' ,
15221570 ),
15231571 ),
15241572 );
@@ -1925,10 +1973,42 @@ protected function check_is_comment_content_allowed( $prepared_comment ) {
19251973 return true ;
19261974 }
19271975
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+
19281986 /*
19291987 * Do not allow a comment to be created with missing or empty
19301988 * comment_content. See wp_handle_comment_submission().
19311989 */
19321990 return '' !== $ check ['comment_content ' ];
19331991 }
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+ }
19342014}
0 commit comments