From 53f3380960e9cb30eb3cf27651f89f90d5ad29b0 Mon Sep 17 00:00:00 2001 From: "vivi-the-going-merry[bot]" <308115520+vivi-the-going-merry[bot]@users.noreply.github.com> Date: Tue, 20 Oct 2026 20:26:05 -0600 Subject: [PATCH 1/2] Add failing tests for create-form defaults (antispam, email action) Co-Authored-By: Claude Sonnet 5.5 --- .../test_FrmAbilitiesFormsController.php | 76 +++++++++++++++++++ 1 file changed, 76 insertions(+) diff --git a/tests/phpunit/forms/test_FrmAbilitiesFormsController.php b/tests/phpunit/forms/test_FrmAbilitiesFormsController.php index a9af8ec87d..79486658cd 100644 --- a/tests/phpunit/forms/test_FrmAbilitiesFormsController.php +++ b/tests/phpunit/forms/test_FrmAbilitiesFormsController.php @@ -174,6 +174,82 @@ public function test_create_form_applies_submitted_options() { $this->assertSame( 'Send it', $form->options['submit_value'] ?? null, 'A submitted option should be applied, not dropped to its default.' ); } + /** + * The builder turns anti-spam on and adds the default email action to every + * new form, so a form made through the ability has to match. + * + * @return void + */ + public function test_create_form_defaults_to_antispam_and_one_email_action() { + $created = $this->execute( 'create-form', array( 'name' => 'Form With Defaults' ) ); + + $this->assertNotWPError( $created ); + + $form = FrmForm::getOne( $created['id'] ); + $this->assertSame( 1, (int) ( $form->options['antispam'] ?? 0 ), 'Anti-spam should be on by default.' ); + $this->assertCount( 1, FrmFormAction::get_action_for_form( $created['id'], 'email' ), 'The default email action should be created.' ); + } + + /** + * @return void + */ + public function test_create_form_keeps_antispam_off_when_the_caller_turns_it_off() { + $created = $this->execute( + 'create-form', + array( + 'name' => 'Form Without Antispam', + 'options' => array( 'antispam' => 0 ), + ) + ); + + $this->assertNotWPError( $created ); + + $form = FrmForm::getOne( $created['id'] ); + $this->assertSame( 0, (int) ( $form->options['antispam'] ?? 1 ), 'An explicit antispam of 0 should be kept.' ); + } + + /** + * @return void + */ + public function test_create_form_skips_the_email_action_for_templates_and_child_forms() { + $template = $this->execute( + 'create-form', + array( + 'name' => 'Template Form', + 'is_template' => 1, + ) + ); + $this->assertNotWPError( $template ); + $this->assertCount( 0, FrmFormAction::get_action_for_form( $template['id'], 'email' ), 'A template should not get an email action.' ); + + $parent = $this->execute( 'create-form', array( 'name' => 'Parent Form' ) ); + $this->assertNotWPError( $parent ); + + $child = $this->execute( + 'create-form', + array( + 'name' => 'Child Form', + 'parent_form_id' => $parent['id'], + ) + ); + $this->assertNotWPError( $child ); + $this->assertCount( 0, FrmFormAction::get_action_for_form( $child['id'], 'email' ), 'A child form should not get an email action.' ); + } + + /** + * @return void + */ + public function test_create_form_respects_the_default_email_action_filter() { + add_filter( 'frm_create_default_email_action', '__return_false' ); + + $created = $this->execute( 'create-form', array( 'name' => 'Form With Filter' ) ); + + remove_filter( 'frm_create_default_email_action', '__return_false' ); + + $this->assertNotWPError( $created ); + $this->assertCount( 0, FrmFormAction::get_action_for_form( $created['id'], 'email' ), 'The filter should be able to stop the default email action.' ); + } + /** * A partial options update has to merge over what is stored, not replace * it outright, or every option left out of the request would reset to From 6f81b26a95d01578775cdf087949373073d94632 Mon Sep 17 00:00:00 2001 From: "vivi-the-going-merry[bot]" <308115520+vivi-the-going-merry[bot]@users.noreply.github.com> Date: Tue, 20 Oct 2026 20:30:08 -0600 Subject: [PATCH 2/2] Give create-form the builder's anti-spam and email action defaults Co-Authored-By: Claude Sonnet 5.5 --- classes/controllers/FrmAbilitiesFormsController.php | 12 ++++++++++++ classes/controllers/FrmFormsController.php | 3 ++- 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/classes/controllers/FrmAbilitiesFormsController.php b/classes/controllers/FrmAbilitiesFormsController.php index 3b71329268..254831084b 100644 --- a/classes/controllers/FrmAbilitiesFormsController.php +++ b/classes/controllers/FrmAbilitiesFormsController.php @@ -567,6 +567,13 @@ public static function execute_create_form( $input ) { $form['options'] = array_merge( $stored, self::sanitize_option_values( $input['options'] ) ); } + if ( ! isset( $input['options']['antispam'] ) ) { + // The builder turns anti-spam on for every new form, while the plain + // default is off. Only a caller who sets it explicitly keeps it off. + $form['options'] = isset( $form['options'] ) && is_array( $form['options'] ) ? $form['options'] : array(); + $form['options']['antispam'] = 1; + } + if ( empty( $input['form_key'] ) && ! empty( $input['name'] ) ) { // The builder derives the form key from the form name whenever the // name is set, in FrmFormsController::update_form_name(). It cannot @@ -586,6 +593,11 @@ public static function execute_create_form( $input ) { $new_form = FrmForm::getOne( $form_id ); + if ( empty( $input['is_template'] ) && empty( $input['parent_form_id'] ) ) { + // Same default notification the builder adds to a new form. + FrmFormsController::create_default_email_action( $new_form ); + } + if ( ! empty( $input['fields'] ) && is_array( $input['fields'] ) ) { foreach ( $input['fields'] as $field ) { // Share create-field's pipeline so inline fields get the same diff --git a/classes/controllers/FrmFormsController.php b/classes/controllers/FrmFormsController.php index 409e9da615..058048ef25 100644 --- a/classes/controllers/FrmFormsController.php +++ b/classes/controllers/FrmFormsController.php @@ -120,12 +120,13 @@ public static function list_form() { * Create the default email action * * @since 2.02.11 + * @since x.x Changed from private to public. * * @param int|object $form * * @return void */ - private static function create_default_email_action( $form ) { + public static function create_default_email_action( $form ) { FrmForm::maybe_get_form( $form ); if ( ! is_object( $form ) ) {