diff --git a/inc/Engine/Cache/PostSubscriber.php b/inc/Engine/Cache/PostSubscriber.php new file mode 100644 index 0000000000..9f4dbb2f01 --- /dev/null +++ b/inc/Engine/Cache/PostSubscriber.php @@ -0,0 +1,74 @@ + 'disable_cache_on_not_valid_pages', + 'rocket_buffer' => [ 'stop_optimizations_for_not_valid_pages', 1 ], + ]; + } + + /** + * Disable caching invalid page urls. + * + * @param bool $can_cache Filter callback passed value. + * @return bool + */ + public function disable_cache_on_not_valid_pages( $can_cache ) { + if ( $this->is_not_valid_page() ) { + return false; + } + + return $can_cache; + } + + /** + * Stop optimizing those invalid 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_pages( $html ) { + return $this->is_not_valid_page() ? '' : $html; + } + + /** + * Check if we are on the post frontend page, but it's not valid url query. + * + * @return bool (True when not valid post url, False if it's a valid one) + */ + private function is_not_valid_page() { + if ( ! is_singular() ) { + return false; + } + + $post_id = get_queried_object_id(); + if ( empty( $post_id ) ) { + return false; + } + + global $wp; + + $post_link = get_permalink( $post_id ); + if ( ! $post_link ) { + return false; + } + + $current_link = home_url( add_query_arg( [], $wp->request ?? '' ) ); + if ( is_paged() ) { + $post_link = trailingslashit( $post_link ) . 'page/' . get_query_var( 'paged' ); + } + + return urldecode( untrailingslashit( $post_link ) ) !== urldecode( untrailingslashit( $current_link ) ); + } +} diff --git a/inc/Engine/Cache/ServiceProvider.php b/inc/Engine/Cache/ServiceProvider.php index eb34187aaf..2025722caf 100644 --- a/inc/Engine/Cache/ServiceProvider.php +++ b/inc/Engine/Cache/ServiceProvider.php @@ -28,6 +28,7 @@ class ServiceProvider extends AbstractServiceProvider { 'preload_caches_query', 'cache_config', 'taxonomy_subscriber', + 'post_subscriber', ]; /** @@ -77,5 +78,6 @@ public function register(): void { ->addArgument( $this->getContainer()->get( 'options' ) ) ->addArgument( $this->getContainer()->get( 'options_api' ) ); $this->getContainer()->addShared( 'taxonomy_subscriber', TaxonomySubscriber::class ); + $this->getContainer()->addShared( 'post_subscriber', PostSubscriber::class ); } } diff --git a/inc/Engine/Common/PerformanceHints/Frontend/Subscriber.php b/inc/Engine/Common/PerformanceHints/Frontend/Subscriber.php index d23230c97c..2dee747b3a 100644 --- a/inc/Engine/Common/PerformanceHints/Frontend/Subscriber.php +++ b/inc/Engine/Common/PerformanceHints/Frontend/Subscriber.php @@ -54,6 +54,10 @@ public static function get_subscribed_events(): array { * @return string */ public function maybe_apply_optimizations( $html ): string { + if ( empty( $html ) ) { + return $html; + } + if ( ! isset( $_GET['wpr_imagedimensions'] ) && isset( $_GET['wpr_lazyrendercontent'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended return $html; } diff --git a/inc/Plugin.php b/inc/Plugin.php index 1300cbc134..8fca97800b 100644 --- a/inc/Plugin.php +++ b/inc/Plugin.php @@ -408,6 +408,7 @@ private function init_common_subscribers() { 'media_fonts_frontend_subscriber', 'media_fonts_admin_subscriber', 'media_fonts_clean_subscriber', + 'post_subscriber', ]; $host_type = HostResolver::get_host_service(); diff --git a/tests/Fixtures/inc/Engine/Cache/PostSubscriber/disableCacheOnNotValidPages.php b/tests/Fixtures/inc/Engine/Cache/PostSubscriber/disableCacheOnNotValidPages.php new file mode 100644 index 0000000000..3bc59992af --- /dev/null +++ b/tests/Fixtures/inc/Engine/Cache/PostSubscriber/disableCacheOnNotValidPages.php @@ -0,0 +1,68 @@ + [ + 'testIsNotInPostPage' => [ + 'config' => [ + 'is_singular' => false, + ], + 'can_cache' => true, + ], + 'testValidPostPage' => [ + 'config' => [ + 'is_singular' => true, + 'current_post_id' => 1, + 'current_post_link' => 'http://example.com/test1', + 'current_page_url' => 'http://example.com/test1', + ], + 'can_cache' => true, + ], + 'testValidPostPageWithPagination' => [ + 'config' => [ + 'is_singular' => true, + 'current_post_id' => 1, + 'current_post_link' => 'http://example.com/test1', + 'current_page_url' => 'http://example.com/test1/page/2', + 'page' => 2, + ], + 'can_cache' => true, + ], + 'testEmptyPostId' => [ + 'config' => [ + 'is_singular' => true, + 'current_post_id' => 0, + 'current_post_link' => '', + 'current_post_url' => 'http://example.com/test1', + ], + 'can_cache' => true, + ], + 'testNotValidPostPage' => [ + 'config' => [ + 'is_singular' => true, + 'current_post_id' => 1, + 'current_post_link' => 'http://example.com/test1', + 'current_post_url' => 'http://example.com/additional-query/test1', + ], + 'can_cache' => false, + ], + 'testNotValidPostPageWithPagination' => [ + 'config' => [ + 'is_singular' => true, + 'current_post_id' => 1, + 'current_post_link' => 'http://example.com/test1', + 'current_page_url' => 'http://example.com/additional-query/test1/page/2', + 'page' => 2, + ], + 'can_cache' => false, + ], + 'testValidPostPageWithNonLatinCharactersInUrl' => [ + 'config' => [ + 'is_singular' => true, + 'current_post_id' => 1, + 'current_post_link' => 'http://example.com/%D0%BF%D1%80%D0%BE%D0%B4%D1%83%D0%BA%D1%82%D0%BE%D0%B2%D0%B0-%D0%BA%D0%B0%D1%82%D0%B5%D0%B3%D0%BE%D1%80%D0%B8%D1%8F/', + 'current_page_url' => 'http://example.com/продуктова-категория/', + ], + 'can_cache' => true, + ], + ], +]; diff --git a/tests/Unit/inc/Engine/Cache/PostSubscriber/disableCacheOnNotValidPages.php b/tests/Unit/inc/Engine/Cache/PostSubscriber/disableCacheOnNotValidPages.php new file mode 100644 index 0000000000..864d879bb9 --- /dev/null +++ b/tests/Unit/inc/Engine/Cache/PostSubscriber/disableCacheOnNotValidPages.php @@ -0,0 +1,42 @@ +subscriber = new PostSubscriber(); + } + + + /** + * @dataProvider configTestData + */ + public function testShouldReturnExpected( $config, $can_cache ) { + Functions\expect( 'is_singular' )->once()->andReturn( ! empty( $config['is_singular'] ) ); + Functions\when( 'get_queried_object_id' )->justReturn( $config['current_post_id'] ?? 0 ); + + Functions\when( 'get_permalink' )->justReturn( $config['current_post_link'] ?? '' ); + Functions\when( 'add_query_arg' )->justReturn( '' ); + Functions\when( 'home_url' )->justReturn( $config['current_page_url'] ?? '' ); + Functions\when( 'is_paged' )->justReturn( ! empty( $config['page'] ) ); + Functions\when( 'get_query_var' )->justReturn( $config['page'] ?? 0 ); + + $this->assertSame( $can_cache, $this->subscriber->disable_cache_on_not_valid_pages( true ) ); + } +}