Changeset 57919
- Timestamp:
- 04/03/2024 03:09:38 PM (8 months ago)
- Location:
- trunk
- Files:
-
- 1 added
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/wp-includes/block-template-utils.php
r57790 r57919 726 726 727 727 /** 728 * Builds a unified template object based a post Object. 729 * 730 * @since 5.9.0 731 * @since 6.3.0 Added `modified` property to template objects. 732 * @since 6.4.0 Added support for a revision post to be passed to this function. 728 * Builds a block template object from a post object. 729 * 730 * This is a helper function that creates a block template object from a given post object. 731 * It is self-sufficient in that it only uses information passed as arguments; it does not 732 * query the database for additional information. 733 * 734 * @since 6.5.1 733 735 * @access private 734 736 * 735 * @param WP_Post $post Template post. 737 * @param WP_Post $post Template post. 738 * @param array $terms Additional terms to inform the template object. 739 * @param array $meta Additional meta fields to inform the template object. 736 740 * @return WP_Block_Template|WP_Error Template or error object. 737 741 */ 738 function _build_block_template_result_from_post( $post ) { 742 function _build_block_template_object_from_post_object( $post, $terms = array(), $meta = array() ) { 743 if ( empty( $terms['wp_theme'] ) ) { 744 return new WP_Error( 'template_missing_theme', __( 'No theme is defined for this template.' ) ); 745 } 746 $theme = $terms['wp_theme']; 747 739 748 $default_template_types = get_default_block_template_types(); 740 749 741 $post_id = wp_is_post_revision( $post );742 if ( ! $post_id ) {743 $post_id = $post;744 }745 $parent_post = get_post( $post_id );746 747 $terms = get_the_terms( $parent_post, 'wp_theme' );748 749 if ( is_wp_error( $terms ) ) {750 return $terms;751 }752 753 if ( ! $terms ) {754 return new WP_Error( 'template_missing_theme', __( 'No theme is defined for this template.' ) );755 }756 757 $theme = $terms[0]->name;758 750 $template_file = _get_block_template_file( $post->post_type, $post->post_name ); 759 751 $has_theme_file = get_stylesheet() === $theme && null !== $template_file; 760 752 761 $origin = get_post_meta( $parent_post->ID, 'origin', true );762 $is_wp_suggestion = get_post_meta( $parent_post->ID, 'is_wp_suggestion', true );763 764 753 $template = new WP_Block_Template(); 765 754 $template->wp_id = $post->ID; 766 $template->id = $theme . '//' . $p arent_post->post_name;755 $template->id = $theme . '//' . $post->post_name; 767 756 $template->theme = $theme; 768 757 $template->content = $post->post_content; 769 758 $template->slug = $post->post_name; 770 759 $template->source = 'custom'; 771 $template->origin = ! empty( $ origin ) ? $origin: null;760 $template->origin = ! empty( $meta['origin'] ) ? $meta['origin'] : null; 772 761 $template->type = $post->post_type; 773 762 $template->description = $post->post_excerpt; … … 775 764 $template->status = $post->post_status; 776 765 $template->has_theme_file = $has_theme_file; 777 $template->is_custom = empty( $ is_wp_suggestion);766 $template->is_custom = empty( $meta['is_wp_suggestion'] ); 778 767 $template->author = $post->post_author; 779 768 $template->modified = $post->post_modified; 780 769 781 if ( 'wp_template' === $p arent_post->post_type && $has_theme_file && isset( $template_file['postTypes'] ) ) {770 if ( 'wp_template' === $post->post_type && $has_theme_file && isset( $template_file['postTypes'] ) ) { 782 771 $template->post_types = $template_file['postTypes']; 783 772 } 784 773 785 if ( 'wp_template' === $p arent_post->post_type && isset( $default_template_types[ $template->slug ] ) ) {774 if ( 'wp_template' === $post->post_type && isset( $default_template_types[ $template->slug ] ) ) { 786 775 $template->is_custom = false; 787 776 } 777 778 if ( 'wp_template_part' === $post->post_type && isset( $terms['wp_template_part_area'] ) ) { 779 $template->area = $terms['wp_template_part_area']; 780 } 781 782 return $template; 783 } 784 785 /** 786 * Builds a unified template object based a post Object. 787 * 788 * @since 5.9.0 789 * @since 6.3.0 Added `modified` property to template objects. 790 * @since 6.4.0 Added support for a revision post to be passed to this function. 791 * @access private 792 * 793 * @param WP_Post $post Template post. 794 * @return WP_Block_Template|WP_Error Template or error object. 795 */ 796 function _build_block_template_result_from_post( $post ) { 797 $post_id = wp_is_post_revision( $post ); 798 if ( ! $post_id ) { 799 $post_id = $post; 800 } 801 $parent_post = get_post( $post_id ); 802 $post->post_name = $parent_post->post_name; 803 $post->post_type = $parent_post->post_type; 804 805 $terms = get_the_terms( $parent_post, 'wp_theme' ); 806 807 if ( is_wp_error( $terms ) ) { 808 return $terms; 809 } 810 811 if ( ! $terms ) { 812 return new WP_Error( 'template_missing_theme', __( 'No theme is defined for this template.' ) ); 813 } 814 815 $terms = array( 816 'wp_theme' => $terms[0]->name, 817 ); 788 818 789 819 if ( 'wp_template_part' === $parent_post->post_type ) { 790 820 $type_terms = get_the_terms( $parent_post, 'wp_template_part_area' ); 791 821 if ( ! is_wp_error( $type_terms ) && false !== $type_terms ) { 792 $template->area = $type_terms[0]->name; 793 } 822 $terms['wp_template_part_area'] = $type_terms[0]->name; 823 } 824 } 825 826 $meta = array( 827 'origin' => get_post_meta( $parent_post->ID, 'origin', true ), 828 'is_wp_suggestion' => get_post_meta( $parent_post->ID, 'is_wp_suggestion', true ), 829 ); 830 831 $template = _build_block_template_object_from_post_object( $post, $terms, $meta ); 832 833 if ( is_wp_error( $template ) ) { 834 return $template; 794 835 } 795 836 … … 1445 1486 * @access private 1446 1487 * 1447 * @param stdClass $post An object representing a template or template part 1448 * prepared for inserting or updating the database. 1449 * @param WP_REST_Request $request Request object. 1450 * @return stdClass The updated object representing a template or template part. 1451 */ 1452 function inject_ignored_hooked_blocks_metadata_attributes( $post, $request ) { 1453 $filter_name = current_filter(); 1454 if ( ! str_starts_with( $filter_name, 'rest_pre_insert_' ) ) { 1455 return $post; 1456 } 1457 $post_type = str_replace( 'rest_pre_insert_', '', $filter_name ); 1488 * @param stdClass $changes An object representing a template or template part 1489 * prepared for inserting or updating the database. 1490 * @param WP_REST_Request $deprecated Deprecated. Not used. 1491 * @return stdClass|WP_Error The updated object representing a template or template part. 1492 */ 1493 function inject_ignored_hooked_blocks_metadata_attributes( $changes, $deprecated = null ) { 1494 if ( null !== $deprecated ) { 1495 _deprecated_argument( __FUNCTION__, '6.5.1' ); 1496 } 1458 1497 1459 1498 $hooked_blocks = get_hooked_blocks(); 1460 1499 if ( empty( $hooked_blocks ) && ! has_filter( 'hooked_block_types' ) ) { 1461 return $post; 1462 } 1463 1464 // At this point, the post has already been created. 1465 // We need to build the corresponding `WP_Block_Template` object as context argument for the visitor. 1466 // To that end, we need to suppress hooked blocks from getting inserted into the template. 1467 add_filter( 'hooked_block_types', '__return_empty_array', 99999, 0 ); 1468 $template = $request['id'] ? get_block_template( $request['id'], $post_type ) : null; 1469 remove_filter( 'hooked_block_types', '__return_empty_array', 99999 ); 1500 return $changes; 1501 } 1502 1503 $meta = isset( $changes->meta_input ) ? $changes->meta_input : array(); 1504 $terms = isset( $changes->tax_input ) ? $changes->tax_input : array(); 1505 1506 if ( empty( $changes->ID ) ) { 1507 // There's no post object for this template in the database for this template yet. 1508 $post = $changes; 1509 } else { 1510 // Find the existing post object. 1511 $post = get_post( $changes->ID ); 1512 1513 // If the post is a revision, use the parent post's post_name and post_type. 1514 $post_id = wp_is_post_revision( $post ); 1515 if ( $post_id ) { 1516 $parent_post = get_post( $post_id ); 1517 $post->post_name = $parent_post->post_name; 1518 $post->post_type = $parent_post->post_type; 1519 } 1520 1521 // Apply the changes to the existing post object. 1522 $post = (object) array_merge( (array) $post, (array) $changes ); 1523 1524 $type_terms = get_the_terms( $changes->ID, 'wp_theme' ); 1525 $terms['wp_theme'] = ! is_wp_error( $type_terms ) && ! empty( $type_terms ) ? $type_terms[0]->name : null; 1526 } 1527 1528 // Required for the WP_Block_Template. Update the post object with the current time. 1529 $post->post_modified = current_time( 'mysql' ); 1530 1531 // If the post_author is empty, set it to the current user. 1532 if ( empty( $post->post_author ) ) { 1533 $post->post_author = get_current_user_id(); 1534 } 1535 1536 if ( 'wp_template_part' === $post->post_type && ! isset( $terms['wp_template_part_area'] ) ) { 1537 $area_terms = get_the_terms( $changes->ID, 'wp_template_part_area' ); 1538 $terms['wp_template_part_area'] = ! is_wp_error( $area_terms ) && ! empty( $area_terms ) ? $area_terms[0]->name : null; 1539 } 1540 1541 $template = _build_block_template_object_from_post_object( new WP_Post( $post ), $terms, $meta ); 1542 1543 if ( is_wp_error( $template ) ) { 1544 return $template; 1545 } 1470 1546 1471 1547 $before_block_visitor = make_before_block_visitor( $hooked_blocks, $template, 'set_ignored_hooked_blocks_metadata' ); 1472 1548 $after_block_visitor = make_after_block_visitor( $hooked_blocks, $template, 'set_ignored_hooked_blocks_metadata' ); 1473 1549 1474 $blocks = parse_blocks( $post->post_content ); 1475 $content = traverse_and_serialize_blocks( $blocks, $before_block_visitor, $after_block_visitor ); 1476 1477 $post->post_content = $content; 1478 return $post; 1479 } 1550 $blocks = parse_blocks( $changes->post_content ); 1551 $changes->post_content = traverse_and_serialize_blocks( $blocks, $before_block_visitor, $after_block_visitor ); 1552 1553 return $changes; 1554 } -
trunk/src/wp-includes/default-filters.php
r57790 r57919 754 754 755 755 // Add ignoredHookedBlocks metadata attribute to the template and template part post types. 756 add_filter( 'rest_pre_insert_wp_template', 'inject_ignored_hooked_blocks_metadata_attributes' , 10, 2);757 add_filter( 'rest_pre_insert_wp_template_part', 'inject_ignored_hooked_blocks_metadata_attributes' , 10, 2);756 add_filter( 'rest_pre_insert_wp_template', 'inject_ignored_hooked_blocks_metadata_attributes' ); 757 add_filter( 'rest_pre_insert_wp_template_part', 'inject_ignored_hooked_blocks_metadata_attributes' ); 758 758 759 759 unset( $filter, $action ); -
trunk/src/wp-includes/rest-api/endpoints/class-wp-rest-templates-controller.php
r57790 r57919 533 533 * 534 534 * @param WP_REST_Request $request Request object. 535 * @return stdClass Changes to pass to wp_update_post.535 * @return stdClass|WP_Error Changes to pass to wp_update_post. 536 536 */ 537 537 protected function prepare_item_for_database( $request ) { -
trunk/tests/phpunit/tests/block-template-utils.php
r57799 r57919 404 404 $this->assertTrue( $has_html_files, 'contains at least one html file' ); 405 405 } 406 407 /**408 * @ticket 60671409 *410 * @covers inject_ignored_hooked_blocks_metadata_attributes411 */412 public function test_inject_ignored_hooked_blocks_metadata_attributes_into_template() {413 global $wp_current_filter;414 // Mock currently set filter. The $wp_current_filter global is reset during teardown by415 // WP_UnitTestCase_Base::_restore_hooks() in tests/phpunit/includes/abstract-testcase.php.416 $wp_current_filter[] = 'rest_pre_insert_wp_template';417 418 register_block_type(419 'tests/hooked-block',420 array(421 'block_hooks' => array(422 'tests/anchor-block' => 'after',423 ),424 )425 );426 427 $id = self::TEST_THEME . '//' . 'my_template';428 $request = new WP_REST_Request( 'POST', '/wp/v2/templates/' . $id );429 430 $changes = new stdClass();431 $changes->post_content = '<!-- wp:tests/anchor-block -->Hello<!-- /wp:tests/anchor-block -->';432 433 $post = inject_ignored_hooked_blocks_metadata_attributes( $changes, $request );434 $this->assertSame(435 '<!-- wp:tests/anchor-block {"metadata":{"ignoredHookedBlocks":["tests/hooked-block"]}} -->Hello<!-- /wp:tests/anchor-block -->',436 $post->post_content,437 'The hooked block was not injected into the anchor block\'s ignoredHookedBlocks metadata.'438 );439 }440 441 /**442 * @ticket 60671443 *444 * @covers inject_ignored_hooked_blocks_metadata_attributes445 */446 public function test_inject_ignored_hooked_blocks_metadata_attributes_into_template_part() {447 global $wp_current_filter;448 // Mock currently set filter. The $wp_current_filter global is reset during teardown by449 // WP_UnitTestCase_Base::_restore_hooks() in tests/phpunit/includes/abstract-testcase.php.450 $wp_current_filter[] = 'rest_pre_insert_wp_template_part';451 452 register_block_type(453 'tests/hooked-block',454 array(455 'block_hooks' => array(456 'tests/anchor-block' => 'after',457 ),458 )459 );460 461 $id = self::TEST_THEME . '//' . 'my_template_part';462 $request = new WP_REST_Request( 'POST', '/wp/v2/template-parts/' . $id );463 464 $changes = new stdClass();465 $changes->post_content = '<!-- wp:tests/anchor-block -->Hello<!-- /wp:tests/anchor-block -->';466 467 $post = inject_ignored_hooked_blocks_metadata_attributes( $changes, $request );468 $this->assertSame(469 '<!-- wp:tests/anchor-block {"metadata":{"ignoredHookedBlocks":["tests/hooked-block"]}} -->Hello<!-- /wp:tests/anchor-block -->',470 $post->post_content,471 'The hooked block was not injected into the anchor block\'s ignoredHookedBlocks metadata.'472 );473 }474 406 } -
trunk/tests/phpunit/tests/rest-api/wpRestTemplatesController.php
r57790 r57919 15 15 */ 16 16 protected static $admin_id; 17 private static $post; 17 private static $template_post; 18 private static $template_part_post; 18 19 19 20 /** … … 30 31 31 32 // Set up template post. 32 $args = array(33 $args = array( 33 34 'post_type' => 'wp_template', 34 35 'post_name' => 'my_template', … … 42 43 ), 43 44 ); 44 self::$post = self::factory()->post->create_and_get( $args ); 45 wp_set_post_terms( self::$post->ID, get_stylesheet(), 'wp_theme' ); 45 self::$template_post = self::factory()->post->create_and_get( $args ); 46 wp_set_post_terms( self::$template_post->ID, get_stylesheet(), 'wp_theme' ); 47 48 // Set up template part post. 49 $args = array( 50 'post_type' => 'wp_template_part', 51 'post_name' => 'my_template_part', 52 'post_title' => 'My Template Part', 53 'post_content' => 'Content', 54 'post_excerpt' => 'Description of my template part.', 55 'tax_input' => array( 56 'wp_theme' => array( 57 get_stylesheet(), 58 ), 59 'wp_template_part_area' => array( 60 WP_TEMPLATE_PART_AREA_HEADER, 61 ), 62 ), 63 ); 64 self::$template_part_post = self::factory()->post->create_and_get( $args ); 65 wp_set_post_terms( self::$template_part_post->ID, get_stylesheet(), 'wp_theme' ); 66 wp_set_post_terms( self::$template_part_post->ID, WP_TEMPLATE_PART_AREA_HEADER, 'wp_template_part_area' ); 46 67 } 47 68 48 69 public static function wpTearDownAfterClass() { 49 wp_delete_post( self::$ post->ID );70 wp_delete_post( self::$template_post->ID ); 50 71 } 51 72 … … 57 78 public function tear_down() { 58 79 if ( has_filter( 'rest_pre_insert_wp_template_part', 'inject_ignored_hooked_blocks_metadata_attributes' ) ) { 59 remove_filter( 'rest_pre_insert_wp_template_part', 'inject_ignored_hooked_blocks_metadata_attributes' , 10);80 remove_filter( 'rest_pre_insert_wp_template_part', 'inject_ignored_hooked_blocks_metadata_attributes' ); 60 81 } 61 82 if ( WP_Block_Type_Registry::get_instance()->is_registered( 'tests/block' ) ) { … … 131 152 ), 132 153 'status' => 'publish', 133 'wp_id' => self::$ post->ID,154 'wp_id' => self::$template_post->ID, 134 155 'has_theme_file' => false, 135 156 'is_custom' => true, 136 157 'author' => 0, 137 'modified' => mysql_to_rfc3339( self::$ post->post_modified ),158 'modified' => mysql_to_rfc3339( self::$template_post->post_modified ), 138 159 'author_text' => 'Test Blog', 139 160 'original_source' => 'site', … … 178 199 ), 179 200 'status' => 'publish', 180 'wp_id' => self::$ post->ID,201 'wp_id' => self::$template_post->ID, 181 202 'has_theme_file' => false, 182 203 'is_custom' => true, 183 204 'author' => 0, 184 'modified' => mysql_to_rfc3339( self::$ post->post_modified ),205 'modified' => mysql_to_rfc3339( self::$template_post->post_modified ), 185 206 'author_text' => 'Test Blog', 186 207 'original_source' => 'site', … … 217 238 ), 218 239 'status' => 'publish', 219 'wp_id' => self::$ post->ID,240 'wp_id' => self::$template_post->ID, 220 241 'has_theme_file' => false, 221 242 'is_custom' => true, 222 243 'author' => 0, 223 'modified' => mysql_to_rfc3339( self::$ post->post_modified ),244 'modified' => mysql_to_rfc3339( self::$template_post->post_modified ), 224 245 'author_text' => 'Test Blog', 225 246 'original_source' => 'site', … … 945 966 ); 946 967 947 add_filter( 'rest_pre_insert_wp_template_part', 'inject_ignored_hooked_blocks_metadata_attributes' , 10, 2);968 add_filter( 'rest_pre_insert_wp_template_part', 'inject_ignored_hooked_blocks_metadata_attributes' ); 948 969 949 970 $endpoint = new WP_REST_Templates_Controller( 'wp_template_part' ); … … 952 973 $prepare_item_for_database->setAccessible( true ); 953 974 975 $id = get_stylesheet() . '//' . 'my_template_part'; 954 976 $body_params = array( 955 ' title' => 'Untitled Template Part',956 'slug' => ' untitled-template-part',977 'id' => $id, 978 'slug' => 'my_template_part', 957 979 'content' => '<!-- wp:tests/anchor-block -->Hello<!-- /wp:tests/anchor-block -->', 958 980 );
Note: See TracChangeset
for help on using the changeset viewer.