PluginProbe
Formidable Forms – WordPress Form Builder for Contact Forms, Calculators, Quizzes & More / 6.19
Formidable Forms – WordPress Form Builder for Contact Forms, Calculators, Quizzes & More v6.19
6.35 6.34 6.33.1 6.33 6.32.1 6.32 6.31 6.25 6.25.1 6.26 6.26.1 6.27 6.28 6.29 6.3 6.3.1 6.3.2 6.30 6.4 6.4.1 6.4.2 6.5 6.5.1 6.5.2 6.5.3 All 141 releases
formidable / classes / models / FrmSalesApi.php

FrmSalesApi.php in Formidable Forms – WordPress Form Builder for Contact Forms, Calculators, Quizzes & More 6.19, at classes/models/FrmSalesApi.php

230 lines 4.9 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 if ( ! defined( 'ABSPATH' ) ) {
3 die( 'You are not allowed to call this page directly.' );
4 }
5
6 /**
7 * @since 6.17
8 */
9 class FrmSalesApi extends FrmFormApi {
10
11 /**
12 * @var FrmSalesApi|null
13 */
14 private static $instance;
15
16 protected $cache_key;
17
18 /**
19 * All sales from API data.
20 *
21 * @var array|false
22 */
23 private static $sales = false;
24
25 /**
26 * Best sale from API data.
27 *
28 * @var array|false|null
29 */
30 private static $best_sale;
31
32 public function __construct() {
33 $this->set_cache_key();
34
35 if ( false === self::$sales ) {
36 $this->set_sales();
37 }
38 }
39
40 /**
41 * @since 6.17
42 *
43 * @return void
44 */
45 protected function set_cache_key() {
46 $this->cache_key = 'frm_sales_cache';
47 }
48
49 /**
50 * @since 6.17
51 *
52 * @return string
53 */
54 protected function api_url() {
55 return 'https://plapi.formidableforms.com/sales/';
56 }
57
58 /**
59 * @since 6.17
60 *
61 * @return void
62 */
63 private function set_sales() {
64 self::$sales = array();
65
66 $api = $this->get_api_info();
67 if ( empty( $api ) ) {
68 return;
69 }
70
71 foreach ( $api as $sale ) {
72 $this->add_sale( $sale );
73 }
74 }
75
76 /**
77 * @param array|string $sale
78 *
79 * @return void
80 */
81 private function add_sale( $sale ) {
82 if ( ! is_array( self::$sales ) ) {
83 // This gets set in the constructor.
84 // This check is just here for Psalm analysis.
85 return;
86 }
87
88 if ( ! is_array( $sale ) || ! isset( $sale['key'] ) ) {
89 // if the API response is invalid, $sale may not be an array.
90 // 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.
91 return;
92 }
93
94 if ( ! $this->sale_is_active( $sale ) ) {
95 return;
96 }
97
98 self::$sales[ $sale['key'] ] = $this->fill_sale( $sale );
99 }
100
101 /**
102 * @param array $sale
103 * @return array
104 */
105 private function fill_sale( $sale ) {
106 $defaults = array(
107 'key' => '',
108 'starts' => '',
109 'expires' => '',
110 // Use 'free', 'personal', 'business', 'elite', 'grandfathered'.
111 'who' => 'all',
112 'discount_percent' => 0,
113 'test_group' => '',
114 'lite_banner_cta_link' => '',
115 'lite_banner_cta_text' => '',
116 'menu_cta_link' => '',
117 'menu_cta_text' => '',
118 'dashboard_license_cta_link' => '',
119 'dashboard_license_cta_text' => '',
120 'global_settings_license_cta_link' => '',
121 'global_settings_license_cta_text' => '',
122 'global_settings_unlock_more_cta_link' => '',
123 'global_settings_unlock_more_cta_text' => '',
124 'global_settings_upgrade_cta_link' => '',
125 'builder_sidebar_cta_link' => '',
126 'builder_sidebar_cta_text' => '',
127 );
128
129 return array_merge( $defaults, $sale );
130 }
131
132 /**
133 * Check if a sale is within the active period.
134 *
135 * @since 6.17
136 *
137 * @param array $sale
138 * @return bool
139 */
140 private function sale_is_active( $sale ) {
141 $starts = $sale['starts'];
142 $expires = $sale['expires'] + DAY_IN_SECONDS;
143 $date = new DateTime( 'now', new DateTimeZone( 'America/New_York' ) );
144 $today = $date->getTimestamp();
145 return $today >= $starts && $today <= $expires;
146 }
147
148 /**
149 * @since 6.17
150 *
151 * @return array|false
152 */
153 public function get_best_sale() {
154 if ( ! self::$sales ) {
155 return false;
156 }
157
158 if ( isset( self::$best_sale ) ) {
159 return self::$best_sale;
160 }
161
162 $best_sale = false;
163 foreach ( self::$sales as $sale ) {
164 if ( ! FrmApiHelper::is_for_user( $sale ) ) {
165 continue;
166 }
167
168 if ( ! $this->matches_ab_group( $sale ) ) {
169 continue;
170 }
171
172 if ( ! $best_sale || $sale['discount_percent'] > $best_sale['discount_percent'] ) {
173 $best_sale = $sale;
174 }
175 }
176
177 self::$best_sale = $best_sale;
178 return self::$best_sale;
179 }
180
181 /**
182 * Get text for best sale if applicable.
183 *
184 * @since 6.17
185 *
186 * @param string $key
187 * @return false|string False if no sale is active.
188 */
189 public static function get_best_sale_value( $key ) {
190 if ( ! isset( self::$instance ) ) {
191 self::$instance = new FrmSalesApi();
192 }
193
194 $sale = self::$instance->get_best_sale();
195
196 return is_array( $sale ) && ! empty( $sale[ $key ] ) ? $sale[ $key ] : false;
197 }
198
199 /**
200 * @since 6.17
201 *
202 * @param array $sale
203 * @return bool True if the sale is a match for the applicable group (if one is defined).
204 */
205 private function matches_ab_group( $sale ) {
206 if ( ! is_numeric( $sale['test_group'] ) ) {
207 // No test group, so return true.
208 return true;
209 }
210
211 $ab_group = $this->get_ab_group_for_current_site();
212 return $ab_group === $sale['test_group'];
213 }
214
215 /**
216 * @since 6.17
217 *
218 * @return int 1 or 0.
219 */
220 private function get_ab_group_for_current_site() {
221 $option = get_option( 'frm_sale_ab_group' );
222 if ( ! is_numeric( $option ) ) {
223 // Generate either 0 or 1.
224 $option = mt_rand( 0, 1 );
225 update_option( 'frm_sale_ab_group', $option, false );
226 }
227 return (int) $option;
228 }
229 }
230