Skip to content

Rock: Email Gathering Modal - Form Templates#2453

Merged
Crabcyborg merged 73 commits into
masterfrom
rock-email-gathering-modal
Oct 3, 2025
Merged

Rock: Email Gathering Modal - Form Templates#2453
Crabcyborg merged 73 commits into
masterfrom
rock-email-gathering-modal

Conversation

@shervElmi
Copy link
Copy Markdown
Contributor

@shervElmi shervElmi commented Aug 8, 2025

@shervElmi shervElmi self-assigned this Aug 8, 2025
- Add condition to show email collection modal only for non-Pro users
- Set up modal with title "Get 30+ Free Form Templates"
- Include description and submit button text for the modal
- Add the modal view to template parts array
- Replace hardcoded defaults with configurable parameters
- Add conditional rendering for API URL section
- Add null safety with null coalescing operators
- Make button text customizable with fallbacks
- Support custom default email addresses
- Simplify argument handling
- Change subscribe_to_active_campaign() from private to public method
- Add optional email parameter to allow custom email subscriptions
- Update method to use provided email instead of only current user's email
- Update documentation to reflect parameter changes
- Remove empty line in test email array
- Add email modal elements to elements registry
- Create showError.js utility for email validation errors
- Add query parameter detection for automatically showing email modal
- Update showModal.js to support displaying the leave email modal
- Add FREE plan case to locked template modal handler
…ebase

- Rename banner file from access-free-templates-banner.php to get-free-templates-banner.php
- Update all function names from access_free_templates to get_free_templates
- Rename CSS class from frm-access-free-templates-banner to frm-get-free-templates-banner
- Update SCSS file name and import to match new naming convention
- Rename banner image file to get-free-templates-banner.png
- Update URL parameter from access-free-templates to free-templates
- Fix indentation in dashboard controller
- Update button text context for translation
- Add set_free_license_code() and get_free_license_code() methods to FrmFormTemplateApi
- Update API URL to include free license parameter when code exists
- Add free license code check to email modal condition in FrmFormTemplatesController
- Hide get free templates banner when user already has free license code
- Remove TODO comment after implementing free license code check
- Add ajax_get_free_templates() method to FrmFormTemplatesController
- Subscribe user email to ActiveCampaign when requesting free templates
- Set free license code flag after successful subscription
- Reset template API cache to refresh available templates
- Register wp_ajax_frm_get_free_templates hook in FrmHooksController
- Add .frm-text-left utility class for left text alignment
- Add !important to .frm-text-grey-500 to increase CSS specificity
- Remove selectedTemplate from initial page state in form templates
- Remove selectedTemplate assignment in useTemplateButtonListener
- Add removeParamFromHistory() utility function to core/utils/url.js
- Add getFreeTemplatesListener.js with email validation and AJAX submission
- Add banner button and modal button elements to elements registry
- Integrate get free templates event listeners into main events system
- Remove unused showConfirmEmailAddressError function
- Handle success/error states and page reload after successful submission
- Add URL parameter management for free templates flow
- Change query parameter from 'registered_for_free_templates' to 'registered-for-free-templates'
- Update setupInitialView.js to use getSingleState instead of getState for better performance
- Add automatic navigation to Available Templates category after registration
- Remove unused imports and optimize element access patterns
- Add conditional check to only display count for non-available-templates categories
- Keep count span element but leave it empty for available-templates category
- Maintain consistent markup structure across all categories
- Create new counter.js utility for animating number transitions
- Implement performance optimizations with frame drop detection
- Add fallback to CSS transitions when browser performance is degraded
- Export counter from core UI module
- Update core index.js to export all UI components
- Extract available templates setup into dedicated functions
- Add animation effect for template count after registration
- Use the new counter utility for smooth number transitions
- Remove redundant sidebar show() call
- Improve code organization with separate helper functions
- Fix upsellBanner element selection with fallback mechanism
- Show upsell banner alongside templates in category views
- Add upsellBanner to both regular and available template displays
- Add backgroundHighlight CSS animation with primary color fade
- Add frm-background-highlight class for 1000ms animation
- Reorder template registration effects for better user experience
- Add background highlight to available templates after counter animation
- Improve visual feedback when users gain access to free templates
- Add proper event listener cleanup after background highlight animation
- Prevent memory leaks by removing animationend listeners after completion
- Update available templates category setup to use effects function
- Comment out direct text content assignment for debugging
- Add needs_get_free_templates_banner() helper method to FrmFormTemplatesHelper
- Replace duplicate banner visibility checks with centralized method
- Add conditional rendering to dashboard banner display
- Update form templates controller and index view to use new helper
- Improve code maintainability by eliminating duplicate logic
- Add loading state to submit button during AJAX request
- Extract showFailedToGetTemplates() function for error handling
- Hide modal footer when displaying error messages
- Consolidate duplicate error handling code
- Set cursor to not-allowed and add loading class to button
Comment thread classes/controllers/FrmFormTemplatesController.php Outdated
Replace ternary operator with if condition in subscribe_to_active_campaign()
to avoid unnecessary reassignment when email parameter is already provided.
Only assign user's email when the email parameter is empty.
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (1)
classes/controllers/FrmFormTemplatesController.php (1)

