Skip to content

Commit bc4ecd4

Browse files
sunyatasattvantsekourasgziolo
authored
Add a filter to build_query_vars_from_query_block (#43590)
* Add a filter to `build_query_vars_from_query_block` The filter allows Query Loop block variation to hook into the query and possibly inject custom query parameters. * Move `build_query_vars_from_query_block` to 6.1 compat and add docs * Apply suggestions from code review * Change filter name to `query_loop_block_query_vars` * Fix docs typo * Fix docs version Co-authored-by: Nik Tsekouras <[email protected]> * Elaborate filter docs * Update lib/compat/wordpress-6.1/blocks.php * Update lib/compat/wordpress-6.1/blocks.php Co-authored-by: Nik Tsekouras <[email protected]> Co-authored-by: Greg Ziółkowski <[email protected]>
1 parent 8bdfdff commit bc4ecd4

File tree

2 files changed

+142
-121
lines changed

2 files changed

+142
-121
lines changed

lib/compat/wordpress-6.0/blocks.php

Lines changed: 0 additions & 121 deletions
Original file line numberDiff line numberDiff line change
@@ -5,127 +5,6 @@
55
* @package gutenberg
66
*/
77

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-
);
29-
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;
35-
}
36-
}
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-
/**
41-
* Passing an empty array to post__in will return have_posts() as true (and all posts will be returned).
42-
* Logic should be used before hand to determine if WP_Query should be used in the event that the array
43-
* being passed to post__in is empty.
44-
*
45-
* @see https://core.trac.wordpress.org/ticket/28099
46-
*/
47-
$query['post__in'] = ! empty( $sticky ) ? $sticky : array( 0 );
48-
$query['ignore_sticky_posts'] = 1;
49-
} else {
50-
$query['post__not_in'] = array_merge( $query['post__not_in'], $sticky );
51-
}
52-
}
53-
if ( ! empty( $block->context['query']['exclude'] ) ) {
54-
$excluded_post_ids = array_map( 'intval', $block->context['query']['exclude'] );
55-
$excluded_post_ids = array_filter( $excluded_post_ids );
56-
$query['post__not_in'] = array_merge( $query['post__not_in'], $excluded_post_ids );
57-
}
58-
if (
59-
isset( $block->context['query']['perPage'] ) &&
60-
is_numeric( $block->context['query']['perPage'] )
61-
) {
62-
$per_page = absint( $block->context['query']['perPage'] );
63-
$offset = 0;
64-
65-
if (
66-
isset( $block->context['query']['offset'] ) &&
67-
is_numeric( $block->context['query']['offset'] )
68-
) {
69-
$offset = absint( $block->context['query']['offset'] );
70-
}
71-
72-
$query['offset'] = ( $per_page * ( $page - 1 ) ) + $offset;
73-
$query['posts_per_page'] = $per_page;
74-
}
75-
76-
// We need to migrate `categoryIds` and `tagIds` to `tax_query` for backwards compatibility.
77-
if ( ! empty( $block->context['query']['categoryIds'] ) || ! empty( $block->context['query']['tagIds'] ) ) {
78-
$tax_query = array();
79-
if ( ! empty( $block->context['query']['categoryIds'] ) ) {
80-
$tax_query[] = array(
81-
'taxonomy' => 'category',
82-
'terms' => array_filter( array_map( 'intval', $block->context['query']['categoryIds'] ) ),
83-
'include_children' => false,
84-
);
85-
}
86-
if ( ! empty( $block->context['query']['tagIds'] ) ) {
87-
$tax_query[] = array(
88-
'taxonomy' => 'post_tag',
89-
'terms' => array_filter( array_map( 'intval', $block->context['query']['tagIds'] ) ),
90-
'include_children' => false,
91-
);
92-
}
93-
$query['tax_query'] = $tax_query;
94-
}
95-
if ( ! empty( $block->context['query']['taxQuery'] ) ) {
96-
$query['tax_query'] = array();
97-
foreach ( $block->context['query']['taxQuery'] as $taxonomy => $terms ) {
98-
if ( is_taxonomy_viewable( $taxonomy ) && ! empty( $terms ) ) {
99-
$query['tax_query'][] = array(
100-
'taxonomy' => $taxonomy,
101-
'terms' => array_filter( array_map( 'intval', $terms ) ),
102-
'include_children' => false,
103-
);
104-
}
105-
}
106-
}
107-
if (
108-
isset( $block->context['query']['order'] ) &&
109-
in_array( strtoupper( $block->context['query']['order'] ), array( 'ASC', 'DESC' ), true )
110-
) {
111-
$query['order'] = strtoupper( $block->context['query']['order'] );
112-
}
113-
if ( isset( $block->context['query']['orderBy'] ) ) {
114-
$query['orderby'] = $block->context['query']['orderBy'];
115-
}
116-
if ( ! empty( $block->context['query']['author'] ) ) {
117-
$query['author'] = $block->context['query']['author'];
118-
}
119-
if ( ! empty( $block->context['query']['search'] ) ) {
120-
$query['s'] = $block->context['query']['search'];
121-
}
122-
if ( ! empty( $block->context['query']['parents'] ) && is_post_type_hierarchical( $query['post_type'] ) ) {
123-
$query['post_parent__in'] = array_filter( array_map( 'intval', $block->context['query']['parents'] ) );
124-
}
125-
}
126-
return $query;
127-
}
128-
1298
if ( ! function_exists( 'build_comment_query_vars_from_block' ) ) {
1309
/**
13110
* Helper function that constructs a comment query vars array from the passed block properties.

lib/compat/wordpress-6.1/blocks.php

Lines changed: 142 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -206,6 +206,148 @@ function gutenberg_block_type_metadata_multiple_view_scripts( $metadata ) {
206206
}
207207
add_filter( 'block_type_metadata', 'gutenberg_block_type_metadata_multiple_view_scripts' );
208208

209+
/**
210+
* Helper function that constructs a WP_Query args array from
211+
* a `Query` block properties.
212+
*
213+
* It's used in QueryLoop, QueryPaginationNumbers and QueryPaginationNext blocks.
214+
*
215+
* `build_query_vars_from_query_block` was introduced in 5.8, for 6.1 we just need
216+
* to update that function and not create a new one.
217+
*
218+
* @param WP_Block $block Block instance.
219+
* @param int $page Current query's page.
220+
*
221+
* @return array Returns the constructed WP_Query arguments.
222+
*/
223+
function gutenberg_build_query_vars_from_query_block( $block, $page ) {
224+
$query = array(
225+
'post_type' => 'post',
226+
'order' => 'DESC',
227+
'orderby' => 'date',
228+
'post__not_in' => array(),
229+
);
230+
231+
if ( isset( $block->context['query'] ) ) {
232+
if ( ! empty( $block->context['query']['postType'] ) ) {
233+
$post_type_param = $block->context['query']['postType'];
234+
if ( is_post_type_viewable( $post_type_param ) ) {
235+
$query['post_type'] = $post_type_param;
236+
}
237+
}
238+
if ( isset( $block->context['query']['sticky'] ) && ! empty( $block->context['query']['sticky'] ) ) {
239+
$sticky = get_option( 'sticky_posts' );
240+
if ( 'only' === $block->context['query']['sticky'] ) {
241+
/**
242+
* Passing an empty array to post__in will return have_posts() as true (and all posts will be returned).
243+
* Logic should be used before hand to determine if WP_Query should be used in the event that the array
244+
* being passed to post__in is empty.
245+
*
246+
* @see https://core.trac.wordpress.org/ticket/28099
247+
*/
248+
$query['post__in'] = ! empty( $sticky ) ? $sticky : array( 0 );
249+
$query['ignore_sticky_posts'] = 1;
250+
} else {
251+
$query['post__not_in'] = array_merge( $query['post__not_in'], $sticky );
252+
}
253+
}
254+
if ( ! empty( $block->context['query']['exclude'] ) ) {
255+
$excluded_post_ids = array_map( 'intval', $block->context['query']['exclude'] );
256+
$excluded_post_ids = array_filter( $excluded_post_ids );
257+
$query['post__not_in'] = array_merge( $query['post__not_in'], $excluded_post_ids );
258+
}
259+
if (
260+
isset( $block->context['query']['perPage'] ) &&
261+
is_numeric( $block->context['query']['perPage'] )
262+
) {
263+
$per_page = absint( $block->context['query']['perPage'] );
264+
$offset = 0;
265+
266+
if (
267+
isset( $block->context['query']['offset'] ) &&
268+
is_numeric( $block->context['query']['offset'] )
269+
) {
270+
$offset = absint( $block->context['query']['offset'] );
271+
}
272+
273+
$query['offset'] = ( $per_page * ( $page - 1 ) ) + $offset;
274+
$query['posts_per_page'] = $per_page;
275+
}
276+
277+
// We need to migrate `categoryIds` and `tagIds` to `tax_query` for backwards compatibility.
278+
if ( ! empty( $block->context['query']['categoryIds'] ) || ! empty( $block->context['query']['tagIds'] ) ) {
279+
$tax_query = array();
280+
if ( ! empty( $block->context['query']['categoryIds'] ) ) {
281+
$tax_query[] = array(
282+
'taxonomy' => 'category',
283+
'terms' => array_filter( array_map( 'intval', $block->context['query']['categoryIds'] ) ),
284+
'include_children' => false,
285+
);
286+
}
287+
if ( ! empty( $block->context['query']['tagIds'] ) ) {
288+
$tax_query[] = array(
289+
'taxonomy' => 'post_tag',
290+
'terms' => array_filter( array_map( 'intval', $block->context['query']['tagIds'] ) ),
291+
'include_children' => false,
292+
);
293+
}
294+
$query['tax_query'] = $tax_query;
295+
}
296+
if ( ! empty( $block->context['query']['taxQuery'] ) ) {
297+
$query['tax_query'] = array();
298+
foreach ( $block->context['query']['taxQuery'] as $taxonomy => $terms ) {
299+
if ( is_taxonomy_viewable( $taxonomy ) && ! empty( $terms ) ) {
300+
$query['tax_query'][] = array(
301+
'taxonomy' => $taxonomy,
302+
'terms' => array_filter( array_map( 'intval', $terms ) ),
303+
'include_children' => false,
304+
);
305+
}
306+
}
307+
}
308+
if (
309+
isset( $block->context['query']['order'] ) &&
310+
in_array( strtoupper( $block->context['query']['order'] ), array( 'ASC', 'DESC' ), true )
311+
) {
312+
$query['order'] = strtoupper( $block->context['query']['order'] );
313+
}
314+
if ( isset( $block->context['query']['orderBy'] ) ) {
315+
$query['orderby'] = $block->context['query']['orderBy'];
316+
}
317+
if ( ! empty( $block->context['query']['author'] ) ) {
318+
$query['author'] = $block->context['query']['author'];
319+
}
320+
if ( ! empty( $block->context['query']['search'] ) ) {
321+
$query['s'] = $block->context['query']['search'];
322+
}
323+
if ( ! empty( $block->context['query']['parents'] ) && is_post_type_hierarchical( $query['post_type'] ) ) {
324+
$query['post_parent__in'] = array_filter( array_map( 'intval', $block->context['query']['parents'] ) );
325+
}
326+
}
327+
328+
/**
329+
* Filters the arguments which will be passed to `WP_Query` for the Query Loop Block.
330+
*
331+
* Anything to this filter should be compatible with the `WP_Query` API to form
332+
* the query context which will be passed down to the Query Loop Block's children.
333+
* This can help, for example, to include additional settings or meta queries not
334+
* directly supported by the core Query Loop Block, and extend its capabilities.
335+
*
336+
* Please note that this will only influence the query that will be rendered on the
337+
* front-end. The editor preview is not affected by this filter. Also, worth noting
338+
* that the editor preview uses the REST API, so, ideally, one should aim to provide
339+
* attributes which are also compatible with the REST API, in order to be able to
340+
* implement identical queries on both sides.
341+
*
342+
* @since 6.1.0
343+
*
344+
* @param array $query Array containing parameters for `WP_Query` as parsed by the block context.
345+
* @param WP_Block $block Block instance.
346+
* @param int $page Current query's page.
347+
*/
348+
return apply_filters( 'query_loop_block_query_vars', $query, $block, $page );
349+
}
350+
209351
/**
210352
* Register render template for core blocks if handling is missing in WordPress core.
211353
*

0 commit comments

Comments
 (0)