diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index d59ffb260..c59a882fb 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -33,7 +33,7 @@ jobs: WORDPRESS_DB_SQL_DUMP_FILE: tests/Support/Data/dump.sql # Used to populate the test site database for WordPress 6.2.8 INSTALL_PLUGINS: "admin-menu-editor autoptimize beaver-builder-lite-version block-visibility contact-form-7 classic-editor custom-post-type-ui debloat elementor forminator jetpack-boost mailchimp-for-wp rocket-lazy-load woocommerce wordpress-seo wpforms-lite litespeed-cache wp-crontrol wp-super-cache w3-total-cache wp-fastest-cache wp-optimize sg-cachepress" # Don't include this repository's Plugin here. INSTALL_PLUGINS_URLS: "https://downloads.wordpress.org/plugin/convertkit-for-woocommerce.1.6.4.zip http://cktestplugins.wpengine.com/wp-content/uploads/2024/01/convertkit-action-filter-tests.zip http://cktestplugins.wpengine.com/wp-content/uploads/2024/11/disable-doing-it-wrong-notices.zip http://cktestplugins.wpengine.com/wp-content/uploads/2025/03/uncode-js_composer.7.8.zip http://cktestplugins.wpengine.com/wp-content/uploads/2025/03/uncode-core.zip" # URLs to specific third party Plugins - INSTALL_THEMES_URLS: "http://cktestplugins.wpengine.com/wp-content/uploads/2025/03/uncode.zip http://cktestplugins.wpengine.com/wp-content/uploads/2025/04/Divi.zip" + INSTALL_THEMES_URLS: "http://cktestplugins.wpengine.com/wp-content/uploads/2025/03/uncode.zip http://cktestplugins.wpengine.com/wp-content/uploads/2025/04/Divi.zip http://cktestplugins.wpengine.com/wp-content/uploads/2026/01/impeka.zip" CONVERTKIT_API_KEY: ${{ secrets.CONVERTKIT_API_KEY }} # ConvertKit API Key, stored in the repository's Settings > Secrets CONVERTKIT_API_SECRET: ${{ secrets.CONVERTKIT_API_SECRET }} # ConvertKit API Secret, stored in the repository's Settings > Secrets CONVERTKIT_API_KEY_NO_DATA: ${{ secrets.CONVERTKIT_API_KEY_NO_DATA }} # ConvertKit API Key for ConvertKit account with no data, stored in the repository's Settings > Secrets diff --git a/includes/class-convertkit-output-restrict-content.php b/includes/class-convertkit-output-restrict-content.php index ac940b381..17e97b822 100644 --- a/includes/class-convertkit-output-restrict-content.php +++ b/includes/class-convertkit-output-restrict-content.php @@ -1227,21 +1227,24 @@ private function restrict_content( $content ) { $call_to_action = apply_filters( 'convertkit_output_restrict_content_call_to_action', $call_to_action, $this->post_id ); // Fetch container CSS classes. - $container_css_classes = $this->restrict_content_settings->get_by_key( 'container_css_classes' ); + $container_css_classes = explode( ' ', $this->restrict_content_settings->get_by_key( 'container_css_classes' ) ); /** * Define the container CSS classes to wrap the content preview and call to action within. * * @since 3.1.4 * - * @param string $container_css_classes Container CSS classes. - * @param int $post_id Post ID. + * @param array $container_css_classes Container CSS classes. + * @param int $post_id Post ID. */ $container_css_classes = apply_filters( 'convertkit_output_restrict_content_container_css_classes', $container_css_classes, $this->post_id ); + // Remove empty CSS classes. + $container_css_classes = array_filter( $container_css_classes ); + // If container CSS classes are set, return the content preview and call to action wrapped in the container. - if ( $container_css_classes ) { - return '
' . $content_preview . $call_to_action . '
'; + if ( count( $container_css_classes ) ) { + return '
' . $content_preview . $call_to_action . '
'; } // Return the content preview and its call to action. diff --git a/includes/functions.php b/includes/functions.php index 038248f23..6ad62e1e0 100644 --- a/includes/functions.php +++ b/includes/functions.php @@ -641,6 +641,32 @@ function convertkit_output_intercom_messenger() { } +/** + * Checks if the given Theme is active. + * + * @since 3.1.4 + * + * @param string $theme_name Theme name. + * @return bool + */ +function convertkit_is_theme_active( $theme_name ) { + + // Assume Theme isn't active if we can't detect it. + if ( ! function_exists( 'wp_get_theme' ) ) { + return false; + } + + // Check the Parent Theme if we're on a Child Theme. + if ( wp_get_theme()->parent() ) { + $theme = wp_get_theme()->parent(); + } else { + $theme = wp_get_theme(); + } + + return strtolower( $theme->get( 'Name' ) ) === strtolower( $theme_name ); + +} + /** * Returns permitted HTML output when using wp_kses( ..., convertkit_kses_allowed_html()). * diff --git a/includes/integrations/class-convertkit-impeka.php b/includes/integrations/class-convertkit-impeka.php new file mode 100644 index 000000000..42432c16c --- /dev/null +++ b/includes/integrations/class-convertkit-impeka.php @@ -0,0 +1,50 @@ +setupKitPluginResources($I); } + /** + * Test that restricting content by a Product specified in the Page Settings works when + * creating and viewing a new WordPress Page using the Impeka theme automatically + * adds Impeka's grve-container CSS class to the Restrict Content container, + * ensuring correct layout. + * + * @since 3.1.4 + * + * @param EndToEndTester $I Tester. + */ + public function testRestrictContentByProductWithImpekaTheme(EndToEndTester $I) + { + // Activate theme. + $I->useTheme('impeka'); + + // Programmatically create a Page using the Visual Composer Page Builder. + $pageID = $I->havePostInDatabase( + [ + 'post_type' => 'page', + 'post_title' => 'Kit: Page: Restrict Content: Product: Impeka Theme with Visual Composer', + 'post_content' => 'Member-only content.', + + // Don't display a Form on this Page, so we test against Restrict Content's Form. + 'meta_input' => [ + '_wp_convertkit_post_meta' => [ + 'form' => '0', + 'landing_page' => '', + 'tag' => '', + 'restrict_content' => 'product_' . $_ENV['CONVERTKIT_API_PRODUCT_ID'], + ], + ], + ] + ); + + // Test Restrict Content functionality. + $I->testRestrictedContentByProductOnFrontend( + $I, + urlOrPageID: $pageID, + options: [ + 'visible_content' => '', + 'member_content' => 'Member-only content.', + 'settings' => [ + // Test that the grve-container CSS class is added to the Restrict Content container. + 'container_css_classes' => 'grve-container', + ], + ], + ); + } + /** * Test that restricting content by a Product specified in the Page Settings works when * creating and viewing a new WordPress Page using the Uncode theme both using diff --git a/tests/Integration/ThemeDetectionTest.php b/tests/Integration/ThemeDetectionTest.php new file mode 100644 index 000000000..cf0f50613 --- /dev/null +++ b/tests/Integration/ThemeDetectionTest.php @@ -0,0 +1,65 @@ +assertTrue(convertkit_is_theme_active( 'Twenty Twenty-Five' )); + $this->assertFalse(convertkit_is_theme_active( 'Impeka' )); + + // Switch Theme. + switch_theme('impeka'); + $this->assertFalse(convertkit_is_theme_active( 'Twenty Twenty-Five' )); + $this->assertTrue(convertkit_is_theme_active( 'Impeka' )); + } +} diff --git a/wp-convertkit.php b/wp-convertkit.php index 3e15d62fd..4641bce42 100644 --- a/wp-convertkit.php +++ b/wp-convertkit.php @@ -145,6 +145,9 @@ require_once CONVERTKIT_PLUGIN_PATH . '/includes/integrations/forminator/class-convertkit-forminator.php'; require_once CONVERTKIT_PLUGIN_PATH . '/includes/integrations/forminator/class-convertkit-forminator-settings.php'; +// Impeka Integration. +require_once CONVERTKIT_PLUGIN_PATH . '/includes/integrations/class-convertkit-impeka.php'; + // Uncode Integration. require_once CONVERTKIT_PLUGIN_PATH . '/includes/integrations/class-convertkit-uncode.php';