| @@ -4,116 +4,191 @@ | ||
| 4 | 4 | * |
| 5 | 5 | * @package gutenberg |
| 6 | 6 | */ |
| 7 | 7 | |
| 8 | -/** | |
| 9 | - * Helper function that constructs a WP_Query args array from | |
| 10 | - * a `Query` block properties. | |
| 11 | - * | |
| 12 | - * It's used in QueryLoop, QueryPaginationNumbers and QueryPaginationNext blocks. | |
| 13 | - * | |
| 14 | - * `build_query_vars_from_query_block` was introduced in 5.8, for 6.0 we just need | |
| 15 | - * to update that function and not create a new one. | |
| 16 | - * | |
| 17 | - * @param WP_Block $block Block instance. | |
| 18 | - * @param int $page Current query's page. | |
| 19 | - * | |
| 20 | - * @return array Returns the constructed WP_Query arguments. | |
| 21 | - */ | |
| 22 | -function gutenberg_build_query_vars_from_query_block( $block, $page ) { | |
| 23 | - $query = array( | |
| 24 | - 'post_type' => 'post', | |
| 25 | - 'order' => 'DESC', | |
| 26 | - 'orderby' => 'date', | |
| 27 | - 'post__not_in' => array(), | |
| 28 | - ); | |
| 8 | +if ( ! function_exists( 'build_comment_query_vars_from_block' ) ) { | |
| 9 | + /** | |
| 10 | + * Helper function that constructs a comment query vars array from the passed block properties. | |
| 11 | + * | |
| 12 | + * It's used with the Comment Query Loop inner blocks. | |
| 13 | + * | |
| 14 | + * @since 6.0.0 | |
| 15 | + * | |
| 16 | + * @param WP_Block $block Block instance. | |
| 17 | + * | |
| 18 | + * @return array Returns the comment query parameters to use with the WP_Comment_Query constructor. | |
| 19 | + */ | |
| 20 | + function build_comment_query_vars_from_block( $block ) { | |
| 29 | 21 | |
| 30 | - if ( isset( $block->context['query'] ) ) { | |
| 31 | - if ( ! empty( $block->context['query']['postType'] ) ) { | |
| 32 | - $post_type_param = $block->context['query']['postType']; | |
| 33 | - if ( is_post_type_viewable( $post_type_param ) ) { | |
| 34 | - $query['post_type'] = $post_type_param; | |
| 22 | + $comment_args = array( | |
| 23 | + 'orderby' => 'comment_date_gmt', | |
| 24 | + 'order' => 'ASC', | |
| 25 | + 'status' => 'approve', | |
| 26 | + 'no_found_rows' => false, | |
| 27 | + ); | |
| 28 | + | |
| 29 | + if ( is_user_logged_in() ) { | |
| 30 | + $comment_args['include_unapproved'] = array( get_current_user_id() ); | |
| 31 | + } else { | |
| 32 | + $unapproved_email = wp_get_unapproved_comment_author_email(); | |
| 33 | + | |
| 34 | + if ( $unapproved_email ) { | |
| 35 | + $comment_args['include_unapproved'] = array( $unapproved_email ); | |
| 35 | 36 | } |
| 36 | 37 | } |
| 37 | - if ( isset( $block->context['query']['sticky'] ) && ! empty( $block->context['query']['sticky'] ) ) { | |
| 38 | - $sticky = get_option( 'sticky_posts' ); | |
| 39 | - if ( 'only' === $block->context['query']['sticky'] ) { | |
| 40 | - $query['post__in'] = $sticky; | |
| 41 | - } else { | |
| 42 | - $query['post__not_in'] = array_merge( $query['post__not_in'], $sticky ); | |
| 43 | - } | |
| 38 | + | |
| 39 | + if ( ! empty( $block->context['postId'] ) ) { | |
| 40 | + $comment_args['post_id'] = (int) $block->context['postId']; | |
| 44 | 41 | } |
| 45 | - if ( ! empty( $block->context['query']['exclude'] ) ) { | |
| 46 | - $excluded_post_ids = array_map( 'intval', $block->context['query']['exclude'] ); | |
| 47 | - $excluded_post_ids = array_filter( $excluded_post_ids ); | |
| 48 | - $query['post__not_in'] = array_merge( $query['post__not_in'], $excluded_post_ids ); | |
| 42 | + | |
| 43 | + if ( get_option( 'thread_comments' ) ) { | |
| 44 | + $comment_args['hierarchical'] = 'threaded'; | |
| 45 | + } else { | |
| 46 | + $comment_args['hierarchical'] = false; | |
| 49 | 47 | } |
| 50 | - if ( | |
| 51 | - isset( $block->context['query']['perPage'] ) && | |
| 52 | - is_numeric( $block->context['query']['perPage'] ) | |
| 53 | - ) { | |
| 54 | - $per_page = absint( $block->context['query']['perPage'] ); | |
| 55 | - $offset = 0; | |
| 56 | 48 | |
| 57 | - if ( | |
| 58 | - isset( $block->context['query']['offset'] ) && | |
| 59 | - is_numeric( $block->context['query']['offset'] ) | |
| 60 | - ) { | |
| 61 | - $offset = absint( $block->context['query']['offset'] ); | |
| 49 | + if ( get_option( 'page_comments' ) === '1' || get_option( 'page_comments' ) === true ) { | |
| 50 | + $per_page = get_option( 'comments_per_page' ); | |
| 51 | + $default_page = get_option( 'default_comments_page' ); | |
| 52 | + if ( $per_page > 0 ) { | |
| 53 | + $comment_args['number'] = $per_page; | |
| 54 | + | |
| 55 | + $page = (int) get_query_var( 'cpage' ); | |
| 56 | + if ( $page ) { | |
| 57 | + $comment_args['paged'] = $page; | |
| 58 | + } elseif ( 'oldest' === $default_page ) { | |
| 59 | + $comment_args['paged'] = 1; | |
| 60 | + } elseif ( 'newest' === $default_page ) { | |
| 61 | + $max_num_pages = (int) ( new WP_Comment_Query( $comment_args ) )->max_num_pages; | |
| 62 | + if ( 0 !== $max_num_pages ) { | |
| 63 | + $comment_args['paged'] = $max_num_pages; | |
| 64 | + } | |
| 65 | + } | |
| 66 | + // Set the `cpage` query var to ensure the previous and next pagination links are correct | |
| 67 | + // when inheriting the Discussion Settings. | |
| 68 | + if ( 0 === $page && isset( $comment_args['paged'] ) && $comment_args['paged'] > 0 ) { | |
| 69 | + set_query_var( 'cpage', $comment_args['paged'] ); | |
| 70 | + } | |
| 62 | 71 | } |
| 72 | + } | |
| 63 | 73 | |
| 64 | - $query['offset'] = ( $per_page * ( $page - 1 ) ) + $offset; | |
| 65 | - $query['posts_per_page'] = $per_page; | |
| 74 | + return $comment_args; | |
| 75 | + } | |
| 76 | +} | |
| 77 | + | |
| 78 | +if ( ! function_exists( 'get_comments_pagination_arrow' ) ) { | |
| 79 | + /** | |
| 80 | + * Helper function that returns the proper pagination arrow html for | |
| 81 | + * `CommentsPaginationNext` and `CommentsPaginationPrevious` blocks based | |
| 82 | + * on the provided `paginationArrow` from `CommentsPagination` context. | |
| 83 | + * | |
| 84 | + * It's used in CommentsPaginationNext and CommentsPaginationPrevious blocks. | |
| 85 | + * | |
| 86 | + * @since 6.0.0 | |
| 87 | + * | |
| 88 | + * @param WP_Block $block Block instance. | |
| 89 | + * @param string $pagination_type Type of the arrow we will be rendering. Default 'next'. Accepts 'next' or 'previous'. | |
| 90 | + * | |
| 91 | + * @return string|null Returns the constructed WP_Query arguments. | |
| 92 | + */ | |
| 93 | + function get_comments_pagination_arrow( $block, $pagination_type = 'next' ) { | |
| 94 | + $arrow_map = array( | |
| 95 | + 'none' => '', | |
| 96 | + 'arrow' => array( | |
| 97 | + 'next' => '→', | |
| 98 | + 'previous' => '←', | |
| 99 | + ), | |
| 100 | + 'chevron' => array( | |
| 101 | + 'next' => '»', | |
| 102 | + 'previous' => '«', | |
| 103 | + ), | |
| 104 | + ); | |
| 105 | + if ( ! empty( $block->context['comments/paginationArrow'] ) && ! empty( $arrow_map[ $block->context['comments/paginationArrow'] ][ $pagination_type ] ) ) { | |
| 106 | + $arrow_attribute = $block->context['comments/paginationArrow']; | |
| 107 | + $arrow = $arrow_map[ $block->context['comments/paginationArrow'] ][ $pagination_type ]; | |
| 108 | + $arrow_classes = "wp-block-comments-pagination-$pagination_type-arrow is-arrow-$arrow_attribute"; | |
| 109 | + return "<span class='$arrow_classes'>$arrow</span>"; | |
| 66 | 110 | } |
| 111 | + return null; | |
| 112 | + } | |
| 113 | +} | |
| 67 | 114 | |
| 68 | - // We need to migrate `categoryIds` and `tagIds` to `tax_query` for backwards compatibility. | |
| 69 | - if ( ! empty( $block->context['query']['categoryIds'] ) || ! empty( $block->context['query']['tagIds'] ) ) { | |
| 70 | - $tax_query = array(); | |
| 71 | - if ( ! empty( $block->context['query']['categoryIds'] ) ) { | |
| 72 | - $tax_query[] = array( | |
| 73 | - 'taxonomy' => 'category', | |
| 74 | - 'terms' => $block->context['query']['categoryIds'], | |
| 75 | - 'include_children' => false, | |
| 76 | - ); | |
| 115 | +/** | |
| 116 | + * Workaround for getting discussion settings as block editor settings | |
| 117 | + * so any user can access to them without needing to be an admin. | |
| 118 | + * | |
| 119 | + * @param array $settings Default editor settings. | |
| 120 | + * | |
| 121 | + * @return array Filtered editor settings. | |
| 122 | + */ | |
| 123 | +function gutenberg_extend_block_editor_settings_with_discussion_settings( $settings ) { | |
| 124 | + | |
| 125 | + $settings['__experimentalDiscussionSettings'] = array( | |
| 126 | + 'commentOrder' => get_option( 'comment_order' ), | |
| 127 | + 'commentsPerPage' => get_option( 'comments_per_page' ), | |
| 128 | + 'defaultCommentsPage' => get_option( 'default_comments_page' ), | |
| 129 | + 'pageComments' => get_option( 'page_comments' ), | |
| 130 | + 'threadComments' => get_option( 'thread_comments' ), | |
| 131 | + 'threadCommentsDepth' => get_option( 'thread_comments_depth' ), | |
| 132 | + 'defaultCommentStatus' => get_option( 'default_comment_status' ), | |
| 133 | + 'avatarURL' => get_avatar_url( | |
| 134 | + '', | |
| 135 | + array( | |
| 136 | + 'size' => 96, | |
| 137 | + 'force_default' => true, | |
| 138 | + 'default' => get_option( 'avatar_default' ), | |
| 139 | + ) | |
| 140 | + ), | |
| 141 | + ); | |
| 142 | + | |
| 143 | + return $settings; | |
| 144 | +} | |
| 145 | +add_filter( 'block_editor_settings_all', 'gutenberg_extend_block_editor_settings_with_discussion_settings' ); | |
| 146 | + | |
| 147 | +/** | |
| 148 | + * Mark the `children` attr of comments as embeddable so they can be included in | |
| 149 | + * REST API responses without additional requests. | |
| 150 | + * | |
| 151 | + * @return void | |
| 152 | + */ | |
| 153 | +function gutenberg_rest_comment_set_children_as_embeddable() { | |
| 154 | + add_filter( | |
| 155 | + 'rest_prepare_comment', | |
| 156 | + function ( $response ) { | |
| 157 | + $links = $response->get_links(); | |
| 158 | + if ( isset( $links['children'] ) ) { | |
| 159 | + $href = $links['children'][0]['href']; | |
| 160 | + $response->remove_link( 'children', $href ); | |
| 161 | + $response->add_link( 'children', $href, array( 'embeddable' => true ) ); | |
| 77 | 162 | } |
| 78 | - if ( ! empty( $block->context['query']['tagIds'] ) ) { | |
| 79 | - $tax_query[] = array( | |
| 80 | - 'taxonomy' => 'post_tag', | |
| 81 | - 'terms' => $block->context['query']['tagIds'], | |
| 82 | - 'include_children' => false, | |
| 83 | - ); | |
| 84 | - } | |
| 85 | - $query['tax_query'] = $tax_query; | |
| 163 | + return $response; | |
| 86 | 164 | } |
| 87 | - if ( ! empty( $block->context['query']['taxQuery'] ) ) { | |
| 88 | - $query['tax_query'] = array(); | |
| 89 | - foreach ( $block->context['query']['taxQuery'] as $taxonomy => $terms ) { | |
| 90 | - if ( ! empty( $terms ) ) { | |
| 91 | - $term_ids = array_map( 'intval', $terms ); | |
| 92 | - $term_ids = array_filter( $term_ids ); | |
| 165 | + ); | |
| 166 | +} | |
| 167 | +add_action( 'rest_api_init', 'gutenberg_rest_comment_set_children_as_embeddable' ); | |
| 93 | 168 | |
| 94 | - $query['tax_query'][] = array( | |
| 95 | - 'taxonomy' => $taxonomy, | |
| 96 | - 'terms' => $terms, | |
| 97 | - 'include_children' => false, | |
| 98 | - ); | |
| 99 | - } | |
| 100 | - } | |
| 101 | - } | |
| 102 | - if ( | |
| 103 | - isset( $block->context['query']['order'] ) && | |
| 104 | - in_array( strtoupper( $block->context['query']['order'] ), array( 'ASC', 'DESC' ), true ) | |
| 105 | - ) { | |
| 106 | - $query['order'] = strtoupper( $block->context['query']['order'] ); | |
| 107 | - } | |
| 108 | - if ( isset( $block->context['query']['orderBy'] ) ) { | |
| 109 | - $query['orderby'] = $block->context['query']['orderBy']; | |
| 110 | - } | |
| 111 | - if ( ! empty( $block->context['query']['author'] ) ) { | |
| 112 | - $query['author'] = $block->context['query']['author']; | |
| 113 | - } | |
| 114 | - if ( ! empty( $block->context['query']['search'] ) ) { | |
| 115 | - $query['s'] = $block->context['query']['search']; | |
| 116 | - } | |
| 169 | +/** | |
| 170 | + * Registers the lock block attribute for block types. | |
| 171 | + * | |
| 172 | + * Once 6.0 is the minimum supported WordPress version for the Gutenberg | |
| 173 | + * plugin, this shim can be removed | |
| 174 | + * | |
| 175 | + * Doesn't need to be backported into Core. | |
| 176 | + * | |
| 177 | + * @param array $args Array of arguments for registering a block type. | |
| 178 | + * @return array $args | |
| 179 | + */ | |
| 180 | +function gutenberg_register_lock_attribute( $args ) { | |
| 181 | + // Setup attributes if needed. | |
| 182 | + if ( ! isset( $args['attributes'] ) || ! is_array( $args['attributes'] ) ) { | |
| 183 | + $args['attributes'] = array(); | |
| 117 | 184 | } |
| 118 | - return $query; | |
| 185 | + | |
| 186 | + if ( ! array_key_exists( 'lock', $args['attributes'] ) ) { | |
| 187 | + $args['attributes']['lock'] = array( | |
| 188 | + 'type' => 'object', | |
| 189 | + ); | |
| 190 | + } | |
| 191 | + | |
| 192 | + return $args; | |
| 119 | 193 | } |
| 194 | +add_filter( 'register_block_type_args', 'gutenberg_register_lock_attribute' ); | |