PluginProbe
Formidable Forms – WordPress Form Builder for Contact Forms, Calculators, Quizzes & More / 4.11.02
Formidable Forms – WordPress Form Builder for Contact Forms, Calculators, Quizzes & More v4.11.02
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
← All changes | classes/controllers/FrmAddonsController.php +487 -832 6.284.11.02 View file →
@@ -4,98 +4,8 @@
4 4 }
5 5
6 6 class FrmAddonsController {
7 7
8 - /**
9 - * @var string
10 - */
11 - const SCRIPT_HANDLE = 'frm-addons-page';
12 -
13 - /**
14 - * @var array
15 - */
16 - private static $categories = array();
17 -
18 - /**
19 - * @var string
20 - */
21 - private static $request_addon_url;
22 -
23 - /**
24 - * @var string
25 - */
26 - protected static $plugin;
27 -
28 - /**
29 - * @since 6.15
30 - *
31 - * @return void
32 - */
33 - public static function load_admin_hooks() {
34 - add_action( 'admin_menu', self::class . '::menu', 100 );
35 - add_filter( 'pre_set_site_transient_update_plugins', self::class . '::check_update' );
36 -
37 - if ( ! FrmAppHelper::is_admin_page( 'formidable-addons' ) ) {
38 - return;
39 - }
40 -
41 - self::$request_addon_url = 'https://connect.formidableforms.com/add-on-request/';
42 -
43 - add_action( 'admin_enqueue_scripts', self::class . '::enqueue_assets', 15 );
44 - add_filter( 'frm_show_footer_links', '__return_false' );
45 - }
46 -
47 - /**
48 - * Enqueues the Add-Ons page scripts and styles.
49 - *
50 - * @since 6.15
51 - *
52 - * @return void
53 - */
54 - public static function enqueue_assets() {
55 - $plugin_url = FrmAppHelper::plugin_url();
56 - $version = FrmAppHelper::plugin_version();
57 - $js_dependencies = array(
58 - 'wp-i18n',
59 - // This prevents a console error "wp.hooks is undefined" in WP versions older than 5.7.
60 - 'wp-hooks',
61 - 'formidable_dom',
62 - );
63 -
64 - // Enqueue styles that needed.
65 - wp_enqueue_style( 'formidable-admin' );
66 - wp_enqueue_style( 'formidable-grids' );
67 -
68 - // Register and enqueue Add-Ons page style.
69 - wp_register_style( self::SCRIPT_HANDLE, $plugin_url . '/css/admin/addons-page.css', array(), $version );
70 - wp_enqueue_style( self::SCRIPT_HANDLE );
71 -
72 - // Register and enqueue Add-Ons page script.
73 - wp_register_script( self::SCRIPT_HANDLE, $plugin_url . '/js/addons-page.js', $js_dependencies, $version, true );
74 - wp_localize_script( self::SCRIPT_HANDLE, 'frmAddonsVars', self::get_js_variables() );
75 - wp_enqueue_script( self::SCRIPT_HANDLE );
76 - wp_set_script_translations( self::SCRIPT_HANDLE, 'formidable' );
77 -
78 - FrmAppHelper::dequeue_extra_global_scripts();
79 - }
80 -
81 - /**
82 - * Get the Add-Ons page JS variables as an array.
83 - *
84 - * @since 6.15
85 - *
86 - * @return array
87 - */
88 - private static function get_js_variables() {
89 - return array(
90 - 'proIsIncluded' => FrmAppHelper::pro_is_included(),
91 - 'addonRequestURL' => self::$request_addon_url,
92 - );
93 - }
94 -
95 - /**
96 - * @return void
97 - */
98 8 public static function menu() {
99 9 if ( ! current_user_can( 'activate_plugins' ) ) {
100 10 return;
101 11 }
@@ -100,67 +10,50 @@
100 10 return;
101 11 }
102 12
103 13 $label = __( 'Add-Ons', 'formidable' );
104 - $label = '<span style="color:#3FCA89">' . esc_html( $label ) . '</span>';
105 -
14 + if ( FrmAppHelper::pro_is_installed() ) {
15 + $label = '<span style="color:#fe5a1d">' . $label . '</span>';
16 + }
106 17 add_submenu_page( 'formidable', 'Formidable | ' . __( 'Add-Ons', 'formidable' ), $label, 'frm_view_forms', 'formidable-addons', 'FrmAddonsController::list_addons' );
107 18
108 - // Remove default created subpage, make the page with highest priority as default.
109 - remove_submenu_page( 'formidable', 'formidable' );
110 -
111 19 if ( ! FrmAppHelper::pro_is_installed() ) {
112 - $cta_text = FrmSalesApi::get_best_sale_value( 'menu_cta_text' );
113 -
114 - if ( ! $cta_text ) {
115 - $cta_text = __( 'Upgrade', 'formidable' );
116 - }
117 -
118 20 add_submenu_page(
119 21 'formidable',
120 22 'Formidable | ' . __( 'Upgrade', 'formidable' ),
121 - '<span class="frm-upgrade-submenu">' . esc_html( $cta_text ) . '</span>',
23 + '<span style="color:#fe5a1d">' . __( 'Upgrade', 'formidable' ) . '</span>',
122 24 'frm_view_forms',
123 25 'formidable-pro-upgrade',
124 - function () {
125 - // This function doesn't need to do anything.
126 - // The redirect is handled earlier to avoid issues with the headers being sent.
127 - }
26 + 'FrmAddonsController::upgrade_to_pro'
128 27 );
129 28 } elseif ( 'formidable-pro-upgrade' === FrmAppHelper::get_param( 'page' ) ) {
130 29 wp_safe_redirect( admin_url( 'admin.php?page=formidable' ) );
131 30 exit;
132 - }//end if
31 + }
133 32 }
134 33
135 - /**
136 - * @return void
137 - */
138 34 public static function list_addons() {
139 35 FrmAppHelper::include_svg();
36 + $installed_addons = apply_filters( 'frm_installed_addons', array() );
37 + $license_type = '';
140 38
141 - $view_path = FrmAppHelper::plugin_path() . '/classes/views/addons/';
142 - $installed_addons = apply_filters( 'frm_installed_addons', array() );
143 - $addons = self::get_api_addons();
144 - $errors = array();
145 - $license_type = '';
146 - $request_addon_url = self::$request_addon_url;
39 + $addons = self::get_api_addons();
40 + $errors = array();
147 41
148 42 if ( isset( $addons['error'] ) ) {
149 - $api = new FrmFormApi();
150 - $errors = $api->get_error_from_response( $addons );
151 - $license_type = $addons['error']['type'] ?? '';
43 + $api = new FrmFormApi();
44 + $errors = $api->get_error_from_response( $addons );
45 + $license_type = isset( $addons['error']['type'] ) ? $addons['error']['type'] : '';
152 46 unset( $addons['error'] );
153 47 }
154 48
155 - $pro = array(
49 + $pro = array(
156 50 'pro' => array(
157 - 'title' => 'Formidable Forms Pro',
158 - 'slug' => 'formidable-pro',
159 - 'released' => '2011-02-05',
160 - 'docs' => 'knowledgebase/',
161 - 'categories' => array( 'basic', 'plus', 'business', 'elite' ),
162 - 'excerpt' => 'Create calculators, surveys, smart forms, and data-driven applications. Build directories, real estate listings, job boards, and much more.',
51 + 'title' => 'Formidable Forms Pro',
52 + 'slug' => 'formidable-pro',
53 + 'released' => '2011-02-05',
54 + 'docs' => 'knowledgebase/',
55 + 'excerpt' => 'Create calculators, surveys, smart forms, and data-driven applications. Build directories, real estate listings, job boards, and much more.',
163 56 ),
164 57 );
165 58 $addons = $pro + $addons;
166 59 self::prepare_addons( $addons );
@@ -166,128 +59,29 @@
166 59 self::prepare_addons( $addons );
167 60
168 61 $pricing = FrmAppHelper::admin_upgrade_link( 'addons' );
169 62
170 - self::organize_and_get_categories();
171 - $categories = self::$categories;
172 -
173 - include $view_path . 'index.php';
63 + include( FrmAppHelper::plugin_path() . '/classes/views/addons/list.php' );
174 64 }
175 65
176 - /**
177 - * Organize and set categories.
178 - *
179 - * @since 6.15
180 - *
181 - * @return void
182 - */
183 - protected static function organize_and_get_categories() {
184 - unset( self::$categories['strategy11'] );
185 - ksort( self::$categories );
186 -
187 - $bottom_categories = array();
188 - $plans = FrmFormsHelper::get_license_types(
189 - array(
190 - 'include_all' => false,
191 - 'case_lower' => true,
192 - )
193 - );
194 -
195 - // Extract the elements to move
196 - foreach ( $plans as $plan ) {
197 - if ( isset( self::$categories[ $plan ] ) ) {
198 - $bottom_categories[ $plan ] = self::$categories[ $plan ];
199 - unset( self::$categories[ $plan ] );
200 - }
201 - }
202 -
203 - $special_categories = array();
204 -
205 - if ( 'elite' !== self::license_type() ) {
206 - $special_categories['available-addons'] = array(
207 - 'name' => __( 'Available', 'formidable' ),
208 - // To be assigned via JavaScript.
209 - 'count' => 0,
210 - );
211 - }
212 -
213 - $special_categories['active-addons'] = array(
214 - 'name' => __( 'Active', 'formidable' ),
215 - // To be assigned via JavaScript.
216 - 'count' => 0,
217 - );
218 -
219 - $special_categories['all-items'] = array(
220 - 'name' => __( 'All Add-Ons', 'formidable' ),
221 - // To be assigned via JavaScript.
222 - 'count' => 0,
223 - );
224 -
225 - self::$categories = array_merge(
226 - $special_categories,
227 - self::$categories,
228 - $bottom_categories
229 - );
230 - }
231 -
232 - /**
233 - * Organize and set categories.
234 - *
235 - * @since 6.15
236 - *
237 - * @param array $addon The addon array that will be modified by reference.
238 - *
239 - * @return void
240 - */
241 - protected static function set_categories( &$addon ) {
242 - if ( ! isset( $addon['categories'] ) ) {
243 - return;
244 - }
245 -
246 - $addon['category-slugs'] = array();
247 -
248 - foreach ( $addon['categories'] as $category ) {
249 - $category = FrmFormsHelper::convert_legacy_package_names( $category );
250 - $category_slug = sanitize_title( $category );
251 -
252 - // Add the slug to the new array.
253 - $addon['category-slugs'][] = $category_slug;
254 -
255 - if ( ! isset( self::$categories[ $category_slug ] ) ) {
256 - self::$categories[ $category_slug ] = array(
257 - 'name' => $category,
258 - 'count' => 0,
259 - );
260 - }
261 -
262 - ++self::$categories[ $category_slug ]['count'];
263 - }
264 - }
265 -
266 - /**
267 - * @return void
268 - */
269 66 public static function license_settings() {
270 67 $plugins = apply_filters( 'frm_installed_addons', array() );
68 + if ( empty( $plugins ) ) {
69 + esc_html_e( 'There are no plugins on your site that require a license', 'formidable' );
271 70
272 - if ( ! $plugins ) {
273 - esc_html_e( 'There are no plugins on your site that require a license', 'formidable' );
274 71 return;
275 72 }
276 73
277 74 ksort( $plugins );
278 75
279 - include FrmAppHelper::plugin_path() . '/classes/views/addons/settings.php';
76 + include( FrmAppHelper::plugin_path() . '/classes/views/addons/settings.php' );
280 77 }
281 78
282 - /**
283 - * @return array
284 - */
285 79 protected static function get_api_addons() {
286 80 $api = new FrmFormApi();
287 81 $addons = $api->get_api_info();
288 82
289 - if ( ! $addons ) {
83 + if ( empty( $addons ) ) {
290 84 $addons = self::fallback_plugin_list();
291 85 } else {
292 86 foreach ( $addons as $k => $addon ) {
293 87 if ( empty( $addon['excerpt'] ) && $k !== 'error' ) {
@@ -299,24 +93,11 @@
299 93 return $addons;
300 94 }
301 95
302 96 /**
303 - * Retrieves the count of available addons.
304 - *
305 - * @since 6.9
306 - *
307 - * @return int Count of addons.
308 - */
309 - public static function get_addons_count() {
310 - $addons = self::get_api_addons();
311 - return count( $addons );
312 - }
313 -
314 - /**
315 97 * If the API is unable to connect, show something on the addons page
316 98 *
317 99 * @since 3.04.03
318 - *
319 100 * @return array
320 101 */
321 102 protected static function fallback_plugin_list() {
322 103 $list = array(
@@ -326,20 +107,20 @@
326 107 'docs' => '',
327 108 'excerpt' => 'Enhance your basic Formidable forms with a plethora of Pro field types and features. Create advanced forms and data-driven applications in minutes.',
328 109 ),
329 110 'mailchimp' => array(
330 - 'title' => 'Mailchimp Forms',
331 - 'excerpt' => 'Get on the path to more sales and leads in a matter of minutes. Add leads to a Mailchimp mailing list when they submit forms and update their information along with the entry.', // phpcs:ignore SlevomatCodingStandard.Files.LineLength.LineTooLong
111 + 'title' => 'MailChimp Forms',
112 + 'excerpt' => 'Get on the path to more sales and leads in a matter of minutes. Add leads to a MailChimp mailing list when they submit forms and update their information along with the entry.',
332 113 ),
333 114 'registration' => array(
334 115 'title' => 'User Registration Forms',
335 116 'link' => 'downloads/user-registration/',
336 - 'excerpt' => 'Give new users access to your site as quickly and painlessly as possible. Allow users to register, edit and be able to login to their profiles on your site from the front end in a clean, customized registration form.', // phpcs:ignore SlevomatCodingStandard.Files.LineLength.LineTooLong
117 + 'excerpt' => 'Give new users access to your site as quickly and painlessly as possible. Allow users to register, edit and be able to login to their profiles on your site from the front end in a clean, customized registration form.',
337 118 ),
338 119 'paypal' => array(
339 120 'title' => 'PayPal Standard Forms',
340 121 'link' => 'downloads/paypal-standard/',
341 - 'excerpt' => 'Automate your business by collecting instant payments from your clients. Collect information, calculate a total, and send them on to PayPal. Require a payment before publishing content on your site.', // phpcs:ignore SlevomatCodingStandard.Files.LineLength.LineTooLong
122 + 'excerpt' => 'Automate your business by collecting instant payments from your clients. Collect information, calculate a total, and send them on to PayPal. Require a payment before publishing content on your site.',
342 123 ),
343 124 'stripe' => array(
344 125 'title' => 'Stripe Forms',
345 126 'docs' => 'knowledgebase/stripe/',
@@ -371,9 +152,9 @@
371 152 'excerpt' => 'Instantly add Bootstrap styling to all your Formidable forms.',
372 153 ),
373 154 'zapier' => array(
374 155 'title' => 'Zapier Forms',
375 - 'excerpt' => 'Connect with hundreds of different applications through Zapier. Insert a new row in a Google docs spreadsheet, post on Twitter, or add a new Dropbox file with your form.', // phpcs:ignore SlevomatCodingStandard.Files.LineLength.LineTooLong
156 + 'excerpt' => 'Connect with hundreds of different applications through Zapier. Insert a new row in a Google docs spreadsheet, post on Twitter, or add a new Dropbox file with your form.',
376 157 ),
377 158 'signature' => array(
378 159 'title' => 'Digital Signature Forms',
379 160 'excerpt' => 'Add a signature field to your form. The user may write their signature with a trackpad/mouse or just type it.',
@@ -391,13 +172,8 @@
391 172 'views' => array(
392 173 'title' => 'Formidable Views',
393 174 'excerpt' => 'Add the power of views to your Formidable Forms to display your form submissions in listings, tables, calendars, and more.',
394 175 ),
395 - 'quiz_maker' => array(
396 - 'title' => 'Quiz Maker',
397 - 'link' => 'downloads/quiz-maker/',
398 - 'excerpt' => 'Make quizzes, automatically score them and show user scores.',
399 - ),
400 176 );
401 177
402 178 $defaults = array(
403 179 'released' => '',
@@ -406,9 +182,8 @@
406 182 foreach ( $list as $k => $info ) {
407 183 $info['slug'] = $k;
408 184 $list[ $k ] = array_merge( $defaults, $info );
409 185 }
410 -
411 186 return $list;
412 187 }
413 188
414 189 /**
@@ -414,9 +189,8 @@
414 189 /**
415 190 * If Pro is missing but has been authenticated, include a download URL
416 191 *
417 192 * @since 3.04.03
418 - *
419 193 * @return string
420 194 */
421 195 public static function get_pro_download_url() {
422 196 $license = self::get_pro_license();
@@ -423,20 +197,17 @@
423 197 $api = new FrmFormApi( $license );
424 198 $downloads = $api->get_api_info();
425 199 $pro = self::get_pro_from_addons( $downloads );
426 200
427 - return $pro['url'] ?? '';
201 + return isset( $pro['url'] ) ? $pro['url'] : '';
428 202 }
429 203
430 204 /**
431 205 * @since 4.08
432 - *
433 - * @return string
434 206 */
435 207 public static function get_pro_license() {
436 208 $pro_cred_store = 'frmpro-credentials';
437 209 $pro_wpmu_store = 'frmpro-wpmu-sitewide';
438 -
439 210 if ( is_multisite() && get_site_option( $pro_wpmu_store ) ) {
440 211 $creds = get_site_option( $pro_cred_store );
441 212 } else {
442 213 $creds = get_option( $pro_cred_store );
@@ -446,36 +217,28 @@
446 217 return '';
447 218 }
448 219
449 220 $license = $creds['license'];
450 -
451 - if ( ! $license ) {
221 + if ( empty( $license ) ) {
452 222 return '';
453 223 }
454 224
455 - if ( str_contains( $license, '-' ) ) {
456 - // This is a fix for licenses saved in the past
457 - return strtoupper( $license );
225 + if ( strpos( $license, '-' ) ) {
226 + // this is a fix for licenses saved in the past
227 + $license = strtoupper( $license );
458 228 }
459 -
460 229 return $license;
461 230 }
462 231
463 232 /**
464 233 * @since 4.08
465 - *
466 - * @param array $addons
467 - *
468 - * @return array
469 234 */
470 235 protected static function get_pro_from_addons( $addons ) {
471 - return $addons['93790'] ?? array();
236 + return isset( $addons['93790'] ) ? $addons['93790'] : array();
472 237 }
473 238
474 239 /**
475 240 * @since 4.06
476 - *
477 - * @return string
478 241 */
479 242 public static function license_type() {
480 243 if ( is_callable( 'FrmProAddonsController::license_type' ) ) {
481 244 return FrmProAddonsController::license_type();
@@ -485,47 +248,39 @@
485 248 }
486 249
487 250 /**
488 251 * @since 4.0.01
489 - *
490 - * @return bool
491 252 */
492 253 public static function is_license_expired() {
493 254 $version_info = self::get_primary_license_info();
494 -
495 255 if ( ! isset( $version_info['error'] ) ) {
496 256 return false;
497 257 }
498 258
499 - $expires = $version_info['error']['expires'] ?? 0;
259 + return $version_info['error'];
260 + }
500 261
501 - if ( ! $expires || $expires > time() ) {
502 - return false;
262 + /**
263 + * @since 4.08
264 + *
265 + * @return boolean|int false or the number of days until expiration.
266 + */
267 + public static function is_license_expiring() {
268 + if ( is_callable( 'FrmProAddonsController::is_license_expiring' ) ) {
269 + return FrmProAddonsController::is_license_expiring();
503 270 }
504 271
505 - $rate_limited = ! empty( $version_info['response_code'] ) && 429 === (int) $version_info['response_code'];
506 -
507 - if ( $rate_limited ) {
508 - // Do not return false positives for rate limited responses.
509 - return false;
510 - }
511 -
512 - return $version_info['error'];
272 + return false;
513 273 }
514 274
515 275 /**
516 276 * @since 4.08
517 - * @since 6.7 This is public.
518 - *
519 - * @return array|false
520 277 */
521 - public static function get_primary_license_info() {
278 + protected static function get_primary_license_info() {
522 279 $installed_addons = apply_filters( 'frm_installed_addons', array() );
523 -
524 - if ( ! $installed_addons || ! isset( $installed_addons['formidable_pro'] ) ) {
280 + if ( empty( $installed_addons ) || ! isset( $installed_addons['formidable_pro'] ) ) {
525 281 return false;
526 282 }
527 -
528 283 $installed_addons = array(
529 284 'formidable_pro' => $installed_addons['formidable_pro'],
530 285 );
531 286
@@ -533,12 +288,8 @@
533 288 }
534 289
535 290 /**
536 291 * @since 3.04.03
537 - *
538 - * @param mixed $transient
539 - *
540 - * @return object
541 292 */
542 293 public static function check_update( $transient ) {
543 294 if ( ! FrmAppHelper::pro_is_installed() ) {
544 295 // Don't make any changes if only Lite is installed.
@@ -549,18 +300,22 @@
549 300 $transient = new stdClass();
550 301 }
551 302
552 303 $installed_addons = apply_filters( 'frm_installed_addons', array() );
553 -
554 - if ( ! $installed_addons ) {
304 + if ( empty( $installed_addons ) ) {
555 305 return $transient;
556 306 }
557 307
558 - $version_info = self::fill_update_addon_info( $installed_addons );
308 + $version_info = self::fill_update_addon_info( $installed_addons );
309 +
559 310 $transient->last_checked = time();
560 - $wp_plugins = self::get_plugins();
561 311
562 - foreach ( $version_info as $plugin ) {
312 + if ( ! function_exists( 'get_plugins' ) ) {
313 + require_once ABSPATH . 'wp-admin/includes/plugin.php';
314 + }
315 + $wp_plugins = get_plugins();
316 +
317 + foreach ( $version_info as $id => $plugin ) {
563 318 $plugin = (object) $plugin;
564 319
565 320 if ( ! isset( $plugin->new_version ) || ! isset( $plugin->package ) ) {
566 321 continue;
@@ -566,61 +321,49 @@
566 321 continue;
567 322 }
568 323
569 324 $folder = $plugin->plugin;
570 -
571 - if ( ! $folder ) {
325 + if ( empty( $folder ) ) {
572 326 continue;
573 327 }
574 328
575 329 if ( ! self::is_installed( $folder ) ) {
576 - // Don't show an update if the plugin isn't installed
330 + // don't show an update if the plugin isn't installed
577 331 continue;
578 332 }
579 333
580 - $wp_plugin = $wp_plugins[ $folder ] ?? array();
581 - $wp_version = $wp_plugin['Version'] ?? '1.0';
582 - $plugin->slug = explode( '/', $folder )[0];
334 + $wp_plugin = isset( $wp_plugins[ $folder ] ) ? $wp_plugins[ $folder ] : array();
335 + $wp_version = isset( $wp_plugin['Version'] ) ? $wp_plugin['Version'] : '1.0';
583 336
584 337 if ( version_compare( $wp_version, $plugin->new_version, '<' ) ) {
338 + $slug = explode( '/', $folder );
339 + $plugin->slug = $slug[0];
585 340 $transient->response[ $folder ] = $plugin;
586 - } else {
587 - $transient->no_update[ $folder ] = $plugin;
588 341 }
589 342
590 343 $transient->checked[ $folder ] = $wp_version;
591 - }//end foreach
592 344
345 + }
346 +
593 347 return $transient;
594 348 }
595 349
596 350 /**
597 - * Copy of FrmAppHelper::get_plugins.
598 - * Because this gets called on "pre_set_site_transient_update_plugins" an old version of FrmAppHelper may be loaded on plugin update.
599 - * This means that trying to access FrmAppHelper::get_plugins when upgrading from a Lite version before v5.5 results in a one-off error.
600 - *
601 - * @since 5.5.2
602 - *
603 - * @return array
604 - */
605 - protected static function get_plugins() {
606 - if ( ! function_exists( 'get_plugins' ) ) {
607 - require_once ABSPATH . 'wp-admin/includes/plugin.php';
608 - }
609 - return get_plugins();
610 - }
611 -
612 - /**
613 351 * Check if a plugin is installed before showing an update for it
614 352 *
615 353 * @since 3.05
616 354 *
617 - * @param string $plugin The folder/filename.php for a plugin.
355 + * @param string $plugin - the folder/filename.php for a plugin
618 356 *
619 357 * @return bool - True if installed
620 358 */
621 359 protected static function is_installed( $plugin ) {
622 - $all_plugins = self::get_plugins();
360 + if ( ! function_exists( 'get_plugins' ) ) {
361 + require_once ABSPATH . 'wp-admin/includes/plugin.php';
362 + }
363 +
364 + $all_plugins = get_plugins();
365 +
623 366 return isset( $all_plugins[ $plugin ] );
624 367 }
625 368
626 369 /**
@@ -635,51 +378,45 @@
635 378 $version_info = array();
636 379
637 380 foreach ( $installed_addons as $addon ) {
638 381 if ( $addon->store_url !== 'https://formidableforms.com' ) {
639 - // Check if this is a third-party addon
382 + // check if this is a third-party addon
640 383 continue;
641 384 }
642 385
643 386 $new_license = $addon->license;
644 -
645 - if ( ! $new_license || in_array( $new_license, $checked_licenses, true ) ) {
387 + if ( empty( $new_license ) || in_array( $new_license, $checked_licenses ) ) {
646 388 continue;
647 389 }
648 390
649 391 $checked_licenses[] = $new_license;
650 - $api = new FrmFormApi( $new_license );
651 392
652 - if ( ! $version_info ) {
393 + $api = new FrmFormApi( $new_license );
394 + if ( empty( $version_info ) ) {
653 395 $version_info = $api->get_api_info();
654 396 continue;
655 397 }
656 398
657 399 $plugin = $api->get_addon_for_license( $addon, $version_info );
658 -
659 - if ( ! $plugin ) {
400 + if ( empty( $plugin ) ) {
660 401 continue;
661 402 }
662 403
663 - $download_id = $plugin['id'] ?? 0;
404 + $download_id = isset( $plugin['id'] ) ? $plugin['id'] : 0;
405 + if ( ! empty( $download_id ) && ! isset( $version_info[ $download_id ]['package'] ) ) {
406 + // if this addon is using its own license, get the update url
407 + $addon_info = $api->get_api_info();
664 408
665 - if ( ! $download_id || isset( $version_info[ $download_id ]['package'] ) ) {
666 - continue;
409 + $version_info[ $download_id ] = $addon_info[ $download_id ];
410 + if ( isset( $addon_info['error'] ) ) {
411 + $version_info[ $download_id ]['error'] = array(
412 + 'message' => $addon_info['error']['message'],
413 + 'code' => $addon_info['error']['code'],
414 + );
415 + }
667 416 }
417 + }
668 418
669 - // If this addon is using its own license, get the update url
670 - $addon_info = $api->get_api_info();
671 -
672 - $version_info[ $download_id ] = $addon_info[ $download_id ];
673 -
674 - if ( isset( $addon_info['error'] ) ) {
675 - $version_info[ $download_id ]['error'] = array(
676 - 'message' => $addon_info['error']['message'],
677 - 'code' => $addon_info['error']['code'],
678 - );
679 - }
680 - }//end foreach
681 -
682 419 return $version_info;
683 420 }
684 421
685 422 /**
@@ -685,11 +422,9 @@
685 422 /**
686 423 * Get the action link for an addon that isn't active.
687 424 *
688 425 * @since 3.06.03
689 - *
690 - * @param string $plugin The plugin slug.
691 - *
426 + * @param string $plugin The plugin slug
692 427 * @return array
693 428 */
694 429 public static function install_link( $plugin ) {
695 430 $link = array();
@@ -700,28 +435,23 @@
700 435 $link = array(
701 436 'url' => $addon['plugin'],
702 437 'class' => 'frm-activate-addon',
703 438 );
704 - } elseif ( ! empty( $addon['url'] ) ) {
439 + } elseif ( isset( $addon['url'] ) && ! empty( $addon['url'] ) ) {
705 440 $link = array(
706 441 'url' => $addon['url'],
707 442 'class' => 'frm-install-addon',
708 443 );
709 - } elseif ( ! empty( $addon['categories'] ) ) {
444 + } elseif ( isset( $addon['categories'] ) && ! empty( $addon['categories'] ) ) {
710 445 $link = array(
711 446 'categories' => $addon['categories'],
712 447 );
713 448 }
714 449
715 - if ( $link ) {
450 + if ( ! empty( $link ) ) {
716 451 $link['status'] = $addon['status']['type'];
717 452 }
718 - } elseif ( current_user_can( 'activate_plugins' ) && self::is_installed( 'formidable-' . $plugin . '/formidable-' . $plugin . '.php' ) ) {
719 - $link = array(
720 - 'url' => 'formidable-' . $plugin . '/formidable-' . $plugin . '.php',
721 - 'class' => 'frm-activate-addon',
722 - );
723 - }//end if
453 + }
724 454
725 455 return $link;
726 456 }
727 457
@@ -726,41 +456,33 @@
726 456 }
727 457
728 458 /**
729 459 * @since 4.09
730 - *
731 - * @param string $plugin The plugin slug.
732 - *
460 + * @param string $plugin The plugin slug
733 461 * @return array|false
734 462 */
735 - public static function get_addon( $plugin ) {
463 + protected static function get_addon( $plugin ) {
736 464 $addons = self::get_api_addons();
737 465 self::prepare_addons( $addons );
738 -
739 466 foreach ( $addons as $addon ) {
740 467 $slug = explode( '/', $addon['plugin'] );
741 -
742 468 if ( $slug[0] === 'formidable-' . $plugin ) {
743 469 return $addon;
744 470 }
745 471 }
746 -
747 472 return false;
748 473 }
749 474
750 475 /**
751 476 * @since 4.09
752 - *
753 477 * @return string
754 478 */
755 479 protected static function get_license_type() {
756 480 $license_type = '';
757 481 $addons = self::get_api_addons();
758 -
759 482 if ( isset( $addons['error'] ) && isset( $addons['error']['type'] ) ) {
760 - return $addons['error']['type'];
483 + $license_type = $addons['error']['type'];
761 484 }
762 -
763 485 return $license_type;
764 486 }
765 487
766 488 /**
@@ -765,10 +487,10 @@
765 487
766 488 /**
767 489 * @since 3.04.03
768 490 *
769 - * @param array $addons
770 - * @param object $license The FrmAddon object.
491 + * @param array $addons
492 + * @param object $license The FrmAddon object
771 493 *
772 494 * @return array
773 495 */
774 496 public static function get_addon_for_license( $addons, $license ) {
@@ -773,12 +495,11 @@
773 495 */
774 496 public static function get_addon_for_license( $addons, $license ) {
775 497 $download_id = $license->download_id;
776 498 $plugin = array();
777 -
778 - if ( ! $download_id && $addons ) {
499 + if ( empty( $download_id ) && ! empty( $addons ) ) {
779 500 foreach ( $addons as $addon ) {
780 - if ( 0 === strcasecmp( $license->plugin_name, $addon['title'] ) ) {
501 + if ( strtolower( $license->plugin_name ) == strtolower( $addon['title'] ) ) {
781 502 return $addon;
782 503 }
783 504 }
784 505 } elseif ( isset( $addons[ $download_id ] ) ) {
@@ -787,52 +508,36 @@
787 508
788 509 return $plugin;
789 510 }
790 511
791 - /**
792 - * @param array $addons
793 - *
794 - * @return void
795 - */
796 512 protected static function prepare_addons( &$addons ) {
797 - // Reset categories to prevent count accumulation across multiple calls.
798 - self::$categories = array();
799 -
800 513 $activate_url = '';
801 -
802 514 if ( current_user_can( 'activate_plugins' ) ) {
803 515 $activate_url = add_query_arg( array( 'action' => 'activate' ), admin_url( 'plugins.php' ) );
804 516 }
805 517
806 518 $loop_addons = $addons;
807 -
808 519 foreach ( $loop_addons as $id => $addon ) {
809 520 if ( is_numeric( $id ) ) {
810 521 $slug = str_replace( array( '-wordpress-plugin', '-wordpress' ), '', $addon['slug'] );
811 522 $file_name = $addon['plugin'];
812 523 } else {
813 - $slug = $id;
814 - $base_file = $addon['file'] ?? 'formidable-' . $slug;
524 + $slug = $id;
525 + if ( isset( $addon['file'] ) ) {
526 + $base_file = $addon['file'];
527 + } else {
528 + $base_file = 'formidable-' . $slug;
529 + }
815 530 $file_name = $base_file . '/' . $base_file . '.php';
816 -
817 531 if ( ! isset( $addon['plugin'] ) ) {
818 532 $addon['plugin'] = $file_name;
819 533 }
820 534 }
821 535
822 - $addon['installed'] = self::is_installed( $file_name );
823 -
824 - if ( $addon['installed'] && 'formidable-views/formidable-views.php' === $file_name ) {
825 - $active_views_version = self::get_active_views_version();
826 -
827 - if ( false !== $active_views_version && $slug !== $active_views_version ) {
828 - $addon['installed'] = false;
829 - }
830 - }
831 -
536 + $addon['installed'] = self::is_installed( $file_name );
832 537 $addon['activate_url'] = '';
833 538
834 - if ( $addon['installed'] && $activate_url && ! self::is_plugin_active( $file_name, $slug ) ) {
539 + if ( $addon['installed'] && ! empty( $activate_url ) && ! is_plugin_active( $file_name ) ) {
835 540 $addon['activate_url'] = add_query_arg(
836 541 array(
837 542 '_wpnonce' => wp_create_nonce( 'activate-plugin_' . $file_name ),
838 543 'plugin' => $file_name,
@@ -848,62 +553,30 @@
848 553
849 554 if ( ! isset( $addon['link'] ) ) {
850 555 $addon['link'] = 'downloads/' . $slug . '/';
851 556 }
557 + self::prepare_addon_link( $addon['link'] );
852 558
853 - self::prepare_addon_link( $addon['link'] );
854 559 self::set_addon_status( $addon );
855 - self::set_categories( $addon );
856 -
857 560 $addons[ $id ] = $addon;
858 - }//end foreach
859 - }
860 -
861 - /**
862 - * @param string $file_name
863 - * @param string $slug
864 - *
865 - * @return bool
866 - */
867 - private static function is_plugin_active( $file_name, $slug ) {
868 - if ( 'formidable-views/formidable-views.php' === $file_name ) {
869 - return self::get_active_views_version() === $slug;
870 561 }
871 - return is_plugin_active( $file_name );
872 562 }
873 563
874 564 /**
875 - * @return false|string either 'visual-views' or 'views', false if one is not found.
876 - */
877 - private static function get_active_views_version() {
878 - if ( ! is_callable( 'FrmViewsAppHelper::plugin_version' ) ) {
879 - return false;
880 - }
881 -
882 - $plugin_version = FrmViewsAppHelper::plugin_version();
883 - return version_compare( $plugin_version, '5.0', '>=' ) ? 'visual-views' : 'views';
884 - }
885 -
886 - /**
887 565 * @since 3.04.02
888 - *
889 - * @param string $link
890 - *
891 - * @return void
892 566 */
893 567 protected static function prepare_addon_link( &$link ) {
894 568 $site_url = 'https://formidableforms.com/';
895 -
896 - if ( ! str_starts_with( $link, 'http' ) ) {
569 + if ( strpos( $link, 'http' ) !== 0 ) {
897 570 $link = $site_url . $link;
898 571 }
899 -
900 - $link = FrmAppHelper::make_affiliate_url( $link );
901 -
902 - $utm = array(
903 - 'campaign' => 'addons',
572 + $link = FrmAppHelper::make_affiliate_url( $link );
573 + $query_args = array(
574 + 'utm_source' => 'WordPress',
575 + 'utm_medium' => 'addons',
576 + 'utm_campaign' => 'liteplugin',
904 577 );
905 - $link = FrmAppHelper::maybe_add_missing_utm( $link, $utm );
578 + $link = add_query_arg( $query_args, $link );
906 579 }
907 580
908 581 /**
909 582 * Add the status to the addon array. Status options are:
@@ -909,12 +582,8 @@
909 582 * Add the status to the addon array. Status options are:
910 583 * installed, active, not installed
911 584 *
912 585 * @since 3.04.02
913 - *
914 - * @param array $addon
915 - *
916 - * @return void
917 586 */
918 587 protected static function set_addon_status( &$addon ) {
919 588 if ( ! empty( $addon['activate_url'] ) ) {
920 589 $addon['status'] = array(
@@ -933,110 +602,273 @@
933 602 );
934 603 }
935 604 }
936 605
937 - /**
938 - * @since 5.5.2
939 - *
940 - * @param string $plugin
941 - * @param string $redirect
942 - * @param bool $network_wide
943 - * @param bool $silent
944 - *
945 - * @return WP_Error|null Null on success, WP_Error on invalid file.
946 - */
947 - protected static function activate_plugin( $plugin, $redirect = '', $network_wide = false, $silent = false ) {
948 - if ( ! function_exists( 'activate_plugin' ) ) {
949 - require_once ABSPATH . 'wp-admin/includes/plugin.php';
950 - }
951 - return activate_plugin( $plugin, $redirect, $network_wide, $silent );
952 - }
606 + public static function upgrade_to_pro() {
607 + FrmAppHelper::include_svg();
953 608
954 - /**
955 - * Deactivate a specified plugin.
956 - *
957 - * @since 6.8
958 - *
959 - * @param string $plugin
960 - * @param bool $silent
961 - *
962 - * @return void
963 - */
964 - protected static function deactivate_plugin( $plugin, $silent = false ) {
965 - if ( ! function_exists( 'deactivate_plugins' ) ) {
966 - require_once ABSPATH . 'wp-admin/includes/plugin.php';
967 - }
968 - deactivate_plugins( $plugin, $silent );
609 + $link_parts = array(
610 + 'medium' => 'upgrade',
611 + 'content' => 'button',
612 + );
613 +
614 + $features = array(
615 + 'Display Entries' => array(
616 + array(
617 + 'label' => 'Display form data with virtually limitless views',
618 + 'link' => array(
619 + 'content' => 'views',
620 + 'param' => 'views-display-form-data',
621 + ),
622 + 'lite' => false,
623 + ),
624 + array(
625 + 'label' => 'Generate graphs and stats based on your submitted data',
626 + 'link' => array(
627 + 'content' => 'graphs',
628 + 'param' => 'statistics-graphs-wordpress-forms',
629 + ),
630 + 'lite' => false,
631 + ),
632 + ),
633 + 'Entry Management' => array(
634 + array(
635 + 'label' => 'Import entries from a CSV',
636 + 'link' => array(
637 + 'content' => 'import-entries',
638 + 'param' => 'importing-exporting-wordpress-forms',
639 + ),
640 + 'lite' => false,
641 + ),
642 + array(
643 + 'label' => 'Logged-in users can save drafts and return later',
644 + 'link' => array(
645 + 'content' => 'save-drafts',
646 + 'param' => 'save-drafts-wordpress-form',
647 + ),
648 + 'lite' => false,
649 + ),
650 + array(
651 + 'label' => 'Flexibly and powerfully view, edit, and delete entries from anywhere on your site',
652 + 'link' => array(
653 + 'content' => 'front-edit',
654 + 'param' => 'wordpress-front-end-editing',
655 + ),
656 + 'lite' => false,
657 + ),
658 + array(
659 + 'label' => 'View form submissions from the back-end',
660 + 'lite' => true,
661 + ),
662 + array(
663 + 'label' => 'Export your entries to a CSV',
664 + 'lite' => true,
665 + ),
666 + ),
667 + 'Form Building' => array(
668 + array(
669 + 'label' => 'Save a calculated value into a field',
670 + 'link' => array(
671 + 'content' => 'calculations',
672 + 'param' => 'field-calculations-wordpress-form',
673 + ),
674 + 'lite' => false,
675 + ),
676 + array(
677 + 'label' => 'Allow multiple file uploads',
678 + 'link' => array(
679 + 'content' => 'file-uploads',
680 + 'param' => 'wordpress-multi-file-upload-fields',
681 + ),
682 + 'lite' => false,
683 + ),
684 + array(
685 + 'label' => 'Repeat sections of fields',
686 + 'link' => array(
687 + 'content' => 'repeaters',
688 + 'param' => 'repeatable-sections-forms',
689 + ),
690 + 'lite' => false,
691 + ),
692 + array(
693 + 'label' => 'Hide and show fields conditionally based on other fields or the user\'s role',
694 + 'link' => array(
695 + 'content' => 'conditional-logic',
696 + 'param' => 'conditional-logic-wordpress-forms',
697 + ),
698 + 'lite' => false,
699 + ),
700 + array(
701 + 'label' => 'Confirmation fields',
702 + 'link' => array(
703 + 'content' => 'confirmation-fields',
704 + 'param' => 'confirmation-fields-wordpress-forms',
705 + ),
706 + 'lite' => false,
707 + ),
708 + array(
709 + 'label' => 'Multi-paged forms',
710 + 'link' => array(
711 + 'content' => 'page-breaks',
712 + 'param' => 'wordpress-multi-page-forms',
713 + ),
714 + 'lite' => false,
715 + ),
716 + array(
717 + 'label' => 'Include section headings, page breaks, rich text, dates, times, scales, star ratings, sliders, toggles, dynamic fields populated from other forms, passwords, and tags in advanced forms.',
718 + 'lite' => false,
719 + ),
720 + array(
721 + 'label' => 'Include text, email, url, paragraph text, radio, checkbox, dropdown fields, hidden fields, user ID fields, and HTML blocks in your form.',
722 + 'lite' => true,
723 + ),
724 + array(
725 + 'label' => 'Drag & Drop Form building',
726 + 'link' => array(
727 + 'content' => 'drag-drop',
728 + 'param' => 'drag-drop-forms',
729 + ),
730 + 'lite' => true,
731 + ),
732 + array(
733 + 'label' => 'Create forms from Templates',
734 + 'link' => array(
735 + 'content' => 'form-templates',
736 + 'param' => 'wordpress-form-templates',
737 + ),
738 + 'lite' => true,
739 + ),
740 + array(
741 + 'label' => 'Import and export forms with XML',
742 + 'link' => array(
743 + 'content' => 'import',
744 + 'param' => 'importing-exporting-wordpress-forms',
745 + ),
746 + 'lite' => true,
747 + ),
748 + array(
749 + 'label' => 'Use input placeholder text in your fields that clear when typing starts.',
750 + 'lite' => true,
751 + ),
752 + ),
753 + 'Form Actions' => array(
754 + array(
755 + 'label' => 'Conditionally send your email notifications based on values in your form',
756 + 'link' => array(
757 + 'content' => 'conditional-emails',
758 + ),
759 + 'lite' => false,
760 + ),
761 + array(
762 + 'label' => 'Create and edit WordPress posts or custom posts from the front-end',
763 + 'link' => array(
764 + 'content' => 'create-posts',
765 + 'param' => 'create-posts-pages-wordpress-forms',
766 + ),
767 + 'lite' => false,
768 + ),
769 + array(
770 + 'label' => 'Send multiple emails and autoresponders',
771 + 'link' => array(
772 + 'content' => 'multiple-emails',
773 + 'param' => 'virtually-unlimited-emails',
774 + ),
775 + 'lite' => true,
776 + ),
777 + ),
778 + 'Form Appearance' => array(
779 + array(
780 + 'label' => 'Create Multiple styles for different forms',
781 + 'link' => array(
782 + 'content' => 'multiple-styles',
783 + 'param' => 'wordpress-visual-form-styler',
784 + ),
785 + 'lite' => false,
786 + ),
787 + array(
788 + 'label' => 'Customizable layout with CSS classes',
789 + 'link' => array(
790 + 'content' => 'form-layout',
791 + 'param' => 'wordpress-mobile-friendly-forms',
792 + ),
793 + 'lite' => true,
794 + ),
795 + array(
796 + 'label' => 'Customize the HTML for your forms',
797 + 'link' => array(
798 + 'content' => 'custom-html',
799 + 'param' => 'customizable-html-wordpress-form',
800 + ),
801 + 'lite' => true,
802 + ),
803 + array(
804 + 'label' => 'Style your form with the Visual Form Styler',
805 + 'lite' => true,
806 + ),
807 + ),
808 + );
809 +
810 + include( FrmAppHelper::plugin_path() . '/classes/views/addons/upgrade_to_pro.php' );
969 811 }
970 812
971 813 /**
972 - * Uninstall a specified plugin.
814 + * Install Pro after connection with Formidable.
973 815 *
974 - * @since 6.8
975 - *
976 - * @param string $plugin
977 - *
978 - * @return true|WP_Error True on success, WP_Error on invalid file.
816 + * @since 4.02.05
979 817 */
980 - protected static function uninstall_plugin( $plugin ) {
981 - if ( ! current_user_can( 'delete_plugins' ) ) {
982 - return new WP_Error( 'uninstall_failed', __( 'Current user cannot delete plugins.', 'formidable' ) );
983 - }
818 + public static function connect_pro() {
819 + FrmAppHelper::permission_check( 'install_plugins' );
820 + check_ajax_referer( 'frm_ajax', 'nonce' );
984 821
985 - if ( ! function_exists( 'delete_plugins' ) ) {
986 - require_once ABSPATH . 'wp-admin/includes/plugin.php';
822 + $url = FrmAppHelper::get_post_param( 'plugin', '', 'sanitize_text_field' );
823 + if ( FrmAppHelper::pro_is_installed() || empty( $url ) ) {
824 + wp_die();
987 825 }
988 826
989 - self::deactivate_plugin( $plugin, true );
990 - $result = delete_plugins( array( $plugin ) );
827 + $response = array();
991 828
992 - return is_wp_error( $result ) ? $result : true;
993 - }
829 + // It's already installed and active.
830 + $active = activate_plugin( 'formidable-pro/formidable-pro.php', false, false, true );
831 + if ( is_wp_error( $active ) ) {
832 + // The plugin was installed, but not active. Download it now.
833 + self::ajax_install_addon();
834 + } else {
835 + $response['active'] = true;
836 + $response['success'] = true;
837 + }
994 838
995 - /**
996 - * @since 5.0.10
997 - *
998 - * @return string
999 - */
1000 - protected static function get_current_plugin() {
1001 - if ( empty( self::$plugin ) ) {
1002 - self::$plugin = FrmAppHelper::get_param( 'plugin', '', 'post', 'esc_url_raw' );
1003 - }
1004 - return self::$plugin;
839 + echo json_encode( $response );
840 + wp_die();
1005 841 }
1006 842
1007 843 /**
1008 844 * @since 4.08
1009 - *
1010 - * @return mixed[]|null
1011 845 */
1012 846 protected static function download_and_activate() {
847 + // Set the current screen to avoid undefined notices.
1013 848 if ( is_admin() ) {
1014 - FrmAppHelper::set_current_screen_and_hook_suffix();
849 + global $hook_suffix;
850 + set_current_screen();
1015 851 }
1016 852
1017 853 self::maybe_show_cred_form();
1018 854
1019 855 $installed = self::install_addon();
1020 -
1021 856 if ( is_array( $installed ) && isset( $installed['message'] ) ) {
1022 857 return $installed;
1023 858 }
1024 - self::handle_addon_action( $installed, 'activate' );
1025 - return null;
859 + self::maybe_activate_addon( $installed );
1026 860 }
1027 861
1028 862 /**
1029 863 * @since 3.04.02
1030 - *
1031 - * @return void
1032 864 */
1033 865 protected static function maybe_show_cred_form() {
1034 866 if ( ! function_exists( 'request_filesystem_credentials' ) ) {
1035 - include_once ABSPATH . 'wp-admin/includes/file.php';
867 + include_once( ABSPATH . 'wp-admin/includes/file.php' );
1036 868 }
1037 869
1038 - // Start output buffering to catch the filesystem form if credentials are needed.
870 + // Start output bufferring to catch the filesystem form if credentials are needed.
1039 871 ob_start();
1040 872
1041 873 $show_form = false;
1042 874 $method = '';
@@ -1053,8 +885,9 @@
1053 885
1054 886 if ( $show_form ) {
1055 887 $form = ob_get_clean();
1056 888 $message = __( 'Sorry, your site requires FTP authentication. Please download plugins from FormidableForms.com and install them manually.', 'formidable' );
889 + $data = $form;
1057 890 $response = array(
1058 891 'success' => false,
1059 892 'message' => $message,
1060 893 'form' => $form,
@@ -1065,40 +898,18 @@
1065 898 ob_end_clean();
1066 899 }
1067 900
1068 901 /**
1069 - * Checks if an addon download url is allowed.
1070 - *
1071 - * @since 6.2
1072 - *
1073 - * @param string $download_url
1074 - *
1075 - * @return bool
1076 - */
1077 - public static function url_is_allowed( $download_url ) {
1078 - return FrmAppHelper::validate_url_is_in_s3_bucket( $download_url, 'zip' ) || in_array( $download_url, self::allowed_external_urls(), true );
1079 - }
1080 -
1081 - /**
1082 902 * We do not need any extra credentials if we have gotten this far,
1083 903 * so let's install the plugin.
1084 904 *
1085 905 * @since 3.04.02
1086 - *
1087 - * @return array|string
1088 906 */
1089 907 protected static function install_addon() {
1090 - require_once ABSPATH . 'wp-admin/includes/class-wp-upgrader.php';
908 + require_once( ABSPATH . 'wp-admin/includes/class-wp-upgrader.php' );
1091 909
1092 - $download_url = self::get_current_plugin();
910 + $download_url = FrmAppHelper::get_param( 'plugin', '', 'post', 'esc_url_raw' );
1093 911
1094 - if ( ! self::url_is_allowed( $download_url ) ) {
1095 - return array(
1096 - 'message' => 'Plugin URL is not valid',
1097 - 'success' => false,
1098 - );
1099 - }
1100 -
1101 912 // Create the plugin upgrader with our custom skin.
1102 913 $installer = new Plugin_Upgrader( new FrmInstallerSkin() );
1103 914 $installer->install( $download_url );
1104 915
@@ -1105,212 +916,89 @@
1105 916 // Flush the cache and return the newly installed plugin basename.
1106 917 wp_cache_flush();
1107 918
1108 919 $plugin = $installer->plugin_info();
1109 -
1110 - if ( ! $plugin ) {
920 + if ( empty( $plugin ) ) {
1111 921 return array(
1112 922 'message' => 'Plugin was not installed. ' . $installer->result,
1113 923 'success' => false,
1114 924 );
1115 925 }
1116 -
1117 926 return $plugin;
1118 927 }
1119 928
1120 929 /**
1121 - * Handle the AJAX request to activate an add-on.
1122 - *
1123 - * @since 6.8
1124 - *
1125 - * @return void
930 + * @since 3.06.03
1126 931 */
1127 932 public static function ajax_activate_addon() {
1128 - self::process_addon_action(
1129 - function ( $plugin ) {
1130 - return self::handle_addon_action( $plugin, 'activate' );
1131 - },
1132 - array( 'FrmAddonsController', 'get_addon_activation_response' )
1133 - );
1134 - }
1135 933
1136 - /**
1137 - * @since 3.04.02
1138 - *
1139 - * @param string $installed The plugin folder name with file name.
1140 - */
1141 - protected static function maybe_activate_addon( $installed ) {
1142 - self::ajax_activate_addon();
1143 - }
934 + self::install_addon_permissions();
1144 935
1145 - /**
1146 - * Handle the AJAX request to deactivate an add-on.
1147 - *
1148 - * @since 6.8
1149 - *
1150 - * @return void
1151 - */
1152 - public static function ajax_deactivate_addon() {
1153 - self::process_addon_action(
1154 - function ( $plugin ) {
1155 - return self::handle_addon_action( $plugin, 'deactivate' );
1156 - }
1157 - );
1158 - }
936 + // Set the current screen to avoid undefined notices.
937 + global $hook_suffix;
938 + set_current_screen();
1159 939
1160 - /**
1161 - * Handle the AJAX request to uninstall an add-on.
1162 - *
1163 - * @since 6.8
1164 - *
1165 - * @return void
1166 - */
1167 - public static function ajax_uninstall_addon() {
1168 - self::process_addon_action(
1169 - function ( $plugin ) {
1170 - return self::handle_addon_action( $plugin, 'uninstall' );
1171 - }
1172 - );
1173 - }
1174 -
1175 - /**
1176 - * Process a specific action (activate, deactivate, uninstall) on an add-on.
1177 - *
1178 - * @since 6.8
1179 - *
1180 - * @param callable $action_callback The specific add-on action to be executed.
1181 - * @param callable|null $response_callback Optional. The response handling callback. Default null.
1182 - *
1183 - * @return void
1184 - */
1185 - private static function process_addon_action( $action_callback, $response_callback = null ) {
1186 - self::install_addon_permissions();
1187 - FrmAppHelper::set_current_screen_and_hook_suffix();
1188 -
1189 940 $plugin = FrmAppHelper::get_param( 'plugin', '', 'post', 'sanitize_text_field' );
1190 - call_user_func( $action_callback, $plugin );
941 + self::maybe_activate_addon( $plugin );
1191 942
1192 - if ( is_callable( $response_callback ) ) {
1193 - wp_send_json_success( call_user_func( $response_callback ) );
1194 - return;
1195 - }
1196 -
1197 - wp_send_json_success();
943 + // Send back a response.
944 + echo json_encode( __( 'Your plugin has been activated. Please reload the page to see more options.', 'formidable' ) );
945 + wp_die();
1198 946 }
1199 947
1200 948 /**
1201 - * Attempt to perform a specific action (activate, deactivate, uninstall) on an add-on.
1202 - *
1203 - * @since 6.8
1204 - *
1205 - * @param string $installed The plugin folder name with file name.
1206 - * @param string $action The action type ('activate', 'deactivate', 'uninstall').
1207 - *
1208 - * @return mixed[]|null
949 + * @since 3.04.02
950 + * @param string $installed The plugin folder name with file name
1209 951 */
1210 - protected static function handle_addon_action( $installed, $action ) {
1211 - if ( ! $installed || ! $action ) {
1212 - return null;
952 + protected static function maybe_activate_addon( $installed ) {
953 + if ( ! $installed ) {
954 + return;
1213 955 }
1214 956
1215 - $result = null;
1216 - switch ( $action ) {
1217 - case 'activate':
1218 - $result = self::activate_plugin( $installed );
1219 - break;
1220 - case 'deactivate':
1221 - self::deactivate_plugin( $installed );
1222 - break;
1223 - case 'uninstall':
1224 - $result = self::uninstall_plugin( $installed );
1225 - break;
1226 - }
1227 -
1228 - if ( is_wp_error( $result ) ) {
957 + $activate = activate_plugin( $installed );
958 + if ( is_wp_error( $activate ) ) {
1229 959 // Ignore the invalid header message that shows with nested plugins.
1230 - if ( $result->get_error_code() !== 'no_plugin_header' ) {
960 + if ( $activate->get_error_code() !== 'no_plugin_header' ) {
1231 961 if ( wp_doing_ajax() ) {
1232 - wp_send_json_error( array( 'error' => $result->get_error_message() ) );
962 + echo json_encode( array( 'error' => $activate->get_error_message() ) );
963 + wp_die();
1233 964 }
1234 -
1235 965 return array(
1236 - 'message' => $result->get_error_message(),
966 + 'message' => $activate->get_error_message(),
1237 967 'success' => false,
1238 968 );
1239 969 }
1240 970 }
1241 -
1242 - return $result;
1243 971 }
1244 972
1245 973 /**
1246 - * @return array
1247 - */
1248 - private static function get_addon_activation_response() {
1249 - $activating_page = self::get_activating_page();
1250 - $message = $activating_page ? __( 'Your plugin has been activated. Would you like to save and reload the page now?', 'formidable' ) : __( 'Your plugin has been activated.', 'formidable' ); // phpcs:ignore SlevomatCodingStandard.Files.LineLength.LineTooLong
1251 -
1252 - return array(
1253 - 'message' => $message,
1254 - 'saveAndReload' => $activating_page,
1255 - );
1256 - }
1257 -
1258 - /**
1259 - * Return a string that reflects the page from which the addon is being activated on,
1260 - * if it is from settings or form builder, otherwise return empty string.
1261 - *
1262 - * @return string
1263 - */
1264 - private static function get_activating_page() {
1265 - $referer = FrmAppHelper::get_server_value( 'HTTP_REFERER' );
1266 -
1267 - if ( str_contains( $referer, 'frm_action=settings' ) ) {
1268 - return 'settings';
1269 - }
1270 -
1271 - return str_contains( $referer, 'frm_action=edit' ) ? 'form_builder' : '';
1272 - }
1273 -
1274 - /**
1275 974 * Run security checks before installing
1276 975 *
1277 976 * @since 3.04.02
1278 - *
1279 - * @return void
1280 977 */
1281 978 protected static function install_addon_permissions() {
1282 979 check_ajax_referer( 'frm_ajax', 'nonce' );
1283 980
1284 - if ( current_user_can( 'activate_plugins' ) && self::get_current_plugin() ) {
1285 - return;
981 + if ( ! current_user_can( 'activate_plugins' ) || ! isset( $_POST['plugin'] ) ) {
982 + echo json_encode( true );
983 + wp_die();
1286 984 }
1287 -
1288 - echo json_encode( true );
1289 - wp_die();
1290 985 }
1291 986
1292 987 /**
1293 988 * @since 4.08
1294 - *
1295 - * @return string
1296 989 */
1297 990 public static function connect_link() {
1298 991 $auth = get_option( 'frm_connect_token' );
1299 -
1300 - if ( ! $auth ) {
992 + if ( empty( $auth ) ) {
1301 993 $auth = hash( 'sha512', wp_rand() );
1302 - update_option( 'frm_connect_token', $auth, false );
994 + update_option( 'frm_connect_token', $auth );
1303 995 }
1304 -
1305 - $page = FrmAppHelper::simple_get( 'page', 'sanitize_title', 'formidable-settings' );
1306 - $link = 'https://formidableforms.com/api-connect/';
996 + $link = FrmAppHelper::admin_upgrade_link( 'connect', 'api-connect' );
1307 997 $args = array(
1308 998 'v' => 2,
1309 999 'siteurl' => FrmAppHelper::site_url(),
1310 1000 'url' => get_rest_url(),
1311 - 'inst' => (int) FrmAppHelper::pro_is_included(),
1312 - 'return' => $page,
1313 1001 'token' => $auth,
1314 1002 'l' => self::get_pro_license(),
1315 1003 );
1316 1004
@@ -1328,19 +1016,19 @@
1328 1016 // Verify params present (auth & download link).
1329 1017 $post_auth = FrmAppHelper::get_param( 'token', '', 'request', 'sanitize_text_field' );
1330 1018 $post_url = FrmAppHelper::get_param( 'file_url', '', 'request', 'sanitize_text_field' );
1331 1019
1332 - // The download link is not required if already installed.
1333 - $is_installed = FrmAppHelper::pro_is_included();
1334 - $file_missing = ! $is_installed && ! $post_url;
1335 -
1336 - if ( ! $post_auth || $file_missing ) {
1020 + if ( empty( $post_auth ) || empty( $post_url ) ) {
1337 1021 return false;
1338 1022 }
1339 1023
1340 1024 // Verify auth.
1341 1025 $auth = get_option( 'frm_connect_token' );
1342 - return $auth && hash_equals( $auth, $post_auth );
1026 + if ( empty( $auth ) || ! hash_equals( $auth, $post_auth ) ) {
1027 + return false;
1028 + }
1029 +
1030 + return true;
1343 1031 }
1344 1032
1345 1033 /**
1346 1034 * Install and/or activate the add-on file.
@@ -1345,35 +1033,34 @@
1345 1033 /**
1346 1034 * Install and/or activate the add-on file.
1347 1035 *
1348 1036 * @since 4.08
1349 - *
1350 - * @return array
1351 1037 */
1352 1038 public static function install_addon_api() {
1353 - self::$plugin = FrmAppHelper::get_param( 'file_url', '', 'request', 'esc_url_raw' );
1039 + // Sanitize when it's used to prevent double sanitizing.
1040 + // phpcs:ignore WordPress.Security.ValidatedSanitizedInput
1041 + $_POST['plugin'] = isset( $_REQUEST['file_url'] ) ? $_REQUEST['file_url'] : ''; // Set for later use
1354 1042
1043 + $error = esc_html__( 'Could not install an upgrade. Please download from formidableforms.com and install manually.', 'formidable' );
1044 +
1355 1045 // Delete so cannot replay.
1356 1046 delete_option( 'frm_connect_token' );
1357 1047
1358 1048 // It's already installed and active.
1359 - $active = self::activate_plugin( 'formidable-pro/formidable-pro.php', false, false, true );
1360 -
1049 + $active = activate_plugin( 'formidable-pro/formidable-pro.php', false, false, true );
1361 1050 if ( is_wp_error( $active ) ) {
1362 - $response = self::maybe_download_and_activate();
1363 -
1364 - if ( is_array( $response ) ) {
1365 - // The download failed.
1051 + // Download plugin now.
1052 + $response = self::download_and_activate();
1053 + if ( is_array( $response ) && isset( $response['success'] ) ) {
1366 1054 return $response;
1367 1055 }
1368 1056 }
1369 1057
1370 1058 // If empty license, save it now.
1371 - if ( ! self::get_pro_license() && function_exists( 'load_formidable_pro' ) ) {
1059 + if ( empty( self::get_pro_license() ) && function_exists( 'load_formidable_pro' ) ) {
1372 1060 load_formidable_pro();
1373 1061 $license = stripslashes( FrmAppHelper::get_param( 'key', '', 'request', 'sanitize_text_field' ) );
1374 -
1375 - if ( ! $license ) {
1062 + if ( empty( $license ) ) {
1376 1063 return array(
1377 1064 'success' => false,
1378 1065 'error' => 'That site does not have a valid license key.',
1379 1066 );
@@ -1379,9 +1066,8 @@
1379 1066 );
1380 1067 }
1381 1068
1382 1069 $response = FrmAddon::activate_license_for_plugin( $license, 'formidable_pro' );
1383 -
1384 1070 if ( ! $response['success'] ) {
1385 1071 // Could not activate license.
1386 1072 return $response;
1387 1073 }
@@ -1392,60 +1078,22 @@
1392 1078 );
1393 1079 }
1394 1080
1395 1081 /**
1396 - * @since 6.8.3
1397 - *
1398 - * @return array|true
1399 - */
1400 - private static function maybe_download_and_activate() {
1401 - if ( ! self::$plugin ) {
1402 - return array(
1403 - 'success' => false,
1404 - 'message' => __( 'The plugin download was not found.', 'formidable' ),
1405 - );
1406 - }
1407 -
1408 - // Download plugin now.
1409 - $response = self::download_and_activate();
1410 -
1411 - if ( is_array( $response ) && isset( $response['success'] ) ) {
1412 - // The download failed.
1413 - return $response;
1414 - }
1415 -
1416 - return true;
1417 - }
1418 -
1419 - /**
1420 1082 * Render a conditional action button for a specified plugin
1421 1083 *
1084 + * @param string $plugin
1085 + * @param array|string $upgrade_link_args
1422 1086 * @since 4.09
1423 - *
1424 - * @param string $plugin
1425 - * @param array|string $upgrade_link_args
1426 - *
1427 - * @return void
1428 1087 */
1429 1088 public static function conditional_action_button( $plugin, $upgrade_link_args ) {
1430 1089 if ( is_callable( 'FrmProAddonsController::conditional_action_button' ) ) {
1431 - FrmProAddonsController::conditional_action_button( $plugin, $upgrade_link_args );
1432 - return;
1090 + return FrmProAddonsController::conditional_action_button( $plugin, $upgrade_link_args );
1433 1091 }
1434 1092
1435 1093 $addon = self::get_addon( $plugin );
1436 1094 $upgrade_link = FrmAppHelper::admin_upgrade_link( $upgrade_link_args );
1437 -
1438 - if ( ! is_array( $upgrade_link_args ) ) {
1439 - // A string $upgrade_link_args is used for the utm-medium value when calling
1440 - // FrmAppHelper::admin_upgrade_link above.
1441 - // For self::addon_upgrade_link, we'll pass just an empty array with the link key (set below).
1442 - $upgrade_link_args = array();
1443 - }
1444 -
1445 - $upgrade_link_args['link'] = $upgrade_link;
1446 -
1447 - self::addon_upgrade_link( $addon, $upgrade_link_args );
1095 + self::addon_upgrade_link( $addon, $upgrade_link );
1448 1096 }
1449 1097
1450 1098 /**
1451 1099 * Render a conditional action button for an add on
@@ -1450,24 +1098,16 @@
1450 1098 /**
1451 1099 * Render a conditional action button for an add on
1452 1100 *
1453 1101 * @since 4.09.01
1454 - *
1455 - * @param array $atts {
1456 - * Button attributes.
1457 - *
1458 - * @type array $addon
1459 - * @type false|string $license_type
1460 - * @type string $plan_required
1461 - * @type string $upgrade_link
1462 - * }
1463 - *
1464 - * @return void
1102 + * @param array $addon
1103 + * @param string|false $license_type
1104 + * @param string $plan_required
1105 + * @param string $upgrade_link
1465 1106 */
1466 1107 public static function show_conditional_action_button( $atts ) {
1467 1108 if ( is_callable( 'FrmProAddonsController::show_conditional_action_button' ) ) {
1468 - FrmProAddonsController::show_conditional_action_button( $atts );
1469 - return;
1109 + return FrmProAddonsController::show_conditional_action_button( $atts );
1470 1110 }
1471 1111
1472 1112 self::addon_upgrade_link( $atts['addon'], $atts['upgrade_link'] );
1473 1113 }
@@ -1473,19 +1113,10 @@
1473 1113 }
1474 1114
1475 1115 /**
1476 1116 * @since 4.09.01
1477 - *
1478 - * @param array|false $addon
1479 - * @param array|string $upgrade_link
1480 - *
1481 - * @return void
1482 1117 */
1483 - public static function addon_upgrade_link( $addon, $upgrade_link ) {
1484 - $atts = is_array( $upgrade_link ) ? $upgrade_link : array();
1485 - $upgrade_link = is_array( $upgrade_link ) ? $upgrade_link['link'] : $upgrade_link;
1486 - $text = ! empty( $atts['text'] ) ? $atts['text'] : __( 'Upgrade Now', 'formidable' );
1487 -
1118 + protected static function addon_upgrade_link( $addon, $upgrade_link ) {
1488 1119 if ( $addon ) {
1489 1120 $upgrade_link .= '&utm_content=' . $addon['slug'];
1490 1121 }
1491 1122
@@ -1492,94 +1123,118 @@
1492 1123 if ( $addon && isset( $addon['categories'] ) && in_array( 'Solution', $addon['categories'], true ) ) {
1493 1124 // Solutions will go to a separate page.
1494 1125 $upgrade_link = FrmAppHelper::admin_upgrade_link( 'addons', $addon['link'] );
1495 1126 }
1496 -
1497 - $class = ! empty( $atts['class'] ) ? $atts['class'] : '';
1498 -
1499 - if ( ! str_contains( $class, 'frm-button' ) ) {
1500 - $class .= ' frm-button-secondary frm-button-sm';
1501 - }
1502 - // phpcs:disable Generic.WhiteSpace.ScopeIndent
1503 1127 ?>
1504 - <a class="install-now button <?php echo esc_attr( $class ); ?>" href="<?php echo esc_url( $upgrade_link ); ?>" target="_blank" rel="noopener" aria-label="<?php esc_attr_e( 'Upgrade Now', 'formidable' ); ?>"><?php // phpcs:ignore SlevomatCodingStandard.Files.LineLength.LineTooLong ?>
1505 - <?php echo esc_html( $text ); ?>
1128 + <a class="install-now button button-secondary frm-button-secondary" href="<?php echo esc_url( $upgrade_link ); ?>" target="_blank" rel="noopener" aria-label="<?php esc_attr_e( 'Upgrade Now', 'formidable' ); ?>">
1129 + <?php esc_html_e( 'Upgrade Now', 'formidable' ); ?>
1506 1130 </a>
1507 1131 <?php
1508 - // phpcs:enable Generic.WhiteSpace.ScopeIndent
1509 1132 }
1510 1133
1511 1134 /**
1512 1135 * @since 3.04.02
1513 - *
1514 - * @return void
1515 1136 */
1516 1137 public static function ajax_install_addon() {
1517 1138 self::install_addon_permissions();
1518 1139
1519 - $result = self::download_and_activate();
1140 + self::download_and_activate();
1520 1141
1521 - if ( isset( $result['success'] ) && ! $result['success'] ) {
1522 - echo json_encode( $result );
1523 - wp_die();
1524 - }
1142 + // Send back a response.
1143 + echo json_encode( __( 'Your plugin has been installed. Please reload the page to see more options.', 'formidable' ) );
1144 + wp_die();
1145 + }
1525 1146
1526 - echo json_encode( self::get_addon_activation_response() );
1527 - wp_die();
1147 + /**
1148 + * @since 4.06.02
1149 + * @deprecated 4.09.01
1150 + */
1151 + public static function ajax_multiple_addons() {
1152 + FrmDeprecated::ajax_multiple_addons();
1528 1153 }
1529 1154
1530 1155 /**
1531 - * Allowed URLs used for internal source of plugins installation.
1156 + * @since 3.04.03
1157 + * @deprecated 3.06
1158 + * @codeCoverageIgnore
1159 + * @return array
1160 + */
1161 + public static function error_for_license( $license ) {
1162 + return FrmDeprecated::error_for_license( $license );
1163 + }
1164 +
1165 + /**
1166 + * @since 3.04.03
1167 + * @deprecated 3.06
1168 + * @codeCoverageIgnore
1169 + */
1170 + public static function get_pro_updater() {
1171 + return FrmDeprecated::get_pro_updater();
1172 + }
1173 +
1174 + /**
1175 + * @since 3.04.03
1176 + * @deprecated 3.06
1177 + * @codeCoverageIgnore
1532 1178 *
1533 - * @since 6.3.1
1534 - *
1535 1179 * @return array
1536 1180 */
1537 - private static function allowed_external_urls() {
1538 - $allowed_url_list = array(
1539 - 'https://downloads.wordpress.org/plugin/formidable-gravity-forms-importer.zip',
1540 - 'https://downloads.wordpress.org/plugin/formidable-import-pirate-forms.zip',
1541 - 'https://downloads.wordpress.org/plugin/wp-mail-smtp.zip',
1542 - );
1181 + public static function get_addon_info( $license = '' ) {
1182 + return FrmDeprecated::get_addon_info( $license );
1183 + }
1543 1184
1544 - /**
1545 - * List of URLs used in plugin formidable internal installation.
1546 - *
1547 - * @since 6.3.1
1548 - *
1549 - * @param array $allowed_url_list List of URLs.
1550 - */
1551 - $allowed_url_list = apply_filters( 'frm_allowed_external_urls', $allowed_url_list );
1185 + /**
1186 + * @since 3.04.03
1187 + * @deprecated 3.06
1188 + * @codeCoverageIgnore
1189 + *
1190 + * @return string
1191 + */
1192 + public static function get_cache_key( $license ) {
1193 + return FrmDeprecated::get_cache_key( $license );
1194 + }
1552 1195
1553 - if ( ! is_array( $allowed_url_list ) ) {
1554 - _doing_it_wrong( __METHOD__, 'Only an array of URLs could be used within this filter.', '6.3.1' );
1555 - return array();
1556 - }
1196 + /**
1197 + * @since 3.04.03
1198 + * @deprecated 3.06
1199 + * @codeCoverageIgnore
1200 + */
1201 + public static function reset_cached_addons( $license = '' ) {
1202 + FrmDeprecated::reset_cached_addons( $license );
1203 + }
1557 1204
1558 - return $allowed_url_list;
1205 + /**
1206 + * @since 2.03.08
1207 + * @deprecated 3.04.03
1208 + * @codeCoverageIgnore
1209 + *
1210 + * @param boolean $return
1211 + * @param string $package
1212 + *
1213 + * @return boolean
1214 + */
1215 + public static function add_shorten_edd_filename_filter( $return, $package ) {
1216 + return FrmDeprecated::add_shorten_edd_filename_filter( $return, $package );
1559 1217 }
1560 1218
1561 1219 /**
1562 - * Gets required plan for an addon.
1220 + * @since 2.03.08
1221 + * @deprecated 3.04.03
1222 + * @codeCoverageIgnore
1563 1223 *
1564 - * @since 6.4.2
1224 + * @param string $filename
1225 + * @param string $ext
1565 1226 *
1566 - * @param int|string $addon_id
1567 - *
1568 - * @return string Empty string if no plan is required for active license.
1227 + * @return string
1569 1228 */
1570 - public static function get_addon_required_plan( $addon_id ) {
1571 - $api = new FrmFormApi();
1572 - $addons = $api->get_api_info();
1229 + public static function shorten_edd_filename( $filename, $ext ) {
1230 + return FrmDeprecated::shorten_edd_filename( $filename, $ext );
1231 + }
1573 1232
1574 - if ( is_array( $addons ) && array_key_exists( $addon_id, $addons ) ) {
1575 - $dates = $addons[ $addon_id ];
1576 - $requires = FrmFormsHelper::get_plan_required( $dates );
1577 - }
1578 -
1579 - if ( ! isset( $requires ) || ! is_string( $requires ) ) {
1580 - return '';
1581 - }
1582 -
1583 - return $requires;
1233 + /**
1234 + * @deprecated 3.04.03
1235 + * @codeCoverageIgnore
1236 + */
1237 + public static function get_licenses() {
1238 + FrmDeprecated::get_licenses();
1584 1239 }
1585 1240 }