From 800877b2b02022fa2daf3ce087b0c0221af5c85c Mon Sep 17 00:00:00 2001 From: Tim Carr Date: Fri, 17 Jul 2026 10:31:31 +0800 Subject: [PATCH 1/3] Exclude Member Content Pages from Siteground Speed Optimizer --- includes/class-convertkit-cache-plugins.php | 30 +++++++++++++++++++ .../Integration/RestrictContentCacheTest.php | 20 +++++++++++++ 2 files changed, 50 insertions(+) diff --git a/includes/class-convertkit-cache-plugins.php b/includes/class-convertkit-cache-plugins.php index e777f560f..eb9294d09 100644 --- a/includes/class-convertkit-cache-plugins.php +++ b/includes/class-convertkit-cache-plugins.php @@ -80,6 +80,9 @@ public function __construct() { add_filter( 'convertkit_output_script_footer', array( $this, 'siteground_speed_optimizer_exclude_js_combine' ) ); add_filter( 'convertkit_resource_forms_output_script', array( $this, 'siteground_speed_optimizer_exclude_js_combine' ) ); + // Siteground Speed Optimizer: Set Member Content Pages in "Exclude URLs from Caching". + add_filter( 'sgo_exclude_urls_from_cache', array( $this, 'exclude_restrict_content_pages_from_caching' ) ); + // Rocket LazyLoad: Exclude images from lazy loading. add_filter( 'rocket_lazyload_excluded_src', array( $this, 'exclude_hosts' ) ); @@ -340,4 +343,31 @@ public function exclude_local_js_from_minification( $scripts ) { } + /** + * Exclude Restrict Content Pages from caching when the Siteground Speed Optimizer Plugin is installed, active + * and its "Exclude URLs from Caching" setting is enabled. + * + * @since 3.3.6 + * + * @param array $excluded_urls URLs to exclude from caching. + * @return array + */ + public function exclude_restrict_content_pages_from_caching( $excluded_urls ) { + + // Get the list of relative URLs for posts with restrict_content enabled + // from the Plugin's cache. + $restrict_content_cache = WP_ConvertKit()->get_class( 'restrict_content_cache' ); + if ( ! $restrict_content_cache ) { + return $excluded_urls; + } + + // Cache stores Restrict Content pages as id => relative url pairs. + // Siteground just needs to the relative URLs. + $restrict_content_urls = array_values( $restrict_content_cache->get() ); + + // Merge the list of relative URLs with the list of URLs already excluded from caching. + return array_merge( $excluded_urls, $restrict_content_urls ); + + } + } diff --git a/tests/Integration/RestrictContentCacheTest.php b/tests/Integration/RestrictContentCacheTest.php index 6581ec004..d52a11004 100644 --- a/tests/Integration/RestrictContentCacheTest.php +++ b/tests/Integration/RestrictContentCacheTest.php @@ -685,6 +685,26 @@ public function testCacheSurvivesPostMetaWithMalformedData() $this->assertArrayNotHasKey( $post_id, $cache ); } + /** + * Test that the SiteGround Speed Optimizer filter integration returns the + * restrict content post URLs. This proves the end-to-end integration: + * ConvertKit_Cache_Plugins::exclude_restrict_content_pages_from_caching() + * consumes the cache and merges the URLs into the excluded URLs list. + * + * @since 3.3.6 + */ + public function testSitegroundExcludeRestrictContentUrlsFilter() + { + $post_id = $this->createRestrictContentPost(); + + $excluded_urls = apply_filters( 'sgo_exclude_urls_from_cache', array() ); + + $this->assertContains( + wp_make_link_relative( get_permalink( $post_id ) ), + $excluded_urls + ); + } + /** * Helper: create a Post with Kit meta setting restrict_content to the given value. * From 98582423ddb8da44258c1c5fbe7c2982ad68ea24 Mon Sep 17 00:00:00 2001 From: Tim Carr Date: Fri, 17 Jul 2026 16:14:22 +0800 Subject: [PATCH 2/3] Added test --- .../general/RestrictContentCacheCest.php | 90 +++++++++++++++++++ 1 file changed, 90 insertions(+) diff --git a/tests/EndToEnd/restrict-content/general/RestrictContentCacheCest.php b/tests/EndToEnd/restrict-content/general/RestrictContentCacheCest.php index 347d3315d..ee8e7a0b4 100644 --- a/tests/EndToEnd/restrict-content/general/RestrictContentCacheCest.php +++ b/tests/EndToEnd/restrict-content/general/RestrictContentCacheCest.php @@ -539,6 +539,96 @@ public function testRestrictContentWPRocketCache(EndToEndTester $I) $I->deactivateThirdPartyPlugin($I, 'disable-_load_textdomain_just_in_time-doing_it_wrong-notice'); } + /** + * Tests that the SiteGround Speed Optimizer Plugin does not interfere with + * Restrict Content output when a ck_subscriber_id cookie is present, and + * that the Restrict Content Page is registered against the + * sgo_exclude_urls_from_cache filter via the Plugin's cache option. + * + * @since 3.3.6 + * + * @param EndToEndTester $I Tester. + */ + public function testRestrictContentSitegroundSpeedOptimizer(EndToEndTester $I) + { + // Activate SiteGround Speed Optimizer Plugin. + $I->activateThirdPartyPlugin($I, 'sg-cachepress'); + + // Enable SG Speed Optimizer's Dynamic Cache so its exclusion logic is active. + $I->haveOptionInDatabase('siteground_optimizer_enable_cache', 1); + + // Configure SG Speed Optimizer's Heartbeat, to prevent the Plugin from + // making requests to the site during the test. + $I->haveOptionInDatabase('siteground_optimizer_heartbeat_post_interval', 120); + $I->haveOptionInDatabase('siteground_optimizer_heartbeat_dashboard_interval', 120); + $I->haveOptionInDatabase('siteground_optimizer_heartbeat_frontend_interval', 120); + + // Confirm the Plugin's Restrict Content cache option is empty, as no + // Restrict Content Page has been configured yet. + $cache = $I->grabOptionFromDatabase('_wp_convertkit_restrict_content_posts'); + $I->assertTrue( empty( $cache ) ); + + // Add a Page using the Gutenberg editor. + $I->addGutenbergPage( + $I, + title: 'Kit: Restrict Content: Product: SG Speed Optimizer' + ); + + // Configure metabox's Restrict Content setting = Product name. + $I->configurePluginSidebarSettings( + $I, + form: 'None', + restrictContent: $_ENV['CONVERTKIT_API_PRODUCT_NAME'] + ); + + // Add blocks. + $I->addGutenbergParagraphBlock($I, 'Visible content.'); + $I->addGutenbergBlock( + $I, + blockName: 'More', + blockProgrammaticName: 'more' + ); + $I->addGutenbergParagraphBlock($I, 'Member-only content.'); + + // Publish Page. + $url = $I->publishGutenbergPage($I); + + // Load the Dashboard. + $I->amOnAdminPage('index.php'); + $I->waitForElementVisible('body.index-php'); + + // Confirm the Plugin's Restrict Content cache option now includes + // the relative URL for this Page. This URL is fed to + // SiteGround Speed Optimizer via the sgo_exclude_urls_from_cache + // filter at runtime, so that SG excludes the Restrict Content Page + // from its cache. + $cache = $I->grabOptionFromDatabase('_wp_convertkit_restrict_content_posts'); + $I->assertIsArray($cache); + $I->assertContains(wp_make_link_relative($url), array_values($cache)); + + // Log out, so that caching is honored. + $I->logOut(); + + // Navigate to the page. + $I->amOnUrl($url); + + // Test that the restricted content CTA displays when no valid signed subscriber ID is used, + // to confirm caching does not show member-only content. + $I->testRestrictContentByProductHidesContentWithCTA($I); + + // Test that the restricted content displays when a valid signed subscriber ID is used, + // to confirm caching does not show the incorrect content. + $I->setRestrictContentCookieAndReload( + $I, + subscriberID: $_ENV['CONVERTKIT_API_SIGNED_SUBSCRIBER_ID'], + urlOrPageID: $url + ); + $I->testRestrictContentDisplaysContent($I); + + // Deactivate SiteGround Speed Optimizer Plugin. + $I->deactivateThirdPartyPlugin($I, 'sg-cachepress'); + } + /** * Deactivate and reset Plugin(s) after each test, if the test passes. * We don't use _after, as this would provide a screenshot of the Plugin From c3917ab616b7f93d3b5bd9a14006614b11564047 Mon Sep 17 00:00:00 2001 From: Tim Carr Date: Mon, 20 Jul 2026 12:10:16 +0800 Subject: [PATCH 3/3] Tests: Clear caches for Member Content Posts between tests --- tests/Support/Helper/KitPlugin.php | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/Support/Helper/KitPlugin.php b/tests/Support/Helper/KitPlugin.php index 93fee63e9..790877f81 100644 --- a/tests/Support/Helper/KitPlugin.php +++ b/tests/Support/Helper/KitPlugin.php @@ -603,6 +603,7 @@ public function resetKitPlugin($I) // Cache. $I->dontHaveOptionInDatabase('convertkit_restrict_content_enabled'); + $I->dontHaveOptionInDatabase('_wp_convertkit_restrict_content_posts'); // Cookies. $I->resetCookie('ck_subscriber_id');