diff --git a/inc/Engine/Cache/ServiceProvider.php b/inc/Engine/Cache/ServiceProvider.php index 6a9a8f3cd0..eb34187aaf 100644 --- a/inc/Engine/Cache/ServiceProvider.php +++ b/inc/Engine/Cache/ServiceProvider.php @@ -27,6 +27,7 @@ class ServiceProvider extends AbstractServiceProvider { 'expired_cache_purge_subscriber', 'preload_caches_query', 'cache_config', + 'taxonomy_subscriber', ]; /** @@ -75,5 +76,6 @@ public function register(): void { $this->getContainer()->add( 'cache_config', ConfigSubscriber::class ) ->addArgument( $this->getContainer()->get( 'options' ) ) ->addArgument( $this->getContainer()->get( 'options_api' ) ); + $this->getContainer()->addShared( 'taxonomy_subscriber', TaxonomySubscriber::class ); } } diff --git a/inc/Engine/Cache/TaxonomySubscriber.php b/inc/Engine/Cache/TaxonomySubscriber.php new file mode 100644 index 0000000000..0289029947 --- /dev/null +++ b/inc/Engine/Cache/TaxonomySubscriber.php @@ -0,0 +1,71 @@ + 'disable_cache_on_not_valid_taxonomy_pages', + 'rocket_buffer' => [ 'stop_optimizations_for_not_valid_taxonomy_pages', 1 ], + ]; + } + + /** + * Disable caching invalid taxonomy frontend pages. + * + * @param bool $can_cache Filter callback passed value. + * @return bool + */ + public function disable_cache_on_not_valid_taxonomy_pages( $can_cache ) { + if ( $this->is_not_valid_taxonomy_page() ) { + return false; + } + + return $can_cache; + } + + /** + * Stop optimizing those invalid taxonomy pages by returning empty html string, + * So it fall back to the normal page's HTML. + * + * @param string $html Page's buffer HTML. + * @return string + */ + public function stop_optimizations_for_not_valid_taxonomy_pages( $html ) { + return $this->is_not_valid_taxonomy_page() ? '' : $html; + } + + /** + * Check if we are on the taxonomy frontend page, but it's not valid url query. + * + * @return bool (True when not valid taxonomy page, False if it's a valid one) + */ + private function is_not_valid_taxonomy_page() { + if ( ! is_category() && ! is_tag() && ! is_tax() ) { + return false; + } + + $term_id = get_queried_object_id(); + if ( empty( $term_id ) ) { + return false; + } + + global $wp; + + $term_link = get_term_link( $term_id ); + if ( is_wp_error( $term_link ) ) { + return false; + } + + $current_link = home_url( add_query_arg( [], $wp->request ?? '' ) ); + + return untrailingslashit( $term_link ) !== untrailingslashit( $current_link ); + } +} diff --git a/inc/Engine/Optimization/Buffer/Optimization.php b/inc/Engine/Optimization/Buffer/Optimization.php index 4eb9bf9144..356de45529 100755 --- a/inc/Engine/Optimization/Buffer/Optimization.php +++ b/inc/Engine/Optimization/Buffer/Optimization.php @@ -97,7 +97,13 @@ public function maybe_process_buffer( $buffer ) { * * @param string $buffer The page content. */ - $buffer = (string) apply_filters( 'rocket_buffer', $buffer ); + $filtered_buffer = (string) apply_filters( 'rocket_buffer', $buffer ); + + if ( empty( $filtered_buffer ) ) { + $this->log_last_test_error(); + $this->log( 'Empty buffer.', [], 'error' ); + return $buffer; + } $this->log( 'Page optimized.', [], 'info' ); @@ -108,7 +114,7 @@ public function maybe_process_buffer( $buffer ) { */ do_action( 'rocket_after_process_buffer' ); - return $buffer; + return $filtered_buffer; } /** diff --git a/inc/Plugin.php b/inc/Plugin.php index eccb82bf5f..c9733eec93 100644 --- a/inc/Plugin.php +++ b/inc/Plugin.php @@ -400,6 +400,7 @@ private function init_common_subscribers() { 'performance_hints_warmup_subscriber', 'performance_hints_admin_subscriber', 'lrc_frontend_subscriber', + 'taxonomy_subscriber', ]; $host_type = HostResolver::get_host_service(); diff --git a/tests/Fixtures/inc/Engine/Cache/TaxonomySubscriber/disableCacheOnNotValidTaxonomyPages.php b/tests/Fixtures/inc/Engine/Cache/TaxonomySubscriber/disableCacheOnNotValidTaxonomyPages.php new file mode 100644 index 0000000000..1330b420c6 --- /dev/null +++ b/tests/Fixtures/inc/Engine/Cache/TaxonomySubscriber/disableCacheOnNotValidTaxonomyPages.php @@ -0,0 +1,71 @@ + [ + 'testIsNotInCategoryPage' => [ + 'config' => [ + 'is_category' => false, + ], + 'can_cache' => true, + ], + 'testIsNotInTagPage' => [ + 'config' => [ + 'is_category' => false, + 'is_tag' => false, + ], + 'can_cache' => true, + ], + 'testIsNotInTaxPage' => [ + 'config' => [ + 'is_category' => false, + 'is_tag' => false, + 'is_tax' => false, + ], + 'can_cache' => true, + ], + 'testValidTaxonomyPage' => [ + 'config' => [ + 'is_category' => true, + 'is_tag' => false, + 'is_tax' => false, + 'current_term_id' => 1, + 'current_term_link' => 'http://example.com/category/test1', + 'current_page_url' => 'http://example.com/category/test1', + ], + 'can_cache' => true, + ], + 'testEmptyTermId' => [ + 'config' => [ + 'is_category' => true, + 'is_tag' => false, + 'is_tax' => false, + 'current_term_id' => 0, + 'current_term_link' => '', + 'current_page_url' => 'http://example.com/category/test1', + ], + 'can_cache' => true, + ], + 'testNotValidTermLink' => [ + 'config' => [ + 'is_category' => true, + 'is_tag' => false, + 'is_tax' => false, + 'current_term_id' => 0, + 'current_term_link' => new WP_Error(), + 'current_page_url' => 'http://example.com/category/test1', + ], + 'can_cache' => true, + ], + 'testNotValidTaxonomyPage' => [ + 'config' => [ + 'is_category' => true, + 'is_tag' => false, + 'is_tax' => false, + 'current_term_id' => 1, + 'current_term_link' => 'http://example.com/category/test1', + 'current_page_url' => 'http://example.com/category/additional-query/test1', + ], + 'can_cache' => false, + ], + ], +]; diff --git a/tests/Integration/ContentTrait.php b/tests/Integration/ContentTrait.php index f24618ed43..ff18874612 100644 --- a/tests/Integration/ContentTrait.php +++ b/tests/Integration/ContentTrait.php @@ -55,6 +55,9 @@ protected function setUpCategory( $args = [] ) { $category = $this->factory->category->create_and_get( $args ); $this->go_to( "/?cat={$category->term_id}" ); + global $wp; + $wp->request = "category/{$category->slug}"; + $this->assertTrue( is_category() ); return $category; @@ -71,6 +74,9 @@ protected function setUpTag( $args = [] ) { $tag = $this->factory->term->create_and_get( $args ); $this->go_to( "/?tag={$tag->slug}" ); + global $wp; + $wp->request = "tag/{$tag->slug}"; + $this->assertTrue( is_tag() ); return $tag; @@ -99,6 +105,9 @@ protected function setUpTax( $taxonomy = 'wptests_tax', $object_type = 'post', a $this->go_to( "/?{$taxonomy}={$term->slug}" ); + global $wp; + $wp->request = "{$taxonomy}/{$term->slug}"; + $this->assertTrue( is_tax() ); return [ diff --git a/tests/Unit/inc/Engine/Cache/TaxonomySubscriber/disableCacheOnNotValidTaxonomyPages.php b/tests/Unit/inc/Engine/Cache/TaxonomySubscriber/disableCacheOnNotValidTaxonomyPages.php new file mode 100644 index 0000000000..32c3f2b680 --- /dev/null +++ b/tests/Unit/inc/Engine/Cache/TaxonomySubscriber/disableCacheOnNotValidTaxonomyPages.php @@ -0,0 +1,41 @@ +subscriber = new TaxonomySubscriber(); + } + + + /** + * @dataProvider configTestData + */ + public function testShouldReturnExpected( $config, $can_cache ) { + Functions\expect( 'is_category' )->once()->andReturn( ! empty( $config['is_category'] ) ); + Functions\when( 'is_tag' )->justReturn( ! empty( $config['is_tag'] ) ); + Functions\when( 'is_tax' )->justReturn( ! empty( $config['is_tax'] ) ); + Functions\when( 'get_queried_object_id' )->justReturn( $config['current_term_id'] ?? 0 ); + + Functions\when( 'get_term_link' )->justReturn( $config['current_term_link'] ?? '' ); + Functions\when( 'add_query_arg' )->justReturn( '' ); + Functions\when( 'home_url' )->justReturn( $config['current_page_url'] ?? '' ); + + $this->assertSame( $can_cache, $this->subscriber->disable_cache_on_not_valid_taxonomy_pages( true ) ); + } +}