Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for the format property in query #7314

Closed
wants to merge 27 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
7b34ec9
Add support for the `format` property in query
carolinan Sep 9, 2024
24efb21
Tests: Add format as a valid parameter in WP_Test_REST_Posts_Controll…
carolinan Sep 9, 2024
8e44597
build_query_vars_from_query_block: Fix incorrect variable name and br…
carolinan Sep 11, 2024
d7ab338
Tests: Update the qunit fixture in `wp-api-generated.js`
carolinan Sep 11, 2024
a4fb1b4
`WP_REST_Posts_Controller`: remove redundant array conversion for the…
carolinan Sep 11, 2024
7eec23a
`WP_REST_Posts_Controller`: Tidy up the inline comments.
carolinan Sep 11, 2024
83eefcb
`WP_REST_Posts_Controller` `get_collection_params`: add `uniqueItems`…
carolinan Sep 11, 2024
5fb2c49
Tests: Update the qunit fixtures in wp-api-generated.js
carolinan Sep 11, 2024
5058604
Update the format of inline comments
carolinan Sep 12, 2024
1b974aa
Remove unnecessary `terms` from the query for the standard format
carolinan Sep 17, 2024
3244361
Change the `relation` from `OR` to `AND` when querying for the `format`
carolinan Sep 17, 2024
5ee2750
In build_query_vars_from_query_block: validate the formats
carolinan Sep 17, 2024
c71f92f
WP_REST_Posts_Controller: Change the `relation` from `AND` to `OR` wh…
carolinan Sep 19, 2024
19ba793
build_query_vars_from_query_block: Change the `relation` when queryin…
carolinan Sep 19, 2024
ef44367
Formats: address feedback from code review and PHPCS issues
carolinan Sep 19, 2024
47e1581
build_query_vars_from_query_block: Try to resolve the nested relations
carolinan Sep 19, 2024
ad5ea9f
Merge branch 'WordPress:trunk' into try/post-formats-62014
carolinan Sep 20, 2024
0d3d4dc
Merge branch 'WordPress:trunk' into try/post-formats-62014
carolinan Sep 23, 2024
4e69a77
Merge branch 'WordPress:trunk' into try/post-formats-62014
carolinan Sep 25, 2024
6a78361
build_query_vars_from_query_block: Update variable names and if/else …
carolinan Sep 25, 2024
290a106
Oops
carolinan Sep 25, 2024
8ae0075
Tests: Tests_Blocks_wpBlock: Update arrays used in `assertSame`
carolinan Sep 25, 2024
53e45f4
Merge branch 'WordPress:trunk' into try/post-formats-62014
carolinan Sep 27, 2024
54f6b67
Merge branch 'trunk' into try/post-formats-62014
peterwilsoncc Sep 29, 2024
16223d6
Merge branch 'trunk' into try/post-formats-62014
peterwilsoncc Sep 29, 2024
4aa0b29
Add tests for the rest api format getter.
peterwilsoncc Sep 30, 2024
f1508b7
Add tests for post formats in query block builder.
peterwilsoncc Sep 30, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
82 changes: 76 additions & 6 deletions src/wp-includes/blocks.php
Original file line number Diff line number Diff line change
Expand Up @@ -2335,6 +2335,7 @@ function wp_migrate_old_typography_shape( $metadata ) {
*
* @since 5.8.0
* @since 6.1.0 Added `query_loop_block_query_vars` filter and `parents` support in query.
* @since 6.7.0 Added support for the `format` property in query.
*
* @param WP_Block $block Block instance.
* @param int $page Current query's page.
Expand All @@ -2347,6 +2348,7 @@ function build_query_vars_from_query_block( $block, $page ) {
'order' => 'DESC',
'orderby' => 'date',
'post__not_in' => array(),
'tax_query' => array(),
);

if ( isset( $block->context['query'] ) ) {
Expand Down Expand Up @@ -2396,35 +2398,103 @@ function build_query_vars_from_query_block( $block, $page ) {
}
// Migrate `categoryIds` and `tagIds` to `tax_query` for backwards compatibility.
if ( ! empty( $block->context['query']['categoryIds'] ) || ! empty( $block->context['query']['tagIds'] ) ) {
$tax_query = array();
$tax_query_back_compat = array();
if ( ! empty( $block->context['query']['categoryIds'] ) ) {
$tax_query[] = array(
$tax_query_back_compat[] = array(
'taxonomy' => 'category',
'terms' => array_filter( array_map( 'intval', $block->context['query']['categoryIds'] ) ),
'include_children' => false,
);
}
if ( ! empty( $block->context['query']['tagIds'] ) ) {
$tax_query[] = array(
$tax_query_back_compat[] = array(
'taxonomy' => 'post_tag',
'terms' => array_filter( array_map( 'intval', $block->context['query']['tagIds'] ) ),
'include_children' => false,
);
}
$query['tax_query'] = $tax_query;
$query['tax_query'] = array_merge( $query['tax_query'], $tax_query_back_compat );
}
if ( ! empty( $block->context['query']['taxQuery'] ) ) {
$query['tax_query'] = array();
$tax_query = array();
foreach ( $block->context['query']['taxQuery'] as $taxonomy => $terms ) {
if ( is_taxonomy_viewable( $taxonomy ) && ! empty( $terms ) ) {
$query['tax_query'][] = array(
$tax_query[] = array(
'taxonomy' => $taxonomy,
'terms' => array_filter( array_map( 'intval', $terms ) ),
'include_children' => false,
);
}
}
$query['tax_query'] = array_merge( $query['tax_query'], $tax_query );
}
if ( ! empty( $block->context['query']['format'] ) && is_array( $block->context['query']['format'] ) ) {
$formats = $block->context['query']['format'];
/*
* Validate that the format is either `standard` or a supported post format.
* - First, add `standard` to the array of valid formats.
* - Then, remove any invalid formats.
*/
$valid_formats = array_merge( array( 'standard' ), get_post_format_slugs() );
$formats = array_intersect( $formats, $valid_formats );

/*
* The relation needs to be set to `OR` since the request can contain
* two separate conditions. The user may be querying for items that have
* either the `standard` format or a specific format.
*/
$formats_query = array( 'relation' => 'OR' );

/*
* The default post format, `standard`, is not stored in the database.
* If `standard` is part of the request, the query needs to exclude all post items that
* have a format assigned.
*/
if ( in_array( 'standard', $formats, true ) ) {
$formats_query[] = array(
'taxonomy' => 'post_format',
'field' => 'slug',
'operator' => 'NOT EXISTS',
);
// Remove the `standard` format, since it cannot be queried.
unset( $formats[ array_search( 'standard', $formats, true ) ] );
}
// Add any remaining formats to the formats query.
if ( ! empty( $formats ) ) {
// Add the `post-format-` prefix.
$terms = array_map(
static function ( $format ) {
return "post-format-$format";
},
$formats
);
$formats_query[] = array(
'taxonomy' => 'post_format',
'field' => 'slug',
'terms' => $terms,
'operator' => 'IN',
);
}

/*
* Add `$formats_query` to `$query`, as long as it contains more than one key:
* If `$formats_query` only contains the initial `relation` key, there are no valid formats to query,
* and the query should not be modified.
*/
if ( count( $formats_query ) > 1 ) {
// Enable filtering by both post formats and other taxonomies by combining them with `AND`.
if ( empty( $query['tax_query'] ) ) {
$query['tax_query'] = $formats_query;
} else {
$query['tax_query'] = array(
'relation' => 'AND',
$query['tax_query'],
$formats_query,
);
}
}
}

if (
isset( $block->context['query']['order'] ) &&
in_array( strtoupper( $block->context['query']['order'] ), array( 'ASC', 'DESC' ), true )
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -346,6 +346,59 @@ public function get_items( $request ) {

$args = $this->prepare_tax_query( $args, $request );

if ( ! empty( $request['format'] ) ) {
$formats = $request['format'];
/*
* The relation needs to be set to `OR` since the request can contain
* two separate conditions. The user may be querying for items that have
* either the `standard` format or a specific format.
*/
$formats_query = array( 'relation' => 'OR' );

/*
* The default post format, `standard`, is not stored in the database.
* If `standard` is part of the request, the query needs to exclude all post items that
* have a format assigned.
*/
if ( in_array( 'standard', $formats, true ) ) {
$formats_query[] = array(
'taxonomy' => 'post_format',
'field' => 'slug',
'operator' => 'NOT EXISTS',
);
// Remove the `standard` format, since it cannot be queried.
unset( $formats[ array_search( 'standard', $formats, true ) ] );
}

// Add any remaining formats to the formats query.
if ( ! empty( $formats ) ) {
// Add the `post-format-` prefix.
$terms = array_map(
static function ( $format ) {
return "post-format-$format";
},
$formats
);

$formats_query[] = array(
'taxonomy' => 'post_format',
'field' => 'slug',
'terms' => $terms,
'operator' => 'IN',
);
}

// Enable filtering by both post formats and other taxonomies by combining them with `AND`.
if ( isset( $args['tax_query'] ) ) {
$args['tax_query'][] = array(
'relation' => 'AND',
$formats_query,
);
} else {
$args['tax_query'] = $formats_query;
}
}

// Force the post_type argument, since it's not a user input variable.
$args['post_type'] = $this->post_type;

Expand Down Expand Up @@ -2992,6 +3045,18 @@ public function get_collection_params() {
);
}

if ( post_type_supports( $this->post_type, 'post-formats' ) ) {
$query_params['format'] = array(
'description' => __( 'Limit result set to items assigned one or more given formats.' ),
'type' => 'array',
'uniqueItems' => true,
'items' => array(
'enum' => array_values( get_post_format_slugs() ),
'type' => 'string',
),
);
}

/**
* Filters collection parameters for the posts controller.
*
Expand Down
133 changes: 133 additions & 0 deletions tests/phpunit/tests/blocks/wpBlock.php
Original file line number Diff line number Diff line change
Expand Up @@ -463,6 +463,134 @@ public function test_build_query_vars_from_query_block() {
);
}

/**
* @ticket 62014
*/
public function test_build_query_vars_from_query_block_standard_post_formats() {
$this->registry->register(
'core/example',
array( 'uses_context' => array( 'query' ) )
);

$parsed_blocks = parse_blocks( '<!-- wp:example {"ok":true} -->a<!-- wp:example /-->b<!-- /wp:example -->' );
$parsed_block = $parsed_blocks[0];
$context = array(
'query' => array(
'postType' => 'post',
'format' => array( 'standard' ),
),
);
$block = new WP_Block( $parsed_block, $context, $this->registry );
$query = build_query_vars_from_query_block( $block, 1 );

$this->assertSame(
array(
'post_type' => 'post',
'order' => 'DESC',
'orderby' => 'date',
'post__not_in' => array(),
'tax_query' => array(
'relation' => 'OR',
array(
'taxonomy' => 'post_format',
'field' => 'slug',
'operator' => 'NOT EXISTS',
),
),
),
$query
);
}

/**
* @ticket 62014
*/
public function test_build_query_vars_from_query_block_post_format() {
$this->registry->register(
'core/example',
array( 'uses_context' => array( 'query' ) )
);

$parsed_blocks = parse_blocks( '<!-- wp:example {"ok":true} -->a<!-- wp:example /-->b<!-- /wp:example -->' );
$parsed_block = $parsed_blocks[0];
$context = array(
'query' => array(
'postType' => 'post',
'format' => array( 'aside' ),
),
);
$block = new WP_Block( $parsed_block, $context, $this->registry );
$query = build_query_vars_from_query_block( $block, 1 );

$this->assertSame(
array(
'post_type' => 'post',
'order' => 'DESC',
'orderby' => 'date',
'post__not_in' => array(),
'tax_query' => array(
'relation' => 'OR',
array(
'taxonomy' => 'post_format',
'field' => 'slug',
'terms' => array( 'post-format-aside' ),
'operator' => 'IN',
),
),
),
$query
);
}
/**
* @ticket 62014
*/
public function test_build_query_vars_from_query_block_post_formats_with_category() {
$this->registry->register(
'core/example',
array( 'uses_context' => array( 'query' ) )
);

$parsed_blocks = parse_blocks( '<!-- wp:example {"ok":true} -->a<!-- wp:example /-->b<!-- /wp:example -->' );
$parsed_block = $parsed_blocks[0];
$context = array(
'query' => array(
'postType' => 'post',
'format' => array( 'standard' ),
'categoryIds' => array( 56 ),
),
);
$block = new WP_Block( $parsed_block, $context, $this->registry );
$query = build_query_vars_from_query_block( $block, 1 );

$this->assertSame(
array(
'post_type' => 'post',
'order' => 'DESC',
'orderby' => 'date',
'post__not_in' => array(),
'tax_query' => array(
'relation' => 'AND',
array(
array(
'taxonomy' => 'category',
'terms' => array( 56 ),
'include_children' => false,
),
),
array(
'relation' => 'OR',
array(
'taxonomy' => 'post_format',
'field' => 'slug',
'operator' => 'NOT EXISTS',
),
),
),
),
$query
);
}

/**
* @ticket 52991
*/
Expand All @@ -481,6 +609,7 @@ public function test_build_query_vars_from_query_block_no_context() {
'order' => 'DESC',
'orderby' => 'date',
'post__not_in' => array(),
'tax_query' => array(),
)
);
}
Expand Down Expand Up @@ -512,6 +641,7 @@ public function test_build_query_vars_from_query_block_first_page() {
'order' => 'DESC',
'orderby' => 'date',
'post__not_in' => array(),
'tax_query' => array(),
'offset' => 0,
'posts_per_page' => 2,
)
Expand Down Expand Up @@ -544,6 +674,7 @@ public function test_build_query_vars_from_query_block_page_no_offset() {
'order' => 'DESC',
'orderby' => 'date',
'post__not_in' => array(),
'tax_query' => array(),
'offset' => 10,
'posts_per_page' => 5,
)
Expand Down Expand Up @@ -576,6 +707,7 @@ public function test_build_query_vars_from_query_block_page_with_offset() {
'order' => 'DESC',
'orderby' => 'date',
'post__not_in' => array(),
'tax_query' => array(),
'offset' => 12,
'posts_per_page' => 5,
)
Expand Down Expand Up @@ -619,6 +751,7 @@ static function ( $query, $block, $page ) {
'order' => 'DESC',
'orderby' => 'title',
'post__not_in' => array(),
'tax_query' => array(),
)
);
}
Expand Down
Loading
Loading