From bf19f2eea2f16283d8924221bafbbc466b16b9a1 Mon Sep 17 00:00:00 2001 From: Mike Letellier Date: Tue, 7 Jan 2025 13:33:32 -0400 Subject: [PATCH 01/31] New sales API (first commit_ --- classes/helpers/FrmAppHelper.php | 14 +- classes/models/FrmSalesAPI.php | 271 +++++++++++++++++++++++++++++++ 2 files changed, 283 insertions(+), 2 deletions(-) create mode 100644 classes/models/FrmSalesAPI.php diff --git a/classes/helpers/FrmAppHelper.php b/classes/helpers/FrmAppHelper.php index c33f35e351..4b9d2a283a 100644 --- a/classes/helpers/FrmAppHelper.php +++ b/classes/helpers/FrmAppHelper.php @@ -1370,6 +1370,15 @@ public static function print_admin_banner( $should_show_lite_upgrade ) { ?>
get_best_sale(); + + if ( is_array( $sale ) && ! empty( $sale['lite_banner_cta_text'] ) ) { + $cta_text = $sale['lite_banner_cta_text']; + } else { + $cta_text = __( 'upgrading to PRO', 'formidable' ); + } + $upgrade_link = self::admin_upgrade_link( array( 'medium' => 'settings-license', @@ -1377,9 +1386,10 @@ public static function print_admin_banner( $should_show_lite_upgrade ) { ) ); printf( - /* translators: %1$s: Start link HTML, %2$s: End link HTML */ - esc_html__( 'You\'re using Formidable Forms Lite. To unlock more features consider %1$supgrading to PRO%2$s.', 'formidable' ), + /* translators: %1$s: Start link HTML, %2$s: CTA text ("upgrading to PRO" by default), %3$s: End link HTML */ + esc_html__( 'You\'re using Formidable Forms Lite. To unlock more features consider %1$s%2$s%3$s.', 'formidable' ), '', + esc_html( $cta_text ), '' ); ?> diff --git a/classes/models/FrmSalesAPI.php b/classes/models/FrmSalesAPI.php new file mode 100644 index 0000000000..4a304b2a2f --- /dev/null +++ b/classes/models/FrmSalesAPI.php @@ -0,0 +1,271 @@ +set_cache_key(); + + if ( false === self::$sales ) { + $this->set_sales(); + } + } + + /** + * @since x.x + * + * @return void + */ + protected function set_cache_key() { + $this->cache_key = 'frm_sales_cache'; + } + + /** + * @since x.x + * + * @return string + */ + protected function api_url() { + return 'http://dev-site.local/wp-json/s11-sales/v1/list/'; +// return 'https://formidableforms.com/wp-json/s11-sales/v1/list/'; + } + + /** + * @since x.x + * + * @return array + */ + public function get_sales( ) { + return self::$sales; + } + + /** + * @since x.x + * + * @return void + */ + public function set_sales() { + self::$sales = array(); + + $api = $this->get_api_info(); + if ( empty( $api ) ) { + return; + } + + foreach ( $api as $sale ) { + $this->add_sale( $sale ); + } + } + + /** + * @param array|string $sale + * + * @return void + */ + public function add_sale( $sale ) { + if ( ! is_array( $sale ) || ! isset( $sale['key'] ) ) { + // if the API response is invalid, $sale may not be an array. + // if there are no sales from the API, it is returning a "No Entries Found" item with no key, so check for a key as well. + return; + } + + if ( $this->is_expired( $sale ) ) { + return; + } + + if ( isset( self::$sales[ $sale['key'] ] ) ) { + // Move up and mark as new. + unset( self::$sales[ $sale['key'] ] ); + } + + self::$sales[ $sale['key'] ] = $this->fill_sale( $sale ); + } + + /** + * @param array $sale + * @return array + */ + private function fill_sale( $sale ) { + $defaults = array( + 'key' => '', + 'starts' => '', + 'expires' => '', + // Use 'free', 'personal', 'business', 'elite', 'grandfathered'. + 'who' => 'all', + 'discount_percent' => 0, + 'test_group' => '', + 'lite_banner_cta_link' => '', + 'lite_banner_cta_text' => '', + 'menu_cta_link' => '', + 'menu_cta_text' => '', + 'dashboard_license_cta_link' => '', + 'dashboard_license_cta_text' => '', + 'global_settings_license_cta_link' => '', + 'global_settings_license_cta_text' => '', + 'global_settings_unlock_more_cta_link' => '', + 'global_settings_unlock_more_cta_text' => '', + 'global_settings_upgrade_cta_link' => '', + 'builder_sidebar_cta_link' => '', + 'builder_sidebar_cta_text' => '', + ); + + return array_merge( $defaults, $sale ); + } + + /** + * @param array $sale + * + * @return bool + */ + private function is_expired( $sale ) { + return $sale['expires'] < time(); + } + + /** + * Show different sales for different accounts. + * + * @param array $sale + * @return bool + */ + private function is_for_user( $sale ) { + if ( ! isset( $sale['who'] ) || $sale['who'] === 'all' ) { + return true; + } + $who = (array) $sale['who']; + if ( $this->is_for_everyone( $who ) ) { + return true; + } + if ( $this->is_user_type( $who ) ) { + return true; + } + if ( in_array( 'free_first_30', $who, true ) && $this->is_free_first_30() ) { + return true; + } + if ( in_array( 'free_not_first_30', $who, true ) && $this->is_free_not_first_30() ) { + return true; + } + return false; + } + + /** + * @since x.x + * + * @param array $who + * @return bool + */ + private function is_for_everyone( $who ) { + return in_array( 'all', $who, true ); + } + + /** + * @since x.x + * + * @param array $who + * @return bool + */ + private function is_user_type( $who ) { + return in_array( $this->get_user_type(), $who, true ); + } + + private function get_user_type() { + if ( ! FrmAppHelper::pro_is_installed() ) { + return 'free'; + } + + return FrmAddonsController::license_type(); + } + + /** + * Check if user is still using the Lite version only, and within + * the first 30 days of activation. + * + * @since x.x + * + * @return bool + */ + private function is_free_first_30() { + return $this->is_free() && $this->is_first_30(); + } + + /** + * @since x.x + * + * @return bool + */ + private function is_first_30() { + $activation_timestamp = get_option( 'frm_first_activation' ); + if ( false === $activation_timestamp ) { + // If the option does not exist, assume that it is + // because the user was active before this option was introduced. + return false; + } + $cutoff = strtotime( '-30 days' ); + return $activation_timestamp > $cutoff; + } + + /** + * @since x.x + * + * @return bool + */ + private function is_free_not_first_30() { + return $this->is_free() && ! $this->is_first_30(); + } + + /** + * Check if the Pro plugin is active. If not, consider the user to be on the free version. + * + * @since x.x + * + * @return bool + */ + private function is_free() { + return ! FrmAppHelper::pro_is_included(); + } + + /** + * @since x.x + * + * @return array|false + */ + public function get_best_sale() { + if ( ! self::$sales ) { + return false; + } + + $best_sale = false; + foreach ( self::$sales as $sale ) { + if ( ! $this->is_for_user( $sale ) ) { + continue; + } + + if ( ! $best_sale || $sale['discount_percent'] > $best_sale['discount_percent'] ) { + $best_sale = $sale; + } + } + + return $best_sale; + } + + /** + * This is just here for testing so skip the API. + * Remove this before launching (and inherit from the base class instead). + * + * @return array + */ + public function get_api_info() { + return json_decode( + '[{"key":"no-brainer","starts":1735689600,"expires":1738281600,"who":["all"],"discount_percent":50,"test_group":1,"lite_banner_cta_link":"https://formidableforms.com/cta1","lite_banner_cta_text":"Lite Banner Text","menu_cta_link":"https://formidableforms.com/cta2","menu_cta_text":"Menu Text","dashboard_license_cta_link":"https://formidableforms.com/cta3","dashboard_license_cta_text":"Dashboard License Text","global_settings_license_cta_link":"https://formidableforms.com/cta4","global_settings_license_cta_text":"License Text","global_settings_unlock_more_cta_link":"https://formidableforms.com/cta5","global_settings_unlock_more_cta_text":"Unlock More Text","global_settings_upgrade_cta_link":"https://formidableforms.com/cta6","builder_sidebar_cta_link":"https://formidableforms.com/cta7","builder_sidebar_cta_text":"Form Builder Text"},{"key":"anniversary","starts":1735689600,"expires":1738281600,"who":["all"],"discount_percent":60,"test_group":2,"lite_banner_cta_link":"https://formidableforms.com/cta1","lite_banner_cta_text":"Lite Banner Text","menu_cta_link":"https://formidableforms.com/cta2","menu_cta_text":"Menu Text","dashboard_license_cta_link":"https://formidableforms.com/cta3","dashboard_license_cta_text":"Dashboard License Text","global_settings_license_cta_link":"https://formidableforms.com/cta4","global_settings_license_cta_text":"License Text","global_settings_unlock_more_cta_link":"https://formidableforms.com/cta5","global_settings_unlock_more_cta_text":"Unlock More Text","global_settings_upgrade_cta_link":"https://formidableforms.com/cta6","builder_sidebar_cta_link":"https://formidableforms.com/cta7","builder_sidebar_cta_text":"Form Builder Text"}]', + true + ); + } +} From 295abc4910f58bf9c8bc936270920f8c19885be7 Mon Sep 17 00:00:00 2001 From: Mike Letellier Date: Tue, 7 Jan 2025 13:41:22 -0400 Subject: [PATCH 02/31] Add a new helper function to reduce code --- classes/models/FrmSalesAPI.php | 35 ++++++++++++++++++++-------------- 1 file changed, 21 insertions(+), 14 deletions(-) diff --git a/classes/models/FrmSalesAPI.php b/classes/models/FrmSalesAPI.php index 4a304b2a2f..7b123e978b 100644 --- a/classes/models/FrmSalesAPI.php +++ b/classes/models/FrmSalesAPI.php @@ -10,8 +10,20 @@ class FrmSalesAPI extends FrmFormApi { protected $cache_key; + /** + * All sales from API data. + * + * @var array|false + */ private static $sales = false; + /** + * Best sale from API data. + * + * @var array|false|null + */ + private static $best_sale; + public function __construct( $for_parent = null ) { $this->set_cache_key(); @@ -35,17 +47,7 @@ protected function set_cache_key() { * @return string */ protected function api_url() { - return 'http://dev-site.local/wp-json/s11-sales/v1/list/'; -// return 'https://formidableforms.com/wp-json/s11-sales/v1/list/'; - } - - /** - * @since x.x - * - * @return array - */ - public function get_sales( ) { - return self::$sales; + return 'https://formidableforms.com/wp-json/s11-sales/v1/list/'; } /** @@ -53,7 +55,7 @@ public function get_sales( ) { * * @return void */ - public function set_sales() { + private function set_sales() { self::$sales = array(); $api = $this->get_api_info(); @@ -71,7 +73,7 @@ public function set_sales() { * * @return void */ - public function add_sale( $sale ) { + private function add_sale( $sale ) { if ( ! is_array( $sale ) || ! isset( $sale['key'] ) ) { // if the API response is invalid, $sale may not be an array. // if there are no sales from the API, it is returning a "No Entries Found" item with no key, so check for a key as well. @@ -242,6 +244,10 @@ public function get_best_sale() { return false; } + if ( isset( self::$best_sale ) ) { + return self::$best_sale; + } + $best_sale = false; foreach ( self::$sales as $sale ) { if ( ! $this->is_for_user( $sale ) ) { @@ -253,7 +259,8 @@ public function get_best_sale() { } } - return $best_sale; + self::$best_sale = $best_sale; + return self::$best_sale; } /** From 60996bf36b77e502036bfd8b6ddcedc914b598bc Mon Sep 17 00:00:00 2001 From: Mike Letellier Date: Tue, 7 Jan 2025 13:43:32 -0400 Subject: [PATCH 03/31] Add a new helper function to reduce code --- classes/helpers/FrmAppHelper.php | 8 ++------ classes/models/FrmSalesAPI.php | 14 ++++++++++++++ 2 files changed, 16 insertions(+), 6 deletions(-) diff --git a/classes/helpers/FrmAppHelper.php b/classes/helpers/FrmAppHelper.php index 4b9d2a283a..a159da82bc 100644 --- a/classes/helpers/FrmAppHelper.php +++ b/classes/helpers/FrmAppHelper.php @@ -1370,12 +1370,8 @@ public static function print_admin_banner( $should_show_lite_upgrade ) { ?>
get_best_sale(); - - if ( is_array( $sale ) && ! empty( $sale['lite_banner_cta_text'] ) ) { - $cta_text = $sale['lite_banner_cta_text']; - } else { + $cta_text = FrmSalesApi::get_best_sale_text( 'lite_banner_cta_text' ); + if ( ! $cta_text ) { $cta_text = __( 'upgrading to PRO', 'formidable' ); } diff --git a/classes/models/FrmSalesAPI.php b/classes/models/FrmSalesAPI.php index 7b123e978b..58b56744d7 100644 --- a/classes/models/FrmSalesAPI.php +++ b/classes/models/FrmSalesAPI.php @@ -275,4 +275,18 @@ public function get_api_info() { true ); } + + /** + * Get text for best sale if applicable. + * + * @since x.x + * + * @param string $key + * @return string|false False if no sale is active. + */ + public static function get_best_sale_text( $key ) { + $api = new FrmSalesAPI(); + $sale = $api->get_best_sale(); + return is_array( $sale ) && ! empty( $sale[ $key ] ) ? $sale[ $key ] : false; + } } From 0f2fd41dec03a27a8bc6eb1f2b7c15321a788a66 Mon Sep 17 00:00:00 2001 From: Mike Letellier Date: Tue, 7 Jan 2025 13:50:15 -0400 Subject: [PATCH 04/31] Optimize, update function --- classes/helpers/FrmAppHelper.php | 18 +++++++++++------- classes/models/FrmSalesAPI.php | 14 +++++++++++--- 2 files changed, 22 insertions(+), 10 deletions(-) diff --git a/classes/helpers/FrmAppHelper.php b/classes/helpers/FrmAppHelper.php index a159da82bc..23e53bf35a 100644 --- a/classes/helpers/FrmAppHelper.php +++ b/classes/helpers/FrmAppHelper.php @@ -1370,17 +1370,21 @@ public static function print_admin_banner( $should_show_lite_upgrade ) { ?>
'settings-license', - 'content' => 'lite-banner', - ) - ); + $upgrade_link = FrmSalesApi::get_best_sale_value( 'lite_banner_cta_link' ); + if ( ! $upgrade_link ) { + $upgrade_link = self::admin_upgrade_link( + array( + 'medium' => 'settings-license', + 'content' => 'lite-banner', + ) + ); + } + printf( /* translators: %1$s: Start link HTML, %2$s: CTA text ("upgrading to PRO" by default), %3$s: End link HTML */ esc_html__( 'You\'re using Formidable Forms Lite. To unlock more features consider %1$s%2$s%3$s.', 'formidable' ), diff --git a/classes/models/FrmSalesAPI.php b/classes/models/FrmSalesAPI.php index 58b56744d7..8b3e657543 100644 --- a/classes/models/FrmSalesAPI.php +++ b/classes/models/FrmSalesAPI.php @@ -8,6 +8,11 @@ */ class FrmSalesAPI extends FrmFormApi { + /** + * @var FrmSalesAPI|null + */ + private static $instance; + protected $cache_key; /** @@ -284,9 +289,12 @@ public function get_api_info() { * @param string $key * @return string|false False if no sale is active. */ - public static function get_best_sale_text( $key ) { - $api = new FrmSalesAPI(); - $sale = $api->get_best_sale(); + public static function get_best_sale_value( $key ) { + if ( ! isset( self::$instance ) ) { + self::$instance = new FrmSalesAPI(); + } + + $sale = self::$instance->get_best_sale(); return is_array( $sale ) && ! empty( $sale[ $key ] ) ? $sale[ $key ] : false; } } From faebd90f23ebc39af71563bb6da8e73aebef23d0 Mon Sep 17 00:00:00 2001 From: Mike Letellier Date: Tue, 7 Jan 2025 15:11:05 -0400 Subject: [PATCH 05/31] Add footer CTA to API --- classes/models/FrmSalesAPI.php | 2 +- classes/views/shared/admin-footer-links.php | 15 ++++++++++++--- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/classes/models/FrmSalesAPI.php b/classes/models/FrmSalesAPI.php index 8b3e657543..20cc574cb6 100644 --- a/classes/models/FrmSalesAPI.php +++ b/classes/models/FrmSalesAPI.php @@ -276,7 +276,7 @@ public function get_best_sale() { */ public function get_api_info() { return json_decode( - '[{"key":"no-brainer","starts":1735689600,"expires":1738281600,"who":["all"],"discount_percent":50,"test_group":1,"lite_banner_cta_link":"https://formidableforms.com/cta1","lite_banner_cta_text":"Lite Banner Text","menu_cta_link":"https://formidableforms.com/cta2","menu_cta_text":"Menu Text","dashboard_license_cta_link":"https://formidableforms.com/cta3","dashboard_license_cta_text":"Dashboard License Text","global_settings_license_cta_link":"https://formidableforms.com/cta4","global_settings_license_cta_text":"License Text","global_settings_unlock_more_cta_link":"https://formidableforms.com/cta5","global_settings_unlock_more_cta_text":"Unlock More Text","global_settings_upgrade_cta_link":"https://formidableforms.com/cta6","builder_sidebar_cta_link":"https://formidableforms.com/cta7","builder_sidebar_cta_text":"Form Builder Text"},{"key":"anniversary","starts":1735689600,"expires":1738281600,"who":["all"],"discount_percent":60,"test_group":2,"lite_banner_cta_link":"https://formidableforms.com/cta1","lite_banner_cta_text":"Lite Banner Text","menu_cta_link":"https://formidableforms.com/cta2","menu_cta_text":"Menu Text","dashboard_license_cta_link":"https://formidableforms.com/cta3","dashboard_license_cta_text":"Dashboard License Text","global_settings_license_cta_link":"https://formidableforms.com/cta4","global_settings_license_cta_text":"License Text","global_settings_unlock_more_cta_link":"https://formidableforms.com/cta5","global_settings_unlock_more_cta_text":"Unlock More Text","global_settings_upgrade_cta_link":"https://formidableforms.com/cta6","builder_sidebar_cta_link":"https://formidableforms.com/cta7","builder_sidebar_cta_text":"Form Builder Text"}]', + '[{"key":"no-brainer","starts":1735689600,"expires":1738281600,"who":["all"],"discount_percent":50,"test_group":"Group One","lite_banner_cta_link":"https://formidableforms.com/cta1","lite_banner_cta_text":"Lite Banner Text","menu_cta_link":"https://formidableforms.com/cta2","menu_cta_text":"Menu Text","dashboard_license_cta_link":"https://formidableforms.com/cta3","dashboard_license_cta_text":"Dashboard License Text","global_settings_license_cta_link":"https://formidableforms.com/cta4","global_settings_license_cta_text":"License Text","global_settings_unlock_more_cta_link":"https://formidableforms.com/cta5","global_settings_unlock_more_cta_text":"Unlock More Text","global_settings_upgrade_cta_link":"https://formidableforms.com/cta6","builder_sidebar_cta_link":"https://formidableforms.com/cta7","builder_sidebar_cta_text":"Form Builder Text","footer_cta_link":"https://formidableforms.com/cta8","footer_cta_text":"Footer Text"},{"key":"anniversary","starts":1735689600,"expires":1738281600,"who":["all"],"discount_percent":60,"test_group":"Group One","lite_banner_cta_link":"https://formidableforms.com/cta1","lite_banner_cta_text":"Lite Banner Text","menu_cta_link":"https://formidableforms.com/cta2","menu_cta_text":"Menu Text","dashboard_license_cta_link":"https://formidableforms.com/cta3","dashboard_license_cta_text":"Dashboard License Text","global_settings_license_cta_link":"https://formidableforms.com/cta4","global_settings_license_cta_text":"License Text","global_settings_unlock_more_cta_link":"https://formidableforms.com/cta5","global_settings_unlock_more_cta_text":"Unlock More Text","global_settings_upgrade_cta_link":"https://formidableforms.com/cta6","builder_sidebar_cta_link":"https://formidableforms.com/cta7","builder_sidebar_cta_text":"Form Builder Text","footer_cta_link":"https://formidableforms.com/cta8","footer_cta_text":"Footer Text"}]', true ); } diff --git a/classes/views/shared/admin-footer-links.php b/classes/views/shared/admin-footer-links.php index 81023ee028..e9732501ea 100644 --- a/classes/views/shared/admin-footer-links.php +++ b/classes/views/shared/admin-footer-links.php @@ -6,8 +6,11 @@ // Determine the support link based on lite vs pro. $support_link = ! FrmAppHelper::pro_is_installed() ? 'https://wordpress.org/support/plugin/formidable/' : 'https://formidableforms.com/new-topic/'; -// Determine the upgrade link based on lite vs pro. -$upgrade_link = ! FrmAppHelper::pro_is_installed() ? 'https://formidableforms.com/lite-upgrade/' : 'https://formidableforms.com/account/downloads/'; +$upgrade_link = FrmSalesAPI::get_best_sale_value( 'footer_cta_link' ); +if ( ! $upgrade_link ) { + // Determine the upgrade link based on lite vs pro. + $upgrade_link = ! FrmAppHelper::pro_is_installed() ? 'https://formidableforms.com/lite-upgrade/' : 'https://formidableforms.com/account/downloads/'; +} ?> From aa766ed6bb71cf8fdd2dcc05c7688248bff3ef11 Mon Sep 17 00:00:00 2001 From: Mike Letellier Date: Tue, 7 Jan 2025 15:14:45 -0400 Subject: [PATCH 06/31] Replace the menu link/text --- classes/controllers/FrmAddonsController.php | 7 ++++++- classes/controllers/FrmAppController.php | 11 +++++++---- 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/classes/controllers/FrmAddonsController.php b/classes/controllers/FrmAddonsController.php index b0d90d1b37..d26b3ba6e8 100644 --- a/classes/controllers/FrmAddonsController.php +++ b/classes/controllers/FrmAddonsController.php @@ -105,10 +105,15 @@ public static function menu() { remove_submenu_page( 'formidable', 'formidable' ); if ( ! FrmAppHelper::pro_is_installed() ) { + $cta_text = FrmSalesAPI::get_best_sale_value( 'menu_cta_text' ); + if ( ! $cta_text ) { + $cta_text = __( 'Upgrade', 'formidable' ); + } + add_submenu_page( 'formidable', 'Formidable | ' . __( 'Upgrade', 'formidable' ), - '' . __( 'Upgrade', 'formidable' ) . '', + '' . esc_html( $cta_text ) . '', 'frm_view_forms', 'formidable-pro-upgrade', function () { diff --git a/classes/controllers/FrmAppController.php b/classes/controllers/FrmAppController.php index 977dc81ad3..13f18f73b1 100644 --- a/classes/controllers/FrmAppController.php +++ b/classes/controllers/FrmAppController.php @@ -557,14 +557,17 @@ public static function admin_init() { } if ( 'formidable-pro-upgrade' === FrmAppHelper::get_param( 'page' ) && ! FrmAppHelper::pro_is_installed() && current_user_can( 'frm_view_forms' ) ) { - wp_redirect( - FrmAppHelper::admin_upgrade_link( + $redirect = FrmSalesAPI::get_best_sale_value( 'menu_cta_link' ); + if ( ! $redirect ) { + $redirct = FrmAppHelper::admin_upgrade_link( array( 'medium' => 'upgrade', 'content' => 'submenu-upgrade', ) - ) - ); + ); + } + + wp_redirect( $redirect ); die(); } From 3bde007fb22640502e57770ba6acdb47dd4f0c58 Mon Sep 17 00:00:00 2001 From: Mike Letellier Date: Tue, 7 Jan 2025 15:22:03 -0400 Subject: [PATCH 07/31] Also update the dashboard license box --- classes/controllers/FrmAddonsController.php | 2 +- classes/helpers/FrmDashboardHelper.php | 22 ++++++++++++++------- 2 files changed, 16 insertions(+), 8 deletions(-) diff --git a/classes/controllers/FrmAddonsController.php b/classes/controllers/FrmAddonsController.php index d26b3ba6e8..e200165396 100644 --- a/classes/controllers/FrmAddonsController.php +++ b/classes/controllers/FrmAddonsController.php @@ -97,7 +97,7 @@ public static function menu() { } $label = __( 'Add-Ons', 'formidable' ); - $label = '' . $label . ''; + $label = '' . esc_html( $label ) . ''; add_submenu_page( 'formidable', 'Formidable | ' . __( 'Add-Ons', 'formidable' ), $label, 'frm_view_forms', 'formidable-addons', 'FrmAddonsController::list_addons' ); diff --git a/classes/helpers/FrmDashboardHelper.php b/classes/helpers/FrmDashboardHelper.php index 2cbd0116e6..c28ea55c52 100644 --- a/classes/helpers/FrmDashboardHelper.php +++ b/classes/helpers/FrmDashboardHelper.php @@ -196,12 +196,20 @@ class="" * @return array */ public static function get_license_buttons() { - $upgrade_link = FrmAppHelper::admin_upgrade_link( - array( - 'medium' => 'settings-license', - 'content' => 'dashboard-license-box', - ) - ); + $cta_text = FrmSalesAPI::get_best_sale_value( 'dashboard_license_cta_text' ); + if ( ! $cta_text ) { + $cta_text = __( 'Get Formidable PRO', 'formidable' ); + } + + $upgrade_link = FrmSalesAPI::get_best_sale_value( 'dashboard_license_cta_link' ); + if ( ! $upgrade_link ) { + $upgrade_link = FrmAppHelper::admin_upgrade_link( + array( + 'medium' => 'settings-license', + 'content' => 'dashboard-license-box', + ) + ); + } return array( array( @@ -210,7 +218,7 @@ public static function get_license_buttons() { 'classes' => 'frm-button-primary frm-show-unauthorized', ), array( - 'label' => __( 'Get Formidable PRO', 'formidable' ), + 'label' => $cta_text, 'link' => $upgrade_link, 'classes' => 'frm-button-secondary frm-show-unauthorized', ), From 5985f4bda0db9fca6c8273387d8b4d7f4cd03a0a Mon Sep 17 00:00:00 2001 From: Mike Letellier Date: Tue, 7 Jan 2025 15:28:54 -0400 Subject: [PATCH 08/31] Update strings in the license box --- classes/views/frm-settings/license_box.php | 48 +++++++++++++++------- 1 file changed, 33 insertions(+), 15 deletions(-) diff --git a/classes/views/frm-settings/license_box.php b/classes/views/frm-settings/license_box.php index 1a3a516cad..2e107456d5 100644 --- a/classes/views/frm-settings/license_box.php +++ b/classes/views/frm-settings/license_box.php @@ -3,18 +3,35 @@ die( 'You are not allowed to call this page directly.' ); } -$button_upgrade_link = FrmAppHelper::admin_upgrade_link( - array( - 'medium' => 'settings-license', - 'content' => 'global-settings-license-box-get-formidable-button', - ) -); -$unlock_more_upgrade_link = FrmAppHelper::admin_upgrade_link( - array( - 'medium' => 'settings-license', - 'content' => 'global-settings-license-box-unlock-more', - ) -); +$button_upgrade_text = FrmSalesAPI::get_best_sale_value( 'global_settings_license_cta_text' ); +if ( ! $button_upgrade_text ) { + $button_upgrade_text = __( 'Get Formidable Now', 'formidable' ); +} + +$button_upgrade_link = FrmSalesAPI::get_best_sale_value( 'global_settings_license_cta_link' ); +if ( ! $button_upgrade_link ) { + $button_upgrade_link = FrmAppHelper::admin_upgrade_link( + array( + 'medium' => 'settings-license', + 'content' => 'global-settings-license-box-get-formidable-button', + ) + ); +} + +$unlock_more_upgrade_text = FrmSalesAPI::get_best_sale_value( 'global_settings_unlock_more_cta_text' ); +if ( ! $unlock_more_upgrade_text ) { + $unlock_more_upgrade_text = __( 'upgrading to PRO', 'formidable' ); +} + +$unlock_more_upgrade_link = FrmSalesAPI::get_best_sale_value( 'global_settings_unlock_more_cta_link' ); +if ( ! $unlock_more_upgrade_link ) { + $unlock_more_upgrade_link = FrmAppHelper::admin_upgrade_link( + array( + 'medium' => 'settings-license', + 'content' => 'global-settings-license-box-unlock-more', + ) + ); +} ?>

@@ -23,7 +40,7 @@ - +

@@ -34,9 +51,10 @@

', + esc_html( $unlock_more_upgrade_text ), '' ); ?> From 07efda9b148fc93602f434c9b12b9f20f215d4a5 Mon Sep 17 00:00:00 2001 From: Mike Letellier Date: Tue, 7 Jan 2025 15:33:36 -0400 Subject: [PATCH 09/31] Update another URL --- .../dashboard/templates/pro-features-list.php | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/classes/views/dashboard/templates/pro-features-list.php b/classes/views/dashboard/templates/pro-features-list.php index 1f4ff86bfe..456a49482c 100644 --- a/classes/views/dashboard/templates/pro-features-list.php +++ b/classes/views/dashboard/templates/pro-features-list.php @@ -10,12 +10,17 @@ die( 'You are not allowed to call this page directly.' ); } -$discount_link = FrmAppHelper::admin_upgrade_link( - array( - 'medium' => 'dashboard-discount', - 'content' => 'dashboard-defy-limits-cta', - ) -); +$discount_text = __( 'Upgrade to Pro & Get 50% Off', 'formidable' ); + +$discount_link = FrmSalesAPI::get_best_sale_value( 'global_settings_upgrade_cta_link' ); +if ( ! $discount_link ) { + $discount_link = FrmAppHelper::admin_upgrade_link( + array( + 'medium' => 'dashboard-discount', + 'content' => 'dashboard-defy-limits-cta', + ) + ); +} ?>

@@ -30,7 +35,7 @@ - +
From 8b965d3537901f0bc962df47cc58fc4058b68795 Mon Sep 17 00:00:00 2001 From: Mike Letellier Date: Tue, 7 Jan 2025 15:42:53 -0400 Subject: [PATCH 10/31] Use best discount if higher than 50 --- classes/views/dashboard/templates/pro-features-list.php | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/classes/views/dashboard/templates/pro-features-list.php b/classes/views/dashboard/templates/pro-features-list.php index 456a49482c..1eb210f8d0 100644 --- a/classes/views/dashboard/templates/pro-features-list.php +++ b/classes/views/dashboard/templates/pro-features-list.php @@ -10,7 +10,13 @@ die( 'You are not allowed to call this page directly.' ); } -$discount_text = __( 'Upgrade to Pro & Get 50% Off', 'formidable' ); +$best_discount = FrmSalesAPI::get_best_sale_value( 'discount_percent' ); +$use_discount = $best_discount > 50 ? $best_discount : 50; +$discount_text = sprintf( + // translators: %s is the discount percentage (ie 50%). + __( 'Upgrade to Pro & Get %1$s Off', 'formidable' ), + $use_discount . '%' +); $discount_link = FrmSalesAPI::get_best_sale_value( 'global_settings_upgrade_cta_link' ); if ( ! $discount_link ) { From ce22f7f6f9615a9b9cdfc1ac6ee6b7bda2fb019a Mon Sep 17 00:00:00 2001 From: Mike Letellier Date: Tue, 7 Jan 2025 15:58:10 -0400 Subject: [PATCH 11/31] Change case --- classes/controllers/FrmAddonsController.php | 2 +- classes/controllers/FrmAppController.php | 2 +- classes/helpers/FrmDashboardHelper.php | 4 +-- classes/models/FrmSalesAPI.php | 30 +++++++++++++++++-- .../dashboard/templates/pro-features-list.php | 4 +-- classes/views/frm-settings/license_box.php | 8 ++--- classes/views/shared/admin-footer-links.php | 4 +-- 7 files changed, 39 insertions(+), 15 deletions(-) diff --git a/classes/controllers/FrmAddonsController.php b/classes/controllers/FrmAddonsController.php index e200165396..7c2efb7cdc 100644 --- a/classes/controllers/FrmAddonsController.php +++ b/classes/controllers/FrmAddonsController.php @@ -105,7 +105,7 @@ public static function menu() { remove_submenu_page( 'formidable', 'formidable' ); if ( ! FrmAppHelper::pro_is_installed() ) { - $cta_text = FrmSalesAPI::get_best_sale_value( 'menu_cta_text' ); + $cta_text = FrmSalesApi::get_best_sale_value( 'menu_cta_text' ); if ( ! $cta_text ) { $cta_text = __( 'Upgrade', 'formidable' ); } diff --git a/classes/controllers/FrmAppController.php b/classes/controllers/FrmAppController.php index 13f18f73b1..34e10d4b46 100644 --- a/classes/controllers/FrmAppController.php +++ b/classes/controllers/FrmAppController.php @@ -557,7 +557,7 @@ public static function admin_init() { } if ( 'formidable-pro-upgrade' === FrmAppHelper::get_param( 'page' ) && ! FrmAppHelper::pro_is_installed() && current_user_can( 'frm_view_forms' ) ) { - $redirect = FrmSalesAPI::get_best_sale_value( 'menu_cta_link' ); + $redirect = FrmSalesApi::get_best_sale_value( 'menu_cta_link' ); if ( ! $redirect ) { $redirct = FrmAppHelper::admin_upgrade_link( array( diff --git a/classes/helpers/FrmDashboardHelper.php b/classes/helpers/FrmDashboardHelper.php index c28ea55c52..f9dcd75209 100644 --- a/classes/helpers/FrmDashboardHelper.php +++ b/classes/helpers/FrmDashboardHelper.php @@ -196,12 +196,12 @@ class="" * @return array */ public static function get_license_buttons() { - $cta_text = FrmSalesAPI::get_best_sale_value( 'dashboard_license_cta_text' ); + $cta_text = FrmSalesApi::get_best_sale_value( 'dashboard_license_cta_text' ); if ( ! $cta_text ) { $cta_text = __( 'Get Formidable PRO', 'formidable' ); } - $upgrade_link = FrmSalesAPI::get_best_sale_value( 'dashboard_license_cta_link' ); + $upgrade_link = FrmSalesApi::get_best_sale_value( 'dashboard_license_cta_link' ); if ( ! $upgrade_link ) { $upgrade_link = FrmAppHelper::admin_upgrade_link( array( diff --git a/classes/models/FrmSalesAPI.php b/classes/models/FrmSalesAPI.php index 20cc574cb6..e0c5835bde 100644 --- a/classes/models/FrmSalesAPI.php +++ b/classes/models/FrmSalesAPI.php @@ -6,10 +6,10 @@ /** * @since x.x */ -class FrmSalesAPI extends FrmFormApi { +class FrmSalesApi extends FrmFormApi { /** - * @var FrmSalesAPI|null + * @var FrmSalesApi|null */ private static $instance; @@ -259,6 +259,10 @@ public function get_best_sale() { continue; } + if ( ! $this->matches_ab_group( $sale ) ) { + continue; + } + if ( ! $best_sale || $sale['discount_percent'] > $best_sale['discount_percent'] ) { $best_sale = $sale; } @@ -291,10 +295,30 @@ public function get_api_info() { */ public static function get_best_sale_value( $key ) { if ( ! isset( self::$instance ) ) { - self::$instance = new FrmSalesAPI(); + self::$instance = new FrmSalesApi(); } $sale = self::$instance->get_best_sale(); return is_array( $sale ) && ! empty( $sale[ $key ] ) ? $sale[ $key ] : false; } + + /** + * @since x.x + * + * @param array $sale + * @return bool True if the sale is a match for the applicable group (if one is defined). + */ + private function matches_ab_group( $sale ) { + if ( ! is_numeric( $sale['test_group'] ) ) { + // No test group, so return true. + return true; + } + + $ab_group = $this->get_ab_group_for_current_site(); + return $ab_group === $sale['test_group']; + } + + private function get_ab_group_for_current_site() { + return 1; + } } diff --git a/classes/views/dashboard/templates/pro-features-list.php b/classes/views/dashboard/templates/pro-features-list.php index 1eb210f8d0..d9308e1e5c 100644 --- a/classes/views/dashboard/templates/pro-features-list.php +++ b/classes/views/dashboard/templates/pro-features-list.php @@ -10,7 +10,7 @@ die( 'You are not allowed to call this page directly.' ); } -$best_discount = FrmSalesAPI::get_best_sale_value( 'discount_percent' ); +$best_discount = FrmSalesApi::get_best_sale_value( 'discount_percent' ); $use_discount = $best_discount > 50 ? $best_discount : 50; $discount_text = sprintf( // translators: %s is the discount percentage (ie 50%). @@ -18,7 +18,7 @@ $use_discount . '%' ); -$discount_link = FrmSalesAPI::get_best_sale_value( 'global_settings_upgrade_cta_link' ); +$discount_link = FrmSalesApi::get_best_sale_value( 'global_settings_upgrade_cta_link' ); if ( ! $discount_link ) { $discount_link = FrmAppHelper::admin_upgrade_link( array( diff --git a/classes/views/frm-settings/license_box.php b/classes/views/frm-settings/license_box.php index 2e107456d5..6cf27f4186 100644 --- a/classes/views/frm-settings/license_box.php +++ b/classes/views/frm-settings/license_box.php @@ -3,12 +3,12 @@ die( 'You are not allowed to call this page directly.' ); } -$button_upgrade_text = FrmSalesAPI::get_best_sale_value( 'global_settings_license_cta_text' ); +$button_upgrade_text = FrmSalesApi::get_best_sale_value( 'global_settings_license_cta_text' ); if ( ! $button_upgrade_text ) { $button_upgrade_text = __( 'Get Formidable Now', 'formidable' ); } -$button_upgrade_link = FrmSalesAPI::get_best_sale_value( 'global_settings_license_cta_link' ); +$button_upgrade_link = FrmSalesApi::get_best_sale_value( 'global_settings_license_cta_link' ); if ( ! $button_upgrade_link ) { $button_upgrade_link = FrmAppHelper::admin_upgrade_link( array( @@ -18,12 +18,12 @@ ); } -$unlock_more_upgrade_text = FrmSalesAPI::get_best_sale_value( 'global_settings_unlock_more_cta_text' ); +$unlock_more_upgrade_text = FrmSalesApi::get_best_sale_value( 'global_settings_unlock_more_cta_text' ); if ( ! $unlock_more_upgrade_text ) { $unlock_more_upgrade_text = __( 'upgrading to PRO', 'formidable' ); } -$unlock_more_upgrade_link = FrmSalesAPI::get_best_sale_value( 'global_settings_unlock_more_cta_link' ); +$unlock_more_upgrade_link = FrmSalesApi::get_best_sale_value( 'global_settings_unlock_more_cta_link' ); if ( ! $unlock_more_upgrade_link ) { $unlock_more_upgrade_link = FrmAppHelper::admin_upgrade_link( array( diff --git a/classes/views/shared/admin-footer-links.php b/classes/views/shared/admin-footer-links.php index e9732501ea..6b2b0dc519 100644 --- a/classes/views/shared/admin-footer-links.php +++ b/classes/views/shared/admin-footer-links.php @@ -6,7 +6,7 @@ // Determine the support link based on lite vs pro. $support_link = ! FrmAppHelper::pro_is_installed() ? 'https://wordpress.org/support/plugin/formidable/' : 'https://formidableforms.com/new-topic/'; -$upgrade_link = FrmSalesAPI::get_best_sale_value( 'footer_cta_link' ); +$upgrade_link = FrmSalesApi::get_best_sale_value( 'footer_cta_link' ); if ( ! $upgrade_link ) { // Determine the upgrade link based on lite vs pro. $upgrade_link = ! FrmAppHelper::pro_is_installed() ? 'https://formidableforms.com/lite-upgrade/' : 'https://formidableforms.com/account/downloads/'; @@ -30,7 +30,7 @@ Date: Tue, 7 Jan 2025 16:04:19 -0400 Subject: [PATCH 12/31] Check for A/B test groups --- classes/models/FrmSalesAPI.php | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/classes/models/FrmSalesAPI.php b/classes/models/FrmSalesAPI.php index e0c5835bde..efabb055d2 100644 --- a/classes/models/FrmSalesAPI.php +++ b/classes/models/FrmSalesAPI.php @@ -280,7 +280,7 @@ public function get_best_sale() { */ public function get_api_info() { return json_decode( - '[{"key":"no-brainer","starts":1735689600,"expires":1738281600,"who":["all"],"discount_percent":50,"test_group":"Group One","lite_banner_cta_link":"https://formidableforms.com/cta1","lite_banner_cta_text":"Lite Banner Text","menu_cta_link":"https://formidableforms.com/cta2","menu_cta_text":"Menu Text","dashboard_license_cta_link":"https://formidableforms.com/cta3","dashboard_license_cta_text":"Dashboard License Text","global_settings_license_cta_link":"https://formidableforms.com/cta4","global_settings_license_cta_text":"License Text","global_settings_unlock_more_cta_link":"https://formidableforms.com/cta5","global_settings_unlock_more_cta_text":"Unlock More Text","global_settings_upgrade_cta_link":"https://formidableforms.com/cta6","builder_sidebar_cta_link":"https://formidableforms.com/cta7","builder_sidebar_cta_text":"Form Builder Text","footer_cta_link":"https://formidableforms.com/cta8","footer_cta_text":"Footer Text"},{"key":"anniversary","starts":1735689600,"expires":1738281600,"who":["all"],"discount_percent":60,"test_group":"Group One","lite_banner_cta_link":"https://formidableforms.com/cta1","lite_banner_cta_text":"Lite Banner Text","menu_cta_link":"https://formidableforms.com/cta2","menu_cta_text":"Menu Text","dashboard_license_cta_link":"https://formidableforms.com/cta3","dashboard_license_cta_text":"Dashboard License Text","global_settings_license_cta_link":"https://formidableforms.com/cta4","global_settings_license_cta_text":"License Text","global_settings_unlock_more_cta_link":"https://formidableforms.com/cta5","global_settings_unlock_more_cta_text":"Unlock More Text","global_settings_upgrade_cta_link":"https://formidableforms.com/cta6","builder_sidebar_cta_link":"https://formidableforms.com/cta7","builder_sidebar_cta_text":"Form Builder Text","footer_cta_link":"https://formidableforms.com/cta8","footer_cta_text":"Footer Text"}]', + '[{"key":"no-brainer","starts":1735689600,"expires":1738281600,"who":["all"],"discount_percent":50,"test_group":1,"lite_banner_cta_link":"https://formidableforms.com/cta1","lite_banner_cta_text":"Lite Banner Text","menu_cta_link":"https://formidableforms.com/cta2","menu_cta_text":"Menu Text","dashboard_license_cta_link":"https://formidableforms.com/cta3","dashboard_license_cta_text":"Dashboard License Text","global_settings_license_cta_link":"https://formidableforms.com/cta4","global_settings_license_cta_text":"License Text","global_settings_unlock_more_cta_link":"https://formidableforms.com/cta5","global_settings_unlock_more_cta_text":"Unlock More Text","global_settings_upgrade_cta_link":"https://formidableforms.com/cta6","builder_sidebar_cta_link":"https://formidableforms.com/cta7","builder_sidebar_cta_text":"Form Builder Text","footer_cta_link":"https://formidableforms.com/cta8","footer_cta_text":"Footer Text"},{"key":"anniversary","starts":1735689600,"expires":1738281600,"who":["all"],"discount_percent":60,"test_group":0,"lite_banner_cta_link":"https://formidableforms.com/cta1","lite_banner_cta_text":"Lite Banner Text","menu_cta_link":"https://formidableforms.com/cta2","menu_cta_text":"Menu Text","dashboard_license_cta_link":"https://formidableforms.com/cta3","dashboard_license_cta_text":"Dashboard License Text","global_settings_license_cta_link":"https://formidableforms.com/cta4","global_settings_license_cta_text":"License Text","global_settings_unlock_more_cta_link":"https://formidableforms.com/cta5","global_settings_unlock_more_cta_text":"Unlock More Text","global_settings_upgrade_cta_link":"https://formidableforms.com/cta6","builder_sidebar_cta_link":"https://formidableforms.com/cta7","builder_sidebar_cta_text":"Form Builder Text","footer_cta_link":"https://formidableforms.com/cta8","footer_cta_text":"Footer Text"}]', true ); } @@ -299,6 +299,10 @@ public static function get_best_sale_value( $key ) { } $sale = self::$instance->get_best_sale(); + + var_dump( $sale['key'] ); + die(); + return is_array( $sale ) && ! empty( $sale[ $key ] ) ? $sale[ $key ] : false; } @@ -318,7 +322,18 @@ private function matches_ab_group( $sale ) { return $ab_group === $sale['test_group']; } + /** + * @since x.x + * + * @return int 1 or 0. + */ private function get_ab_group_for_current_site() { - return 1; + $option = get_option( 'frm_sale_ab_group' ); + if ( ! is_numeric( $option ) ) { + // Generate either 0 or 1. + $option = mt_rand( 0, 1 ); + update_option( 'frm_sale_ab_group', $option ); + } + return (int) $option; } } From 218d8e51a3c90fa2842ec7e4c13c161f71036ced Mon Sep 17 00:00:00 2001 From: Mike Letellier Date: Tue, 7 Jan 2025 16:05:38 -0400 Subject: [PATCH 13/31] Remove die copde --- classes/models/FrmSalesAPI.php | 3 --- 1 file changed, 3 deletions(-) diff --git a/classes/models/FrmSalesAPI.php b/classes/models/FrmSalesAPI.php index efabb055d2..fd5ebe51a9 100644 --- a/classes/models/FrmSalesAPI.php +++ b/classes/models/FrmSalesAPI.php @@ -300,9 +300,6 @@ public static function get_best_sale_value( $key ) { $sale = self::$instance->get_best_sale(); - var_dump( $sale['key'] ); - die(); - return is_array( $sale ) && ! empty( $sale[ $key ] ) ? $sale[ $key ] : false; } From 0eff75106294f0cec64f4392e353b30932ca22e2 Mon Sep 17 00:00:00 2001 From: Mike Letellier Date: Tue, 7 Jan 2025 16:06:47 -0400 Subject: [PATCH 14/31] Run php cs fixer --- classes/models/FrmSalesAPI.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/classes/models/FrmSalesAPI.php b/classes/models/FrmSalesAPI.php index fd5ebe51a9..1d8cd1cc7d 100644 --- a/classes/models/FrmSalesAPI.php +++ b/classes/models/FrmSalesAPI.php @@ -291,7 +291,7 @@ public function get_api_info() { * @since x.x * * @param string $key - * @return string|false False if no sale is active. + * @return false|string False if no sale is active. */ public static function get_best_sale_value( $key ) { if ( ! isset( self::$instance ) ) { From e000ed94a49bff3b39740df68315e94ad783bdaf Mon Sep 17 00:00:00 2001 From: Mike Letellier Date: Tue, 7 Jan 2025 16:10:10 -0400 Subject: [PATCH 15/31] phpcs fixes --- classes/controllers/FrmAddonsController.php | 2 +- classes/models/FrmSalesAPI.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/classes/controllers/FrmAddonsController.php b/classes/controllers/FrmAddonsController.php index 7c2efb7cdc..4ac16dd37d 100644 --- a/classes/controllers/FrmAddonsController.php +++ b/classes/controllers/FrmAddonsController.php @@ -124,7 +124,7 @@ function () { } elseif ( 'formidable-pro-upgrade' === FrmAppHelper::get_param( 'page' ) ) { wp_safe_redirect( admin_url( 'admin.php?page=formidable' ) ); exit; - } + }//end if } /** diff --git a/classes/models/FrmSalesAPI.php b/classes/models/FrmSalesAPI.php index 1d8cd1cc7d..60c225d8cc 100644 --- a/classes/models/FrmSalesAPI.php +++ b/classes/models/FrmSalesAPI.php @@ -329,7 +329,7 @@ private function get_ab_group_for_current_site() { if ( ! is_numeric( $option ) ) { // Generate either 0 or 1. $option = mt_rand( 0, 1 ); - update_option( 'frm_sale_ab_group', $option ); + update_option( 'frm_sale_ab_group', $option ); } return (int) $option; } From 28f684f4fbb44241c54e4b7a46185ddd1ec96b52 Mon Sep 17 00:00:00 2001 From: Mike Letellier Date: Tue, 7 Jan 2025 16:17:09 -0400 Subject: [PATCH 16/31] Check starts timestamp as well and compare against New York time --- classes/models/FrmSalesAPI.php | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/classes/models/FrmSalesAPI.php b/classes/models/FrmSalesAPI.php index 60c225d8cc..9bd31fddc0 100644 --- a/classes/models/FrmSalesAPI.php +++ b/classes/models/FrmSalesAPI.php @@ -85,7 +85,7 @@ private function add_sale( $sale ) { return; } - if ( $this->is_expired( $sale ) ) { + if ( ! $this->sale_is_active( $sale ) ) { return; } @@ -129,12 +129,19 @@ private function fill_sale( $sale ) { } /** - * @param array $sale + * Check if a sale is within the active period. + * + * @since x.x * + * @param array $sale * @return bool */ - private function is_expired( $sale ) { - return $sale['expires'] < time(); + private function sale_is_active( $sale ) { + $starts = $sale['starts']; + $expires = $sale['expires']; + $date = new DateTime( 'now', new DateTimeZone( 'America/New_York' ) ); + $today = $date->getTimestamp(); + return $today >= $starts && $today <= $expires; } /** From 93914e137d3a3993e5ccc5c2fff811300360ad7b Mon Sep 17 00:00:00 2001 From: Mike Letellier Date: Tue, 7 Jan 2025 16:20:06 -0400 Subject: [PATCH 17/31] Remove more code that is not required --- classes/models/FrmSalesAPI.php | 5 ----- 1 file changed, 5 deletions(-) diff --git a/classes/models/FrmSalesAPI.php b/classes/models/FrmSalesAPI.php index 9bd31fddc0..f3e6e80b93 100644 --- a/classes/models/FrmSalesAPI.php +++ b/classes/models/FrmSalesAPI.php @@ -89,11 +89,6 @@ private function add_sale( $sale ) { return; } - if ( isset( self::$sales[ $sale['key'] ] ) ) { - // Move up and mark as new. - unset( self::$sales[ $sale['key'] ] ); - } - self::$sales[ $sale['key'] ] = $this->fill_sale( $sale ); } From 14c163b21fb99d6bbc5017dcd7495cacee0144f7 Mon Sep 17 00:00:00 2001 From: Mike Letellier Date: Tue, 7 Jan 2025 16:40:11 -0400 Subject: [PATCH 18/31] Do not autoload the option --- classes/models/FrmSalesAPI.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/classes/models/FrmSalesAPI.php b/classes/models/FrmSalesAPI.php index f3e6e80b93..05c9a85db4 100644 --- a/classes/models/FrmSalesAPI.php +++ b/classes/models/FrmSalesAPI.php @@ -331,7 +331,7 @@ private function get_ab_group_for_current_site() { if ( ! is_numeric( $option ) ) { // Generate either 0 or 1. $option = mt_rand( 0, 1 ); - update_option( 'frm_sale_ab_group', $option ); + update_option( 'frm_sale_ab_group', $option, false ); } return (int) $option; } From 212146e8ee0899b3fba219d401b33fb316546ec7 Mon Sep 17 00:00:00 2001 From: Mike Letellier Date: Tue, 7 Jan 2025 16:58:57 -0400 Subject: [PATCH 19/31] Re-use code in inbox code --- classes/helpers/FrmApiHelper.php | 118 +++++++++++++++++++++++++++++++ classes/models/FrmInbox.php | 92 +----------------------- classes/models/FrmSalesAPI.php | 104 +-------------------------- 3 files changed, 121 insertions(+), 193 deletions(-) create mode 100644 classes/helpers/FrmApiHelper.php diff --git a/classes/helpers/FrmApiHelper.php b/classes/helpers/FrmApiHelper.php new file mode 100644 index 0000000000..39cf64e517 --- /dev/null +++ b/classes/helpers/FrmApiHelper.php @@ -0,0 +1,118 @@ + $cutoff; + } + + /** + * @since x.x + * + * @return bool + */ + private static function is_free_not_first_30() { + return self::is_free() && ! self::is_first_30(); + } + + /** + * Check if the Pro plugin is active. If not, consider the user to be on the free version. + * + * @since x.x + * + * @return bool + */ + private static function is_free() { + return ! FrmAppHelper::pro_is_included(); + } + +} diff --git a/classes/models/FrmInbox.php b/classes/models/FrmInbox.php index 933ca32c53..ac9a409e6d 100644 --- a/classes/models/FrmInbox.php +++ b/classes/models/FrmInbox.php @@ -205,22 +205,10 @@ private function is_expired( $message ) { * @return bool */ private function is_for_user( $message ) { - if ( ! isset( $message['who'] ) || $message['who'] === 'all' ) { - return true; - } - $who = (array) $message['who']; - if ( $this->is_for_everyone( $who ) ) { - return true; - } - if ( $this->is_user_type( $who ) ) { - return true; - } - if ( in_array( 'free_first_30', $who, true ) && $this->is_free_first_30() ) { - return true; - } - if ( in_array( 'free_not_first_30', $who, true ) && $this->is_free_not_first_30() ) { + if ( FrmApiHelper::is_for_user( $message ) ) { return true; } + /** * Allow for other special inbox cases in other add-ons. * @@ -233,34 +221,6 @@ private function is_for_user( $message ) { return (bool) apply_filters( 'frm_inbox_message_is_for_user', false, $who, $message ); } - /** - * @since 6.16.3 - * - * @param array $who - * @return bool - */ - private function is_for_everyone( $who ) { - return in_array( 'all', $who, true ) || in_array( 'everyone', $who, true ); - } - - /** - * @since 6.16.3 - * - * @param array $who - * @return bool - */ - private function is_user_type( $who ) { - return in_array( $this->get_user_type(), $who, true ); - } - - private function get_user_type() { - if ( ! FrmAppHelper::pro_is_installed() ) { - return 'free'; - } - - return FrmAddonsController::license_type(); - } - /** * @param string $key * @@ -392,54 +352,6 @@ private function update_list() { update_option( $this->option, self::$messages, 'no' ); } - /** - * Check if user is still using the Lite version only, and within - * the first 30 days of activation. - * - * @since 6.16 - * - * @return bool - */ - private function is_free_first_30() { - return $this->is_free() && $this->is_first_30(); - } - - /** - * @since 6.16.3 - * - * @return bool - */ - private function is_first_30() { - $activation_timestamp = get_option( 'frm_first_activation' ); - if ( false === $activation_timestamp ) { - // If the option does not exist, assume that it is - // because the user was active before this option was introduced. - return false; - } - $cutoff = strtotime( '-30 days' ); - return $activation_timestamp > $cutoff; - } - - /** - * @since 6.16.3 - * - * @return bool - */ - private function is_free_not_first_30() { - return $this->is_free() && ! $this->is_first_30(); - } - - /** - * Check if the Pro plugin is active. If not, consider the user to be on the free version. - * - * @since 6.16.3 - * - * @return bool - */ - private function is_free() { - return ! FrmAppHelper::pro_is_included(); - } - /** * Show a banner message if one is available. * diff --git a/classes/models/FrmSalesAPI.php b/classes/models/FrmSalesAPI.php index 05c9a85db4..b9d7c3182c 100644 --- a/classes/models/FrmSalesAPI.php +++ b/classes/models/FrmSalesAPI.php @@ -139,108 +139,6 @@ private function sale_is_active( $sale ) { return $today >= $starts && $today <= $expires; } - /** - * Show different sales for different accounts. - * - * @param array $sale - * @return bool - */ - private function is_for_user( $sale ) { - if ( ! isset( $sale['who'] ) || $sale['who'] === 'all' ) { - return true; - } - $who = (array) $sale['who']; - if ( $this->is_for_everyone( $who ) ) { - return true; - } - if ( $this->is_user_type( $who ) ) { - return true; - } - if ( in_array( 'free_first_30', $who, true ) && $this->is_free_first_30() ) { - return true; - } - if ( in_array( 'free_not_first_30', $who, true ) && $this->is_free_not_first_30() ) { - return true; - } - return false; - } - - /** - * @since x.x - * - * @param array $who - * @return bool - */ - private function is_for_everyone( $who ) { - return in_array( 'all', $who, true ); - } - - /** - * @since x.x - * - * @param array $who - * @return bool - */ - private function is_user_type( $who ) { - return in_array( $this->get_user_type(), $who, true ); - } - - private function get_user_type() { - if ( ! FrmAppHelper::pro_is_installed() ) { - return 'free'; - } - - return FrmAddonsController::license_type(); - } - - /** - * Check if user is still using the Lite version only, and within - * the first 30 days of activation. - * - * @since x.x - * - * @return bool - */ - private function is_free_first_30() { - return $this->is_free() && $this->is_first_30(); - } - - /** - * @since x.x - * - * @return bool - */ - private function is_first_30() { - $activation_timestamp = get_option( 'frm_first_activation' ); - if ( false === $activation_timestamp ) { - // If the option does not exist, assume that it is - // because the user was active before this option was introduced. - return false; - } - $cutoff = strtotime( '-30 days' ); - return $activation_timestamp > $cutoff; - } - - /** - * @since x.x - * - * @return bool - */ - private function is_free_not_first_30() { - return $this->is_free() && ! $this->is_first_30(); - } - - /** - * Check if the Pro plugin is active. If not, consider the user to be on the free version. - * - * @since x.x - * - * @return bool - */ - private function is_free() { - return ! FrmAppHelper::pro_is_included(); - } - /** * @since x.x * @@ -257,7 +155,7 @@ public function get_best_sale() { $best_sale = false; foreach ( self::$sales as $sale ) { - if ( ! $this->is_for_user( $sale ) ) { + if ( ! FrmApiHelper::is_for_user( $sale ) ) { continue; } From 4111ec1063ce52aa3edf08284d86d0368bab7f4e Mon Sep 17 00:00:00 2001 From: Mike Letellier Date: Tue, 7 Jan 2025 17:03:10 -0400 Subject: [PATCH 20/31] phpcs fixes --- classes/helpers/FrmApiHelper.php | 3 +-- classes/models/FrmSalesAPI.php | 26 +++++++++++++------------- 2 files changed, 14 insertions(+), 15 deletions(-) diff --git a/classes/helpers/FrmApiHelper.php b/classes/helpers/FrmApiHelper.php index 39cf64e517..88e64a19d2 100644 --- a/classes/helpers/FrmApiHelper.php +++ b/classes/helpers/FrmApiHelper.php @@ -114,5 +114,4 @@ private static function is_free_not_first_30() { private static function is_free() { return ! FrmAppHelper::pro_is_included(); } - -} +} \ No newline at end of file diff --git a/classes/models/FrmSalesAPI.php b/classes/models/FrmSalesAPI.php index b9d7c3182c..e0fe5d9506 100644 --- a/classes/models/FrmSalesAPI.php +++ b/classes/models/FrmSalesAPI.php @@ -172,19 +172,6 @@ public function get_best_sale() { return self::$best_sale; } - /** - * This is just here for testing so skip the API. - * Remove this before launching (and inherit from the base class instead). - * - * @return array - */ - public function get_api_info() { - return json_decode( - '[{"key":"no-brainer","starts":1735689600,"expires":1738281600,"who":["all"],"discount_percent":50,"test_group":1,"lite_banner_cta_link":"https://formidableforms.com/cta1","lite_banner_cta_text":"Lite Banner Text","menu_cta_link":"https://formidableforms.com/cta2","menu_cta_text":"Menu Text","dashboard_license_cta_link":"https://formidableforms.com/cta3","dashboard_license_cta_text":"Dashboard License Text","global_settings_license_cta_link":"https://formidableforms.com/cta4","global_settings_license_cta_text":"License Text","global_settings_unlock_more_cta_link":"https://formidableforms.com/cta5","global_settings_unlock_more_cta_text":"Unlock More Text","global_settings_upgrade_cta_link":"https://formidableforms.com/cta6","builder_sidebar_cta_link":"https://formidableforms.com/cta7","builder_sidebar_cta_text":"Form Builder Text","footer_cta_link":"https://formidableforms.com/cta8","footer_cta_text":"Footer Text"},{"key":"anniversary","starts":1735689600,"expires":1738281600,"who":["all"],"discount_percent":60,"test_group":0,"lite_banner_cta_link":"https://formidableforms.com/cta1","lite_banner_cta_text":"Lite Banner Text","menu_cta_link":"https://formidableforms.com/cta2","menu_cta_text":"Menu Text","dashboard_license_cta_link":"https://formidableforms.com/cta3","dashboard_license_cta_text":"Dashboard License Text","global_settings_license_cta_link":"https://formidableforms.com/cta4","global_settings_license_cta_text":"License Text","global_settings_unlock_more_cta_link":"https://formidableforms.com/cta5","global_settings_unlock_more_cta_text":"Unlock More Text","global_settings_upgrade_cta_link":"https://formidableforms.com/cta6","builder_sidebar_cta_link":"https://formidableforms.com/cta7","builder_sidebar_cta_text":"Form Builder Text","footer_cta_link":"https://formidableforms.com/cta8","footer_cta_text":"Footer Text"}]', - true - ); - } - /** * Get text for best sale if applicable. * @@ -233,4 +220,17 @@ private function get_ab_group_for_current_site() { } return (int) $option; } + + /** + * This is just here for testing so skip the API. + * Remove this before launching (and inherit from the base class instead). + * + * @return array + */ + public function get_api_info() { + return json_decode( + '[{"key":"no-brainer","starts":1735689600,"expires":1738281600,"who":["all"],"discount_percent":50,"test_group":1,"lite_banner_cta_link":"https://formidableforms.com/cta1","lite_banner_cta_text":"Lite Banner Text","menu_cta_link":"https://formidableforms.com/cta2","menu_cta_text":"Menu Text","dashboard_license_cta_link":"https://formidableforms.com/cta3","dashboard_license_cta_text":"Dashboard License Text","global_settings_license_cta_link":"https://formidableforms.com/cta4","global_settings_license_cta_text":"License Text","global_settings_unlock_more_cta_link":"https://formidableforms.com/cta5","global_settings_unlock_more_cta_text":"Unlock More Text","global_settings_upgrade_cta_link":"https://formidableforms.com/cta6","builder_sidebar_cta_link":"https://formidableforms.com/cta7","builder_sidebar_cta_text":"Form Builder Text","footer_cta_link":"https://formidableforms.com/cta8","footer_cta_text":"Footer Text"},{"key":"anniversary","starts":1735689600,"expires":1738281600,"who":["all"],"discount_percent":60,"test_group":0,"lite_banner_cta_link":"https://formidableforms.com/cta1","lite_banner_cta_text":"Lite Banner Text","menu_cta_link":"https://formidableforms.com/cta2","menu_cta_text":"Menu Text","dashboard_license_cta_link":"https://formidableforms.com/cta3","dashboard_license_cta_text":"Dashboard License Text","global_settings_license_cta_link":"https://formidableforms.com/cta4","global_settings_license_cta_text":"License Text","global_settings_unlock_more_cta_link":"https://formidableforms.com/cta5","global_settings_unlock_more_cta_text":"Unlock More Text","global_settings_upgrade_cta_link":"https://formidableforms.com/cta6","builder_sidebar_cta_link":"https://formidableforms.com/cta7","builder_sidebar_cta_text":"Form Builder Text","footer_cta_link":"https://formidableforms.com/cta8","footer_cta_text":"Footer Text"}]', // phpcs:ignore SlevomatCodingStandard.Files.LineLength.LineTooLong + true + ); + } } From 05b3cb329e22c2ad4b603ba794d967dc1397b4b7 Mon Sep 17 00:00:00 2001 From: Mike Letellier Date: Tue, 7 Jan 2025 17:06:02 -0400 Subject: [PATCH 21/31] Add line break --- classes/helpers/FrmApiHelper.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/classes/helpers/FrmApiHelper.php b/classes/helpers/FrmApiHelper.php index 88e64a19d2..d6bde77339 100644 --- a/classes/helpers/FrmApiHelper.php +++ b/classes/helpers/FrmApiHelper.php @@ -114,4 +114,4 @@ private static function is_free_not_first_30() { private static function is_free() { return ! FrmAppHelper::pro_is_included(); } -} \ No newline at end of file + From a127f8c3814a78892bd4ddfe2b9b566f9658e25e Mon Sep 17 00:00:00 2001 From: Mike Letellier Date: Tue, 7 Jan 2025 17:07:57 -0400 Subject: [PATCH 22/31] Fix broken php --- classes/helpers/FrmApiHelper.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/classes/helpers/FrmApiHelper.php b/classes/helpers/FrmApiHelper.php index d6bde77339..926360b9bb 100644 --- a/classes/helpers/FrmApiHelper.php +++ b/classes/helpers/FrmApiHelper.php @@ -114,4 +114,4 @@ private static function is_free_not_first_30() { private static function is_free() { return ! FrmAppHelper::pro_is_included(); } - +} From 0c9821e0a8a83e241ed093820aa8a17167e33656 Mon Sep 17 00:00:00 2001 From: Mike Letellier Date: Tue, 7 Jan 2025 17:14:35 -0400 Subject: [PATCH 23/31] Add a comment --- classes/helpers/FrmApiHelper.php | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/classes/helpers/FrmApiHelper.php b/classes/helpers/FrmApiHelper.php index 926360b9bb..f6bec2d51f 100644 --- a/classes/helpers/FrmApiHelper.php +++ b/classes/helpers/FrmApiHelper.php @@ -9,16 +9,18 @@ class FrmApiHelper { /** + * Check if an API item matches the current site license target. + * * @since x.x * - * @param array $sale + * @param array $item Inbox or Sale item. * @return bool */ - public static function is_for_user( $sale ) { - if ( ! isset( $sale['who'] ) || $sale['who'] === 'all' ) { + public static function is_for_user( $item ) { + if ( ! isset( $item['who'] ) || $item['who'] === 'all' ) { return true; } - $who = (array) $sale['who']; + $who = (array) $item['who']; if ( self::is_for_everyone( $who ) ) { return true; } From 50eb65b2d7f58f21461f7cf1b1caf5bfc05355f2 Mon Sep 17 00:00:00 2001 From: Mike Letellier Date: Wed, 8 Jan 2025 11:16:06 -0400 Subject: [PATCH 24/31] Add missing var --- classes/models/FrmInbox.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/classes/models/FrmInbox.php b/classes/models/FrmInbox.php index ac9a409e6d..a516c58652 100644 --- a/classes/models/FrmInbox.php +++ b/classes/models/FrmInbox.php @@ -209,6 +209,8 @@ private function is_for_user( $message ) { return true; } + $who = (array) $message['who']; + /** * Allow for other special inbox cases in other add-ons. * From 8ab852a37fac2929c6a2d5e6e178c90aa71652c9 Mon Sep 17 00:00:00 2001 From: Mike Letellier Date: Fri, 10 Jan 2025 10:49:32 -0400 Subject: [PATCH 25/31] Remove unused $for_parent constructor param --- classes/models/FrmInbox.php | 2 +- classes/models/FrmSalesAPI.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/classes/models/FrmInbox.php b/classes/models/FrmInbox.php index a516c58652..b54b9ce395 100644 --- a/classes/models/FrmInbox.php +++ b/classes/models/FrmInbox.php @@ -19,7 +19,7 @@ class FrmInbox extends FrmFormApi { */ private static $banner_messages; - public function __construct( $for_parent = null ) { + public function __construct() { $this->set_cache_key(); if ( false === self::$messages ) { diff --git a/classes/models/FrmSalesAPI.php b/classes/models/FrmSalesAPI.php index e0fe5d9506..fe13841622 100644 --- a/classes/models/FrmSalesAPI.php +++ b/classes/models/FrmSalesAPI.php @@ -29,7 +29,7 @@ class FrmSalesApi extends FrmFormApi { */ private static $best_sale; - public function __construct( $for_parent = null ) { + public function __construct() { $this->set_cache_key(); if ( false === self::$sales ) { From d22d88e857de15ec26b8d9826f55d66002a86ab5 Mon Sep 17 00:00:00 2001 From: Mike Letellier Date: Fri, 10 Jan 2025 10:50:09 -0400 Subject: [PATCH 26/31] Remove phpstan exception --- phpstan.neon | 1 - 1 file changed, 1 deletion(-) diff --git a/phpstan.neon b/phpstan.neon index 553a54fea6..d426a09b91 100644 --- a/phpstan.neon +++ b/phpstan.neon @@ -52,7 +52,6 @@ parameters: message: '#has an unused parameter#' paths: - classes/models/FrmFieldOption.php - - classes/models/FrmInbox.php - classes/models/FrmSolution.php - stubs.php - From 1fac9356c54eddd9cf576631e6f1c809195506dd Mon Sep 17 00:00:00 2001 From: Mike Letellier Date: Mon, 13 Jan 2025 10:00:18 -0400 Subject: [PATCH 27/31] Clear sales API when clearing caches, stop using hard coded test data --- classes/models/FrmAddon.php | 3 +++ classes/models/FrmSalesAPI.php | 13 ------------- 2 files changed, 3 insertions(+), 13 deletions(-) diff --git a/classes/models/FrmAddon.php b/classes/models/FrmAddon.php index 3da3453484..0f52e0d891 100644 --- a/classes/models/FrmAddon.php +++ b/classes/models/FrmAddon.php @@ -330,6 +330,9 @@ protected function delete_cache() { $api = new FrmApplicationApi( $this->license ); $api->reset_cached(); + + $api = new FrmSalesApi(); + $api->reset_cached(); } /** diff --git a/classes/models/FrmSalesAPI.php b/classes/models/FrmSalesAPI.php index fe13841622..335c0c28bb 100644 --- a/classes/models/FrmSalesAPI.php +++ b/classes/models/FrmSalesAPI.php @@ -220,17 +220,4 @@ private function get_ab_group_for_current_site() { } return (int) $option; } - - /** - * This is just here for testing so skip the API. - * Remove this before launching (and inherit from the base class instead). - * - * @return array - */ - public function get_api_info() { - return json_decode( - '[{"key":"no-brainer","starts":1735689600,"expires":1738281600,"who":["all"],"discount_percent":50,"test_group":1,"lite_banner_cta_link":"https://formidableforms.com/cta1","lite_banner_cta_text":"Lite Banner Text","menu_cta_link":"https://formidableforms.com/cta2","menu_cta_text":"Menu Text","dashboard_license_cta_link":"https://formidableforms.com/cta3","dashboard_license_cta_text":"Dashboard License Text","global_settings_license_cta_link":"https://formidableforms.com/cta4","global_settings_license_cta_text":"License Text","global_settings_unlock_more_cta_link":"https://formidableforms.com/cta5","global_settings_unlock_more_cta_text":"Unlock More Text","global_settings_upgrade_cta_link":"https://formidableforms.com/cta6","builder_sidebar_cta_link":"https://formidableforms.com/cta7","builder_sidebar_cta_text":"Form Builder Text","footer_cta_link":"https://formidableforms.com/cta8","footer_cta_text":"Footer Text"},{"key":"anniversary","starts":1735689600,"expires":1738281600,"who":["all"],"discount_percent":60,"test_group":0,"lite_banner_cta_link":"https://formidableforms.com/cta1","lite_banner_cta_text":"Lite Banner Text","menu_cta_link":"https://formidableforms.com/cta2","menu_cta_text":"Menu Text","dashboard_license_cta_link":"https://formidableforms.com/cta3","dashboard_license_cta_text":"Dashboard License Text","global_settings_license_cta_link":"https://formidableforms.com/cta4","global_settings_license_cta_text":"License Text","global_settings_unlock_more_cta_link":"https://formidableforms.com/cta5","global_settings_unlock_more_cta_text":"Unlock More Text","global_settings_upgrade_cta_link":"https://formidableforms.com/cta6","builder_sidebar_cta_link":"https://formidableforms.com/cta7","builder_sidebar_cta_text":"Form Builder Text","footer_cta_link":"https://formidableforms.com/cta8","footer_cta_text":"Footer Text"}]', // phpcs:ignore SlevomatCodingStandard.Files.LineLength.LineTooLong - true - ); - } } From 616826c5cc6de5ac2ef242b126d9c5fdc7d8b684 Mon Sep 17 00:00:00 2001 From: Mike Letellier Date: Mon, 13 Jan 2025 11:10:39 -0400 Subject: [PATCH 28/31] Add a check for Psalm --- classes/models/FrmSalesAPI.php | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/classes/models/FrmSalesAPI.php b/classes/models/FrmSalesAPI.php index 335c0c28bb..e1ca8dbb30 100644 --- a/classes/models/FrmSalesAPI.php +++ b/classes/models/FrmSalesAPI.php @@ -79,6 +79,12 @@ private function set_sales() { * @return void */ private function add_sale( $sale ) { + if ( ! is_array( self::$sales ) ) { + // This gets set in the constructor. + // This check is just here for Psalm analysis. + return; + } + if ( ! is_array( $sale ) || ! isset( $sale['key'] ) ) { // if the API response is invalid, $sale may not be an array. // if there are no sales from the API, it is returning a "No Entries Found" item with no key, so check for a key as well. From 8bb347a25bb7ef4d4593785d24559182da4bf193 Mon Sep 17 00:00:00 2001 From: Mike Letellier Date: Mon, 13 Jan 2025 13:58:40 -0400 Subject: [PATCH 29/31] Update sales API URL (use cloudflare worker) --- classes/models/FrmSalesAPI.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/classes/models/FrmSalesAPI.php b/classes/models/FrmSalesAPI.php index e1ca8dbb30..b6d60433cc 100644 --- a/classes/models/FrmSalesAPI.php +++ b/classes/models/FrmSalesAPI.php @@ -52,7 +52,7 @@ protected function set_cache_key() { * @return string */ protected function api_url() { - return 'https://formidableforms.com/wp-json/s11-sales/v1/list/'; + return 'https://plapi.formidableforms.com/sales/'; } /** From fd6524c6ed24fd13051b66faf354695967f66ca6 Mon Sep 17 00:00:00 2001 From: Mike Letellier Date: Mon, 13 Jan 2025 16:01:34 -0400 Subject: [PATCH 30/31] Add day in seconds to expires check to include the expires date --- classes/models/FrmSalesAPI.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/classes/models/FrmSalesAPI.php b/classes/models/FrmSalesAPI.php index b6d60433cc..01f87ccc9e 100644 --- a/classes/models/FrmSalesAPI.php +++ b/classes/models/FrmSalesAPI.php @@ -139,7 +139,7 @@ private function fill_sale( $sale ) { */ private function sale_is_active( $sale ) { $starts = $sale['starts']; - $expires = $sale['expires']; + $expires = $sale['expires'] + DAY_IN_SECONDS; $date = new DateTime( 'now', new DateTimeZone( 'America/New_York' ) ); $today = $date->getTimestamp(); return $today >= $starts && $today <= $expires; From 8c3a688cc39e20f2f0c006ca99e9405f4378b05b Mon Sep 17 00:00:00 2001 From: Mike Letellier Date: Tue, 14 Jan 2025 09:43:03 -0400 Subject: [PATCH 31/31] Also update the link in the plugins page --- classes/controllers/FrmAppController.php | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/classes/controllers/FrmAppController.php b/classes/controllers/FrmAppController.php index 34e10d4b46..b00550a184 100644 --- a/classes/controllers/FrmAppController.php +++ b/classes/controllers/FrmAppController.php @@ -337,16 +337,31 @@ private static function get_form_nav_items( $form ) { return (array) apply_filters( 'frm_form_nav_list', $nav_items, $nav_args ); } - // Adds a settings link to the plugins page /** + * Adds a settings link to the plugins page + * + * @param array $links * @return array */ public static function settings_link( $links ) { $settings = array(); if ( ! FrmAppHelper::pro_is_installed() ) { - $label = FrmAddonsController::is_license_expired() ? __( 'Renew', 'formidable' ) : __( 'Upgrade to Pro', 'formidable' ); - $settings[] = '' . esc_html( $label ) . ''; + if ( FrmAddonsController::is_license_expired() ) { + $label = __( 'Renew', 'formidable' ); + } else { + $label = FrmSalesApi::get_best_sale_value( 'plugin_page_cta_text' ); + if ( ! $label ) { + $label = __( 'Upgrade to Pro', 'formidable' ); + } + } + + $upgrade_link = FrmSalesApi::get_best_sale_value( 'plugin_page_cta_link' ); + if ( ! $upgrade_link ) { + $upgrade_link = FrmAppHelper::admin_upgrade_link( 'plugin-row' ); + } + + $settings[] = '' . esc_html( $label ) . ''; } $settings[] = '' . __( 'Build a Form', 'formidable' ) . '';