Changeset 59115
- Timestamp:
- 09/30/2024 01:17:40 AM (2 weeks ago)
- Location:
- trunk
- Files:
-
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/wp-includes/blocks.php
r59101 r59115 2336 2336 * @since 5.8.0 2337 2337 * @since 6.1.0 Added `query_loop_block_query_vars` filter and `parents` support in query. 2338 * @since 6.7.0 Added support for the `format` property in query. 2338 2339 * 2339 2340 * @param WP_Block $block Block instance. … … 2348 2349 'orderby' => 'date', 2349 2350 'post__not_in' => array(), 2351 'tax_query' => array(), 2350 2352 ); 2351 2353 … … 2397 2399 // Migrate `categoryIds` and `tagIds` to `tax_query` for backwards compatibility. 2398 2400 if ( ! empty( $block->context['query']['categoryIds'] ) || ! empty( $block->context['query']['tagIds'] ) ) { 2399 $tax_query = array();2401 $tax_query_back_compat = array(); 2400 2402 if ( ! empty( $block->context['query']['categoryIds'] ) ) { 2401 $tax_query [] = array(2403 $tax_query_back_compat[] = array( 2402 2404 'taxonomy' => 'category', 2403 2405 'terms' => array_filter( array_map( 'intval', $block->context['query']['categoryIds'] ) ), … … 2406 2408 } 2407 2409 if ( ! empty( $block->context['query']['tagIds'] ) ) { 2408 $tax_query [] = array(2410 $tax_query_back_compat[] = array( 2409 2411 'taxonomy' => 'post_tag', 2410 2412 'terms' => array_filter( array_map( 'intval', $block->context['query']['tagIds'] ) ), … … 2412 2414 ); 2413 2415 } 2414 $query['tax_query'] = $tax_query;2416 $query['tax_query'] = array_merge( $query['tax_query'], $tax_query_back_compat ); 2415 2417 } 2416 2418 if ( ! empty( $block->context['query']['taxQuery'] ) ) { 2417 $ query['tax_query']= array();2419 $tax_query = array(); 2418 2420 foreach ( $block->context['query']['taxQuery'] as $taxonomy => $terms ) { 2419 2421 if ( is_taxonomy_viewable( $taxonomy ) && ! empty( $terms ) ) { 2420 $ query['tax_query'][] = array(2422 $tax_query[] = array( 2421 2423 'taxonomy' => $taxonomy, 2422 2424 'terms' => array_filter( array_map( 'intval', $terms ) ), … … 2425 2427 } 2426 2428 } 2427 } 2429 $query['tax_query'] = array_merge( $query['tax_query'], $tax_query ); 2430 } 2431 if ( ! empty( $block->context['query']['format'] ) && is_array( $block->context['query']['format'] ) ) { 2432 $formats = $block->context['query']['format']; 2433 /* 2434 * Validate that the format is either `standard` or a supported post format. 2435 * - First, add `standard` to the array of valid formats. 2436 * - Then, remove any invalid formats. 2437 */ 2438 $valid_formats = array_merge( array( 'standard' ), get_post_format_slugs() ); 2439 $formats = array_intersect( $formats, $valid_formats ); 2440 2441 /* 2442 * The relation needs to be set to `OR` since the request can contain 2443 * two separate conditions. The user may be querying for items that have 2444 * either the `standard` format or a specific format. 2445 */ 2446 $formats_query = array( 'relation' => 'OR' ); 2447 2448 /* 2449 * The default post format, `standard`, is not stored in the database. 2450 * If `standard` is part of the request, the query needs to exclude all post items that 2451 * have a format assigned. 2452 */ 2453 if ( in_array( 'standard', $formats, true ) ) { 2454 $formats_query[] = array( 2455 'taxonomy' => 'post_format', 2456 'field' => 'slug', 2457 'operator' => 'NOT EXISTS', 2458 ); 2459 // Remove the `standard` format, since it cannot be queried. 2460 unset( $formats[ array_search( 'standard', $formats, true ) ] ); 2461 } 2462 // Add any remaining formats to the formats query. 2463 if ( ! empty( $formats ) ) { 2464 // Add the `post-format-` prefix. 2465 $terms = array_map( 2466 static function ( $format ) { 2467 return "post-format-$format"; 2468 }, 2469 $formats 2470 ); 2471 $formats_query[] = array( 2472 'taxonomy' => 'post_format', 2473 'field' => 'slug', 2474 'terms' => $terms, 2475 'operator' => 'IN', 2476 ); 2477 } 2478 2479 /* 2480 * Add `$formats_query` to `$query`, as long as it contains more than one key: 2481 * If `$formats_query` only contains the initial `relation` key, there are no valid formats to query, 2482 * and the query should not be modified. 2483 */ 2484 if ( count( $formats_query ) > 1 ) { 2485 // Enable filtering by both post formats and other taxonomies by combining them with `AND`. 2486 if ( empty( $query['tax_query'] ) ) { 2487 $query['tax_query'] = $formats_query; 2488 } else { 2489 $query['tax_query'] = array( 2490 'relation' => 'AND', 2491 $query['tax_query'], 2492 $formats_query, 2493 ); 2494 } 2495 } 2496 } 2497 2428 2498 if ( 2429 2499 isset( $block->context['query']['order'] ) && -
trunk/src/wp-includes/rest-api/endpoints/class-wp-rest-posts-controller.php
r59064 r59115 346 346 347 347 $args = $this->prepare_tax_query( $args, $request ); 348 349 if ( ! empty( $request['format'] ) ) { 350 $formats = $request['format']; 351 /* 352 * The relation needs to be set to `OR` since the request can contain 353 * two separate conditions. The user may be querying for items that have 354 * either the `standard` format or a specific format. 355 */ 356 $formats_query = array( 'relation' => 'OR' ); 357 358 /* 359 * The default post format, `standard`, is not stored in the database. 360 * If `standard` is part of the request, the query needs to exclude all post items that 361 * have a format assigned. 362 */ 363 if ( in_array( 'standard', $formats, true ) ) { 364 $formats_query[] = array( 365 'taxonomy' => 'post_format', 366 'field' => 'slug', 367 'operator' => 'NOT EXISTS', 368 ); 369 // Remove the `standard` format, since it cannot be queried. 370 unset( $formats[ array_search( 'standard', $formats, true ) ] ); 371 } 372 373 // Add any remaining formats to the formats query. 374 if ( ! empty( $formats ) ) { 375 // Add the `post-format-` prefix. 376 $terms = array_map( 377 static function ( $format ) { 378 return "post-format-$format"; 379 }, 380 $formats 381 ); 382 383 $formats_query[] = array( 384 'taxonomy' => 'post_format', 385 'field' => 'slug', 386 'terms' => $terms, 387 'operator' => 'IN', 388 ); 389 } 390 391 // Enable filtering by both post formats and other taxonomies by combining them with `AND`. 392 if ( isset( $args['tax_query'] ) ) { 393 $args['tax_query'][] = array( 394 'relation' => 'AND', 395 $formats_query, 396 ); 397 } else { 398 $args['tax_query'] = $formats_query; 399 } 400 } 348 401 349 402 // Force the post_type argument, since it's not a user input variable. … … 2993 3046 } 2994 3047 3048 if ( post_type_supports( $this->post_type, 'post-formats' ) ) { 3049 $query_params['format'] = array( 3050 'description' => __( 'Limit result set to items assigned one or more given formats.' ), 3051 'type' => 'array', 3052 'uniqueItems' => true, 3053 'items' => array( 3054 'enum' => array_values( get_post_format_slugs() ), 3055 'type' => 'string', 3056 ), 3057 ); 3058 } 3059 2995 3060 /** 2996 3061 * Filters collection parameters for the posts controller. -
trunk/tests/phpunit/tests/blocks/wpBlock.php
r58160 r59115 465 465 466 466 /** 467 * @ticket 62014 468 */ 469 public function test_build_query_vars_from_query_block_standard_post_formats() { 470 $this->registry->register( 471 'core/example', 472 array( 'uses_context' => array( 'query' ) ) 473 ); 474 475 $parsed_blocks = parse_blocks( '<!-- wp:example {"ok":true} -->a<!-- wp:example /-->b<!-- /wp:example -->' ); 476 $parsed_block = $parsed_blocks[0]; 477 $context = array( 478 'query' => array( 479 'postType' => 'post', 480 'format' => array( 'standard' ), 481 ), 482 ); 483 $block = new WP_Block( $parsed_block, $context, $this->registry ); 484 $query = build_query_vars_from_query_block( $block, 1 ); 485 486 $this->assertSame( 487 array( 488 'post_type' => 'post', 489 'order' => 'DESC', 490 'orderby' => 'date', 491 'post__not_in' => array(), 492 'tax_query' => array( 493 'relation' => 'OR', 494 array( 495 'taxonomy' => 'post_format', 496 'field' => 'slug', 497 'operator' => 'NOT EXISTS', 498 ), 499 ), 500 ), 501 $query 502 ); 503 } 504 505 /** 506 * @ticket 62014 507 */ 508 public function test_build_query_vars_from_query_block_post_format() { 509 $this->registry->register( 510 'core/example', 511 array( 'uses_context' => array( 'query' ) ) 512 ); 513 514 $parsed_blocks = parse_blocks( '<!-- wp:example {"ok":true} -->a<!-- wp:example /-->b<!-- /wp:example -->' ); 515 $parsed_block = $parsed_blocks[0]; 516 $context = array( 517 'query' => array( 518 'postType' => 'post', 519 'format' => array( 'aside' ), 520 ), 521 ); 522 $block = new WP_Block( $parsed_block, $context, $this->registry ); 523 $query = build_query_vars_from_query_block( $block, 1 ); 524 525 $this->assertSame( 526 array( 527 'post_type' => 'post', 528 'order' => 'DESC', 529 'orderby' => 'date', 530 'post__not_in' => array(), 531 'tax_query' => array( 532 'relation' => 'OR', 533 array( 534 'taxonomy' => 'post_format', 535 'field' => 'slug', 536 'terms' => array( 'post-format-aside' ), 537 'operator' => 'IN', 538 ), 539 ), 540 ), 541 $query 542 ); 543 } 544 /** 545 * @ticket 62014 546 */ 547 public function test_build_query_vars_from_query_block_post_formats_with_category() { 548 $this->registry->register( 549 'core/example', 550 array( 'uses_context' => array( 'query' ) ) 551 ); 552 553 $parsed_blocks = parse_blocks( '<!-- wp:example {"ok":true} -->a<!-- wp:example /-->b<!-- /wp:example -->' ); 554 $parsed_block = $parsed_blocks[0]; 555 $context = array( 556 'query' => array( 557 'postType' => 'post', 558 'format' => array( 'standard' ), 559 'categoryIds' => array( 56 ), 560 ), 561 ); 562 $block = new WP_Block( $parsed_block, $context, $this->registry ); 563 $query = build_query_vars_from_query_block( $block, 1 ); 564 565 $this->assertSame( 566 array( 567 'post_type' => 'post', 568 'order' => 'DESC', 569 'orderby' => 'date', 570 'post__not_in' => array(), 571 'tax_query' => array( 572 'relation' => 'AND', 573 array( 574 array( 575 'taxonomy' => 'category', 576 'terms' => array( 56 ), 577 'include_children' => false, 578 ), 579 ), 580 array( 581 'relation' => 'OR', 582 array( 583 'taxonomy' => 'post_format', 584 'field' => 'slug', 585 'operator' => 'NOT EXISTS', 586 ), 587 ), 588 ), 589 ), 590 $query 591 ); 592 } 593 594 /** 467 595 * @ticket 52991 468 596 */ … … 482 610 'orderby' => 'date', 483 611 'post__not_in' => array(), 612 'tax_query' => array(), 484 613 ) 485 614 ); … … 513 642 'orderby' => 'date', 514 643 'post__not_in' => array(), 644 'tax_query' => array(), 515 645 'offset' => 0, 516 646 'posts_per_page' => 2, … … 545 675 'orderby' => 'date', 546 676 'post__not_in' => array(), 677 'tax_query' => array(), 547 678 'offset' => 10, 548 679 'posts_per_page' => 5, … … 577 708 'orderby' => 'date', 578 709 'post__not_in' => array(), 710 'tax_query' => array(), 579 711 'offset' => 12, 580 712 'posts_per_page' => 5, … … 620 752 'orderby' => 'title', 621 753 'post__not_in' => array(), 754 'tax_query' => array(), 622 755 ) 623 756 ); -
trunk/tests/phpunit/tests/rest-api/rest-posts-controller.php
r59036 r59115 197 197 'context', 198 198 'exclude', 199 'format', 199 200 'include', 200 201 'modified_after', … … 5498 5499 5499 5500 /** 5501 * Test the REST API support for the standard post format. 5502 * 5503 * @ticket 62014 5504 * 5505 * @covers WP_REST_Posts_Controller::get_items 5506 */ 5507 public function test_standard_post_format_support() { 5508 $initial_theme_support = get_theme_support( 'post-formats' ); 5509 add_theme_support( 'post-formats', array( 'aside', 'gallery', 'link', 'image', 'quote', 'status', 'video', 'audio', 'chat' ) ); 5510 5511 $post_id = self::factory()->post->create( 5512 array( 5513 'post_type' => 'post', 5514 'post_status' => 'publish', 5515 ) 5516 ); 5517 set_post_format( $post_id, 'aside' ); 5518 5519 $request = new WP_REST_Request( 'GET', '/wp/v2/posts' ); 5520 $request->set_param( 'format', array( 'standard' ) ); 5521 $request->set_param( 'per_page', REST_TESTS_IMPOSSIBLY_HIGH_NUMBER ); 5522 5523 $response = rest_get_server()->dispatch( $request ); 5524 5525 /* 5526 * Restore the initial post formats support. 5527 * 5528 * This needs to be done prior to the assertions to avoid unexpected 5529 * results for other tests should an assertion fail. 5530 */ 5531 if ( $initial_theme_support ) { 5532 add_theme_support( 'post-formats', $initial_theme_support[0] ); 5533 } else { 5534 remove_theme_support( 'post-formats' ); 5535 } 5536 5537 $this->assertCount( 3, $response->get_data(), 'The response should only include standard post formats' ); 5538 } 5539 5540 /** 5541 * Test the REST API support for post formats. 5542 * 5543 * @ticket 62014 5544 * 5545 * @covers WP_REST_Posts_Controller::get_items 5546 */ 5547 public function test_post_format_support() { 5548 $initial_theme_support = get_theme_support( 'post-formats' ); 5549 add_theme_support( 'post-formats', array( 'aside', 'gallery', 'link', 'image', 'quote', 'status', 'video', 'audio', 'chat' ) ); 5550 5551 $post_id = self::factory()->post->create( 5552 array( 5553 'post_type' => 'post', 5554 'post_status' => 'publish', 5555 ) 5556 ); 5557 set_post_format( $post_id, 'aside' ); 5558 5559 $request = new WP_REST_Request( 'GET', '/wp/v2/posts' ); 5560 $request->set_param( 'format', array( 'aside' ) ); 5561 5562 $response_aside = rest_get_server()->dispatch( $request ); 5563 5564 $request->set_param( 'format', array( 'invalid_format' ) ); 5565 $response_invalid = rest_get_server()->dispatch( $request ); 5566 5567 /* 5568 * Restore the initial post formats support. 5569 * 5570 * This needs to be done prior to the assertions to avoid unexpected 5571 * results for other tests should an assertion fail. 5572 */ 5573 if ( $initial_theme_support ) { 5574 add_theme_support( 'post-formats', $initial_theme_support[0] ); 5575 } else { 5576 remove_theme_support( 'post-formats' ); 5577 } 5578 5579 $this->assertCount( 1, $response_aside->get_data(), 'Only one post is expected to be returned.' ); 5580 $this->assertErrorResponse( 'rest_invalid_param', $response_invalid, 400, 'An invalid post format should return an error' ); 5581 } 5582 5583 /** 5584 * Test the REST API support for multiple post formats. 5585 * 5586 * @ticket 62014 5587 * 5588 * @covers WP_REST_Posts_Controller::get_items 5589 */ 5590 public function test_multiple_post_format_support() { 5591 $initial_theme_support = get_theme_support( 'post-formats' ); 5592 add_theme_support( 'post-formats', array( 'aside', 'gallery', 'link', 'image', 'quote', 'status', 'video', 'audio', 'chat' ) ); 5593 5594 $post_id = self::factory()->post->create( 5595 array( 5596 'post_type' => 'post', 5597 'post_status' => 'publish', 5598 ) 5599 ); 5600 set_post_format( $post_id, 'aside' ); 5601 5602 $post_id_2 = self::factory()->post->create( 5603 array( 5604 'post_type' => 'post', 5605 'post_status' => 'publish', 5606 ) 5607 ); 5608 set_post_format( $post_id_2, 'gallery' ); 5609 5610 $request = new WP_REST_Request( 'GET', '/wp/v2/posts' ); 5611 $request->set_param( 'format', array( 'aside', 'gallery' ) ); 5612 5613 $response = rest_get_server()->dispatch( $request ); 5614 5615 /* 5616 * Restore the initial post formats support. 5617 * 5618 * This needs to be done prior to the assertions to avoid unexpected 5619 * results for other tests should an assertion fail. 5620 */ 5621 if ( $initial_theme_support ) { 5622 add_theme_support( 'post-formats', $initial_theme_support[0] ); 5623 } else { 5624 remove_theme_support( 'post-formats' ); 5625 } 5626 5627 $this->assertCount( 2, $response->get_data(), 'Two posts are expected to be returned' ); 5628 } 5629 5630 /** 5500 5631 * Internal function used to disable an insert query which 5501 5632 * will trigger a wpdb error for testing purposes. -
trunk/tests/qunit/fixtures/wp-api-generated.js
r59034 r59115 626 626 "description": "Limit result set to items that are sticky.", 627 627 "type": "boolean", 628 "required": false 629 }, 630 "format": { 631 "description": "Limit result set to items assigned one or more given formats.", 632 "type": "array", 633 "uniqueItems": true, 634 "items": { 635 "enum": [ 636 "standard", 637 "aside", 638 "chat", 639 "gallery", 640 "link", 641 "image", 642 "quote", 643 "status", 644 "video", 645 "audio" 646 ], 647 "type": "string" 648 }, 628 649 "required": false 629 650 }
Note: See TracChangeset
for help on using the changeset viewer.