Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
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
77 changes: 77 additions & 0 deletions lib/compat/wordpress-6.1/class-wp-theme-json-resolver-6-1.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,83 @@
* @access private
*/
class WP_Theme_JSON_Resolver_6_1 extends WP_Theme_JSON_Resolver_6_0 {
/**
* Returns the custom post type that contains the user's origin config
* for the current theme or a void array if none are found.
*
* This can also create and return a new draft custom post type.
*
* @param WP_Theme $theme The theme object. If empty, it
* defaults to the current theme.
* @param bool $create_post Optional. Whether a new custom post
* type should be created if none are
* found. False by default.
* @param array $post_status_filter Filter Optional. custom post type by
* post status. ['publish'] by default,
* so it only fetches published posts.
* @return array Custom Post Type for the user's origin config.
*/
public static function get_user_data_from_wp_global_styles( $theme, $create_post = false, $post_status_filter = array( 'publish' ) ) {
if ( ! $theme instanceof WP_Theme ) {
$theme = wp_get_theme();
}
$user_cpt = array();
$post_type_filter = 'wp_global_styles';
$args = array(
'posts_per_page' => 1,
'orderby' => 'post_date',
'order' => 'desc',
'post_type' => $post_type_filter,
'post_status' => $post_status_filter,
'tax_query' => array(
array(
'taxonomy' => 'wp_theme',
'field' => 'name',
'terms' => $theme->get_stylesheet(),
),
),
'ignore_sticky_posts' => true,
'no_found_rows' => true,
);

$cache_key = sprintf( 'wp_global_styles_%s', md5( serialize( $args ) ) );
$post_id = (int) get_transient( $cache_key );
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use transient is better for performance here. Most sites do not run object caches. Transinets save to options table and will have 3 database queries per page load.

// Special case: '-1' is a results not found.
if ( -1 === $post_id && ! $create_post ) {
return $user_cpt;
}

if ( $post_id > 0 && in_array( get_post_status( $post_id ), (array) $post_status_filter, true ) ) {
return get_post( $post_id, ARRAY_A );
}
Comment on lines +65 to +67
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Improve handling of post status changed. If this post is deleted or changed to draft.


$gs_query = new WP_Query();
$recent_posts = $gs_query->query( $args );
if ( count( $recent_posts ) === 1 ) {
$user_cpt = get_post( $recent_posts[0], ARRAY_A );
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This fixes an issue, where a WP_Post object is returned.

} elseif ( $create_post ) {
$cpt_post_id = wp_insert_post(
array(
'post_content' => '{"version": ' . WP_Theme_JSON_Gutenberg::LATEST_SCHEMA . ', "isGlobalStylesUserThemeJSON": true }',
'post_status' => 'publish',
'post_title' => __( 'Custom Styles', 'default' ),
'post_type' => $post_type_filter,
'post_name' => 'wp-global-styles-' . urlencode( wp_get_theme()->get_stylesheet() ),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

'tax_input' => array(
'wp_theme' => array( wp_get_theme()->get_stylesheet() ),
),
),
true
);
if ( ! is_wp_error( $cpt_post_id ) ) {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This check should always have been here. WP_Insert_post can sometimes return a WP_Error.

Copy link
Contributor

@draganescu draganescu Jul 5, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What happens if is_wp_error is true? It seems it remains empty array and we count on array with length zero to be evaluated to false. Could we make this clear in code?

$user_cpt = get_post( $cpt_post_id, ARRAY_A );
}
}
$cache_expiration = $user_cpt ? DAY_IN_SECONDS : HOUR_IN_SECONDS;
set_transient( $cache_key, $user_cpt ? $user_cpt['ID'] : -1, $cache_expiration );

return $user_cpt;
}

/**
* Container for data coming from core.
Expand Down
51 changes: 49 additions & 2 deletions phpunit/class-wp-theme-json-resolver-test.php
Original file line number Diff line number Diff line change
Expand Up @@ -268,6 +268,9 @@ function test_merges_child_theme_json_into_parent_theme_json() {
);
}

/**
* @covers WP_Theme_JSON_Resolver_Gutenberg::get_user_data_from_wp_global_styles
*/
function test_get_user_data_from_wp_global_styles_does_not_use_uncached_queries() {
add_filter( 'query', array( $this, 'filter_db_query' ) );
$query_count = count( $this->queries );
Expand All @@ -276,7 +279,7 @@ function test_get_user_data_from_wp_global_styles_does_not_use_uncached_queries(
WP_Theme_JSON_Resolver_Gutenberg::clean_cached_data();
}
$query_count = count( $this->queries ) - $query_count;
$this->assertEquals( 1, $query_count, 'Only one SQL query should be peformed for multiple invocations of WP_Theme_JSON_Resolver_Gutenberg::get_user_data_from_wp_global_styles()' );
$this->assertEquals( 0, $query_count, 'Unexpected SQL queries detected for the wp_global_style post type' );

$user_cpt = WP_Theme_JSON_Resolver_Gutenberg::get_user_data_from_wp_global_styles( wp_get_theme() );
$this->assertEmpty( $user_cpt );
Expand All @@ -286,11 +289,55 @@ function test_get_user_data_from_wp_global_styles_does_not_use_uncached_queries(

$query_count = count( $this->queries );
for ( $i = 0; $i < 3; $i++ ) {
WP_Theme_JSON_Resolver_Gutenberg::get_user_data_from_wp_global_styles( wp_get_theme() );
$new_user_cpt = WP_Theme_JSON_Resolver_Gutenberg::get_user_data_from_wp_global_styles( wp_get_theme() );
WP_Theme_JSON_Resolver_Gutenberg::clean_cached_data();
$this->assertSameSets( $user_cpt, $new_user_cpt );
}
$query_count = count( $this->queries ) - $query_count;
$this->assertEquals( 0, $query_count, 'Unexpected SQL queries detected for the wp_global_style post type' );
remove_filter( 'query', array( $this, 'filter_db_query' ) );
}

/**
* @covers WP_Theme_JSON_Resolver_Gutenberg::get_user_data_from_wp_global_styles
* @ticket 55392
*/
function test_get_user_data_from_wp_global_styles_does_exist() {
$post1 = WP_Theme_JSON_Resolver_Gutenberg::get_user_data_from_wp_global_styles( wp_get_theme(), true );
$this->assertIsArray( $post1 );
$this->assertArrayHasKey( 'ID', $post1 );
wp_delete_post( $post1['ID'], true );
$post2 = WP_Theme_JSON_Resolver_Gutenberg::get_user_data_from_wp_global_styles( wp_get_theme(), true );
$this->assertIsArray( $post2 );
$this->assertArrayHasKey( 'ID', $post2 );
}

/**
* @covers WP_Theme_JSON_Resolver_Gutenberg::get_user_data_from_wp_global_styles
* @ticket 55392
*/
function test_get_user_data_from_wp_global_styles_create_post() {
$post1 = WP_Theme_JSON_Resolver_Gutenberg::get_user_data_from_wp_global_styles( wp_get_theme( 'testing' ) );
$this->assertIsArray( $post1 );
$this->assertSameSets( array(), $post1 );
$post2 = WP_Theme_JSON_Resolver_Gutenberg::get_user_data_from_wp_global_styles( wp_get_theme( 'testing' ) );
$this->assertIsArray( $post2 );
$this->assertSameSets( array(), $post2 );
$post3 = WP_Theme_JSON_Resolver_Gutenberg::get_user_data_from_wp_global_styles( wp_get_theme( 'testing' ), true );
$this->assertIsArray( $post3 );
$this->assertArrayHasKey( 'ID', $post3 );
}

/**
* @covers WP_Theme_JSON_Resolver_Gutenberg::get_user_data_from_wp_global_styles
* @ticket 55392
*/
function test_get_user_data_from_wp_global_styles_filter_state() {
$post1 = WP_Theme_JSON_Resolver_Gutenberg::get_user_data_from_wp_global_styles( wp_get_theme( 'foo' ), true, array( 'publish' ) );
$this->assertIsArray( $post1 );
$this->assertArrayHasKey( 'ID', $post1 );
$post2 = WP_Theme_JSON_Resolver_Gutenberg::get_user_data_from_wp_global_styles( wp_get_theme( 'foo' ), false, array( 'draft' ) );
$this->assertIsArray( $post2 );
$this->assertSameSets( array(), $post2 );
}
}