51-56: Add @SInCE to the new constant docblock

Include a @SInCE tag for consistency with surrounding docs.

 /**
  * The keys of the free templates.
  *
- * @var array Unique keys for the free templates.
+ * @since x.x
+ * @var array Unique keys for the free templates.
  */
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 3283c28 and fcf456e.

📒 Files selected for processing (1)
  • classes/controllers/FrmFormTemplatesController.php (4 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
classes/controllers/FrmFormTemplatesController.php (4)
classes/helpers/FrmFormTemplatesHelper.php (2)
  • FrmFormTemplatesHelper (17-251)
  • needs_get_free_templates_banner (234-236)
classes/helpers/FrmAppHelper.php (3)
  • FrmAppHelper (6-4622)
  • permission_check (2188-2196)
  • get_post_param (682-692)
classes/models/FrmFormTemplateApi.php (2)
  • FrmFormTemplateApi (6-113)
  • set_free_license_code (70-72)
classes/helpers/FrmEmailCollectionHelper.php (2)
  • FrmEmailCollectionHelper (17-90)
  • subscribe_to_active_campaign (27-57)
🪛 PHPMD (2.15.0)
classes/controllers/FrmFormTemplatesController.php

237-237: Avoid unused local variables such as '$leave_email_args'. (undefined)

(UnusedLocalVariable)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
  • GitHub Check: PHP 7.4 tests in WP trunk
  • GitHub Check: PHP 8 tests in WP trunk
  • GitHub Check: Run PHP Syntax inspection (8.3)
  • GitHub Check: Cypress
🔇 Additional comments (4)
classes/controllers/FrmFormTemplatesController.php (4)

236-243: Pass $leave_email_args explicitly to the modal partial (avoid hidden include-scope coupling / fix PHPMD warning)

Pass args with the view part to make the contract explicit and silence PHPMD “UnusedLocalVariable”.

-				$view_parts[]     = 'modals/leave-email-modal.php';
+				$view_parts[]     = array(
+					'file' => 'modals/leave-email-modal.php',
+					'args' => $leave_email_args,
+				);

Outside this file (classes/views/form-templates/modal.php), ensure the include loop supports array entries and resets $args per iteration:

foreach ( $view_parts as $part ) {
	if ( isset( $args ) ) { unset( $args ); }
	$file = is_array( $part ) ? $part['file'] : $part;
	if ( is_array( $part ) && isset( $part['args'] ) ) { $args = $part['args']; }
	require $view_path . $file;
}

405-413: Server-side email validation looks good

Nonce + capability checks, sanitize_email + is_email, and 400 response are correct.


723-724: Expose FREE_TEMPLATES_KEYS to JS — LGTM

Consistent with how FEATURED_TEMPLATES_KEYS is exposed.


414-420: Call static method on the class, not via an instance

Using instance::staticMethod is unconventional and confuses analyzers. Call the static on FrmFormTemplateApi.

 		self::$form_template_api = new FrmFormTemplateApi();
 		self::$form_template_api->reset_cached();
 
 		FrmEmailCollectionHelper::subscribe_to_active_campaign( $email );
-		self::$form_template_api::set_free_license_code( '1' );
+		FrmFormTemplateApi::set_free_license_code( '1' );

Optional: if reset_cached() has a static variant or is unnecessary here, drop the instantiation altogether.

Rename FEATURED_TEMPLATES_KEYS to FEATURED_TEMPLATES_IDS and
FREE_TEMPLATES_KEYS to FREE_TEMPLATES_IDS to better reflect that
these contain template IDs rather than generic "keys". Update all
references across controller, helper, and test files, along with
documentation comments.
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (2)
classes/controllers/FrmFormTemplatesController.php (2)

394-421: AJAX: good validation; fix instance::static call and reset cache after setting code.

Call the static method on the class and refresh cache after updating.

-		self::$form_template_api = new FrmFormTemplateApi();
-		self::$form_template_api->reset_cached();
-
-		FrmEmailCollectionHelper::subscribe_to_active_campaign( $email );
-		self::$form_template_api::set_free_license_code( '1' );
+		FrmEmailCollectionHelper::subscribe_to_active_campaign( $email );
+		FrmFormTemplateApi::set_free_license_code( '1' );
+		self::$form_template_api = new FrmFormTemplateApi();
+		self::$form_template_api->reset_cached();

723-724: If you rename the constant, mirror it in JS variables.

Keep server and client in sync.

-			'FEATURED_TEMPLATES_KEYS' => self::FEATURED_TEMPLATES_KEYS,
-			'FREE_TEMPLATES_KEYS'     => self::FREE_TEMPLATES_KEYS,
+			'FEATURED_TEMPLATES_KEYS' => self::FEATURED_TEMPLATES_KEYS,
+			'FREE_TEMPLATES_IDS'      => self::FREE_TEMPLATES_IDS,
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between fcf456e and 99ca078.

📒 Files selected for processing (2)
  • classes/controllers/FrmFormTemplatesController.php (5 hunks)
  • classes/helpers/FrmEmailCollectionHelper.php (1 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
classes/controllers/FrmFormTemplatesController.php (4)
classes/helpers/FrmFormTemplatesHelper.php (2)
  • FrmFormTemplatesHelper (17-251)
  • needs_get_free_templates_banner (234-236)
classes/helpers/FrmAppHelper.php (3)
  • FrmAppHelper (6-4622)
  • permission_check (2188-2196)
  • get_post_param (682-692)
classes/models/FrmFormTemplateApi.php (2)
  • FrmFormTemplateApi (6-113)
  • set_free_license_code (70-72)
classes/helpers/FrmEmailCollectionHelper.php (2)
  • FrmEmailCollectionHelper (17-92)
  • subscribe_to_active_campaign (27-59)
🪛 PHPMD (2.15.0)
classes/controllers/FrmFormTemplatesController.php

237-237: Avoid unused local variables such as '$leave_email_args'. (undefined)

(UnusedLocalVariable)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Cypress
🔇 Additional comments (8)
classes/helpers/FrmEmailCollectionHelper.php (5)

69-91: Make fake-email detection sanitized, case-insensitive, and extensible.

Prevents bypasses like Test@Example.com and allows site-specific blocks.

-	public static function is_fake_email( $email ) {
-		if ( ! is_email( $email ) ) {
+	public static function is_fake_email( $email ) {
+		$email = is_string( $email ) ? sanitize_email( strtolower( $email ) ) : '';
+		if ( ! is_email( $email ) ) {
 			return true;
 		}
 
-		$substrings = array(
+		$substrings = array(
 			'@wpengine.local',
 			'@example.com',
 			'@localhost',
 			'@local.dev',
 			'@local.test',
 			'test@gmail.com',
 			'admin@gmail.com',
 		);
 
-		foreach ( $substrings as $substring ) {
-			if ( false !== strpos( $email, $substring ) ) {
+		$substrings = apply_filters( 'frm_fake_email_substrings', $substrings );
+
+		foreach ( $substrings as $substring ) {
+			if ( false !== stripos( $email, (string) $substring ) ) {
 				return true;
 			}
 		}
 
 		return false;
 	}

15-16: Replace @SInCE x.x placeholders before release.

Set the actual version numbers for new methods/classes.


27-35: Sanitize, validate, and normalize the email before use (lowercase).

Ensure a clean, valid email is used for checks and external calls.

 		$user = wp_get_current_user();
-		if ( ! $email ) {
-			$email = $user->user_email;
-		}
-
-		if ( self::is_fake_email( $email ) ) {
+		if ( ! $email ) {
+			$email = $user->user_email;
+		}
+		$email = is_string( $email ) ? sanitize_email( $email ) : '';
+		if ( empty( $email ) || ! is_email( $email ) ) {
+			return;
+		}
+		$email = strtolower( $email );
+		if ( self::is_fake_email( $email ) ) {
 			return;
 		}

37-40: Sanitize first_name/last_name before sending off-site.

Harden PII prior to transmission.

 		$user_id    = $user->ID;
-		$first_name = get_user_meta( $user_id, 'first_name', true );
-		$last_name  = get_user_meta( $user_id, 'last_name', true );
+		$first_name = get_user_meta( $user_id, 'first_name', true );
+		$last_name  = get_user_meta( $user_id, 'last_name', true );
+		$first_name = is_string( $first_name ) ? sanitize_text_field( $first_name ) : '';
+		$last_name  = is_string( $last_name ) ? sanitize_text_field( $last_name ) : '';

41-58: Gate the sandbox endpoint via a filter; add timeout, headers, and non-blocking request.

Prevents accidentally shipping sandbox URL; improves resiliency.

-		wp_remote_post(
-			'https://sandbox.formidableforms.com/api/wp-admin/admin-ajax.php?action=frm_forms_preview&form=subscribe-onboarding',
-			array(
-				'body' => http_build_query(
-					array(
-						'form_key'      => 'subscribe-onboarding',
-						'frm_action'    => 'create',
-						'form_id'       => 5,
-						'item_key'      => '',
-						'item_meta[0]'  => '',
-						'item_meta[15]' => $email,
-						'item_meta[17]' => 'Source - FF Lite Plugin Onboarding',
-						'item_meta[18]' => is_string( $first_name ) ? $first_name : '',
-						'item_meta[19]' => is_string( $last_name ) ? $last_name : '',
-					)
-				),
-			)
-		);
+		$default_url = 'https://sandbox.formidableforms.com/api/wp-admin/admin-ajax.php?action=frm_forms_preview&form=subscribe-onboarding';
+		$url         = apply_filters( 'frm_email_collection_endpoint', $default_url );
+		$body        = array(
+			'form_key'      => 'subscribe-onboarding',
+			'frm_action'    => 'create',
+			'form_id'       => 5,
+			'item_key'      => '',
+			'item_meta[0]'  => '',
+			'item_meta[15]' => $email,
+			'item_meta[17]' => apply_filters( 'frm_email_collection_source', 'Source - FF Lite Plugin Onboarding' ),
+			'item_meta[18]' => $first_name,
+			'item_meta[19]' => $last_name,
+		);
+		$args = array(
+			'timeout'  => 3,
+			'blocking' => false,
+			'headers'  => array( 'Content-Type' => 'application/x-www-form-urlencoded; charset=utf-8' ),
+			'body'     => $body,
+		);
+		$args = apply_filters( 'frm_email_collection_request_args', $args, $email, $first_name, $last_name );
+		wp_remote_post( esc_url_raw( $url ), $args );
classes/controllers/FrmFormTemplatesController.php (3)

23-31: LGTM on doc clarity.

Docblocks for PAGE_SLUG and SCRIPT_HANDLE read cleanly.


51-57: Rename FREE_TEMPLATES_KEYS to FREE_TEMPLATES_IDS to avoid confusion with “key”.

These are numeric IDs; rename for clarity and consistency.

-	/**
-	 * The keys of the free templates.
-	 *
-	 * @var array Unique keys for the free templates.
-	 */
-	const FREE_TEMPLATES_KEYS = array( 20872734, 28223640 );
+	/**
+	 * The IDs of the free templates.
+	 *
+	 * @var array Unique IDs for the free templates.
+	 */
+	const FREE_TEMPLATES_IDS = array( 20872734, 28223640 );

Follow-ups (outside this file):

  • Update FrmFormTemplatesHelper::needs_free_plan() to reference FrmFormTemplatesController::FREE_TEMPLATES_IDS.
  • Update JS consumers accordingly (see comment on Lines 723-724).
#!/bin/bash
rg -nP 'FREE_TEMPLATES_KEYS|FEATURED_TEMPLATES_KEYS'

236-243: Pass $leave_email_args explicitly to the partial (avoid hidden include-scope coupling).

Fixes PHPMD “unused variable” and makes intent explicit.

 			if ( FrmFormTemplatesHelper::needs_get_free_templates_banner() ) {
 				$leave_email_args = array(
 					'title'              => esc_html__( 'Get 30+ Free Form Templates', 'formidable' ),
 					'description'        => esc_html__( 'Just add your email address and you\'ll get 30+ free form templates to your account.', 'formidable' ),
 					'submit_button_text' => esc_html_x( 'Get Templates', 'get free templates modal submit button text', 'formidable' ),
 				);
-				$view_parts[]     = 'modals/leave-email-modal.php';
+				$view_parts[] = array(
+					'file' => 'modals/leave-email-modal.php',
+					'args' => $leave_email_args,
+				);
 			}

Also update classes/views/form-templates/modal.php to accept array entries:

// replace the foreach in modal.php
foreach ( $view_parts as $part ) {
	if ( isset( $args ) ) {
		unset( $args );
	}
	$file = is_array( $part ) ? $part['file'] : $part;
	if ( is_array( $part ) && isset( $part['args'] ) ) {
		$args = $part['args'];
	}
	require $view_path . $file;
}

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (1)
classes/controllers/FrmFormTemplatesController.php (1)

418-418: Fix instance method call on static method.

Line 418 incorrectly calls a static method on an instance (self::$form_template_api::set_free_license_code). This should call the static method directly on the class.

Apply this diff to fix the static method call:

-		self::$form_template_api::set_free_license_code( '1' );
+		FrmFormTemplateApi::set_free_license_code( '1' );
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 99ca078 and b98d61a.

📒 Files selected for processing (7)
  • classes/controllers/FrmFormTemplatesController.php (5 hunks)
  • classes/helpers/FrmFormTemplatesHelper.php (2 hunks)
  • js/src/form-templates/shared/constants.js (1 hunks)
  • js/src/form-templates/ui/setupInitialView.js (3 hunks)
  • js/src/form-templates/utils/validation.js (2 hunks)
  • resources/scss/admin/frm_admin.scss (1 hunks)
  • tests/phpunit/form-templates/test_FrmFormTemplatesControllerAjax.php (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • resources/scss/admin/frm_admin.scss
🧰 Additional context used
🧬 Code graph analysis (4)
js/src/form-templates/ui/setupInitialView.js (4)
js/src/core/factory/createPageState.js (1)
  • getSingleState (30-36)
js/src/form-templates/ui/showHeaderCancelButton.js (1)
  • showHeaderCancelButton (16-19)
js/src/form-templates/shared/pageState.js (2)
  • availableTemplatesCount (13-13)
  • getElements (12-12)
js/src/core/ui/counter.js (1)
  • counter (12-54)
classes/helpers/FrmFormTemplatesHelper.php (3)
classes/helpers/FrmAppHelper.php (2)
  • FrmAppHelper (6-4622)
  • pro_is_installed (307-309)
classes/models/FrmFormTemplateApi.php (2)
  • FrmFormTemplateApi (6-113)
  • get_free_license_code (81-83)
classes/controllers/FrmFormTemplatesController.php (1)
  • FrmFormTemplatesController (18-891)
js/src/form-templates/shared/constants.js (1)
js/src/form-templates/shared/pageState.js (1)
  • window (11-11)
classes/controllers/FrmFormTemplatesController.php (4)
classes/helpers/FrmFormTemplatesHelper.php (2)
  • FrmFormTemplatesHelper (17-251)
  • needs_get_free_templates_banner (234-236)
classes/helpers/FrmAppHelper.php (3)
  • FrmAppHelper (6-4622)
  • permission_check (2188-2196)
  • get_post_param (682-692)
classes/models/FrmFormTemplateApi.php (2)
  • FrmFormTemplateApi (6-113)
  • set_free_license_code (70-72)
classes/helpers/FrmEmailCollectionHelper.php (2)
  • FrmEmailCollectionHelper (17-92)
  • subscribe_to_active_campaign (27-59)
🪛 PHPMD (2.15.0)
classes/helpers/FrmFormTemplatesHelper.php

216-216: Avoid unused local variables such as '$args'. (undefined)

(UnusedLocalVariable)

classes/controllers/FrmFormTemplatesController.php

237-237: Avoid unused local variables such as '$leave_email_args'. (undefined)

(UnusedLocalVariable)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: PHP 8 tests in WP trunk
  • GitHub Check: PHP 7.4 tests in WP trunk
  • GitHub Check: Cypress
🔇 Additional comments (20)
js/src/form-templates/ui/setupInitialView.js (7)

5-6: LGTM!

The imports are correctly updated to include the new removeParamFromHistory utility and counter UI component, which align with their usage in the new URL parameter handling and animation logic.


13-13: LGTM!

The import correctly updates from FEATURED_TEMPLATES_KEYS to FEATURED_TEMPLATES_IDS and adds FREE_TEMPLATES_IDS, maintaining consistency with the broader refactoring across the codebase.


28-29: LGTM!

The element destructuring adds the necessary UI elements (availableTemplatesCategory and extraTemplateCountElements) that are used in the new functionality.


39-39: LGTM!

The call to setupAvailableTemplatesCategory properly separates this concern into its own function, improving code organization.


42-42: LGTM!

The extra template count update correctly uses the new getSingleState pattern for consistency with the rest of the state management.


55-74: LGTM!

The setupAvailableTemplatesCategory function properly handles the conditional logic for the free templates flow. The implementation correctly checks for the URL parameter and either updates the count directly or triggers the effects chain.


76-111: LGTM!

The runAvailableTemplatesEffects function implements a well-orchestrated sequence of UI effects:

  1. Triggers category expansion with a synthetic click event
  2. Animates the counter with appropriate timing
  3. Highlights non-free templates with proper cleanup

The animation event listener properly removes itself after completion to prevent memory leaks.

js/src/form-templates/utils/validation.js (2)

10-10: LGTM!

The import correctly updates from FEATURED_TEMPLATES_KEYS to FEATURED_TEMPLATES_IDS, maintaining consistency with the codebase-wide refactoring from keys to IDs.


60-61: LGTM!

The isFeaturedTemplate function correctly uses FEATURED_TEMPLATES_IDS and properly converts the dataset.id to a number for the membership check, maintaining the intended functionality while aligning with the ID-based approach.

tests/phpunit/form-templates/test_FrmFormTemplatesControllerAjax.php (1)

27-27: LGTM!

The test correctly updates to use FEATURED_TEMPLATES_IDS instead of the previous FEATURED_TEMPLATES_KEYS, maintaining consistency with the constant rename across the codebase.

js/src/form-templates/shared/constants.js (1)

2-2: LGTM!

The destructuring correctly updates to export FEATURED_TEMPLATES_IDS and FREE_TEMPLATES_IDS instead of FEATURED_TEMPLATES_KEYS, maintaining consistency with the server-side constant changes and supporting the new free templates functionality.

classes/helpers/FrmFormTemplatesHelper.php (4)

32-34: LGTM!

The conditional override for the free plan correctly integrates with the template preparation logic, allowing the system to dynamically adjust template requirements based on user eligibility.


215-225: Apply previous review feedback: Pass $args explicitly to avoid PHPMD warning.

The $args variable is flagged as unused by PHPMD since it's only referenced within the included view. This creates implicit coupling between the wrapper and the included file.


234-236: LGTM!

The needs_get_free_templates_banner method correctly checks both conditions (PRO not installed and no free license code) to determine when the banner should be displayed.


246-250: LGTM!

The needs_free_plan method implements proper logic to determine when a template should be overridden to the free plan, checking all necessary conditions: banner eligibility, 'free' category membership, and exclusion from FREE_TEMPLATES_IDS.

classes/controllers/FrmFormTemplatesController.php (5)

41-56: LGTM!

The constant updates correctly rename FEATURED_TEMPLATES_KEYS to FEATURED_TEMPLATES_IDS and add the new FREE_TEMPLATES_IDS constant. The documentation is updated appropriately, and the IDs match the expected template identifiers.


236-243: Apply previous review feedback: Pass $leave_email_args explicitly to avoid PHPMD coupling.

The PHPMD warning indicates $leave_email_args is unused in this scope because it's only consumed by the included view through implicit scope coupling.


578-586: LGTM!

The method correctly updates to iterate over FEATURED_TEMPLATES_IDS instead of FEATURED_TEMPLATES_KEYS, maintaining the intended functionality while aligning with the ID-based approach.


720-732: LGTM!

The JavaScript variables correctly expose FEATURED_TEMPLATES_IDS and FREE_TEMPLATES_IDS to the frontend, replacing the previous FEATURED_TEMPLATES_KEYS. The data structure remains consistent and properly supports the new free templates functionality.


394-421: WP_Http::BAD_REQUEST usage is correct — no action needed.
Confirmed at classes/controllers/FrmFormTemplatesController.php:410; the constant returns HTTP 400 and the handler validates the email server-side (sanitize_email + is_email).

@shervElmi
Copy link
Copy Markdown
Contributor Author

@Crabcyborg and @lauramekaj1 it looks like the E2E test needs to be updated since we changed our strategy for the initial free templates list.

@Crabcyborg
Copy link
Copy Markdown
Contributor

Thanks @shervElmi. The old tests are shown in the diff here https://github.com/Strategy11/formidable-forms/pull/2277/files

@lauramekaj1 should be able to help with updating them.

@Crabcyborg Crabcyborg added this to the 6.25 milestone Oct 3, 2025
Copy link
Copy Markdown
Contributor

@Crabcyborg Crabcyborg left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @shervElmi and @lauramekaj1 for working on this!

I think this should be good to merge now.

🚀

@Crabcyborg Crabcyborg merged commit 2b31c54 into master Oct 3, 2025
15 of 16 checks passed
@Crabcyborg Crabcyborg deleted the rock-email-gathering-modal branch October 3, 2025 18:58
@coderabbitai coderabbitai Bot mentioned this pull request Oct 16, 2025
stephywells pushed a commit that referenced this pull request Apr 4, 2026
Rock: Email Gathering Modal - Form Templates
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants