diff --git a/admin/section/class-convertkit-admin-section-restrict-content.php b/admin/section/class-convertkit-admin-section-restrict-content.php index 6f6ba2512..7107876bf 100644 --- a/admin/section/class-convertkit-admin-section-restrict-content.php +++ b/admin/section/class-convertkit-admin-section-restrict-content.php @@ -333,6 +333,21 @@ public function register_fields() { ) ); + add_settings_field( + 'container_css_classes', + __( 'Container CSS Classes', 'convertkit' ), + array( $this, 'text_callback' ), + $this->settings_key, + $this->name, + array( + 'name' => 'container_css_classes', + 'label_for' => 'container_css_classes', + 'description' => array( + __( 'Optional CSS classes to apply to the container wrapping the content preview and call to action for non-authenticated subscribers.', 'convertkit' ), + ), + ) + ); + } /** diff --git a/includes/class-convertkit-output-restrict-content.php b/includes/class-convertkit-output-restrict-content.php index d07fcfdc9..ac940b381 100644 --- a/includes/class-convertkit-output-restrict-content.php +++ b/includes/class-convertkit-output-restrict-content.php @@ -1226,6 +1226,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' ); + + /** + * 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. + */ + $container_css_classes = apply_filters( 'convertkit_output_restrict_content_container_css_classes', $container_css_classes, $this->post_id ); + + // 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 . '
'; + } + // Return the content preview and its call to action. return $content_preview . $call_to_action; diff --git a/includes/class-convertkit-settings-restrict-content.php b/includes/class-convertkit-settings-restrict-content.php index e061b2dc6..6653c18df 100644 --- a/includes/class-convertkit-settings-restrict-content.php +++ b/includes/class-convertkit-settings-restrict-content.php @@ -151,6 +151,7 @@ public function get_defaults() { 'email_description_text' => __( 'We\'ll email you a magic code to log you in without a password.', 'convertkit' ), 'email_check_heading' => __( 'We just emailed you a log in code', 'convertkit' ), 'email_check_text' => __( 'Enter the code below to finish logging in', 'convertkit' ), + 'container_css_classes' => '', ); /** diff --git a/tests/EndToEnd/restrict-content/general/RestrictContentFormCest.php b/tests/EndToEnd/restrict-content/general/RestrictContentFormCest.php index 8507bae3a..a9934245d 100644 --- a/tests/EndToEnd/restrict-content/general/RestrictContentFormCest.php +++ b/tests/EndToEnd/restrict-content/general/RestrictContentFormCest.php @@ -157,6 +157,68 @@ public function testRestrictContentByInvalidForm(EndToEndTester $I) $I->testRestrictContentDisplaysContent($I); } + /** + * Test that restricting content by a Form specified in the Page Settings works when + * creating and viewing a new WordPress Page, and that the container CSS classes are applied + * to the content preview and call to action. + * + * @since 3.1.4 + * + * @param EndToEndTester $I Tester. + */ + public function testRestrictContentContainerCSSClasses(EndToEndTester $I) + { + // Setup Kit Plugin, disabling JS. + $I->setupKitPluginDisableJS($I); + $I->setupKitPluginResources($I); + + // Define Restrict Content settings. + $settings = [ + 'container_css_classes' => 'custom-container-css-class', + ]; + + // Setup Restrict Content functionality with container CSS classes. + $I->setupKitPluginRestrictContent($I, $settings); + + // Add a Page using the Gutenberg editor. + $I->addGutenbergPage( + $I, + title: 'Kit: Page: Restrict Content: Form' + ); + + // Configure metabox's Restrict Content setting = Form name. + $I->configureMetaboxSettings( + $I, + 'wp-convertkit-meta-box', + [ + 'form' => [ 'select2', 'None' ], + 'restrict_content' => [ 'select2', $_ENV['CONVERTKIT_API_FORM_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); + + // Test Restrict Content functionality. + $I->testRestrictedContentByFormOnFrontend( + $I, + urlOrPageID: $url, + formID: $_ENV['CONVERTKIT_API_FORM_ID'], + options: [ + 'settings' => $settings, + ] + ); + } + /** * Test that restricting content by a Form specified in the Page Settings works when * using the Quick Edit functionality. diff --git a/tests/EndToEnd/restrict-content/general/RestrictContentSettingsCest.php b/tests/EndToEnd/restrict-content/general/RestrictContentSettingsCest.php index dd9813ec7..5ef30d890 100644 --- a/tests/EndToEnd/restrict-content/general/RestrictContentSettingsCest.php +++ b/tests/EndToEnd/restrict-content/general/RestrictContentSettingsCest.php @@ -167,6 +167,7 @@ public function testSaveSettings(EndToEndTester $I) 'email_description_text' => 'Email Description Text', 'email_check_heading' => 'Email Check Heading', 'email_check_text' => 'Email Check Text', + 'container_css_classes' => 'customer-container-class', ); // Save settings. diff --git a/tests/EndToEnd/restrict-content/general/RestrictContentTagCest.php b/tests/EndToEnd/restrict-content/general/RestrictContentTagCest.php index 906e68dfa..2762a9e56 100644 --- a/tests/EndToEnd/restrict-content/general/RestrictContentTagCest.php +++ b/tests/EndToEnd/restrict-content/general/RestrictContentTagCest.php @@ -304,6 +304,68 @@ public function testRestrictContentByInvalidTag(EndToEndTester $I) $I->testRestrictContentDisplaysContent($I); } + /** + * Test that restricting content by a Tag specified in the Page Settings works when + * creating and viewing a new WordPress Page, and that the container CSS classes are applied + * to the content preview and call to action. + * + * @since 3.1.4 + * + * @param EndToEndTester $I Tester. + */ + public function testRestrictContentContainerCSSClasses(EndToEndTester $I) + { + // Setup Kit Plugin, disabling JS. + $I->setupKitPluginDisableJS($I); + $I->setupKitPluginResources($I); + + // Define Restrict Content settings. + $settings = [ + 'container_css_classes' => 'custom-container-css-class', + ]; + + // Setup Restrict Content functionality with container CSS classes. + $I->setupKitPluginRestrictContent($I, $settings); + + // Add a Page using the Gutenberg editor. + $I->addGutenbergPage( + $I, + title: 'Kit: Page: Restrict Content: Tag: Container CSS Classes' + ); + + // Configure metabox's Restrict Content setting = Tag name. + $I->configureMetaboxSettings( + $I, + 'wp-convertkit-meta-box', + [ + 'form' => [ 'select2', 'None' ], + 'restrict_content' => [ 'select2', $_ENV['CONVERTKIT_API_TAG_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); + + // Test Restrict Content functionality. + $I->testRestrictedContentByTagOnFrontend( + $I, + urlOrPageID: $url, + emailAddress: $I->generateEmailAddress(), + options: [ + 'settings' => $settings, + ] + ); + } + /** * Test that restricting content by a Tag specified in the Page Settings works when * creating and viewing a new WordPress Page, with Google's reCAPTCHA enabled. diff --git a/tests/EndToEnd/restrict-content/post-types/RestrictContentProductCPTCest.php b/tests/EndToEnd/restrict-content/post-types/RestrictContentProductCPTCest.php index 0ff27b9f8..a630481f3 100644 --- a/tests/EndToEnd/restrict-content/post-types/RestrictContentProductCPTCest.php +++ b/tests/EndToEnd/restrict-content/post-types/RestrictContentProductCPTCest.php @@ -289,6 +289,68 @@ public function testRestrictContentModalByProduct(EndToEndTester $I) $I->testRestrictedContentModal($I, $url); } + /** + * Test that restricting content by a Product specified in the CPT Settings works when + * creating and viewing a new WordPress CPT, and that the container CSS classes are applied + * to the content preview and call to action. + * + * @since 3.1.4 + * + * @param EndToEndTester $I Tester. + */ + public function testRestrictContentContainerCSSClasses(EndToEndTester $I) + { + // Setup Kit Plugin, disabling JS. + $I->setupKitPluginDisableJS($I); + $I->setupKitPluginResources($I); + + // Define Restrict Content settings. + $settings = [ + 'container_css_classes' => 'custom-container-css-class', + ]; + + // Setup Restrict Content functionality with container CSS classes. + $I->setupKitPluginRestrictContent($I, $settings); + + // Add the CPT using the Gutenberg editor. + $I->addGutenbergPage( + $I, + postType: 'article', + title: 'Kit: Article: Restrict Content: Container CSS Classes' + ); + + // Configure metabox's Restrict Content setting = Product name. + $I->configureMetaboxSettings( + $I, + metabox: 'wp-convertkit-meta-box', + configuration: [ + 'form' => [ 'select2', 'None' ], + 'restrict_content' => [ 'select2', $_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); + + // Test Restrict Content functionality. + $I->testRestrictedContentByProductOnFrontend( + $I, + urlOrPageID: $url, + options: [ + 'settings' => $settings, + ] + ); + } + /** * Test that restricting content by a Product that does not exist does not output * a fatal error and instead displays all of the CPT's content. diff --git a/tests/EndToEnd/restrict-content/post-types/RestrictContentProductPageCest.php b/tests/EndToEnd/restrict-content/post-types/RestrictContentProductPageCest.php index 8a80cd146..9f14baba4 100644 --- a/tests/EndToEnd/restrict-content/post-types/RestrictContentProductPageCest.php +++ b/tests/EndToEnd/restrict-content/post-types/RestrictContentProductPageCest.php @@ -254,6 +254,67 @@ public function testRestrictContentModalByProduct(EndToEndTester $I) $I->testRestrictedContentModal($I, $url); } + /** + * Test that restricting content by a Product specified in the Page Settings works when + * creating and viewing a new WordPress Page, and that the container CSS classes are applied + * to the content preview and call to action. + * + * @since 3.1.4 + * + * @param EndToEndTester $I Tester. + */ + public function testRestrictContentContainerCSSClasses(EndToEndTester $I) + { + // Setup Kit Plugin, disabling JS. + $I->setupKitPluginDisableJS($I); + $I->setupKitPluginResources($I); + + // Define Restrict Content settings. + $settings = [ + 'container_css_classes' => 'custom-container-css-class', + ]; + + // Setup Restrict Content functionality with container CSS classes. + $I->setupKitPluginRestrictContent($I, $settings); + + // Add the Page using the Gutenberg editor. + $I->addGutenbergPage( + $I, + title: 'Kit: Page: Restrict Content: Container CSS Classes' + ); + + // Configure metabox's Restrict Content setting = Product name. + $I->configureMetaboxSettings( + $I, + metabox: 'wp-convertkit-meta-box', + configuration: [ + 'form' => [ 'select2', 'None' ], + 'restrict_content' => [ 'select2', $_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); + + // Test Restrict Content functionality. + $I->testRestrictedContentByProductOnFrontend( + $I, + urlOrPageID: $url, + options: [ + 'settings' => $settings, + ] + ); + } + /** * Test that restricting content by a Product specified in the Page Settings displays * an inline error message when the subscriber logged in to view content gated diff --git a/tests/EndToEnd/restrict-content/post-types/RestrictContentProductPostCest.php b/tests/EndToEnd/restrict-content/post-types/RestrictContentProductPostCest.php index ddd1a65e8..786f8d3bf 100644 --- a/tests/EndToEnd/restrict-content/post-types/RestrictContentProductPostCest.php +++ b/tests/EndToEnd/restrict-content/post-types/RestrictContentProductPostCest.php @@ -327,6 +327,68 @@ public function testRestrictContentModalByProduct(EndToEndTester $I) $I->testRestrictedContentModal($I, $url); } + /** + * Test that restricting content by a Product specified in the Post Settings works when + * creating and viewing a new WordPress Post, and that the container CSS classes are applied + * to the content preview and call to action. + * + * @since 3.1.4 + * + * @param EndToEndTester $I Tester. + */ + public function testRestrictContentContainerCSSClasses(EndToEndTester $I) + { + // Setup Kit Plugin, disabling JS. + $I->setupKitPluginDisableJS($I); + $I->setupKitPluginResources($I); + + // Define Restrict Content settings. + $settings = [ + 'container_css_classes' => 'custom-container-css-class', + ]; + + // Setup Restrict Content functionality with container CSS classes. + $I->setupKitPluginRestrictContent($I, $settings); + + // Add the Post using the Gutenberg editor. + $I->addGutenbergPage( + $I, + postType: 'post', + title: 'Kit: Post: Restrict Content: Container CSS Classes' + ); + + // Configure metabox's Restrict Content setting = Product name. + $I->configureMetaboxSettings( + $I, + metabox: 'wp-convertkit-meta-box', + configuration: [ + 'form' => [ 'select2', 'None' ], + 'restrict_content' => [ 'select2', $_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); + + // Test Restrict Content functionality. + $I->testRestrictedContentByProductOnFrontend( + $I, + urlOrPageID: $url, + options: [ + 'settings' => $settings, + ] + ); + } + /** * Test that restricting content by a Product that does not exist does not output * a fatal error and instead displays all of the Post's content. diff --git a/tests/Support/Helper/KitRestrictContent.php b/tests/Support/Helper/KitRestrictContent.php index dc95c6010..f92f00ba9 100644 --- a/tests/Support/Helper/KitRestrictContent.php +++ b/tests/Support/Helper/KitRestrictContent.php @@ -637,6 +637,11 @@ public function testRestrictContentByProductHidesContentWithCTA($I, $options = f } $I->dontSee($options['member_content']); + // If a container CSS classes is set, confirm that the container is displayed. + if ( ! empty($options['settings']['container_css_classes'])) { + $I->seeInSource('
'); + } + // Confirm that the CTA displays with the expected headings, text, buttons and other elements. $I->seeElementInDOM('#convertkit-restrict-content');