From cc8c199b86ae231dca2ad96ecfca95dfd18d27bd Mon Sep 17 00:00:00 2001 From: David Arenas Date: Tue, 18 Jan 2022 13:24:52 +0100 Subject: [PATCH 01/25] REST: Set children attr of comments as embeddable --- lib/rest-api.php | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/lib/rest-api.php b/lib/rest-api.php index 9fef898eb6d60c..99743a7167a718 100644 --- a/lib/rest-api.php +++ b/lib/rest-api.php @@ -220,3 +220,22 @@ function gutenberg_register_edit_site_export_endpoint() { $editor_settings->register_routes(); } add_action( 'rest_api_init', 'gutenberg_register_edit_site_export_endpoint' ); + +/** + * Mark the `children` attr of comments as embeddable so they can be included in + * REST API responses without additional requests. + * + * @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 5b6c68c7853df9418ca24f671ba24b79e527ba79 Mon Sep 17 00:00:00 2001 From: David Arenas Date: Mon, 24 Jan 2022 11:15:36 +0100 Subject: [PATCH 02/25] REST: Expose some discussion settings --- lib/rest-api.php | 44 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/lib/rest-api.php b/lib/rest-api.php index 99743a7167a718..bb56b24418282b 100644 --- a/lib/rest-api.php +++ b/lib/rest-api.php @@ -239,3 +239,47 @@ function gutenberg_rest_comment_set_children_as_embeddable() { } ); } add_action( 'rest_api_init', 'gutenberg_rest_comment_set_children_as_embeddable'); + +/** + * Register some comment-related settings to make them appear in the REST API. + * + * @return void + */ +function gutenberg_rest_settings_add_discussion_settings() { + register_setting( + 'discussion', + 'comments_per_page', + array( + 'show_in_rest' => array( + 'name' => 'comments_per_page', + ), + 'type' => 'number', + 'description' => __( 'Number of comments per page.' ), + ) + ); + + register_setting( + 'discussion', + 'comment_order', + array( + 'show_in_rest' => array( + 'name' => 'comment_order', + ), + 'type' => 'string', + 'description' => __( 'Order in which comments should appear.' ), + ) + ); + + register_setting( + 'discussion', + 'default_comments_page', + array( + 'show_in_rest' => array( + 'name' => 'default_comments_page', + ), + 'type' => 'string', + 'description' => __( 'Page displayed by default.' ), + ) + ); +} +add_action( 'rest_api_init', 'gutenberg_rest_settings_add_discussion_settings' ); From 56e4c619138b674fc1e983110a6860da9bf71fe8 Mon Sep 17 00:00:00 2001 From: David Arenas Date: Mon, 24 Jan 2022 11:21:47 +0100 Subject: [PATCH 03/25] Add hook to generate comment query args --- .../src/comment-template/edit.js | 76 ++++------- .../src/comment-template/hooks.js | 120 ++++++++++++++++++ 2 files changed, 147 insertions(+), 49 deletions(-) create mode 100644 packages/block-library/src/comment-template/hooks.js diff --git a/packages/block-library/src/comment-template/edit.js b/packages/block-library/src/comment-template/edit.js index 45a42678e5a56e..c30faa0b8d31c8 100644 --- a/packages/block-library/src/comment-template/edit.js +++ b/packages/block-library/src/comment-template/edit.js @@ -12,12 +12,12 @@ import { __experimentalUseBlockPreview as useBlockPreview, } from '@wordpress/block-editor'; import { Spinner } from '@wordpress/components'; -import { store as coreStore } from '@wordpress/core-data'; +import { store as coreStore, useEntityProp } from '@wordpress/core-data'; /** * Internal dependencies */ -import { convertToTree } from './util'; +import { useCommentQueryArgs, useCommentTree } from './hooks'; const TEMPLATE = [ [ 'core/comment-author-avatar' ], @@ -106,10 +106,10 @@ function CommentTemplateInnerBlocks( { { comment === ( activeComment || firstComment ) ? children : null } { /* To avoid flicker when switching active block contexts, a preview - is ALWAYS rendered and the preview for the active block is hidden. - This ensures that when switching the active block, the component is not + is ALWAYS rendered and the preview for the active block is hidden. + This ensures that when switching the active block, the component is not mounted again but rather it only toggles the `isHidden` prop. - + The same strategy is used for preventing the flicker in the Post Template block. */ } ); -export default function CommentTemplateEdit( { - clientId, - context: { postId, 'comments/perPage': perPage, 'comments/order': order }, -} ) { +export default function CommentTemplateEdit( { clientId, context } ) { const blockProps = useBlockProps(); const [ activeComment, setActiveComment ] = useState(); - const { - commentOrder, - commentsPerPage, - threadCommentsDepth, - threadComments, - } = useSelect( ( select ) => { - const { getSettings } = select( blockEditorStore ); - return getSettings().__experimentalDiscussionSettings; - } ); - const { rawComments, blocks } = useSelect( + const commentQuery = useCommentQueryArgs( { context } ); + + const { topLevelComments, blocks } = useSelect( ( select ) => { const { getEntityRecords } = select( coreStore ); const { getBlocks } = select( blockEditorStore ); - const commentQuery = { - post: postId, - status: 'approve', - context: 'embed', - order: order || commentOrder, - }; - - if ( order ) { - commentQuery.order = order; - } return { - rawComments: getEntityRecords( - 'root', - 'comment', - commentQuery - ), + // Request only top-level comments. Replies are embedded. + topLevelComments: commentQuery + ? getEntityRecords( 'root', 'comment', commentQuery ) + : null, blocks: getBlocks( clientId ), }; }, - [ postId, clientId, order ] + [ clientId, commentQuery ] ); - // TODO: Replicate the logic used on the server. - perPage = perPage || commentsPerPage; - // We convert the flat list of comments to tree. - // Then, we show only a maximum of `perPage` number of comments. - // This is because passing `per_page` to `getEntityRecords()` does not - // take into account nested comments. - let comments = useMemo( - () => convertToTree( rawComments ).slice( 0, perPage ), - [ rawComments, perPage ] - ); + // Reverse the order of top comments if needed, as specified in the + // Discussion settings. + const [ commentOrder ] = useEntityProp( 'root', 'site', 'comment_order' ); + if ( commentOrder === 'desc' ) { + topLevelComments?.reverse(); + } + + // Generate a tree structure of comment IDs. + const { commentTree } = useCommentTree( topLevelComments ); - if ( ! rawComments ) { + if ( ! topLevelComments ) { return (

@@ -271,20 +249,20 @@ export default function CommentTemplateEdit( { } if ( ! postId ) { - comments = getCommentsPlaceholder( { + commentTree = getCommentsPlaceholder( { perPage, threadComments, threadCommentsDepth, } ); } - if ( ! comments.length ) { + if ( ! commentTree.length ) { return

{ __( 'No results found.' ) }

; } return ( { + let { postId, 'comments/perPage': perPage } = context; + + // Initialize the query args that are not going to change. + const defaultQueryArgs = { + status: 'approve', + order: 'asc', + context: 'embed', + parent: 0, + _embed: 'children', + }; + + // Get the Discussion settings that may be needed to query the comments. + const [ commentsPerPage ] = useEntityProp( + 'root', + 'site', + 'comments_per_page' + ); + const [ defaultCommentsPage ] = useEntityProp( + 'root', + 'site', + 'default_comments_page' + ); + + // If a block props is not set, use the settings value to generate the + // appropriate query arg. + perPage = perPage || commentsPerPage; + + // Create a variable for the default page's number. If the default page is + // the newest one, the only way to know the page's index is by using the + // `X-WP-TotalPages` header. In that case, that sadly forces to make an + // additional request. + const [ defaultPage, setDefaultPage ] = useState( 1 ); + const [ isDefaultPageKnown, setIsDefaultPageKnown ] = useState( + defaultCommentsPage !== 'newest' + ); + const isFirstPage = defaultCommentsPage !== 'newest'; + + useLayoutEffect( () => { + if ( defaultCommentsPage !== 'newest' ) { + return; + } + // Reset the page number as it is going to change. + setIsDefaultPageKnown( false ); + apiFetch( { + path: addQueryArgs( '/wp/v2/comments', { + ...defaultQueryArgs, + post: postId, + per_page: perPage, + _fields: 'id', // For performance purposes. + } ), + method: 'HEAD', // We only need headers, no body. + parse: false, + } ).then( ( res ) => { + setDefaultPage( parseInt( res.headers.get( 'X-WP-TotalPages' ) ) ); + setIsDefaultPageKnown( true ); + } ); + }, [ defaultCommentsPage, postId, perPage ] ); + + // Merge, memoize and return all query arguments, unless the default page's + // number is not known yet. + return useMemo( () => { + if ( isFirstPage ) { + return { + ...defaultQueryArgs, + post: postId, + per_page: perPage, + page: 1, + }; + } + + return isDefaultPageKnown + ? { + ...defaultQueryArgs, + post: postId, + per_page: perPage, + page: defaultPage, + } + : null; + }, [ isDefaultPageKnown, postId, perPage, defaultPage ] ); +}; + +/** + * Generate a tree structure of comment IDs. + * + * @param {*} topLevelComments + * @return {Object} TODO Write JSDOC. + */ +export const useCommentTree = ( topLevelComments ) => { + const commentTree = useMemo( + () => + topLevelComments?.map( ( { id, _embedded } ) => { + const [ children ] = _embedded?.children || []; + return { + commentId: id, + children: children?.map( ( child ) => ( { + commentId: child.id, + } ) ), + }; + } ), + [ topLevelComments ] + ); + + return { commentTree }; +}; From 01e0c457ace4588f81219fddd68441da2399d905 Mon Sep 17 00:00:00 2001 From: David Arenas Date: Tue, 25 Jan 2022 00:28:03 +0100 Subject: [PATCH 04/25] Fix how the default comments page index is computed --- .../src/comment-template/hooks.js | 100 ++++++++++-------- 1 file changed, 58 insertions(+), 42 deletions(-) diff --git a/packages/block-library/src/comment-template/hooks.js b/packages/block-library/src/comment-template/hooks.js index 033e7a4a69cb90..5c3dbf664797f3 100644 --- a/packages/block-library/src/comment-template/hooks.js +++ b/packages/block-library/src/comment-template/hooks.js @@ -1,7 +1,7 @@ /** * WordPress dependencies */ -import { useState, useLayoutEffect, useMemo } from '@wordpress/element'; +import { useState, useEffect, useMemo } from '@wordpress/element'; import { useEntityProp } from '@wordpress/core-data'; import { addQueryArgs } from '@wordpress/url'; import apiFetch from '@wordpress/api-fetch'; @@ -17,7 +17,7 @@ export const useCommentQueryArgs = ( { context } ) => { let { postId, 'comments/perPage': perPage } = context; // Initialize the query args that are not going to change. - const defaultQueryArgs = { + const queryArgs = { status: 'approve', order: 'asc', context: 'embed', @@ -41,58 +41,74 @@ export const useCommentQueryArgs = ( { context } ) => { // appropriate query arg. perPage = perPage || commentsPerPage; - // Create a variable for the default page's number. If the default page is - // the newest one, the only way to know the page's index is by using the - // `X-WP-TotalPages` header. In that case, that sadly forces to make an - // additional request. - const [ defaultPage, setDefaultPage ] = useState( 1 ); - const [ isDefaultPageKnown, setIsDefaultPageKnown ] = useState( - defaultCommentsPage !== 'newest' - ); - const isFirstPage = defaultCommentsPage !== 'newest'; + // Get the number of the default page. + const page = useDefaultPage( { + defaultCommentsPage, + postId, + perPage, + queryArgs, + } ); + + // Merge, memoize and return all query arguments, unless the default page's + // number is not known yet. + return useMemo( () => { + return page + ? { + ...queryArgs, + post: postId, + per_page: perPage, + page, + } + : null; + }, [ postId, perPage, page ] ); +}; + +/** + * Return the index of the default page, depending on whether + * `defaultCommentsPage` is `newest` or not. If the default page is the newest + * one, the only way to know the page's index is by using the `X-WP-TotalPages` + * header. That case sadly forces to make an additional request. + * + * @param {*} param0 + * @return {number} Default comments page index. + */ +const useDefaultPage = ( { + defaultCommentsPage, + postId, + perPage, + queryArgs, +} ) => { + // Store the default page indices. + const [ defaultPages, setDefaultPages ] = useState( {} ); + const key = `${ postId }_${ perPage }`; + const page = defaultPages[ key ] || 0; - useLayoutEffect( () => { - if ( defaultCommentsPage !== 'newest' ) { + useEffect( () => { + // Do nothing if the page is already known or not the newest page. + if ( page || defaultCommentsPage !== 'newest' ) { return; } - // Reset the page number as it is going to change. - setIsDefaultPageKnown( false ); + // We need to fetch comments to know the index. Use HEAD and limit + // fields just to ID, to make this call as light as possible. apiFetch( { path: addQueryArgs( '/wp/v2/comments', { - ...defaultQueryArgs, + ...queryArgs, post: postId, per_page: perPage, - _fields: 'id', // For performance purposes. + _fields: 'id', } ), - method: 'HEAD', // We only need headers, no body. + method: 'HEAD', parse: false, } ).then( ( res ) => { - setDefaultPage( parseInt( res.headers.get( 'X-WP-TotalPages' ) ) ); - setIsDefaultPageKnown( true ); + setDefaultPages( { + ...defaultPages, + [ key ]: parseInt( res.headers.get( 'X-WP-TotalPages' ) ), + } ); } ); - }, [ defaultCommentsPage, postId, perPage ] ); - - // Merge, memoize and return all query arguments, unless the default page's - // number is not known yet. - return useMemo( () => { - if ( isFirstPage ) { - return { - ...defaultQueryArgs, - post: postId, - per_page: perPage, - page: 1, - }; - } + }, [ defaultCommentsPage, postId, perPage, setDefaultPages ] ); - return isDefaultPageKnown - ? { - ...defaultQueryArgs, - post: postId, - per_page: perPage, - page: defaultPage, - } - : null; - }, [ isDefaultPageKnown, postId, perPage, defaultPage ] ); + // The oldest one is always the first one. + return defaultCommentsPage === 'newest' ? page : 1; }; /** From 75239add5b9dd51fba1bb1137cdf224d9a2b1073 Mon Sep 17 00:00:00 2001 From: David Arenas Date: Mon, 31 Jan 2022 14:15:18 +0100 Subject: [PATCH 05/25] Move REST API code to experimental --- lib/compat/experimental/blocks.php | 21 ++++++++++ lib/rest-api.php | 63 ------------------------------ 2 files changed, 21 insertions(+), 63 deletions(-) diff --git a/lib/compat/experimental/blocks.php b/lib/compat/experimental/blocks.php index 4022eab22dc423..eda1ef61fc7331 100644 --- a/lib/compat/experimental/blocks.php +++ b/lib/compat/experimental/blocks.php @@ -128,3 +128,24 @@ function extend_block_editor_settings_with_discussion_settings( $settings ) { } } add_filter( 'block_editor_settings_all', 'extend_block_editor_settings_with_discussion_settings' ); + +if ( ! function_exists( 'gutenberg_rest_comment_set_children_as_embeddable' )) { + /** + * Mark the `children` attr of comments as embeddable so they can be included in + * REST API responses without additional requests. + * + * @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/lib/rest-api.php b/lib/rest-api.php index bb56b24418282b..9fef898eb6d60c 100644 --- a/lib/rest-api.php +++ b/lib/rest-api.php @@ -220,66 +220,3 @@ function gutenberg_register_edit_site_export_endpoint() { $editor_settings->register_routes(); } add_action( 'rest_api_init', 'gutenberg_register_edit_site_export_endpoint' ); - -/** - * Mark the `children` attr of comments as embeddable so they can be included in - * REST API responses without additional requests. - * - * @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'); - -/** - * Register some comment-related settings to make them appear in the REST API. - * - * @return void - */ -function gutenberg_rest_settings_add_discussion_settings() { - register_setting( - 'discussion', - 'comments_per_page', - array( - 'show_in_rest' => array( - 'name' => 'comments_per_page', - ), - 'type' => 'number', - 'description' => __( 'Number of comments per page.' ), - ) - ); - - register_setting( - 'discussion', - 'comment_order', - array( - 'show_in_rest' => array( - 'name' => 'comment_order', - ), - 'type' => 'string', - 'description' => __( 'Order in which comments should appear.' ), - ) - ); - - register_setting( - 'discussion', - 'default_comments_page', - array( - 'show_in_rest' => array( - 'name' => 'default_comments_page', - ), - 'type' => 'string', - 'description' => __( 'Page displayed by default.' ), - ) - ); -} -add_action( 'rest_api_init', 'gutenberg_rest_settings_add_discussion_settings' ); From c3a0beb7b9f85e54248686bc7f9d3068f5bfdb58 Mon Sep 17 00:00:00 2001 From: David Arenas Date: Mon, 31 Jan 2022 20:11:17 +0100 Subject: [PATCH 06/25] Use experimental settings in Comment Template --- .../src/comment-template/edit.js | 37 ++++++++++++++----- .../src/comment-template/hooks.js | 25 +++++-------- 2 files changed, 38 insertions(+), 24 deletions(-) diff --git a/packages/block-library/src/comment-template/edit.js b/packages/block-library/src/comment-template/edit.js index c30faa0b8d31c8..af661b4e71236f 100644 --- a/packages/block-library/src/comment-template/edit.js +++ b/packages/block-library/src/comment-template/edit.js @@ -12,7 +12,7 @@ import { __experimentalUseBlockPreview as useBlockPreview, } from '@wordpress/block-editor'; import { Spinner } from '@wordpress/components'; -import { store as coreStore, useEntityProp } from '@wordpress/core-data'; +import { store as coreStore } from '@wordpress/core-data'; /** * Internal dependencies @@ -207,12 +207,24 @@ const CommentsList = ( { ); -export default function CommentTemplateEdit( { clientId, context } ) { +export default function CommentTemplateEdit( { + clientId, + context: { + postId, + 'comments/perPage': perPage, + 'comments/order': order, + 'comments/defaultPage': defaultPage, + }, +} ) { const blockProps = useBlockProps(); const [ activeComment, setActiveComment ] = useState(); - const commentQuery = useCommentQueryArgs( { context } ); + const commentQuery = useCommentQueryArgs( { + postId, + perPage, + defaultPage, + } ); const { topLevelComments, blocks } = useSelect( ( select ) => { @@ -230,15 +242,22 @@ export default function CommentTemplateEdit( { clientId, context } ) { [ clientId, commentQuery ] ); + const { commentOrder } = useSelect( ( select ) => { + const { getSettings } = select( blockEditorStore ); + return getSettings().__experimentalDiscussionSettings; + } ); + order = order || commentOrder; + // Reverse the order of top comments if needed, as specified in the - // Discussion settings. - const [ commentOrder ] = useEntityProp( 'root', 'site', 'comment_order' ); - if ( commentOrder === 'desc' ) { - topLevelComments?.reverse(); - } + // Discussion settings. NOTE that this only changes the order of comments in + // the given page, not the order of pages. // Generate a tree structure of comment IDs. - const { commentTree } = useCommentTree( topLevelComments ); + const { commentTree } = useCommentTree( + order === 'desc' + ? topLevelComments?.slice().reverse() + : topLevelComments + ); if ( ! topLevelComments ) { return ( diff --git a/packages/block-library/src/comment-template/hooks.js b/packages/block-library/src/comment-template/hooks.js index 5c3dbf664797f3..32800f90080ff8 100644 --- a/packages/block-library/src/comment-template/hooks.js +++ b/packages/block-library/src/comment-template/hooks.js @@ -2,7 +2,8 @@ * WordPress dependencies */ import { useState, useEffect, useMemo } from '@wordpress/element'; -import { useEntityProp } from '@wordpress/core-data'; +import { useSelect } from '@wordpress/data'; +import { store as blockEditorStore } from '@wordpress/block-editor'; import { addQueryArgs } from '@wordpress/url'; import apiFetch from '@wordpress/api-fetch'; @@ -13,9 +14,7 @@ import apiFetch from '@wordpress/api-fetch'; * @param {*} param0 * @return {Object} TODO Write JSDOC. */ -export const useCommentQueryArgs = ( { context } ) => { - let { postId, 'comments/perPage': perPage } = context; - +export const useCommentQueryArgs = ( { postId, perPage, defaultPage } ) => { // Initialize the query args that are not going to change. const queryArgs = { status: 'approve', @@ -26,24 +25,20 @@ export const useCommentQueryArgs = ( { context } ) => { }; // Get the Discussion settings that may be needed to query the comments. - const [ commentsPerPage ] = useEntityProp( - 'root', - 'site', - 'comments_per_page' - ); - const [ defaultCommentsPage ] = useEntityProp( - 'root', - 'site', - 'default_comments_page' - ); + const { commentsPerPage, defaultCommentsPage } = useSelect( ( select ) => { + const { getSettings } = select( blockEditorStore ); + const { __experimentalDiscussionSettings } = getSettings(); + return __experimentalDiscussionSettings; + } ); // If a block props is not set, use the settings value to generate the // appropriate query arg. perPage = perPage || commentsPerPage; + defaultPage = defaultPage || defaultCommentsPage; // Get the number of the default page. const page = useDefaultPage( { - defaultCommentsPage, + defaultCommentsPage: defaultPage, postId, perPage, queryArgs, From 7c7cb3d7a5d8efdb52acfced2ed12e2f94d17c29 Mon Sep 17 00:00:00 2001 From: David Arenas Date: Mon, 31 Jan 2022 20:12:56 +0100 Subject: [PATCH 07/25] Add `defaultPage` attribute to Comments Query Loop --- docs/reference-guides/core-blocks.md | 2 +- .../src/comment-template/block.json | 7 ++++- .../src/comments-query-loop/block.json | 5 ++++ .../src/comments-query-loop/edit.js | 13 ++++++---- .../edit/comments-inspector-controls.js | 26 +++++++++++++++++-- 5 files changed, 44 insertions(+), 9 deletions(-) diff --git a/docs/reference-guides/core-blocks.md b/docs/reference-guides/core-blocks.md index 0244c561109081..ac98b799c1b15c 100644 --- a/docs/reference-guides/core-blocks.md +++ b/docs/reference-guides/core-blocks.md @@ -204,7 +204,7 @@ An advanced block that allows displaying post comments based on different query - **Name:** core/comments-query-loop - **Category:** theme - **Supports:** align (full, wide), color (background, gradients, link, text), ~~html~~ -- **Attributes:** inherit, order, perPage, tagName +- **Attributes:** defaultPage, inherit, order, perPage, tagName ## Cover diff --git a/packages/block-library/src/comment-template/block.json b/packages/block-library/src/comment-template/block.json index 5e2309ab3141a3..de55fcb27475f6 100644 --- a/packages/block-library/src/comment-template/block.json +++ b/packages/block-library/src/comment-template/block.json @@ -7,7 +7,12 @@ "parent": [ "core/comments-query-loop" ], "description": "Contains the block elements used to render a comment, like the title, date, author, avatar and more.", "textdomain": "default", - "usesContext": [ "comments/perPage", "postId", "comments/order" ], + "usesContext": [ + "comments/defaultPage", + "comments/order", + "comments/perPage", + "postId" + ], "supports": { "reusable": false, "html": false, diff --git a/packages/block-library/src/comments-query-loop/block.json b/packages/block-library/src/comments-query-loop/block.json index fa3fd0d72c0a50..ded2ad1667f7dc 100644 --- a/packages/block-library/src/comments-query-loop/block.json +++ b/packages/block-library/src/comments-query-loop/block.json @@ -22,11 +22,16 @@ "tagName": { "type": "string", "default": "div" + }, + "defaultPage": { + "type": "string", + "default": "oldest" } }, "providesContext": { "comments/perPage": "perPage", "comments/order": "order", + "comments/defaultPage": "defaultPage", "comments/inherit": "inherit" }, "supports": { diff --git a/packages/block-library/src/comments-query-loop/edit.js b/packages/block-library/src/comments-query-loop/edit.js index 032fcc5649cf8a..fcfc3da940e841 100644 --- a/packages/block-library/src/comments-query-loop/edit.js +++ b/packages/block-library/src/comments-query-loop/edit.js @@ -26,11 +26,13 @@ export default function CommentsQueryLoopEdit( { attributes, setAttributes } ) { template: TEMPLATE, } ); - const { commentOrder, commentsPerPage } = useSelect( ( select ) => { - const { getSettings } = select( blockEditorStore ); - const { __experimentalDiscussionSettings } = getSettings(); - return __experimentalDiscussionSettings; - } ); + const { commentOrder, commentsPerPage, defaultPage } = useSelect( + ( select ) => { + const { getSettings } = select( blockEditorStore ); + const { __experimentalDiscussionSettings } = getSettings(); + return __experimentalDiscussionSettings; + } + ); return ( <> @@ -40,6 +42,7 @@ export default function CommentsQueryLoopEdit( { attributes, setAttributes } ) { defaultSettings={ { defaultOrder: commentOrder, defaultPerPage: commentsPerPage, + defaultDefaultPage: defaultPage, } } /> diff --git a/packages/block-library/src/comments-query-loop/edit/comments-inspector-controls.js b/packages/block-library/src/comments-query-loop/edit/comments-inspector-controls.js index 774fd69ac3a5e2..5cc45a4c14e5e8 100644 --- a/packages/block-library/src/comments-query-loop/edit/comments-inspector-controls.js +++ b/packages/block-library/src/comments-query-loop/edit/comments-inspector-controls.js @@ -21,10 +21,21 @@ const orderOptions = [ }, ]; +const defaultPageOptions = [ + { + label: __( 'Newest' ), + value: 'newest', + }, + { + label: __( 'Oldest' ), + value: 'oldest', + }, +]; + export default function CommentsInspectorControls( { - attributes: { TagName, perPage, order, inherit }, + attributes: { TagName, perPage, order, inherit, defaultPage }, setAttributes, - defaultSettings: { defaultPerPage, defaultOrder }, + defaultSettings: { defaultPerPage, defaultOrder, defaultDefaultPage }, } ) { return ( @@ -37,6 +48,7 @@ export default function CommentsInspectorControls( { inherit: ! inherit, order: inherit ? defaultOrder : null, perPage: inherit ? defaultPerPage : null, + defaultPage: inherit ? defaultDefaultPage : null, } ); } } /> @@ -52,6 +64,16 @@ export default function CommentsInspectorControls( { } ); } } /> + { + setAttributes( { + defaultPage: value, + } ); + } } + /> Date: Tue, 1 Feb 2022 19:46:53 +0100 Subject: [PATCH 08/25] Keep other attributes when `inherit` changes --- .../src/comment-template/block.json | 1 + .../src/comment-template/edit.js | 2 ++ .../src/comment-template/hooks.js | 13 +++++++++++- .../src/comments-query-loop/edit.js | 20 +------------------ .../edit/comments-inspector-controls.js | 4 ---- 5 files changed, 16 insertions(+), 24 deletions(-) diff --git a/packages/block-library/src/comment-template/block.json b/packages/block-library/src/comment-template/block.json index de55fcb27475f6..6a5b0f39a373a6 100644 --- a/packages/block-library/src/comment-template/block.json +++ b/packages/block-library/src/comment-template/block.json @@ -9,6 +9,7 @@ "textdomain": "default", "usesContext": [ "comments/defaultPage", + "comments/inherit", "comments/order", "comments/perPage", "postId" diff --git a/packages/block-library/src/comment-template/edit.js b/packages/block-library/src/comment-template/edit.js index af661b4e71236f..7130d2f1fbd772 100644 --- a/packages/block-library/src/comment-template/edit.js +++ b/packages/block-library/src/comment-template/edit.js @@ -214,6 +214,7 @@ export default function CommentTemplateEdit( { 'comments/perPage': perPage, 'comments/order': order, 'comments/defaultPage': defaultPage, + 'comments/inherit': inherit, }, } ) { const blockProps = useBlockProps(); @@ -224,6 +225,7 @@ export default function CommentTemplateEdit( { postId, perPage, defaultPage, + inherit, } ); const { topLevelComments, blocks } = useSelect( diff --git a/packages/block-library/src/comment-template/hooks.js b/packages/block-library/src/comment-template/hooks.js index 32800f90080ff8..8012f9edcb54ab 100644 --- a/packages/block-library/src/comment-template/hooks.js +++ b/packages/block-library/src/comment-template/hooks.js @@ -14,7 +14,12 @@ import apiFetch from '@wordpress/api-fetch'; * @param {*} param0 * @return {Object} TODO Write JSDOC. */ -export const useCommentQueryArgs = ( { postId, perPage, defaultPage } ) => { +export const useCommentQueryArgs = ( { + postId, + perPage, + defaultPage, + inherit, +} ) => { // Initialize the query args that are not going to change. const queryArgs = { status: 'approve', @@ -31,6 +36,12 @@ export const useCommentQueryArgs = ( { postId, perPage, defaultPage } ) => { return __experimentalDiscussionSettings; } ); + // Overwrite the received attributes if `inherit` is true. + if ( inherit ) { + perPage = commentsPerPage; + defaultPage = defaultCommentsPage; + } + // If a block props is not set, use the settings value to generate the // appropriate query arg. perPage = perPage || commentsPerPage; diff --git a/packages/block-library/src/comments-query-loop/edit.js b/packages/block-library/src/comments-query-loop/edit.js index fcfc3da940e841..096c237baf9f79 100644 --- a/packages/block-library/src/comments-query-loop/edit.js +++ b/packages/block-library/src/comments-query-loop/edit.js @@ -1,17 +1,12 @@ /** * WordPress dependencies */ -import { - useBlockProps, - useInnerBlocksProps, - store as blockEditorStore, -} from '@wordpress/block-editor'; +import { useBlockProps, useInnerBlocksProps } from '@wordpress/block-editor'; /** * Internal dependencies */ import CommentsInspectorControls from './edit/comments-inspector-controls'; -import { useSelect } from '@wordpress/data'; const TEMPLATE = [ [ 'core/comment-template' ], @@ -26,24 +21,11 @@ export default function CommentsQueryLoopEdit( { attributes, setAttributes } ) { template: TEMPLATE, } ); - const { commentOrder, commentsPerPage, defaultPage } = useSelect( - ( select ) => { - const { getSettings } = select( blockEditorStore ); - const { __experimentalDiscussionSettings } = getSettings(); - return __experimentalDiscussionSettings; - } - ); - return ( <> diff --git a/packages/block-library/src/comments-query-loop/edit/comments-inspector-controls.js b/packages/block-library/src/comments-query-loop/edit/comments-inspector-controls.js index 5cc45a4c14e5e8..75f693e2edc7fe 100644 --- a/packages/block-library/src/comments-query-loop/edit/comments-inspector-controls.js +++ b/packages/block-library/src/comments-query-loop/edit/comments-inspector-controls.js @@ -35,7 +35,6 @@ const defaultPageOptions = [ export default function CommentsInspectorControls( { attributes: { TagName, perPage, order, inherit, defaultPage }, setAttributes, - defaultSettings: { defaultPerPage, defaultOrder, defaultDefaultPage }, } ) { return ( @@ -46,9 +45,6 @@ export default function CommentsInspectorControls( { onChange={ () => { setAttributes( { inherit: ! inherit, - order: inherit ? defaultOrder : null, - perPage: inherit ? defaultPerPage : null, - defaultPage: inherit ? defaultDefaultPage : null, } ); } } /> From 754f99d3aee96127d162c515d3c6b71669645f84 Mon Sep 17 00:00:00 2001 From: David Arenas Date: Wed, 2 Feb 2022 10:42:26 +0100 Subject: [PATCH 09/25] Fix `comment_order` option usage --- lib/compat/experimental/blocks.php | 6 +----- packages/block-library/src/comment-template/index.php | 8 ++++++++ 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/lib/compat/experimental/blocks.php b/lib/compat/experimental/blocks.php index eda1ef61fc7331..0848ab3d9f0a25 100644 --- a/lib/compat/experimental/blocks.php +++ b/lib/compat/experimental/blocks.php @@ -19,6 +19,7 @@ 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. @@ -52,11 +53,6 @@ function build_comment_query_vars_from_block( $block ) { } } - $comment_args['order'] = ! empty( $block->context['comments/order'] ) ? $block->context['comments/order'] : null; - if ( empty( $comment_args['order'] ) && get_option( 'comment_order' ) ) { - $comment_args['order'] = get_option( 'comment_order' ); - } - return $comment_args; } } diff --git a/packages/block-library/src/comment-template/index.php b/packages/block-library/src/comment-template/index.php index fb716fbd2fa913..8b97c822db1aa8 100644 --- a/packages/block-library/src/comment-template/index.php +++ b/packages/block-library/src/comment-template/index.php @@ -68,6 +68,14 @@ function render_block_core_comment_template( $attributes, $content, $block ) { return ''; } + $comment_order = ! empty( $block->context['comments/order'] ) + ? $block->context['comments/order'] + : get_option( 'comment_order' ); + + if ( 'desc' === $comment_order ) { + $comments = reverse_array( $comments ); + } + $wrapper_attributes = get_block_wrapper_attributes(); return sprintf( From 238e2bd17a87845036d5b1b68648b3ad25ddb11f Mon Sep 17 00:00:00 2001 From: David Arenas Date: Wed, 2 Feb 2022 10:56:39 +0100 Subject: [PATCH 10/25] Replace `asc` with `ASC` inside `$comment_args` --- lib/compat/experimental/blocks.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/compat/experimental/blocks.php b/lib/compat/experimental/blocks.php index 0848ab3d9f0a25..157f9815f43a8d 100644 --- a/lib/compat/experimental/blocks.php +++ b/lib/compat/experimental/blocks.php @@ -19,7 +19,7 @@ function build_comment_query_vars_from_block( $block ) { $comment_args = array( 'orderby' => 'comment_date_gmt', - 'order' => 'asc', + 'order' => 'ASC', 'status' => 'approve', 'no_found_rows' => false, 'update_comment_meta_cache' => false, // We lazy-load comment meta for performance. From fa0933cb4a843321e356ca2b9311485f99a513ec Mon Sep 17 00:00:00 2001 From: David Arenas Date: Fri, 4 Feb 2022 19:13:29 +0100 Subject: [PATCH 11/25] Fix `array_reverse` and order in comment template --- packages/block-library/src/comment-template/index.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/block-library/src/comment-template/index.php b/packages/block-library/src/comment-template/index.php index 8b97c822db1aa8..81ab3edf05fa7e 100644 --- a/packages/block-library/src/comment-template/index.php +++ b/packages/block-library/src/comment-template/index.php @@ -68,12 +68,12 @@ function render_block_core_comment_template( $attributes, $content, $block ) { return ''; } - $comment_order = ! empty( $block->context['comments/order'] ) + $comment_order = ! empty( $block->context['comments/inherit'] ) && ! empty( $block->context['comments/order'] ) ? $block->context['comments/order'] : get_option( 'comment_order' ); if ( 'desc' === $comment_order ) { - $comments = reverse_array( $comments ); + $comments = array_reverse( $comments ); } $wrapper_attributes = get_block_wrapper_attributes(); From 7f8b50e3b72be5db773e7e0ad610f8b57024fd6c Mon Sep 17 00:00:00 2001 From: David Arenas Date: Fri, 4 Feb 2022 19:15:22 +0100 Subject: [PATCH 12/25] Refactor `build_comment_query_vars` to use `inherit` --- lib/compat/experimental/blocks.php | 36 ++++++++++++++----- .../src/comment-template/index.php | 2 +- 2 files changed, 28 insertions(+), 10 deletions(-) diff --git a/lib/compat/experimental/blocks.php b/lib/compat/experimental/blocks.php index 157f9815f43a8d..08dae17bca8827 100644 --- a/lib/compat/experimental/blocks.php +++ b/lib/compat/experimental/blocks.php @@ -35,22 +35,40 @@ function build_comment_query_vars_from_block( $block ) { $comment_args['hierarchical'] = false; } - $per_page = ! empty( $block->context['comments/perPage'] ) ? (int) $block->context['comments/perPage'] : 0; - if ( 0 === $per_page && get_option( 'page_comments' ) ) { - $per_page = (int) get_query_var( 'comments_per_page' ); - if ( 0 === $per_page ) { - $per_page = (int) get_option( 'comments_per_page' ); - } + $inherit = ! empty( $block->context['comments/inherit'] ); + + $per_page = (int) get_option( 'comments_per_page' ); + $query_per_page = (int) get_query_var( 'comments_per_page' ); + if ( 0 !== $query_per_page ) { + $per_page = $query_per_page; + } + $block_per_page = ! empty( $block->context['comments/perPage'] ) ? (int) $block->context['comments/perPage'] : 0; + if ( ! $inherit && 0 !== $block_per_page ) { + $per_page = $block_per_page; + } + + $default_page = get_option( 'default_comments_page' ); + if ( ! $inherit && ! empty( $block->context['comments/defaultPage'] ) ) { + $default_page = $block->context['comments/defaultPage']; } + if ( $per_page > 0 ) { - $comment_args['number'] = $per_page; - $page = (int) get_query_var( 'cpage' ); + $page = (int) get_query_var( 'cpage' ); if ( $page ) { $comment_args['offset'] = ( $page - 1 ) * $per_page; - } elseif ( 'oldest' === get_option( 'default_comments_page' ) ) { + } elseif ( 'oldest' === $default_page ) { $comment_args['offset'] = 0; + } elseif ( 'newest' === $default_page ) { + // For this specific case, we need to make first a query to know + // the number of pages, and so get the index of the last page + // (newest comments). + $comment_query = new WP_Comment_Query( $comment_args ); + $comment_pages_count = get_comment_pages_count( $comment_query->get_comments(), $per_page, true ); + $comment_args['offset'] = ( $comment_pages_count - 1 ) * $per_page; } + + $comment_args['number'] = $per_page; } return $comment_args; diff --git a/packages/block-library/src/comment-template/index.php b/packages/block-library/src/comment-template/index.php index 81ab3edf05fa7e..68daa5dd36b7fd 100644 --- a/packages/block-library/src/comment-template/index.php +++ b/packages/block-library/src/comment-template/index.php @@ -68,7 +68,7 @@ function render_block_core_comment_template( $attributes, $content, $block ) { return ''; } - $comment_order = ! empty( $block->context['comments/inherit'] ) && ! empty( $block->context['comments/order'] ) + $comment_order = empty( $block->context['comments/inherit'] ) && ! empty( $block->context['comments/order'] ) ? $block->context['comments/order'] : get_option( 'comment_order' ); From ab04e48eaaf7d0eed96e517d886c6925ae4c188e Mon Sep 17 00:00:00 2001 From: David Arenas Date: Tue, 8 Feb 2022 11:45:03 +0100 Subject: [PATCH 13/25] Simplify `build_comment_query_vars` function --- lib/compat/experimental/blocks.php | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-) diff --git a/lib/compat/experimental/blocks.php b/lib/compat/experimental/blocks.php index 08dae17bca8827..155ef9b6d07a99 100644 --- a/lib/compat/experimental/blocks.php +++ b/lib/compat/experimental/blocks.php @@ -53,22 +53,16 @@ function build_comment_query_vars_from_block( $block ) { } if ( $per_page > 0 ) { - $page = (int) get_query_var( 'cpage' ); + $comment_args['number'] = $per_page; + $page = (int) get_query_var( 'cpage' ); if ( $page ) { - $comment_args['offset'] = ( $page - 1 ) * $per_page; + $comment_args['paged'] = $page; } elseif ( 'oldest' === $default_page ) { - $comment_args['offset'] = 0; + $comment_args['paged'] = 0; } elseif ( 'newest' === $default_page ) { - // For this specific case, we need to make first a query to know - // the number of pages, and so get the index of the last page - // (newest comments). - $comment_query = new WP_Comment_Query( $comment_args ); - $comment_pages_count = get_comment_pages_count( $comment_query->get_comments(), $per_page, true ); - $comment_args['offset'] = ( $comment_pages_count - 1 ) * $per_page; + $comment_args['paged'] = ( new WP_Comment_Query( $comment_args ) )->max_num_pages; } - - $comment_args['number'] = $per_page; } return $comment_args; From 817bd6cbe4ac3dbefaf81151d4adafbebfaabf52 Mon Sep 17 00:00:00 2001 From: David Arenas Date: Tue, 8 Feb 2022 12:03:34 +0100 Subject: [PATCH 14/25] Adapt Next and Numbers blocks to use `inherit` --- .../src/comments-pagination-next/block.json | 2 +- .../src/comments-pagination-next/index.php | 14 ++++++-------- .../src/comments-pagination-numbers/block.json | 2 +- .../src/comments-pagination-numbers/index.php | 13 +++---------- 4 files changed, 11 insertions(+), 20 deletions(-) diff --git a/packages/block-library/src/comments-pagination-next/block.json b/packages/block-library/src/comments-pagination-next/block.json index 39279da857b8c9..4064946e907d1a 100644 --- a/packages/block-library/src/comments-pagination-next/block.json +++ b/packages/block-library/src/comments-pagination-next/block.json @@ -12,7 +12,7 @@ "type": "string" } }, - "usesContext": [ "postId", "comments/perPage", "comments/paginationArrow" ], + "usesContext": [ "postId", "comments/perPage", "comments/paginationArrow", "comments/inherit" ], "supports": { "reusable": false, "html": false, diff --git a/packages/block-library/src/comments-pagination-next/index.php b/packages/block-library/src/comments-pagination-next/index.php index c6319a5a1a5186..a535b7c40d6c46 100644 --- a/packages/block-library/src/comments-pagination-next/index.php +++ b/packages/block-library/src/comments-pagination-next/index.php @@ -15,15 +15,13 @@ * @return string Returns the next comments link for the query pagination. */ function render_block_core_comments_pagination_next( $attributes, $content, $block ) { - $per_page = ! empty( $block->context['comments/perPage'] ) ? (int) $block->context['comments/perPage'] : 0; - if ( 0 === $per_page && get_option( 'page_comments' ) ) { - $per_page = (int) get_query_var( 'comments_per_page' ); - if ( 0 === $per_page ) { - $per_page = (int) get_option( 'comments_per_page' ); - } + // Bail out early if the post ID is not set for some reason. + if ( empty( $block->context['postId'] ) ) { + return ''; } - $comments_number = (int) get_comments_number(); - $max_page = 0 !== $per_page ? (int) floor( $comments_number / $per_page ) : 0; + + $comment_vars = build_comment_query_vars_from_block( $block ); + $max_page = ( new WP_Comment_Query( $comment_vars ) )->max_num_pages; $default_label = __( 'Newer Comments' ); $label = isset( $attributes['label'] ) && ! empty( $attributes['label'] ) ? $attributes['label'] : $default_label; $pagination_arrow = get_comments_pagination_arrow( $block, 'next' ); diff --git a/packages/block-library/src/comments-pagination-numbers/block.json b/packages/block-library/src/comments-pagination-numbers/block.json index c2b322e15366c8..c31543f0b71f8d 100644 --- a/packages/block-library/src/comments-pagination-numbers/block.json +++ b/packages/block-library/src/comments-pagination-numbers/block.json @@ -7,7 +7,7 @@ "parent": [ "core/comments-pagination" ], "description": "Displays a list of page numbers for comments pagination.", "textdomain": "default", - "usesContext": [ "comments/perPage", "postId", "comments/order" ], + "usesContext": [ "comments/perPage", "postId", "comments/order", "comments/inherit" ], "supports": { "reusable": false, "html": false diff --git a/packages/block-library/src/comments-pagination-numbers/index.php b/packages/block-library/src/comments-pagination-numbers/index.php index 170b7c267868ff..f872bc4ecaa9f9 100644 --- a/packages/block-library/src/comments-pagination-numbers/index.php +++ b/packages/block-library/src/comments-pagination-numbers/index.php @@ -20,17 +20,10 @@ function render_block_core_comments_pagination_numbers( $attributes, $content, $ return ''; } - $comments_query = new WP_Comment_Query( - build_comment_query_vars_from_block( $block ) - ); - $total = $comments_query->max_num_pages; + $comment_vars = build_comment_query_vars_from_block( $block ); - // Get the current comment page from the URL. - $current = get_query_var( 'cpage' ); - if ( ! $current ) { - // Get the number of the default page. - $current = 'newest' === get_option( 'default_comments_page' ) ? $total : 1; - } + $total = ( new WP_Comment_Query( $comment_vars ) )->max_num_pages; + $current = $comment_vars['paged']; // Render links. $content = paginate_comments_links( From 02e28d8fe10817bf2d6e948301ab5b50eda8ded9 Mon Sep 17 00:00:00 2001 From: David Arenas Date: Tue, 8 Feb 2022 18:08:53 +0100 Subject: [PATCH 15/25] Run `format-php` and fix lint errors --- lib/compat/experimental/blocks.php | 25 +++++++++++-------- .../src/comments-pagination-numbers/index.php | 2 +- 2 files changed, 15 insertions(+), 12 deletions(-) diff --git a/lib/compat/experimental/blocks.php b/lib/compat/experimental/blocks.php index 155ef9b6d07a99..b2a3cde568ae9d 100644 --- a/lib/compat/experimental/blocks.php +++ b/lib/compat/experimental/blocks.php @@ -37,7 +37,7 @@ function build_comment_query_vars_from_block( $block ) { $inherit = ! empty( $block->context['comments/inherit'] ); - $per_page = (int) get_option( 'comments_per_page' ); + $per_page = (int) get_option( 'comments_per_page' ); $query_per_page = (int) get_query_var( 'comments_per_page' ); if ( 0 !== $query_per_page ) { $per_page = $query_per_page; @@ -137,7 +137,7 @@ function extend_block_editor_settings_with_discussion_settings( $settings ) { } add_filter( 'block_editor_settings_all', 'extend_block_editor_settings_with_discussion_settings' ); -if ( ! function_exists( 'gutenberg_rest_comment_set_children_as_embeddable' )) { +if ( ! function_exists( 'gutenberg_rest_comment_set_children_as_embeddable' ) ) { /** * Mark the `children` attr of comments as embeddable so they can be included in * REST API responses without additional requests. @@ -145,15 +145,18 @@ function extend_block_editor_settings_with_discussion_settings( $settings ) { * @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 ) ); + 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; } - return $response; - } ); + ); } } -add_action( 'rest_api_init', 'gutenberg_rest_comment_set_children_as_embeddable'); +add_action( 'rest_api_init', 'gutenberg_rest_comment_set_children_as_embeddable' ); diff --git a/packages/block-library/src/comments-pagination-numbers/index.php b/packages/block-library/src/comments-pagination-numbers/index.php index f872bc4ecaa9f9..11d85c4baa2ebe 100644 --- a/packages/block-library/src/comments-pagination-numbers/index.php +++ b/packages/block-library/src/comments-pagination-numbers/index.php @@ -20,7 +20,7 @@ function render_block_core_comments_pagination_numbers( $attributes, $content, $ return ''; } - $comment_vars = build_comment_query_vars_from_block( $block ); + $comment_vars = build_comment_query_vars_from_block( $block ); $total = ( new WP_Comment_Query( $comment_vars ) )->max_num_pages; $current = $comment_vars['paged']; From ef8bb94b79ec7fa7b76231d0d75d694c4bc8672f Mon Sep 17 00:00:00 2001 From: David Arenas Date: Tue, 8 Feb 2022 18:32:31 +0100 Subject: [PATCH 16/25] Regenerate comment query loop fixtures --- .../fixtures/blocks/core__comments-query-loop.html | 2 +- .../fixtures/blocks/core__comments-query-loop.json | 5 +++-- .../fixtures/blocks/core__comments-query-loop.parsed.json | 4 +++- .../blocks/core__comments-query-loop.serialized.html | 2 +- 4 files changed, 8 insertions(+), 5 deletions(-) diff --git a/test/integration/fixtures/blocks/core__comments-query-loop.html b/test/integration/fixtures/blocks/core__comments-query-loop.html index 90ba70e04ff03b..a2feedf0a708e2 100644 --- a/test/integration/fixtures/blocks/core__comments-query-loop.html +++ b/test/integration/fixtures/blocks/core__comments-query-loop.html @@ -1,4 +1,4 @@ - +
diff --git a/test/integration/fixtures/blocks/core__comments-query-loop.json b/test/integration/fixtures/blocks/core__comments-query-loop.json index b67597222f5a16..8e77727b451185 100644 --- a/test/integration/fixtures/blocks/core__comments-query-loop.json +++ b/test/integration/fixtures/blocks/core__comments-query-loop.json @@ -3,10 +3,11 @@ "name": "core/comments-query-loop", "isValid": true, "attributes": { - "inherit": true, + "inherit": false, "order": "desc", "perPage": 2, - "tagName": "div" + "tagName": "div", + "defaultPage": "oldest" }, "innerBlocks": [ { diff --git a/test/integration/fixtures/blocks/core__comments-query-loop.parsed.json b/test/integration/fixtures/blocks/core__comments-query-loop.parsed.json index e45d5f6448f1a3..1f1522100f5165 100644 --- a/test/integration/fixtures/blocks/core__comments-query-loop.parsed.json +++ b/test/integration/fixtures/blocks/core__comments-query-loop.parsed.json @@ -2,8 +2,10 @@ { "blockName": "core/comments-query-loop", "attrs": { + "inherit": false, "perPage": 2, - "order": "desc" + "order": "desc", + "defaultPage": "oldest" }, "innerBlocks": [ { diff --git a/test/integration/fixtures/blocks/core__comments-query-loop.serialized.html b/test/integration/fixtures/blocks/core__comments-query-loop.serialized.html index b1e30641e70a46..9c27b84474cb61 100644 --- a/test/integration/fixtures/blocks/core__comments-query-loop.serialized.html +++ b/test/integration/fixtures/blocks/core__comments-query-loop.serialized.html @@ -1,4 +1,4 @@ - +
From a1b3e4cca6ed07d68a2df177f7118aacb55a4048 Mon Sep 17 00:00:00 2001 From: David Arenas Date: Tue, 8 Feb 2022 18:55:27 +0100 Subject: [PATCH 17/25] Update comment template PHP tests Added a new test case for when `comments/inherit` is `true`. --- ...ss-block-library-comment-template-test.php | 33 +++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/phpunit/class-block-library-comment-template-test.php b/phpunit/class-block-library-comment-template-test.php index f71f31e6059d64..230c4599bf04f0 100644 --- a/phpunit/class-block-library-comment-template-test.php +++ b/phpunit/class-block-library-comment-template-test.php @@ -68,6 +68,38 @@ function test_build_comment_query_vars_from_block_with_context() { 'post_id' => self::$custom_post->ID, 'hierarchical' => 'threaded', 'number' => 77, + 'paged' => 1, + ) + ); + } + + function test_build_comment_query_vars_from_block_with_context_and_inherit() { + $parsed_blocks = parse_blocks( + '' + ); + + $block = new WP_Block( + $parsed_blocks[0], + array( + 'postId' => self::$custom_post->ID, + 'comments/perPage' => 77, + 'comments/order' => 'desc', + 'comments/inherit' => true, + ) + ); + + $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' => self::$per_page, + 'paged' => 1, ) ); } @@ -89,6 +121,7 @@ function test_build_comment_query_vars_from_block_no_context() { 'update_comment_meta_cache' => false, 'hierarchical' => 'threaded', 'number' => self::$per_page, + 'paged' => 1, ) ); } From 07a2ce4dc82298e12c1729d2a703d84273d597c4 Mon Sep 17 00:00:00 2001 From: David Arenas Date: Wed, 9 Feb 2022 20:29:01 +0100 Subject: [PATCH 18/25] Write JSDocs and refactor Comment Template hooks --- .../src/comment-template/hooks.js | 61 +++++++++++-------- 1 file changed, 35 insertions(+), 26 deletions(-) diff --git a/packages/block-library/src/comment-template/hooks.js b/packages/block-library/src/comment-template/hooks.js index 8012f9edcb54ab..9111f7967428ef 100644 --- a/packages/block-library/src/comment-template/hooks.js +++ b/packages/block-library/src/comment-template/hooks.js @@ -8,11 +8,17 @@ import { addQueryArgs } from '@wordpress/url'; import apiFetch from '@wordpress/api-fetch'; /** - * Return an object with the query args needed to get the comments in the - * default page. + * Return an object with the query args needed to fetch the default page of + * comments. * - * @param {*} param0 - * @return {Object} TODO Write JSDOC. + * @param {Object} props Hook props. + * @param {number} props.postId ID of the post that contains the comments. + * @param {number} props.perPage The number of comments included per page. + * @param {string} props.defaultPage Page shown by default (newest/oldest). + * @param {boolean} props.inherit Overwrite props with values from WP + * discussion settings. + * + * @return {Object} Query args to retrieve the comments. */ export const useCommentQueryArgs = ( { postId, @@ -48,8 +54,8 @@ export const useCommentQueryArgs = ( { defaultPage = defaultPage || defaultCommentsPage; // Get the number of the default page. - const page = useDefaultPage( { - defaultCommentsPage: defaultPage, + const page = useDefaultPageIndex( { + defaultPage, postId, perPage, queryArgs, @@ -70,20 +76,20 @@ export const useCommentQueryArgs = ( { }; /** - * Return the index of the default page, depending on whether - * `defaultCommentsPage` is `newest` or not. If the default page is the newest - * one, the only way to know the page's index is by using the `X-WP-TotalPages` - * header. That case sadly forces to make an additional request. + * Return the index of the default page, depending on whether `defaultPage` is + * `newest` or `oldest`. In the first case, the only way to know the page's + * index is by using the `X-WP-TotalPages` header, which forces to make an + * additional request. + * + * @param {Object} props Hook props. + * @param {string} props.defaultPage Page shown by default (newest/oldest). + * @param {number} props.postId ID of the post that contains the comments. + * @param {number} props.perPage The number of comments included per page. + * @param {Object} props.queryArgs Other query args. * - * @param {*} param0 - * @return {number} Default comments page index. + * @return {number} Index of the default comments page. */ -const useDefaultPage = ( { - defaultCommentsPage, - postId, - perPage, - queryArgs, -} ) => { +const useDefaultPageIndex = ( { defaultPage, postId, perPage, queryArgs } ) => { // Store the default page indices. const [ defaultPages, setDefaultPages ] = useState( {} ); const key = `${ postId }_${ perPage }`; @@ -91,7 +97,7 @@ const useDefaultPage = ( { useEffect( () => { // Do nothing if the page is already known or not the newest page. - if ( page || defaultCommentsPage !== 'newest' ) { + if ( page || defaultPage !== 'newest' ) { return; } // We need to fetch comments to know the index. Use HEAD and limit @@ -111,26 +117,29 @@ const useDefaultPage = ( { [ key ]: parseInt( res.headers.get( 'X-WP-TotalPages' ) ), } ); } ); - }, [ defaultCommentsPage, postId, perPage, setDefaultPages ] ); + }, [ defaultPage, postId, perPage, setDefaultPages ] ); // The oldest one is always the first one. - return defaultCommentsPage === 'newest' ? page : 1; + return defaultPage === 'newest' ? page : 1; }; /** - * Generate a tree structure of comment IDs. + * Generate a tree structure of comment IDs from a list of comment entities. The + * children of each comment are obtained from `_embedded`. + * + * @typedef {{ commentId: number, children: CommentNode }} CommentNode * - * @param {*} topLevelComments - * @return {Object} TODO Write JSDOC. + * @param {Object[]} topLevelComments List of comment entities. + * @return {{ commentTree: CommentNode[]}} Tree of comment IDs. */ export const useCommentTree = ( topLevelComments ) => { const commentTree = useMemo( () => topLevelComments?.map( ( { id, _embedded } ) => { - const [ children ] = _embedded?.children || []; + const [ children ] = _embedded?.children || [ [] ]; return { commentId: id, - children: children?.map( ( child ) => ( { + children: children.map( ( child ) => ( { commentId: child.id, } ) ), }; From feacd2a61621e595afcf17e61f944494fe1994d3 Mon Sep 17 00:00:00 2001 From: David Arenas Date: Sun, 13 Feb 2022 12:59:52 +0100 Subject: [PATCH 19/25] Use spread syntax to clone `topLevelComments` --- packages/block-library/src/comment-template/edit.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/block-library/src/comment-template/edit.js b/packages/block-library/src/comment-template/edit.js index 7130d2f1fbd772..e71de7e7be1f47 100644 --- a/packages/block-library/src/comment-template/edit.js +++ b/packages/block-library/src/comment-template/edit.js @@ -256,8 +256,8 @@ export default function CommentTemplateEdit( { // Generate a tree structure of comment IDs. const { commentTree } = useCommentTree( - order === 'desc' - ? topLevelComments?.slice().reverse() + order === 'desc' && topLevelComments + ? [ ...topLevelComments ].reverse() : topLevelComments ); From ae28650c90bdd94368a4388d1e0d8bcd5bda9e47 Mon Sep 17 00:00:00 2001 From: David Arenas Date: Sun, 13 Feb 2022 13:02:04 +0100 Subject: [PATCH 20/25] Simplify comments. --- packages/block-library/src/comment-template/edit.js | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/packages/block-library/src/comment-template/edit.js b/packages/block-library/src/comment-template/edit.js index e71de7e7be1f47..e02310c9a338a1 100644 --- a/packages/block-library/src/comment-template/edit.js +++ b/packages/block-library/src/comment-template/edit.js @@ -250,12 +250,9 @@ export default function CommentTemplateEdit( { } ); order = order || commentOrder; - // Reverse the order of top comments if needed, as specified in the - // Discussion settings. NOTE that this only changes the order of comments in - // the given page, not the order of pages. - // Generate a tree structure of comment IDs. const { commentTree } = useCommentTree( + // Reverse the order of top comments if needed. order === 'desc' && topLevelComments ? [ ...topLevelComments ].reverse() : topLevelComments From 91e7a7a4125b9cd70b6debeb6e10f9f279525ba1 Mon Sep 17 00:00:00 2001 From: David Arenas Date: Sun, 13 Feb 2022 13:36:25 +0100 Subject: [PATCH 21/25] Adapt some code after rebase --- .../block-library/src/comment-template/edit.js | 14 ++++++++------ .../block-library/src/comment-template/hooks.js | 2 +- 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/packages/block-library/src/comment-template/edit.js b/packages/block-library/src/comment-template/edit.js index e02310c9a338a1..a6d123e9c6d5e2 100644 --- a/packages/block-library/src/comment-template/edit.js +++ b/packages/block-library/src/comment-template/edit.js @@ -1,7 +1,7 @@ /** * WordPress dependencies */ -import { useState, useMemo, memo } from '@wordpress/element'; +import { useState, memo } from '@wordpress/element'; import { useSelect } from '@wordpress/data'; import { __ } from '@wordpress/i18n'; import { @@ -220,6 +220,12 @@ export default function CommentTemplateEdit( { const blockProps = useBlockProps(); const [ activeComment, setActiveComment ] = useState(); + const { commentOrder, threadCommentsDepth, threadComments } = useSelect( + ( select ) => { + const { getSettings } = select( blockEditorStore ); + return getSettings().__experimentalDiscussionSettings; + } + ); const commentQuery = useCommentQueryArgs( { postId, @@ -244,14 +250,10 @@ export default function CommentTemplateEdit( { [ clientId, commentQuery ] ); - const { commentOrder } = useSelect( ( select ) => { - const { getSettings } = select( blockEditorStore ); - return getSettings().__experimentalDiscussionSettings; - } ); order = order || commentOrder; // Generate a tree structure of comment IDs. - const { commentTree } = useCommentTree( + let commentTree = useCommentTree( // Reverse the order of top comments if needed. order === 'desc' && topLevelComments ? [ ...topLevelComments ].reverse() diff --git a/packages/block-library/src/comment-template/hooks.js b/packages/block-library/src/comment-template/hooks.js index 9111f7967428ef..d792887c72e885 100644 --- a/packages/block-library/src/comment-template/hooks.js +++ b/packages/block-library/src/comment-template/hooks.js @@ -147,5 +147,5 @@ export const useCommentTree = ( topLevelComments ) => { [ topLevelComments ] ); - return { commentTree }; + return commentTree; }; From 09f6402ca5398654162829b456b2734e4085b0a5 Mon Sep 17 00:00:00 2001 From: David Arenas Date: Mon, 14 Feb 2022 21:05:42 +0100 Subject: [PATCH 22/25] Fix comment page index for oldest comments --- lib/compat/experimental/blocks.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/compat/experimental/blocks.php b/lib/compat/experimental/blocks.php index b2a3cde568ae9d..83fc3dc3787f51 100644 --- a/lib/compat/experimental/blocks.php +++ b/lib/compat/experimental/blocks.php @@ -59,7 +59,7 @@ function build_comment_query_vars_from_block( $block ) { if ( $page ) { $comment_args['paged'] = $page; } elseif ( 'oldest' === $default_page ) { - $comment_args['paged'] = 0; + $comment_args['paged'] = 1; } elseif ( 'newest' === $default_page ) { $comment_args['paged'] = ( new WP_Comment_Query( $comment_args ) )->max_num_pages; } From d4483b49109aa91fec02b05a935a883eb969dd28 Mon Sep 17 00:00:00 2001 From: David Arenas Date: Mon, 14 Feb 2022 21:48:50 +0100 Subject: [PATCH 23/25] Pass missing context to Comment Pagination blocks --- .../block-library/src/comments-pagination-next/block.json | 8 +++++++- .../src/comments-pagination-numbers/block.json | 8 +++++++- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/packages/block-library/src/comments-pagination-next/block.json b/packages/block-library/src/comments-pagination-next/block.json index 4064946e907d1a..13cc78a0baa296 100644 --- a/packages/block-library/src/comments-pagination-next/block.json +++ b/packages/block-library/src/comments-pagination-next/block.json @@ -12,7 +12,13 @@ "type": "string" } }, - "usesContext": [ "postId", "comments/perPage", "comments/paginationArrow", "comments/inherit" ], + "usesContext": [ + "postId", + "comments/perPage", + "comments/order", + "comments/inherit", + "comments/defaultPage" + ], "supports": { "reusable": false, "html": false, diff --git a/packages/block-library/src/comments-pagination-numbers/block.json b/packages/block-library/src/comments-pagination-numbers/block.json index c31543f0b71f8d..df9abea4ed0b0f 100644 --- a/packages/block-library/src/comments-pagination-numbers/block.json +++ b/packages/block-library/src/comments-pagination-numbers/block.json @@ -7,7 +7,13 @@ "parent": [ "core/comments-pagination" ], "description": "Displays a list of page numbers for comments pagination.", "textdomain": "default", - "usesContext": [ "comments/perPage", "postId", "comments/order", "comments/inherit" ], + "usesContext": [ + "postId", + "comments/perPage", + "comments/order", + "comments/inherit", + "comments/defaultPage" + ], "supports": { "reusable": false, "html": false From a8e1477c9b26a62dd3e59290c7f5ec3ff0c019dc Mon Sep 17 00:00:00 2001 From: David Arenas Date: Mon, 14 Feb 2022 21:54:30 +0100 Subject: [PATCH 24/25] Fix order when `inherit` is true --- packages/block-library/src/comment-template/edit.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/block-library/src/comment-template/edit.js b/packages/block-library/src/comment-template/edit.js index a6d123e9c6d5e2..581c7f7701de70 100644 --- a/packages/block-library/src/comment-template/edit.js +++ b/packages/block-library/src/comment-template/edit.js @@ -250,7 +250,7 @@ export default function CommentTemplateEdit( { [ clientId, commentQuery ] ); - order = order || commentOrder; + order = inherit || ! order ? commentOrder : order; // Generate a tree structure of comment IDs. let commentTree = useCommentTree( From 3cd373df486d473d2ffd911937330a770febaea1 Mon Sep 17 00:00:00 2001 From: David Arenas Date: Wed, 16 Feb 2022 13:35:42 +0100 Subject: [PATCH 25/25] Add `paginationArrow` back to Pagination Next --- packages/block-library/src/comments-pagination-next/block.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/block-library/src/comments-pagination-next/block.json b/packages/block-library/src/comments-pagination-next/block.json index 13cc78a0baa296..7310c119f36663 100644 --- a/packages/block-library/src/comments-pagination-next/block.json +++ b/packages/block-library/src/comments-pagination-next/block.json @@ -17,7 +17,8 @@ "comments/perPage", "comments/order", "comments/inherit", - "comments/defaultPage" + "comments/defaultPage", + "comments/paginationArrow" ], "supports": { "reusable": false,