Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 0 additions & 14 deletions lib/block-editor-settings.php
Original file line number Diff line number Diff line change
Expand Up @@ -124,17 +124,3 @@ function gutenberg_get_block_editor_settings( $settings ) {
return $settings;
}
add_filter( 'block_editor_settings_all', 'gutenberg_get_block_editor_settings', 0 );

/**
* Injects the filtered note reaction emoji list into block editor settings.
*
* @since 7.0.0
*
* @param array $settings Existing block editor settings.
* @return array Updated block editor settings.
*/
function gutenberg_add_note_reaction_emojis_setting( $settings ) {
$settings['noteReactionEmojis'] = gutenberg_get_note_reaction_emojis();
return $settings;
}
add_filter( 'block_editor_settings_all', 'gutenberg_add_note_reaction_emojis_setting' );
9 changes: 4 additions & 5 deletions lib/compat/wordpress-6.9/block-comments.php
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,6 @@ function gutenberg_register_block_comment_metadata() {
if ( ! function_exists( 'update_get_avatar_comment_type' ) ) {
function update_get_avatar_comment_type( $comment_type ) {
$comment_type[] = 'note';
$comment_type[] = 'note_reaction';
return $comment_type;
}
add_filter( 'get_avatar_comment_types', 'update_get_avatar_comment_type' );
Expand All @@ -89,7 +88,7 @@ function exclude_block_comments_from_admin( $clauses, $query ) {
$query->set( 'type', '' );

global $wpdb;
$clauses['where'] .= " AND {$wpdb->comments}.comment_type != 'note' AND {$wpdb->comments}.comment_type != 'note_reaction'";
$clauses['where'] .= " AND {$wpdb->comments}.comment_type != 'note'";
}

return $clauses;
Expand All @@ -110,7 +109,7 @@ function gutenberg_filter_comment_count_query_exclude_block_comments( $query ) {
// Adjust the query if it is a comment count query.
if ( str_starts_with( $query, 'SELECT comment_post_ID, COUNT(comment_ID) as num_comments FROM' ) && str_contains( $query, 'comment_approved' ) ) {
if ( ! str_contains( $query, "comment_type != 'note'" ) ) {
$query = str_replace( 'comment_approved', "comment_type != 'note' AND comment_type != 'note_reaction' AND comment_approved", $query );
$query = str_replace( 'comment_approved', "comment_type != 'note' AND comment_approved", $query );
}
}
return $query;
Expand All @@ -124,7 +123,7 @@ function gutenberg_filter_comment_count_query_exclude_block_comments( $query ) {
* @return array Possibly modified arguments for get_comments().
*/
function gutenberg_hide_note_from_comment_list_table( $args ) {
if ( ! empty( $_REQUEST['comment_type'] ) && in_array( $_REQUEST['comment_type'], array( 'note', 'note_reaction' ), true ) ) {
if ( ! empty( $_REQUEST['comment_type'] ) && 'note' === $_REQUEST['comment_type'] ) {
unset( $args['type'] );
}
return $args;
Expand All @@ -145,7 +144,7 @@ function gutenberg_exclude_notes_from_comment_count( $new_count, $old_count, $po
if ( null !== $new_count ) {
return $new_count;
}
$new_count = (int) $wpdb->get_var( $wpdb->prepare( "SELECT COUNT(*) FROM $wpdb->comments WHERE comment_post_ID = %d AND comment_approved = '1' AND comment_type != 'note' AND comment_type != 'note_reaction'", $post_id ) );
$new_count = (int) $wpdb->get_var( $wpdb->prepare( "SELECT COUNT(*) FROM $wpdb->comments WHERE comment_post_ID = %d AND comment_approved = '1' AND comment_type != 'note'", $post_id ) );
return $new_count;
}
add_filter( 'pre_wp_update_comment_count_now', 'gutenberg_exclude_notes_from_comment_count', 10, 3 );
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
class Gutenberg_REST_Comment_Controller_6_9 extends WP_REST_Comments_Controller {

public function get_items_permissions_check( $request ) {
$is_note = in_array( $request['type'], array( 'note', 'note_reaction' ), true );
$is_note = 'note' === $request['type'];
$is_edit_context = 'edit' === $request['context'];

if ( ! empty( $request['post'] ) ) {
Expand Down Expand Up @@ -99,9 +99,9 @@ public function get_item_permissions_check( $request ) {
return $comment;
}

// Re-map edit context capabilities when requesting `note` or `note_reaction` type.
// Re-map edit context capabilities when requesting `note` type.
// Note: This is only relevant change for the backport.
$edit_cap = in_array( $comment->comment_type, array( 'note', 'note_reaction' ), true ) ? array( 'edit_comment', $comment->comment_ID ) : array( 'moderate_comments' );
$edit_cap = 'note' === $comment->comment_type ? array( 'edit_comment', $comment->comment_ID ) : array( 'moderate_comments' );
if ( ! empty( $request['context'] ) && 'edit' === $request['context'] && ! current_user_can( ...$edit_cap ) ) {
return new WP_Error(
'rest_forbidden_context',
Expand Down Expand Up @@ -132,7 +132,7 @@ public function get_item_permissions_check( $request ) {
}

public function create_item_permissions_check( $request ) {
$is_note = ! empty( $request['type'] ) && in_array( $request['type'], array( 'note', 'note_reaction' ), true );
$is_note = ! empty( $request['type'] ) && 'note' === $request['type'];

// Note: This is only relevant change for the backport.
if ( ! is_user_logged_in() && $is_note ) {
Expand Down Expand Up @@ -292,66 +292,14 @@ public function create_item( $request ) {

// Note: Removes non-default comment type check for the backport.
// Do not allow comments to be created with a non-core type.
if ( ! empty( $request['type'] ) && ! in_array( $request['type'], array( 'comment', 'note', 'note_reaction' ), true ) ) {
if ( ! empty( $request['type'] ) && ! in_array( $request['type'], array( 'comment', 'note' ), true ) ) {
return new WP_Error(
'rest_invalid_comment_type',
__( 'Cannot create a comment with that type.', 'gutenberg' ),
array( 'status' => 400 )
);
}

// Validate note_reaction specific requirements.
if ( ! empty( $request['type'] ) && 'note_reaction' === $request['type'] ) {
// Validate parent is a note.
if ( empty( $request['parent'] ) ) {
return new WP_Error(
'rest_comment_invalid_parent',
__( 'A reaction must have a parent note.', 'gutenberg' ),
array( 'status' => 400 )
);
}

$parent_comment = get_comment( $request['parent'] );
if ( ! $parent_comment || 'note' !== $parent_comment->comment_type ) {
return new WP_Error(
'rest_comment_invalid_parent',
__( 'A reaction must be attached to a note.', 'gutenberg' ),
array( 'status' => 400 )
);
}

// Validate content is a valid emoji slug.
$valid_slugs = array( 'heart', 'celebration', 'smile', 'eyes', 'rocket' );
$emoji_slug = isset( $request['content'] ) ? wp_strip_all_tags( $request['content'] ) : '';
if ( ! in_array( $emoji_slug, $valid_slugs, true ) ) {
return new WP_Error(
'rest_comment_invalid_reaction',
__( 'Invalid reaction emoji.', 'gutenberg' ),
array( 'status' => 400 )
);
}

// Enforce uniqueness: prevent duplicate emoji per user per note.
$existing = get_comments(
array(
'parent' => $request['parent'],
'user_id' => get_current_user_id(),
'type' => 'note_reaction',
'status' => 'any',
)
);

foreach ( $existing as $existing_reaction ) {
if ( wp_strip_all_tags( $existing_reaction->comment_content ) === $emoji_slug ) {
return new WP_Error(
'rest_comment_duplicate_reaction',
__( 'You have already reacted with this emoji.', 'gutenberg' ),
array( 'status' => 409 )
);
}
}
}

$prepared_comment = $this->prepare_item_for_database( $request );
if ( is_wp_error( $prepared_comment ) ) {
return $prepared_comment;
Expand Down Expand Up @@ -430,9 +378,9 @@ public function create_item( $request ) {
);
}

// Don't check for duplicates or flooding for notes and reactions.
// Don't check for duplicates or flooding for notes.
$prepared_comment['comment_approved'] =
in_array( $prepared_comment['comment_type'], array( 'note', 'note_reaction' ), true ) ?
'note' === $prepared_comment['comment_type'] ?
'1' :
wp_allow_comment( $prepared_comment, true );

Expand Down Expand Up @@ -551,7 +499,7 @@ public function create_item( $request ) {
* @param string $post_type Post type name.
* @return bool True if post type supports block comments, false otherwise.
*/
private function check_post_type_supports_notes( $post_type ) {
protected function check_post_type_supports_notes( $post_type ) {
$supports = get_all_post_type_supports( $post_type );
if ( ! isset( $supports['editor'] ) ) {
return false;
Expand Down Expand Up @@ -580,7 +528,7 @@ protected function prepare_links( $comment ) {

// Embedding children for notes requires `type` and `status` inheritance.
// Note: This is only relevant change for the backport.
if ( isset( $links['children'] ) && in_array( $comment->comment_type, array( 'note', 'note_reaction' ), true ) ) {
if ( isset( $links['children'] ) && 'note' === $comment->comment_type ) {
$args = array(
'parent' => $comment->comment_ID,
'type' => $comment->comment_type,
Expand Down Expand Up @@ -657,11 +605,6 @@ protected function check_is_comment_content_allowed( $prepared_comment ) {
return true;
}

// Note reactions always have content (the emoji slug).
if ( isset( $check['comment_type'] ) && 'note_reaction' === $check['comment_type'] ) {
return true;
}

/*
* Do not allow a comment to be created with missing or empty
* comment_content. See wp_handle_comment_submission().
Expand All @@ -670,10 +613,11 @@ protected function check_is_comment_content_allowed( $prepared_comment ) {
}
}

add_action(
'rest_api_init',
function () {
$controller = new Gutenberg_REST_Comment_Controller_6_9();
$controller->register_routes();
}
);
/**
* Registers the Gutenberg REST comment controller for WordPress 6.9 compatibility.
*/
function gutenberg_register_comment_controller_6_9() {
$controller = new Gutenberg_REST_Comment_Controller_6_9();
$controller->register_routes();
}
add_action( 'rest_api_init', 'gutenberg_register_comment_controller_6_9' );
56 changes: 0 additions & 56 deletions lib/compat/wordpress-7.0/block-comments.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,59 +4,3 @@
*
* @package gutenberg
*/

/**
* Returns the default emoji list for note reactions, filterable via the
* 'note_reaction_emojis' hook.
*
* Each emoji definition requires:
* - 'emoji' (string) The emoji character.
* - 'label' (string) Human-readable label.
* - 'value' (string) Storage slug used as the database key.
*
* @since 7.0.0
*
* @return array[] Array of emoji definitions.
*/
function gutenberg_get_note_reaction_emojis() {
$default_emojis = array(
array(
'emoji' => '❤️',
'label' => __( 'Heart', 'gutenberg' ),
'value' => 'heart',
),
array(
'emoji' => '🎉',
'label' => __( 'Celebration', 'gutenberg' ),
'value' => 'celebration',
),
array(
'emoji' => '😄',
'label' => __( 'Smile', 'gutenberg' ),
'value' => 'smile',
),
array(
'emoji' => '👀',
'label' => __( 'Eyes', 'gutenberg' ),
'value' => 'eyes',
),
array(
'emoji' => '🚀',
'label' => __( 'Rocket', 'gutenberg' ),
'value' => 'rocket',
),
);

/**
* Filters the list of emoji available for note reactions.
*
* Each emoji requires an 'emoji' (character), 'label' (human-readable),
* and 'value' (storage slug).
*
* @since 7.0.0
*
* @param array[] $emojis Array of emoji definitions.
*/
return apply_filters( 'note_reaction_emojis', $default_emojis );
}
add_action( 'init', 'gutenberg_register_block_comment_reaction_metadata' );
Loading
Loading