From 65856f886ec43d68d6c439071a5871a7e448fde0 Mon Sep 17 00:00:00 2001 From: David Arenas Date: Fri, 8 Apr 2022 16:50:13 +0200 Subject: [PATCH 1/9] Backport functions needed by Comment blocks --- src/wp-includes/blocks.php | 150 +++++++++++++++++++++++++++++++++++++ 1 file changed, 150 insertions(+) diff --git a/src/wp-includes/blocks.php b/src/wp-includes/blocks.php index 45e36fc1dcc7d..896068ef9aed2 100644 --- a/src/wp-includes/blocks.php +++ b/src/wp-includes/blocks.php @@ -1358,3 +1358,153 @@ function _wp_multiple_block_styles( $metadata ) { return $metadata; } add_filter( 'block_type_metadata', '_wp_multiple_block_styles' ); + +/** + * Helper function that constructs a comment query vars array from the passed + * block properties. + * + * It's used with the Comment Query Loop inner blocks. + * + * @since 6.0.0 + * + * @param WP_Block $block Block instance. + * + * @return array Returns the comment query parameters to use with the + * WP_Comment_Query constructor. + */ +function build_comment_query_vars_from_block( $block ) { + + $comment_args = array( + 'orderby' => 'comment_date_gmt', + 'order' => 'ASC', + 'status' => 'approve', + 'no_found_rows' => false, + 'update_comment_meta_cache' => false, // We lazy-load comment meta for performance. + ); + + if ( ! empty( $block->context['postId'] ) ) { + $comment_args['post_id'] = (int) $block->context['postId']; + } + + if ( get_option( 'thread_comments' ) ) { + $comment_args['hierarchical'] = 'threaded'; + } else { + $comment_args['hierarchical'] = false; + } + + $per_page = get_option( 'comments_per_page' ); + $default_page = get_option( 'default_comments_page' ); + + if ( $per_page > 0 ) { + $comment_args['number'] = $per_page; + + $page = (int) get_query_var( 'cpage' ); + if ( $page ) { + $comment_args['paged'] = $page; + } elseif ( 'oldest' === $default_page ) { + $comment_args['paged'] = 1; + } elseif ( 'newest' === $default_page ) { + $comment_args['paged'] = (int) ( new WP_Comment_Query( $comment_args ) )->max_num_pages; + } + // Set the `cpage` query var to ensure the previous and next pagination links are correct + // when inheriting the Discussion Settings. + if ( 0 === $page && isset( $comment_args['paged'] ) && $comment_args['paged'] > 0 ) { + set_query_var( 'cpage', $comment_args['paged'] ); + } + } + + return $comment_args; +} + +/** + * Helper function that returns the proper pagination arrow html for + * `CommentsPaginationNext` and `CommentsPaginationPrevious` blocks based on the + * provided `paginationArrow` from `CommentsPagination` context. + * + * It's used in CommentsPaginationNext and CommentsPaginationPrevious blocks. + * + * @since 6.0.0 + * + * @param WP_Block $block Block instance. + * @param string $pagination_type Type of the arrow we will be rendering. + * Default 'next'. Accepts 'next' or 'previous'. + * + * @return string|null Returns the constructed WP_Query arguments. + */ +function get_comments_pagination_arrow( $block, $pagination_type = 'next' ) { + $arrow_map = array( + 'none' => '', + 'arrow' => array( + 'next' => '→', + 'previous' => '←', + ), + 'chevron' => array( + 'next' => '»', + 'previous' => '«', + ), + ); + if ( ! empty( $block->context['comments/paginationArrow'] ) && ! empty( $arrow_map[ $block->context['comments/paginationArrow'] ][ $pagination_type ] ) ) { + $arrow_attribute = $block->context['comments/paginationArrow']; + $arrow = $arrow_map[ $block->context['comments/paginationArrow'] ][ $pagination_type ]; + $arrow_classes = "wp-block-comments-pagination-$pagination_type-arrow is-arrow-$arrow_attribute"; + return "$arrow"; + } + return null; +} + +/** + * Workaround for getting discussion settings as block editor settings + * so any user can access to them without needing to be an admin. + * + * @since 6.0.0 + * + * @param array $settings Default editor settings. + * + * @return array Filtered editor settings. + */ +function extend_block_editor_settings_with_discussion_settings( $settings ) { + + $settings['__experimentalDiscussionSettings'] = array( + 'commentOrder' => get_option( 'comment_order' ), + 'commentsPerPage' => get_option( 'comments_per_page' ), + 'defaultCommentsPage' => get_option( 'default_comments_page' ), + 'pageComments' => get_option( 'page_comments' ), + 'threadComments' => get_option( 'thread_comments' ), + 'threadCommentsDepth' => get_option( 'thread_comments_depth' ), + 'avatarURL' => get_avatar_url( + '', + array( + 'size' => 96, + 'force_default' => true, + 'default' => get_option( 'avatar_default' ), + ) + ), + ); + + return $settings; +} +add_filter( 'block_editor_settings_all', 'extend_block_editor_settings_with_discussion_settings' ); + +/** + * Mark the `children` attr of comments as embeddable so they can be included in + * REST API responses without additional requests. + * + * @since 6.0.0 + * + * @return void + */ +function gutenberg_rest_comment_set_children_as_embeddable() { + add_filter( + 'rest_prepare_comment', + function ( $response ) { + $links = $response->get_links(); + if ( isset( $links['children'] ) ) { + $href = $links['children'][0]['href']; + $response->remove_link( 'children', $href ); + $response->add_link( 'children', $href, array( 'embeddable' => true ) ); + } + return $response; + } + ); +} +add_action( 'rest_api_init', 'gutenberg_rest_comment_set_children_as_embeddable' ); From 6bd346402a8e897716aa7d54239f22e8561f7613 Mon Sep 17 00:00:00 2001 From: David Arenas Date: Fri, 8 Apr 2022 16:58:19 +0200 Subject: [PATCH 2/9] Backport Comment Template tests --- .../tests/block-library/commentTemplate.php | 206 ++++++++++++++++++ 1 file changed, 206 insertions(+) create mode 100644 tests/phpunit/tests/block-library/commentTemplate.php diff --git a/tests/phpunit/tests/block-library/commentTemplate.php b/tests/phpunit/tests/block-library/commentTemplate.php new file mode 100644 index 0000000000000..5fe91f45de9d3 --- /dev/null +++ b/tests/phpunit/tests/block-library/commentTemplate.php @@ -0,0 +1,206 @@ +post->create_and_get( + array( + 'post_type' => 'dogs', + 'post_status' => 'publish', + 'post_name' => 'metaldog', + 'post_title' => 'Metal Dog', + 'post_content' => 'Metal Dog content', + 'post_excerpt' => 'Metal Dog', + ) + ); + + self::$comment_ids = self::factory()->comment->create_post_comments( + self::$custom_post->ID, + 1, + array( + 'comment_author' => 'Test', + 'comment_author_email' => 'test@example.org', + 'comment_content' => 'Hello world', + ) + ); + } + + function test_build_comment_query_vars_from_block_with_context() { + $parsed_blocks = parse_blocks( + '' + ); + + $block = new WP_Block( + $parsed_blocks[0], + array( + 'postId' => self::$custom_post->ID, + ) + ); + + $this->assertEquals( + build_comment_query_vars_from_block( $block ), + array( + 'orderby' => 'comment_date_gmt', + 'order' => 'ASC', + 'status' => 'approve', + 'no_found_rows' => false, + 'update_comment_meta_cache' => false, + 'post_id' => self::$custom_post->ID, + 'hierarchical' => 'threaded', + 'number' => 5, + 'paged' => 1, + ) + ); + } + + function test_build_comment_query_vars_from_block_no_context() { + $parsed_blocks = parse_blocks( + '' + ); + + $block = new WP_Block( $parsed_blocks[0] ); + + $this->assertEquals( + build_comment_query_vars_from_block( $block ), + array( + 'orderby' => 'comment_date_gmt', + 'order' => 'ASC', + 'status' => 'approve', + 'no_found_rows' => false, + 'update_comment_meta_cache' => false, + 'hierarchical' => 'threaded', + 'number' => 5, + 'paged' => 1, + ) + ); + } + + /** + * Test rendering a single comment + */ + function test_rendering_comment_template() { + $parsed_blocks = parse_blocks( + '' + ); + + $block = new WP_Block( + $parsed_blocks[0], + array( + 'postId' => self::$custom_post->ID, + ) + ); + + // Here we use the function prefixed with 'gutenberg_*' because it's added + // in the build step. + $this->assertEquals( + gutenberg_render_block_core_comment_template( null, null, $block ), + '
  1. Test
    Hello world
' + ); + } + + /** + * Test rendering 3 nested comments: + * + * └─ comment 1 + *   └─ comment 2 + *    └─ comment 3 + */ + function test_rendering_comment_template_nested() { + $nested_comment_ids = self::factory()->comment->create_post_comments( + self::$custom_post->ID, + 1, + array( + 'comment_parent' => self::$comment_ids[0], + 'comment_author' => 'Test', + 'comment_author_email' => 'test@example.org', + 'comment_content' => 'Hello world', + ) + ); + + self::factory()->comment->create_post_comments( + self::$custom_post->ID, + 1, + array( + 'comment_parent' => $nested_comment_ids[0], + 'comment_author' => 'Test', + 'comment_author_email' => 'test@example.org', + 'comment_content' => 'Hello world', + ) + ); + + $parsed_blocks = parse_blocks( + '' + ); + + $block = new WP_Block( + $parsed_blocks[0], + array( + 'postId' => self::$custom_post->ID, + ) + ); + + $this->assertEquals( + gutenberg_render_block_core_comment_template( null, null, $block ), + '
  1. Test
    Hello world
    1. Test
      Hello world
      1. Test
        Hello world
' + ); + } + /** + * Test that both "Older Comments" and "Newer Comments" are displayed in the correct order + * inside the Comment Query Loop when we enable pagination on Discussion Settings. + * In order to do that, it should exist a query var 'cpage' set with the $comment_args['paged'] value. + */ + function test_build_comment_query_vars_from_block_sets_cpage_var() { + + // This could be any number, we set a fixed one instead of a random for better performance. + $comment_query_max_num_pages = 5; + // We substract 1 because we created 1 comment at the beggining. + $post_comments_numbers = ( self::$per_page * $comment_query_max_num_pages ) - 1; + self::factory()->comment->create_post_comments( + self::$custom_post->ID, + $post_comments_numbers, + array( + 'comment_author' => 'Test', + 'comment_author_email' => 'test@example.org', + 'comment_content' => 'Hello world', + ) + ); + $parsed_blocks = parse_blocks( + '' + ); + + $block = new WP_Block( + $parsed_blocks[0], + array( + 'postId' => self::$custom_post->ID, + 'comments/inherit' => true, + ) + ); + $actual = build_comment_query_vars_from_block( $block ); + $this->assertEquals( $actual['paged'], $comment_query_max_num_pages ); + $this->assertEquals( get_query_var( 'cpage' ), $comment_query_max_num_pages ); + } +} From 2c0a02dc90d2206b7720b94d74daa6adef993269 Mon Sep 17 00:00:00 2001 From: David Arenas Date: Mon, 11 Apr 2022 12:07:21 +0200 Subject: [PATCH 3/9] Update package-lock --- package-lock.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package-lock.json b/package-lock.json index b2052c7006df5..6cb71ec02b797 100644 --- a/package-lock.json +++ b/package-lock.json @@ -7750,7 +7750,7 @@ }, "browserify-aes": { "version": "1.2.0", - "resolved": "http://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz", + "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz", "integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==", "dev": true, "requires": { From 9226c0304d2e78cd4d520bbbea5648b20d4cbe8d Mon Sep 17 00:00:00 2001 From: David Arenas Date: Mon, 11 Apr 2022 12:08:18 +0200 Subject: [PATCH 4/9] Rename setUp to set_up --- tests/phpunit/tests/block-library/commentTemplate.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/phpunit/tests/block-library/commentTemplate.php b/tests/phpunit/tests/block-library/commentTemplate.php index 5fe91f45de9d3..7ebd48df9b6d0 100644 --- a/tests/phpunit/tests/block-library/commentTemplate.php +++ b/tests/phpunit/tests/block-library/commentTemplate.php @@ -20,8 +20,8 @@ class Test_Block_Library_CommentTemplate extends WP_UnitTestCase { private static $comment_ids; private static $per_page = 5; - public function setUp() { - parent::setUp(); + public function set_up() { + parent::set_up(); update_option( 'page_comments', true ); update_option( 'comments_per_page', self::$per_page ); From b8dbf8825dea65fd3bf86dc6fbd92117ce0c9687 Mon Sep 17 00:00:00 2001 From: David Arenas Date: Mon, 11 Apr 2022 12:09:26 +0200 Subject: [PATCH 5/9] Remove gutenberg prefix from render_block function --- tests/phpunit/tests/block-library/commentTemplate.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/phpunit/tests/block-library/commentTemplate.php b/tests/phpunit/tests/block-library/commentTemplate.php index 7ebd48df9b6d0..382d74ebbc557 100644 --- a/tests/phpunit/tests/block-library/commentTemplate.php +++ b/tests/phpunit/tests/block-library/commentTemplate.php @@ -117,7 +117,7 @@ function test_rendering_comment_template() { // Here we use the function prefixed with 'gutenberg_*' because it's added // in the build step. $this->assertEquals( - gutenberg_render_block_core_comment_template( null, null, $block ), + render_block_core_comment_template( null, null, $block ), '
  1. Test
    Hello world
' ); } @@ -164,7 +164,7 @@ function test_rendering_comment_template_nested() { ); $this->assertEquals( - gutenberg_render_block_core_comment_template( null, null, $block ), + render_block_core_comment_template( null, null, $block ), '
  1. Test
    Hello world
    1. Test
      Hello world
      1. Test
        Hello world
' ); } From 17b5ebf14114838cdc0042c0003c1800fd2d25a9 Mon Sep 17 00:00:00 2001 From: David Arenas Date: Mon, 11 Apr 2022 13:01:39 +0200 Subject: [PATCH 6/9] Move experimental discussion settings to block-editor.php --- src/wp-includes/block-editor.php | 17 ++++++++++++++++ src/wp-includes/blocks.php | 33 -------------------------------- 2 files changed, 17 insertions(+), 33 deletions(-) diff --git a/src/wp-includes/block-editor.php b/src/wp-includes/block-editor.php index c5cb180117acc..9fe559fc4187b 100644 --- a/src/wp-includes/block-editor.php +++ b/src/wp-includes/block-editor.php @@ -396,6 +396,23 @@ function get_block_editor_settings( array $custom_settings, $block_editor_contex $editor_settings['localAutosaveInterval'] = 15; + $editor_settings['__experimentalDiscussionSettings'] = array( + 'commentOrder' => get_option( 'comment_order' ), + 'commentsPerPage' => get_option( 'comments_per_page' ), + 'defaultCommentsPage' => get_option( 'default_comments_page' ), + 'pageComments' => get_option( 'page_comments' ), + 'threadComments' => get_option( 'thread_comments' ), + 'threadCommentsDepth' => get_option( 'thread_comments_depth' ), + 'avatarURL' => get_avatar_url( + '', + array( + 'size' => 96, + 'force_default' => true, + 'default' => get_option( 'avatar_default' ), + ) + ), + ); + /** * Filters the settings to pass to the block editor for all editor type. * diff --git a/src/wp-includes/blocks.php b/src/wp-includes/blocks.php index 896068ef9aed2..b691eefc7ed8d 100644 --- a/src/wp-includes/blocks.php +++ b/src/wp-includes/blocks.php @@ -1452,39 +1452,6 @@ function get_comments_pagination_arrow( $block, $pagination_type = 'next' ) { return null; } -/** - * Workaround for getting discussion settings as block editor settings - * so any user can access to them without needing to be an admin. - * - * @since 6.0.0 - * - * @param array $settings Default editor settings. - * - * @return array Filtered editor settings. - */ -function extend_block_editor_settings_with_discussion_settings( $settings ) { - - $settings['__experimentalDiscussionSettings'] = array( - 'commentOrder' => get_option( 'comment_order' ), - 'commentsPerPage' => get_option( 'comments_per_page' ), - 'defaultCommentsPage' => get_option( 'default_comments_page' ), - 'pageComments' => get_option( 'page_comments' ), - 'threadComments' => get_option( 'thread_comments' ), - 'threadCommentsDepth' => get_option( 'thread_comments_depth' ), - 'avatarURL' => get_avatar_url( - '', - array( - 'size' => 96, - 'force_default' => true, - 'default' => get_option( 'avatar_default' ), - ) - ), - ); - - return $settings; -} -add_filter( 'block_editor_settings_all', 'extend_block_editor_settings_with_discussion_settings' ); - /** * Mark the `children` attr of comments as embeddable so they can be included in * REST API responses without additional requests. From 269aef2dd6fa30b56f30fdcf64355b55418b8138 Mon Sep 17 00:00:00 2001 From: David Arenas Date: Mon, 11 Apr 2022 13:53:22 +0200 Subject: [PATCH 7/9] Set embedded true for comment children --- src/wp-includes/blocks.php | 24 ------------------- .../class-wp-rest-comments-controller.php | 3 ++- 2 files changed, 2 insertions(+), 25 deletions(-) diff --git a/src/wp-includes/blocks.php b/src/wp-includes/blocks.php index b691eefc7ed8d..72f0198626e71 100644 --- a/src/wp-includes/blocks.php +++ b/src/wp-includes/blocks.php @@ -1451,27 +1451,3 @@ function get_comments_pagination_arrow( $block, $pagination_type = 'next' ) { } return null; } - -/** - * Mark the `children` attr of comments as embeddable so they can be included in - * REST API responses without additional requests. - * - * @since 6.0.0 - * - * @return void - */ -function gutenberg_rest_comment_set_children_as_embeddable() { - add_filter( - 'rest_prepare_comment', - function ( $response ) { - $links = $response->get_links(); - if ( isset( $links['children'] ) ) { - $href = $links['children'][0]['href']; - $response->remove_link( 'children', $href ); - $response->add_link( 'children', $href, array( 'embeddable' => true ) ); - } - return $response; - } - ); -} -add_action( 'rest_api_init', 'gutenberg_rest_comment_set_children_as_embeddable' ); diff --git a/src/wp-includes/rest-api/endpoints/class-wp-rest-comments-controller.php b/src/wp-includes/rest-api/endpoints/class-wp-rest-comments-controller.php index 6e2daa829a508..c2d9e87635a4e 100644 --- a/src/wp-includes/rest-api/endpoints/class-wp-rest-comments-controller.php +++ b/src/wp-includes/rest-api/endpoints/class-wp-rest-comments-controller.php @@ -1196,7 +1196,8 @@ protected function prepare_links( $comment ) { $rest_url = add_query_arg( $args, rest_url( $this->namespace . '/' . $this->rest_base ) ); $links['children'] = array( - 'href' => $rest_url, + 'href' => $rest_url, + 'embedded' => true, ); } From 537d27225db483c6c16afc1daef6364d4f7668e4 Mon Sep 17 00:00:00 2001 From: David Arenas Date: Mon, 11 Apr 2022 14:05:31 +0200 Subject: [PATCH 8/9] Fix argument order in assertions --- .../tests/block-library/commentTemplate.php | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/tests/phpunit/tests/block-library/commentTemplate.php b/tests/phpunit/tests/block-library/commentTemplate.php index 382d74ebbc557..9555de2fcd14b 100644 --- a/tests/phpunit/tests/block-library/commentTemplate.php +++ b/tests/phpunit/tests/block-library/commentTemplate.php @@ -62,7 +62,6 @@ function test_build_comment_query_vars_from_block_with_context() { ); $this->assertEquals( - build_comment_query_vars_from_block( $block ), array( 'orderby' => 'comment_date_gmt', 'order' => 'ASC', @@ -73,7 +72,8 @@ function test_build_comment_query_vars_from_block_with_context() { 'hierarchical' => 'threaded', 'number' => 5, 'paged' => 1, - ) + ), + build_comment_query_vars_from_block( $block ) ); } @@ -85,7 +85,6 @@ function test_build_comment_query_vars_from_block_no_context() { $block = new WP_Block( $parsed_blocks[0] ); $this->assertEquals( - build_comment_query_vars_from_block( $block ), array( 'orderby' => 'comment_date_gmt', 'order' => 'ASC', @@ -95,7 +94,8 @@ function test_build_comment_query_vars_from_block_no_context() { 'hierarchical' => 'threaded', 'number' => 5, 'paged' => 1, - ) + ), + build_comment_query_vars_from_block( $block ) ); } @@ -117,8 +117,8 @@ function test_rendering_comment_template() { // Here we use the function prefixed with 'gutenberg_*' because it's added // in the build step. $this->assertEquals( - render_block_core_comment_template( null, null, $block ), - '
  1. Test
    Hello world
' + '
  1. Test
    Hello world
', + render_block_core_comment_template( null, null, $block ) ); } @@ -164,8 +164,8 @@ function test_rendering_comment_template_nested() { ); $this->assertEquals( - render_block_core_comment_template( null, null, $block ), - '
  1. Test
    Hello world
    1. Test
      Hello world
      1. Test
        Hello world
' + '
  1. Test
    Hello world
    1. Test
      Hello world
      1. Test
        Hello world
', + render_block_core_comment_template( null, null, $block ) ); } /** @@ -200,7 +200,7 @@ function test_build_comment_query_vars_from_block_sets_cpage_var() { ) ); $actual = build_comment_query_vars_from_block( $block ); - $this->assertEquals( $actual['paged'], $comment_query_max_num_pages ); - $this->assertEquals( get_query_var( 'cpage' ), $comment_query_max_num_pages ); + $this->assertEquals( $comment_query_max_num_pages, $actual['paged'] ); + $this->assertEquals( $comment_query_max_num_pages, get_query_var( 'cpage' ) ); } } From 494d58fa040202e2971690cd70cb6d4c72bcb316 Mon Sep 17 00:00:00 2001 From: David Arenas Date: Mon, 11 Apr 2022 14:13:48 +0200 Subject: [PATCH 9/9] Revert "Update package-lock" This reverts commit 2c0a02dc90d2206b7720b94d74daa6adef993269. --- package-lock.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package-lock.json b/package-lock.json index 6cb71ec02b797..b2052c7006df5 100644 --- a/package-lock.json +++ b/package-lock.json @@ -7750,7 +7750,7 @@ }, "browserify-aes": { "version": "1.2.0", - "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz", + "resolved": "http://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz", "integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==", "dev": true, "requires": {