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

Improve caching and logic in get_user_data_from_wp_global_styles. #2414

Closed
wants to merge 15 commits into from
47 changes: 26 additions & 21 deletions src/wp-includes/class-wp-theme-json-resolver.php
Original file line number Diff line number Diff line change
Expand Up @@ -304,54 +304,59 @@ public static function get_user_data_from_wp_global_styles( $theme, $create_post
}
$user_cpt = array();
$post_type_filter = 'wp_global_styles';
$stylesheet = $theme->get_stylesheet();
$args = array(
'numberposts' => 1,
draganescu marked this conversation as resolved.
Show resolved Hide resolved
'orderby' => 'date',
'order' => 'desc',
'post_type' => $post_type_filter,
'post_status' => $post_status_filter,
'tax_query' => array(
'posts_per_page' => 1,
'orderby' => 'post_date',
'order' => 'desc',
'post_type' => $post_type_filter,
'post_status' => $post_status_filter,
'ignore_sticky_posts' => true,
'no_found_rows' => true,
'tax_query' => array(
array(
'taxonomy' => 'wp_theme',
'field' => 'name',
'terms' => $theme->get_stylesheet(),
'terms' => $stylesheet,
),
),
);

$cache_key = sprintf( 'wp_global_styles_%s', md5( serialize( $args ) ) );
$post_id = wp_cache_get( $cache_key );

if ( (int) $post_id > 0 ) {
return get_post( $post_id, ARRAY_A );
}

$post_id = (int) get_transient( $cache_key );
spacedmonkey marked this conversation as resolved.
Show resolved Hide resolved
// Special case: '-1' is a results not found.
if ( -1 === $post_id && ! $create_post ) {
return $user_cpt;
}

$recent_posts = wp_get_recent_posts( $args );
if ( is_array( $recent_posts ) && ( count( $recent_posts ) === 1 ) ) {
$user_cpt = $recent_posts[0];
if ( $post_id > 0 && in_array( get_post_status( $post_id ), (array) $post_status_filter, true ) ) {
spacedmonkey marked this conversation as resolved.
Show resolved Hide resolved
return get_post( $post_id, ARRAY_A );
}

$global_style_query = new WP_Query();
$recent_posts = $global_style_query->query( $args );
if ( count( $recent_posts ) === 1 ) {
$user_cpt = get_post( $recent_posts[0], ARRAY_A );
} elseif ( $create_post ) {
$cpt_post_id = wp_insert_post(
array(
'post_content' => '{"version": ' . WP_Theme_JSON::LATEST_SCHEMA . ', "isGlobalStylesUserThemeJSON": true }',
'post_status' => 'publish',
'post_title' => 'Custom Styles',
'post_title' => __( 'Custom Styles' ),
'post_type' => $post_type_filter,
'post_name' => 'wp-global-styles-' . urlencode( wp_get_theme()->get_stylesheet() ),
'post_name' => sprintf( 'wp-global-styles-%s', urlencode( $stylesheet ) ),
'tax_input' => array(
'wp_theme' => array( wp_get_theme()->get_stylesheet() ),
'wp_theme' => array( $stylesheet ),
),
),
true
);
$user_cpt = get_post( $cpt_post_id, ARRAY_A );
if ( ! is_wp_error( $cpt_post_id ) ) {
$user_cpt = get_post( $cpt_post_id, ARRAY_A );
}
}
$cache_expiration = $user_cpt ? DAY_IN_SECONDS : HOUR_IN_SECONDS;
wp_cache_set( $cache_key, $user_cpt ? $user_cpt['ID'] : -1, '', $cache_expiration );
set_transient( $cache_key, $user_cpt ? $user_cpt['ID'] : -1, $cache_expiration );

return $user_cpt;
}
Expand Down
64 changes: 58 additions & 6 deletions tests/phpunit/tests/theme/wpThemeJsonResolver.php
Original file line number Diff line number Diff line change
Expand Up @@ -348,29 +348,81 @@ function test_merges_child_theme_json_into_parent_theme_json() {
);
}

/**
* @covers WP_Theme_JSON_Resolver::get_user_data_from_wp_global_styles
*/
function test_get_user_data_from_wp_global_styles_does_not_use_uncached_queries() {
$theme = wp_get_theme();
WP_Theme_JSON_Resolver::get_user_data_from_wp_global_styles( $theme );
add_filter( 'query', array( $this, 'filter_db_query' ) );
$query_count = count( $this->queries );
for ( $i = 0; $i < 3; $i++ ) {
WP_Theme_JSON_Resolver::get_user_data_from_wp_global_styles( wp_get_theme() );
WP_Theme_JSON_Resolver::get_user_data_from_wp_global_styles( $theme );
WP_Theme_JSON_Resolver::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::get_global_styles_from_post()' );
$this->assertEquals( 0, $query_count, 'Unexpected SQL queries detected for the wp_global_style post type' );

$user_cpt = WP_Theme_JSON_Resolver::get_user_data_from_wp_global_styles( wp_get_theme() );
$user_cpt = WP_Theme_JSON_Resolver::get_user_data_from_wp_global_styles( $theme );
$this->assertEmpty( $user_cpt );

$user_cpt = WP_Theme_JSON_Resolver::get_user_data_from_wp_global_styles( wp_get_theme(), true );
$user_cpt = WP_Theme_JSON_Resolver::get_user_data_from_wp_global_styles( $theme, true );
$this->assertNotEmpty( $user_cpt );

$query_count = count( $this->queries );
for ( $i = 0; $i < 3; $i++ ) {
WP_Theme_JSON_Resolver::get_user_data_from_wp_global_styles( wp_get_theme() );
for ( $i = 0; $i < 3; $i ++ ) {
spacedmonkey marked this conversation as resolved.
Show resolved Hide resolved
$new_user_cpt = WP_Theme_JSON_Resolver::get_user_data_from_wp_global_styles( $theme );
WP_Theme_JSON_Resolver::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' ) );
}

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

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

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