From 31fb4973160e8d3cbcac8785a63c0c8074477aaa Mon Sep 17 00:00:00 2001 From: Mike Letellier Date: Thu, 18 Jun 2026 10:44:00 -0300 Subject: [PATCH 1/4] Fix PayPal commerce test mode checkbox not working when paypal addon is active --- paypal/controllers/FrmPayPalLiteHooksController.php | 5 +++++ paypal/models/FrmPayPalLiteSettings.php | 11 ++++++++--- paypal/views/settings/connect-settings-container.php | 1 + 3 files changed, 14 insertions(+), 3 deletions(-) diff --git a/paypal/controllers/FrmPayPalLiteHooksController.php b/paypal/controllers/FrmPayPalLiteHooksController.php index eb93d7804d..b5acbc7680 100644 --- a/paypal/controllers/FrmPayPalLiteHooksController.php +++ b/paypal/controllers/FrmPayPalLiteHooksController.php @@ -32,6 +32,11 @@ public static function load_admin_hooks() { // These are called explicitly below the Lite PayPal settings. add_filter( 'frm_add_settings_section', 'FrmPayPalLiteSettingsController::add_settings_section', 99 ); add_action( 'frm_update_settings', 'FrmPayPalLiteSettingsController::process_form' ); + // Hook with high priority to sync test_mode after add-on saves + add_action( 'frm_update_settings', 'FrmPayPalLiteSettingsController::sync_test_mode_after_addon', 999 ); + + // Hook into update_option to preserve test_mode when add-on saves + add_action( 'update_option_frm_paypal_options', 'FrmPayPalLiteSettingsController::preserve_test_mode_on_update', 10, 2 ); add_filter( 'frm_before_save_payment_action', 'FrmPayPalLiteActionsController::before_save_settings', 20, 2 ); diff --git a/paypal/models/FrmPayPalLiteSettings.php b/paypal/models/FrmPayPalLiteSettings.php index 3f90e5c70b..0470bee573 100644 --- a/paypal/models/FrmPayPalLiteSettings.php +++ b/paypal/models/FrmPayPalLiteSettings.php @@ -65,6 +65,8 @@ public function set_default_options( $settings = false ) { public function get_options() { $settings = get_option( 'frm_' . $this->param() . '_options' ); + error_log( 'PayPal Lite get_options: raw settings = ' . print_r( $settings, true ) ); + if ( is_object( $settings ) ) { $this->set_default_options( $settings ); } elseif ( $settings ) { @@ -75,6 +77,8 @@ public function get_options() { $this->store(); } + error_log( 'PayPal Lite get_options: final test_mode = ' . $this->settings->test_mode ); + return $this->settings; } @@ -85,14 +89,15 @@ public function get_options() { */ public function update( $params ) { $settings = $this->default_options(); + $param = $this->param(); foreach ( $settings as $setting => $default ) { - if ( isset( $params[ 'frm_' . $this->param() . '_' . $setting ] ) ) { - $this->settings->{$setting} = sanitize_text_field( $params[ 'frm_' . $this->param() . '_' . $setting ] ); + if ( isset( $params[ 'frm_' . $param . '_' . $setting ] ) ) { + $this->settings->{$setting} = sanitize_text_field( $params[ 'frm_' . $param . '_' . $setting ] ); } } - $this->settings->test_mode = isset( $params[ 'frm_' . $this->param() . '_test_mode' ] ) ? absint( $params[ 'frm_' . $this->param() . '_test_mode' ] ) : 0; + $this->settings->test_mode = isset( $params[ 'frm_' . $param . '_test_mode' ] ) ? absint( $params[ 'frm_' . $param . '_test_mode' ] ) : 0; } /** diff --git a/paypal/views/settings/connect-settings-container.php b/paypal/views/settings/connect-settings-container.php index 2aade855bc..b6ff1ae6fa 100644 --- a/paypal/views/settings/connect-settings-container.php +++ b/paypal/views/settings/connect-settings-container.php @@ -11,6 +11,7 @@ From 591354baa2387e9b7009f0d3e0f129c5682fb6df Mon Sep 17 00:00:00 2001 From: Mike Letellier Date: Thu, 18 Jun 2026 10:45:42 -0300 Subject: [PATCH 2/4] Fix PayPal commerce test mode checkbox not working when paypal addon is active --- .../FrmPayPalLiteSettingsController.php | 48 +++++++++++++++++++ paypal/models/FrmPayPalLiteSettings.php | 4 -- 2 files changed, 48 insertions(+), 4 deletions(-) diff --git a/paypal/controllers/FrmPayPalLiteSettingsController.php b/paypal/controllers/FrmPayPalLiteSettingsController.php index 16e5501e15..2c02dca4ea 100644 --- a/paypal/controllers/FrmPayPalLiteSettingsController.php +++ b/paypal/controllers/FrmPayPalLiteSettingsController.php @@ -55,4 +55,52 @@ public static function process_form() { $settings->update( $_POST ); $settings->store(); } + + /** + * Sync test_mode after PayPal add-on saves its settings. + * This runs with high priority to ensure it runs after the add-on's process_form. + * + * @param array $params + * + * @return void + */ + public static function sync_test_mode_after_addon( $params ) { + // phpcs:ignore WordPress.Security.NonceVerification.Missing + if ( ! isset( $_POST['frm_paypal_test_mode'] ) ) { + return; + } + + $test_mode = absint( $_POST['frm_paypal_test_mode'] ); + $options = get_option( 'frm_paypal_options' ); + + if ( ! is_object( $options ) ) { + $options = new stdClass(); + } + + // Preserve test_mode which the add-on's update() method doesn't handle + $options->test_mode = $test_mode; + update_option( 'frm_paypal_options', $options ); + } + + /** + * Preserve test_mode when the PayPal add-on updates frm_paypal_options. + * This hooks into update_option to ensure test_mode isn't lost. + * + * @param mixed $old_value The old option value. + * @param mixed $new_value The new option value. + * + * @return void + */ + public static function preserve_test_mode_on_update( $old_value, $new_value ) { + if ( ! is_object( $old_value ) || ! is_object( $new_value ) ) { + return; + } + + // If old value had test_mode but new value doesn't, preserve it + if ( isset( $old_value->test_mode ) && ! isset( $new_value->test_mode ) ) { + $new_value->test_mode = $old_value->test_mode; + // Update the option with the preserved test_mode + update_option( 'frm_paypal_options', $new_value ); + } + } } diff --git a/paypal/models/FrmPayPalLiteSettings.php b/paypal/models/FrmPayPalLiteSettings.php index 0470bee573..975ccec58b 100644 --- a/paypal/models/FrmPayPalLiteSettings.php +++ b/paypal/models/FrmPayPalLiteSettings.php @@ -65,8 +65,6 @@ public function set_default_options( $settings = false ) { public function get_options() { $settings = get_option( 'frm_' . $this->param() . '_options' ); - error_log( 'PayPal Lite get_options: raw settings = ' . print_r( $settings, true ) ); - if ( is_object( $settings ) ) { $this->set_default_options( $settings ); } elseif ( $settings ) { @@ -77,8 +75,6 @@ public function get_options() { $this->store(); } - error_log( 'PayPal Lite get_options: final test_mode = ' . $this->settings->test_mode ); - return $this->settings; } From 83a81ca52c4ba0347c2a68838dc620a11188d3c4 Mon Sep 17 00:00:00 2001 From: Mike Letellier Date: Thu, 18 Jun 2026 10:48:20 -0300 Subject: [PATCH 3/4] Clean up --- .../FrmPayPalLiteHooksController.php | 2 -- .../FrmPayPalLiteSettingsController.php | 26 ------------------- 2 files changed, 28 deletions(-) diff --git a/paypal/controllers/FrmPayPalLiteHooksController.php b/paypal/controllers/FrmPayPalLiteHooksController.php index b5acbc7680..706ba0d58e 100644 --- a/paypal/controllers/FrmPayPalLiteHooksController.php +++ b/paypal/controllers/FrmPayPalLiteHooksController.php @@ -32,8 +32,6 @@ public static function load_admin_hooks() { // These are called explicitly below the Lite PayPal settings. add_filter( 'frm_add_settings_section', 'FrmPayPalLiteSettingsController::add_settings_section', 99 ); add_action( 'frm_update_settings', 'FrmPayPalLiteSettingsController::process_form' ); - // Hook with high priority to sync test_mode after add-on saves - add_action( 'frm_update_settings', 'FrmPayPalLiteSettingsController::sync_test_mode_after_addon', 999 ); // Hook into update_option to preserve test_mode when add-on saves add_action( 'update_option_frm_paypal_options', 'FrmPayPalLiteSettingsController::preserve_test_mode_on_update', 10, 2 ); diff --git a/paypal/controllers/FrmPayPalLiteSettingsController.php b/paypal/controllers/FrmPayPalLiteSettingsController.php index 2c02dca4ea..10c8a8fe1f 100644 --- a/paypal/controllers/FrmPayPalLiteSettingsController.php +++ b/paypal/controllers/FrmPayPalLiteSettingsController.php @@ -56,32 +56,6 @@ public static function process_form() { $settings->store(); } - /** - * Sync test_mode after PayPal add-on saves its settings. - * This runs with high priority to ensure it runs after the add-on's process_form. - * - * @param array $params - * - * @return void - */ - public static function sync_test_mode_after_addon( $params ) { - // phpcs:ignore WordPress.Security.NonceVerification.Missing - if ( ! isset( $_POST['frm_paypal_test_mode'] ) ) { - return; - } - - $test_mode = absint( $_POST['frm_paypal_test_mode'] ); - $options = get_option( 'frm_paypal_options' ); - - if ( ! is_object( $options ) ) { - $options = new stdClass(); - } - - // Preserve test_mode which the add-on's update() method doesn't handle - $options->test_mode = $test_mode; - update_option( 'frm_paypal_options', $options ); - } - /** * Preserve test_mode when the PayPal add-on updates frm_paypal_options. * This hooks into update_option to ensure test_mode isn't lost. From a8c7af5d6697ef70112d41d199e260cfcb4ac607 Mon Sep 17 00:00:00 2001 From: Mike Letellier Date: Thu, 18 Jun 2026 10:51:44 -0300 Subject: [PATCH 4/4] Use early exit (phpcbf --- paypal/controllers/FrmPayPalLiteSettingsController.php | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/paypal/controllers/FrmPayPalLiteSettingsController.php b/paypal/controllers/FrmPayPalLiteSettingsController.php index 10c8a8fe1f..2cd7fab05d 100644 --- a/paypal/controllers/FrmPayPalLiteSettingsController.php +++ b/paypal/controllers/FrmPayPalLiteSettingsController.php @@ -71,10 +71,12 @@ public static function preserve_test_mode_on_update( $old_value, $new_value ) { } // If old value had test_mode but new value doesn't, preserve it - if ( isset( $old_value->test_mode ) && ! isset( $new_value->test_mode ) ) { - $new_value->test_mode = $old_value->test_mode; - // Update the option with the preserved test_mode - update_option( 'frm_paypal_options', $new_value ); + if ( ! isset( $old_value->test_mode ) || isset( $new_value->test_mode ) ) { + return; } + + $new_value->test_mode = $old_value->test_mode; + // Update the option with the preserved test_mode + update_option( 'frm_paypal_options', $new_value ); } }