Completed
Push — master ( 55c46a...94bd81 )
by Stephanie
15s queued 10s
created

FrmAddonsController::conditional_action_button()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
nc 1
nop 2
dl 0
loc 7
rs 10
c 0
b 0
f 0
1
<?php
2
if ( ! defined( 'ABSPATH' ) ) {
3
	die( 'You are not allowed to call this page directly.' );
4
}
5
6
class FrmAddonsController {
7
8
	public static function menu() {
9
		if ( ! current_user_can( 'activate_plugins' ) ) {
10
			return;
11
		}
12
13
		$label = __( 'Add-Ons', 'formidable' );
14
		if ( FrmAppHelper::pro_is_installed() ) {
15
			$label = '<span style="color:#fe5a1d">' . $label . '</span>';
16
		}
17
		add_submenu_page( 'formidable', 'Formidable | ' . __( 'Add-Ons', 'formidable' ), $label, 'frm_view_forms', 'formidable-addons', 'FrmAddonsController::list_addons' );
18
19
		if ( ! FrmAppHelper::pro_is_installed() ) {
20
			add_submenu_page(
21
				'formidable',
22
				'Formidable | ' . __( 'Upgrade', 'formidable' ),
23
				'<span style="color:#fe5a1d">' . __( 'Upgrade', 'formidable' ) . '</span>',
24
				'frm_view_forms',
25
				'formidable-pro-upgrade',
26
				'FrmAddonsController::upgrade_to_pro'
27
			);
28
		} elseif ( 'formidable-pro-upgrade' === FrmAppHelper::get_param( 'page' ) ) {
29
			wp_safe_redirect( admin_url( 'admin.php?page=formidable' ) );
30
			exit;
31
		}
32
	}
33
34
	public static function list_addons() {
35
		FrmAppHelper::include_svg();
36
		$installed_addons = apply_filters( 'frm_installed_addons', array() );
37
		$license_type     = '';
38
39
		$addons = self::get_api_addons();
40
		$errors = array();
41
42
		if ( isset( $addons['error'] ) ) {
43
			$api    = new FrmFormApi();
44
			$errors = $api->get_error_from_response( $addons );
45
			$license_type = isset( $addons['error']['type'] ) ? $addons['error']['type'] : '';
46
			unset( $addons['error'] );
47
		}
48
		self::prepare_addons( $addons );
49
50
		$pricing = FrmAppHelper::admin_upgrade_link( 'addons' );
51
52
		include( FrmAppHelper::plugin_path() . '/classes/views/addons/list.php' );
53
	}
54
55
	public static function license_settings() {
56
		$plugins = apply_filters( 'frm_installed_addons', array() );
57
		if ( empty( $plugins ) ) {
58
			esc_html_e( 'There are no plugins on your site that require a license', 'formidable' );
59
60
			return;
61
		}
62
63
		ksort( $plugins );
64
65
		include( FrmAppHelper::plugin_path() . '/classes/views/addons/settings.php' );
66
	}
67
68
	private static function get_api_addons() {
69
		$api    = new FrmFormApi();
70
		$addons = $api->get_api_info();
71
72
		if ( empty( $addons ) ) {
73
			$addons = self::fallback_plugin_list();
74
		} else {
75
			foreach ( $addons as $k => $addon ) {
76
				if ( empty( $addon['excerpt'] ) && $k !== 'error' ) {
77
					unset( $addons[ $k ] );
78
				}
79
			}
80
		}
81
82
		return $addons;
83
	}
84
85
	/**
86
	 * If the API is unable to connect, show something on the addons page
87
	 *
88
	 * @since 3.04.03
89
	 * @return array
90
	 */
91
	private static function fallback_plugin_list() {
92
		$list = array(
93
			'formidable-pro' => array(
94
				'title'   => 'Formidable Forms',
95
				'link'    => 'pricing/',
96
				'docs'    => '',
97
				'excerpt' => 'Enhance your basic Formidable forms with a plethora of Pro field types and features. Create advanced forms and data-driven applications in minutes.',
98
			),
99
			'mailchimp'      => array(
100
				'title'   => 'MailChimp Forms',
101
				'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.',
102
			),
103
			'registration'   => array(
104
				'title'   => 'User Registration Forms',
105
				'link'    => 'downloads/user-registration/',
106
				'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.',
107
			),
108
			'paypal'         => array(
109
				'title'   => 'PayPal Standard Forms',
110
				'link'    => 'downloads/paypal-standard/',
111
				'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.',
112
			),
113
			'stripe'         => array(
114
				'title'   => 'Stripe Forms',
115
				'docs'    => 'knowledgebase/stripe/',
116
				'excerpt' => 'Any Formidable forms on your site can accept credit card payments without users ever leaving your site.',
117
			),
118
			'authorize-net'  => array(
119
				'title'   => 'Authorize.net AIM Forms',
120
				'link'    => 'downloads/authorize-net-aim/',
121
				'docs'    => 'knowledgebase/authorize-net-aim/',
122
				'excerpt' => 'Accept one-time payments directly on your site, using Authorize.net AIM.',
123
			),
124
			'woocommerce'    => array(
125
				'title'   => 'WooCommerce Forms',
126
				'excerpt' => 'Use a Formidable form on your WooCommerce product pages.',
127
			),
128
			'autoresponder'  => array(
129
				'title'   => 'Form Action Automation',
130
				'docs'    => 'knowledgebase/schedule-autoresponder/',
131
				'excerpt' => 'Schedule email notifications, SMS messages, and API actions.',
132
			),
133
			'modal'          => array(
134
				'title'   => 'Bootstrap Modal Forms',
135
				'link'    => 'downloads/bootstrap-modal/',
136
				'docs'    => 'knowledgebase/bootstrap-modal/',
137
				'excerpt' => 'Open a view or form in a Bootstrap popup.',
138
			),
139
			'bootstrap'      => array(
140
				'title'   => 'Bootstrap Style Forms',
141
				'excerpt' => 'Instantly add Bootstrap styling to all your Formidable forms.',
142
			),
143
			'zapier'         => array(
144
				'title'   => 'Zapier Forms',
145
				'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.',
146
			),
147
			'signature'      => array(
148
				'title'   => 'Digital Signature Forms',
149
				'excerpt' => 'Add a signature field to your form. The user may write their signature with a trackpad/mouse or just type it.',
150
			),
151
			'api'            => array(
152
				'title'   => 'Formidable Forms API',
153
				'link'    => 'downloads/formidable-api/',
154
				'excerpt' => 'Send entry results to any other site that has a Rest API. This includes the option of sending entries from one Formidable site to another.',
155
			),
156
			'twilio'         => array(
157
				'title'   => 'Twilio SMS Forms',
158
				'docs'    => 'knowledgebase/twilio-add-on/',
159
				'excerpt' => 'Allow users to text their votes for polls created by Formidable Forms, or send SMS notifications when entries are submitted or updated.',
160
			),
161
			'views'          => array(
162
				'title'   => 'Formidable Views',
163
				'excerpt' => 'Add the power of views to your Formidable Forms to display your form submissions in listings, tables, calendars, and more.',
164
			),
165
		);
166
167
		$defaults = array(
168
			'released' => '',
169
		);
170
171
		foreach ( $list as $k => $info ) {
172
			$info['slug'] = $k;
173
			$list[ $k ]   = array_merge( $defaults, $info );
174
		}
175
		return $list;
176
	}
177
178
	/**
179
	 * If Pro is missing but has been authenticated, include a download URL
180
	 *
181
	 * @since 3.04.03
182
	 * @return string
183
	 */
184
	public static function get_pro_download_url() {
185
		$license   = self::get_pro_license();
186
		$api       = new FrmFormApi( $license );
187
		$downloads = $api->get_api_info();
188
		$pro       = self::get_pro_from_addons( $downloads );
189
190
		return isset( $pro['url'] ) ? $pro['url'] : '';
191
	}
192
193
	/**
194
	 * @since 4.08
195
	 */
196
	public static function get_pro_license() {
197
		$pro_cred_store = 'frmpro-credentials';
198
		$pro_wpmu_store = 'frmpro-wpmu-sitewide';
199
		if ( is_multisite() && get_site_option( $pro_wpmu_store ) ) {
200
			$creds = get_site_option( $pro_cred_store );
201
		} else {
202
			$creds = get_option( $pro_cred_store );
203
		}
204
205
		if ( empty( $creds ) || ! is_array( $creds ) || ! isset( $creds['license'] ) ) {
206
			return '';
207
		}
208
209
		$license = $creds['license'];
210
		if ( empty( $license ) ) {
211
			return '';
212
		}
213
214
		if ( strpos( $license, '-' ) ) {
215
			// this is a fix for licenses saved in the past
216
			$license = strtoupper( $license );
217
		}
218
		return $license;
219
	}
220
221
	/**
222
	 * @since 4.08
223
	 */
224
	private static function get_pro_from_addons( $addons ) {
225
		return isset( $addons['93790'] ) ? $addons['93790'] : array();
226
	}
227
228
	/**
229
	 * @since 4.06
230
	 */
231
	public static function license_type() {
232
		$api     = new FrmFormApi();
233
		$addons  = $api->get_api_info();
234
		$type    = 'free';
235
236
		if ( isset( $addons['error'] ) ) {
237
			if ( isset( $addons['error']['code'] ) && $addons['error']['code'] === 'expired' ) {
238
				return $addons['error']['code'];
239
			}
240
			$type = isset( $addons['error']['type'] ) ? $addons['error']['type'] : $type;
241
		}
242
243
		$pro = self::get_pro_from_addons( $addons );
244
		if ( $type === 'free' ) {
245
			$type = isset( $pro['type'] ) ? $pro['type'] : $type;
246
			if ( $type === 'free' ) {
247
				return $type;
248
			}
249
		}
250
251
		if ( isset( $pro['code'] ) && $pro['code'] === 'grandfathered' ) {
252
			return $pro['code'];
253
		}
254
255
		$expires = isset( $pro['expires'] ) ? $pro['expires'] : '';
256
		$expired = $expires ? $expires < time() : false;
257
		return $expired ? 'expired' : strtolower( $type );
258
	}
259
260
	/**
261
	 * @since 4.0.01
262
	 */
263
	public static function is_license_expired() {
264
		$version_info = self::get_primary_license_info();
265
		if ( ! isset( $version_info['error'] ) ) {
266
			return false;
267
		}
268
269
		return $version_info['error'];
270
	}
271
272
	/**
273
	 * @since 4.08
274
	 *
275
	 * @return boolean|int false or the number of days until expiration.
276
	 */
277
	public static function is_license_expiring() {
278
		$version_info = self::get_primary_license_info();
279
		if ( ! isset( $version_info['active_sub'] ) || $version_info['active_sub'] !== 'no' ) {
280
			// Check for a subscription first.
281
			return false;
282
		}
283
284
		if ( isset( $version_info['error'] ) || empty( $version_info['expires'] ) ) {
285
			// It's either invalid or already expired.
286
			return false;
287
		}
288
289
		$expiration = $version_info['expires'];
290
		$days_left  = ( $expiration - time() ) / DAY_IN_SECONDS;
291
		if ( $days_left > 30 ) {
292
			return false;
293
		}
294
295
		return $days_left;
296
	}
297
298
	/**
299
	 * @since 4.08
300
	 */
301
	private static function get_primary_license_info() {
302
		$installed_addons = apply_filters( 'frm_installed_addons', array() );
303
		if ( empty( $installed_addons ) || ! isset( $installed_addons['formidable_pro'] ) ) {
304
			return false;
305
		}
306
		$installed_addons = array(
307
			'formidable_pro' => $installed_addons['formidable_pro'],
308
		);
309
310
		return self::fill_update_addon_info( $installed_addons );
311
	}
312
313
	/**
314
	 * @since 3.04.03
315
	 */
316
	public static function check_update( $transient ) {
317
		if ( ! is_object( $transient ) ) {
318
			$transient = new stdClass();
319
		}
320
321
		$installed_addons = apply_filters( 'frm_installed_addons', array() );
322
		if ( empty( $installed_addons ) ) {
323
			return $transient;
324
		}
325
326
		$version_info = self::fill_update_addon_info( $installed_addons );
327
328
		$transient->last_checked = time();
329
330
		if ( ! function_exists( 'get_plugins' ) ) {
331
			require_once ABSPATH . 'wp-admin/includes/plugin.php';
332
		}
333
		$wp_plugins = get_plugins();
334
335
		foreach ( $version_info as $id => $plugin ) {
336
			$plugin = (object) $plugin;
337
338
			if ( ! isset( $plugin->new_version ) || ! isset( $plugin->package ) ) {
339
				continue;
340
			}
341
342
			$folder = $plugin->plugin;
343
			if ( empty( $folder ) ) {
344
				continue;
345
			}
346
347
			if ( ! self::is_installed( $folder ) ) {
348
				// don't show an update if the plugin isn't installed
349
				continue;
350
			}
351
352
			$wp_plugin  = isset( $wp_plugins[ $folder ] ) ? $wp_plugins[ $folder ] : array();
353
			$wp_version = isset( $wp_plugin['Version'] ) ? $wp_plugin['Version'] : '1.0';
354
355
			if ( version_compare( $wp_version, $plugin->new_version, '<' ) ) {
356
				$slug                           = explode( '/', $folder );
357
				$plugin->slug                   = $slug[0];
358
				$transient->response[ $folder ] = $plugin;
359
			}
360
361
			$transient->checked[ $folder ] = $wp_version;
362
363
		}
364
365
		return $transient;
366
	}
367
368
	/**
369
	 * Check if a plugin is installed before showing an update for it
370
	 *
371
	 * @since 3.05
372
	 *
373
	 * @param string $plugin - the folder/filename.php for a plugin
374
	 *
375
	 * @return bool - True if installed
376
	 */
377
	private static function is_installed( $plugin ) {
378
		if ( ! function_exists( 'get_plugins' ) ) {
379
			require_once ABSPATH . 'wp-admin/includes/plugin.php';
380
		}
381
382
		$all_plugins = get_plugins();
383
384
		return isset( $all_plugins[ $plugin ] );
385
	}
386
387
	/**
388
	 * @since 3.04.03
389
	 *
390
	 * @param array $installed_addons
391
	 *
392
	 * @return array
393
	 */
394
	private static function fill_update_addon_info( $installed_addons ) {
395
		$checked_licenses = array();
396
		$version_info     = array();
397
398
		foreach ( $installed_addons as $addon ) {
399
			if ( $addon->store_url !== 'https://formidableforms.com' ) {
400
				// check if this is a third-party addon
401
				continue;
402
			}
403
404
			$new_license = $addon->license;
405
			if ( empty( $new_license ) || in_array( $new_license, $checked_licenses ) ) {
406
				continue;
407
			}
408
409
			$checked_licenses[] = $new_license;
410
411
			$api = new FrmFormApi( $new_license );
412
			if ( empty( $version_info ) ) {
413
				$version_info = $api->get_api_info();
414
				continue;
415
			}
416
417
			$plugin = $api->get_addon_for_license( $addon, $version_info );
418
			if ( empty( $plugin ) ) {
419
				continue;
420
			}
421
422
			$download_id = isset( $plugin['id'] ) ? $plugin['id'] : 0;
423
			if ( ! empty( $download_id ) && ! isset( $version_info[ $download_id ]['package'] ) ) {
424
				// if this addon is using its own license, get the update url
425
				$addon_info = $api->get_api_info();
426
427
				$version_info[ $download_id ] = $addon_info[ $download_id ];
428
				if ( isset( $addon_info['error'] ) ) {
429
					$version_info[ $download_id ]['error'] = array(
430
						'message' => $addon_info['error']['message'],
431
						'code'    => $addon_info['error']['code'],
432
					);
433
				}
434
			}
435
		}
436
437
		return $version_info;
438
	}
439
440
	/**
441
	 * Get the action link for an addon that isn't active.
442
	 *
443
	 * @since 3.06.03
444
	 * @param string $plugin The plugin slug
445
	 * @return array
446
	 */
447
	public static function install_link( $plugin ) {
448
		$link  = array();
449
		$addon = self::get_addon( $plugin );
450
451
		if ( $addon ) {
452
			if ( $addon['status']['type'] === 'installed' && ! empty( $addon['activate_url'] ) ) {
453
				$link = array(
454
					'url'   => $addon['plugin'],
455
					'class' => 'frm-activate-addon',
456
				);
457
			} elseif ( isset( $addon['url'] ) && ! empty( $addon['url'] ) ) {
458
				$link = array(
459
					'url'   => $addon['url'],
460
					'class' => 'frm-install-addon',
461
				);
462
			} elseif ( isset( $addon['categories'] ) && ! empty( $addon['categories'] ) ) {
463
				$link = array(
464
					'categories' => $addon['categories'],
465
				);
466
			}
467
468
			if ( ! empty( $link ) ) {
469
				$link['status'] = $addon['status']['type'];
470
			}
471
		}
472
473
		return $link;
474
	}
475
476
	/**
477
	 * @since 4.09
478
	 * @param string $plugin The plugin slug
479
	 * @return array|false
480
	 */
481
	private static function get_addon( $plugin ) {
482
		$addons = self::get_api_addons();
483
		self::prepare_addons( $addons );
484
		foreach ( $addons as $addon ) {
485
			$slug = explode( '/', $addon['plugin'] );
486
			if ( $slug[0] === 'formidable-' . $plugin ) {
487
				return $addon;
488
			}
489
		}
490
		return false;
491
	}
492
493
	/**
494
	 * @since 4.09
495
	 * @return string
496
	 */
497
	private static function get_license_type() {
498
		$license_type = '';
499
		$addons       = self::get_api_addons();
500
		if ( isset( $addons['error'] ) && isset( $addons['error']['type'] ) ) {
501
			$license_type = $addons['error']['type'];
502
		}
503
		return $license_type;
504
	}
505
506
	/**
507
	 * @since 3.04.03
508
	 *
509
	 * @param array $addons
510
	 * @param object $license The FrmAddon object
511
	 *
512
	 * @return array
513
	 */
514
	public static function get_addon_for_license( $addons, $license ) {
515
		$download_id = $license->download_id;
516
		$plugin      = array();
517 View Code Duplication
		if ( empty( $download_id ) && ! empty( $addons ) ) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
518
			foreach ( $addons as $addon ) {
519
				if ( strtolower( $license->plugin_name ) == strtolower( $addon['title'] ) ) {
520
					return $addon;
521
				}
522
			}
523
		} elseif ( isset( $addons[ $download_id ] ) ) {
524
			$plugin = $addons[ $download_id ];
525
		}
526
527
		return $plugin;
528
	}
529
530
	private static function prepare_addons( &$addons ) {
531
		$activate_url = '';
532
		if ( current_user_can( 'activate_plugins' ) ) {
533
			$activate_url = add_query_arg( array( 'action' => 'activate' ), admin_url( 'plugins.php' ) );
534
		}
535
536
		$loop_addons = $addons;
537
		foreach ( $loop_addons as $id => $addon ) {
538
			if ( is_numeric( $id ) ) {
539
				$slug      = str_replace( array( '-wordpress-plugin', '-wordpress' ), '', $addon['slug'] );
540
				$file_name = $addon['plugin'];
541
			} else {
542
				$slug = $id;
543
				if ( isset( $addon['file'] ) ) {
544
					$base_file = $addon['file'];
545
				} else {
546
					$base_file = 'formidable-' . $slug;
547
				}
548
				$file_name = $base_file . '/' . $base_file . '.php';
549
				if ( ! isset( $addon['plugin'] ) ) {
550
					$addon['plugin'] = $file_name;
551
				}
552
			}
553
554
			$addon['installed']    = self::is_installed( $file_name );
555
			$addon['activate_url'] = '';
556
557
			if ( $addon['installed'] && ! empty( $activate_url ) && ! is_plugin_active( $file_name ) ) {
558
				$addon['activate_url'] = add_query_arg(
559
					array(
560
						'_wpnonce' => wp_create_nonce( 'activate-plugin_' . $file_name ),
561
						'plugin'   => $file_name,
562
					),
563
					$activate_url
564
				);
565
			}
566
567
			if ( ! isset( $addon['docs'] ) ) {
568
				$addon['docs'] = 'knowledgebase/formidable-' . $slug . '/';
569
			}
570
			self::prepare_addon_link( $addon['docs'] );
571
572
			if ( ! isset( $addon['link'] ) ) {
573
				$addon['link'] = 'downloads/' . $slug . '/';
574
			}
575
			self::prepare_addon_link( $addon['link'] );
576
577
			self::set_addon_status( $addon );
578
			$addons[ $id ] = $addon;
579
		}
580
	}
581
582
	/**
583
	 * @since 3.04.02
584
	 */
585
	private static function prepare_addon_link( &$link ) {
586
		$site_url = 'https://formidableforms.com/';
587
		if ( strpos( $link, 'http' ) !== 0 ) {
588
			$link = $site_url . $link;
589
		}
590
		$link       = FrmAppHelper::make_affiliate_url( $link );
591
		$query_args = array(
592
			'utm_source'   => 'WordPress',
593
			'utm_medium'   => 'addons',
594
			'utm_campaign' => 'liteplugin',
595
		);
596
		$link       = add_query_arg( $query_args, $link );
597
	}
598
599
	/**
600
	 * Add the status to the addon array. Status options are:
601
	 * installed, active, not installed
602
	 *
603
	 * @since 3.04.02
604
	 */
605
	private static function set_addon_status( &$addon ) {
606
		if ( ! empty( $addon['activate_url'] ) ) {
607
			$addon['status'] = array(
608
				'type'  => 'installed',
609
				'label' => __( 'Installed', 'formidable' ),
610
			);
611
		} elseif ( $addon['installed'] ) {
612
			$addon['status'] = array(
613
				'type'  => 'active',
614
				'label' => __( 'Active', 'formidable' ),
615
			);
616
		} else {
617
			$addon['status'] = array(
618
				'type'  => 'not-installed',
619
				'label' => __( 'Not Installed', 'formidable' ),
620
			);
621
		}
622
	}
623
624
	public static function upgrade_to_pro() {
625
		FrmAppHelper::include_svg();
626
627
		$link_parts = array(
628
			'medium'  => 'upgrade',
629
			'content' => 'button',
630
		);
631
632
		$features = array(
633
			'Display Entries' => array(
634
				array(
635
					'label' => 'Display form data with virtually limitless views',
636
					'link'  => array(
637
						'content' => 'views',
638
						'param'   => 'views-display-form-data',
639
					),
640
					'lite'  => false,
641
				),
642
				array(
643
					'label' => 'Generate graphs and stats based on your submitted data',
644
					'link'  => array(
645
						'content' => 'graphs',
646
						'param'   => 'statistics-graphs-wordpress-forms',
647
					),
648
					'lite'  => false,
649
				),
650
			),
651
			'Entry Management' => array(
652
				array(
653
					'label' => 'Import entries from a CSV',
654
					'link'  => array(
655
						'content' => 'import-entries',
656
						'param'   => 'importing-exporting-wordpress-forms',
657
					),
658
					'lite'  => false,
659
				),
660
				array(
661
					'label' => 'Logged-in users can save drafts and return later',
662
					'link'  => array(
663
						'content' => 'save-drafts',
664
						'param'   => 'save-drafts-wordpress-form',
665
					),
666
					'lite'  => false,
667
				),
668
				array(
669
					'label' => 'Flexibly and powerfully view, edit, and delete entries from anywhere on your site',
670
					'link'  => array(
671
						'content' => 'front-edit',
672
						'param'   => 'wordpress-front-end-editing',
673
					),
674
					'lite'  => false,
675
				),
676
				array(
677
					'label' => 'View form submissions from the back-end',
678
					'lite'  => true,
679
				),
680
				array(
681
					'label' => 'Export your entries to a CSV',
682
					'lite'  => true,
683
				),
684
			),
685
			'Form Building' => array(
686
				array(
687
					'label' => 'Save a calculated value into a field',
688
					'link'  => array(
689
						'content' => 'calculations',
690
						'param'   => 'field-calculations-wordpress-form',
691
					),
692
					'lite'  => false,
693
				),
694
				array(
695
					'label' => 'Allow multiple file uploads',
696
					'link'  => array(
697
						'content' => 'file-uploads',
698
						'param'   => 'wordpress-multi-file-upload-fields',
699
					),
700
					'lite'  => false,
701
				),
702
				array(
703
					'label' => 'Repeat sections of fields',
704
					'link'  => array(
705
						'content' => 'repeaters',
706
						'param'   => 'repeatable-sections-forms',
707
					),
708
					'lite'  => false,
709
				),
710
				array(
711
					'label' => 'Hide and show fields conditionally based on other fields or the user\'s role',
712
					'link'  => array(
713
						'content' => 'conditional-logic',
714
						'param'   => 'conditional-logic-wordpress-forms',
715
					),
716
					'lite'  => false,
717
				),
718
				array(
719
					'label' => 'Confirmation fields',
720
					'link'  => array(
721
						'content' => 'confirmation-fields',
722
						'param'   => 'confirmation-fields-wordpress-forms',
723
					),
724
					'lite'  => false,
725
				),
726
				array(
727
					'label' => 'Multi-paged forms',
728
					'link'  => array(
729
						'content' => 'page-breaks',
730
						'param'   => 'wordpress-multi-page-forms',
731
					),
732
					'lite'  => false,
733
				),
734
				array(
735
					'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.',
736
					'lite'  => false,
737
				),
738
				array(
739
					'label' => 'Include text, email, url, paragraph text, radio, checkbox, dropdown fields, hidden fields, user ID fields, and HTML blocks in your form.',
740
					'lite'  => true,
741
				),
742
				array(
743
					'label' => 'Drag & Drop Form building',
744
					'link'  => array(
745
						'content' => 'drag-drop',
746
						'param'   => 'drag-drop-forms',
747
					),
748
					'lite'  => true,
749
				),
750
				array(
751
					'label' => 'Create forms from Templates',
752
					'link'  => array(
753
						'content' => 'form-templates',
754
						'param'   => 'wordpress-form-templates',
755
					),
756
					'lite'  => true,
757
				),
758
				array(
759
					'label' => 'Import and export forms with XML',
760
					'link'  => array(
761
						'content' => 'import',
762
						'param'   => 'importing-exporting-wordpress-forms',
763
					),
764
					'lite'  => true,
765
				),
766
				array(
767
					'label' => 'Use input placeholder text in your fields that clear when typing starts.',
768
					'lite'  => true,
769
				),
770
			),
771
			'Form Actions' => array(
772
				array(
773
					'label' => 'Conditionally send your email notifications based on values in your form',
774
					'link'  => array(
775
						'content' => 'conditional-emails',
776
					),
777
					'lite'  => false,
778
				),
779
				array(
780
					'label' => 'Create and edit WordPress posts or custom posts from the front-end',
781
					'link'  => array(
782
						'content' => 'create-posts',
783
						'param'   => 'create-posts-pages-wordpress-forms',
784
					),
785
					'lite'  => false,
786
				),
787
				array(
788
					'label' => 'Send multiple emails and autoresponders',
789
					'link'  => array(
790
						'content' => 'multiple-emails',
791
						'param'   => 'virtually-unlimited-emails',
792
					),
793
					'lite'  => true,
794
				),
795
			),
796
			'Form Appearance' => array(
797
				array(
798
					'label' => 'Create Multiple styles for different forms',
799
					'link'  => array(
800
						'content' => 'multiple-styles',
801
						'param'   => 'wordpress-visual-form-styler',
802
					),
803
					'lite'  => false,
804
				),
805
				array(
806
					'label' => 'Customizable layout with CSS classes',
807
					'link'  => array(
808
						'content' => 'form-layout',
809
						'param'   => 'wordpress-mobile-friendly-forms',
810
					),
811
					'lite'  => true,
812
				),
813
				array(
814
					'label' => 'Customize the HTML for your forms',
815
					'link'  => array(
816
						'content' => 'custom-html',
817
						'param'   => 'customizable-html-wordpress-form',
818
					),
819
					'lite'  => true,
820
				),
821
				array(
822
					'label' => 'Style your form with the Visual Form Styler',
823
					'lite'  => true,
824
				),
825
			),
826
		);
827
828
		include( FrmAppHelper::plugin_path() . '/classes/views/addons/upgrade_to_pro.php' );
829
	}
830
831
	/**
832
	 * Install Pro after connection with Formidable.
833
	 *
834
	 * @since 4.02.05
835
	 */
836
	public static function connect_pro() {
837
		FrmAppHelper::permission_check( 'install_plugins' );
838
		check_ajax_referer( 'frm_ajax', 'nonce' );
839
840
		$url = FrmAppHelper::get_post_param( 'plugin', '', 'sanitize_text_field' );
841
		if ( FrmAppHelper::pro_is_installed() || empty( $url ) ) {
842
			wp_die();
843
		}
844
845
		$response = array();
846
847
		// It's already installed and active.
848
		$active = activate_plugin( 'formidable-pro/formidable-pro.php', false, false, true );
849
		if ( is_wp_error( $active ) ) {
850
			// The plugin was installed, but not active. Download it now.
851
			self::ajax_install_addon();
852
		} else {
853
			$response['active']  = true;
854
			$response['success'] = true;
855
		}
856
857
		echo json_encode( $response );
858
		wp_die();
859
	}
860
861
	/**
862
	 * @since 3.04.02
863
	 */
864
	public static function ajax_install_addon() {
865
866
		self::install_addon_permissions();
867
868
		self::download_and_activate();
869
870
		// Send back a response.
871
		echo json_encode( __( 'Your plugin has been installed. Please reload the page to see more options.', 'formidable' ) );
872
		wp_die();
873
	}
874
875
	/**
876
	 * @since 4.08
877
	 */
878
	private static function download_and_activate() {
879
		// Set the current screen to avoid undefined notices.
880
		if ( is_admin() ) {
881
			global $hook_suffix;
882
			set_current_screen();
883
		}
884
885
		self::maybe_show_cred_form();
886
887
		$installed = self::install_addon();
888
		if ( is_array( $installed ) && isset( $installed['message'] ) ) {
889
			return $installed;
890
		}
891
		self::maybe_activate_addon( $installed );
892
	}
893
894
	/**
895
	 * @since 3.04.02
896
	 */
897
	private static function maybe_show_cred_form() {
898
		if ( ! function_exists( 'request_filesystem_credentials' ) ) {
899
			include_once( ABSPATH . 'wp-admin/includes/file.php' );
900
		}
901
902
		// Start output bufferring to catch the filesystem form if credentials are needed.
903
		ob_start();
904
905
		$show_form = false;
906
		$method    = '';
907
		$url       = add_query_arg( array( 'page' => 'formidable-settings' ), admin_url( 'admin.php' ) );
908
		$url       = esc_url_raw( $url );
909
		$creds     = request_filesystem_credentials( $url, $method, false, false, null );
910
911
		if ( false === $creds ) {
912
			$show_form = true;
913
		} elseif ( ! WP_Filesystem( $creds ) ) {
914
			request_filesystem_credentials( $url, $method, true, false, null );
915
			$show_form = true;
916
		}
917
918
		if ( $show_form ) {
919
			$form     = ob_get_clean();
920
			$message  = __( 'Sorry, your site requires FTP authentication. Please download plugins from FormidableForms.com and install them manually.', 'formidable' );
921
			$data     = $form;
0 ignored issues
show
Unused Code introduced by
$data is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
922
			$response = array(
923
				'success' => false,
924
				'message' => $message,
925
				'form'    => $form,
926
			);
927
			wp_send_json( $response );
928
		}
929
930
		ob_end_clean();
931
	}
932
933
	/**
934
	 * We do not need any extra credentials if we have gotten this far,
935
	 * so let's install the plugin.
936
	 *
937
	 * @since 3.04.02
938
	 */
939
	private static function install_addon() {
940
		require_once( ABSPATH . 'wp-admin/includes/class-wp-upgrader.php' );
941
942
		$download_url = FrmAppHelper::get_param( 'plugin', '', 'post', 'esc_url_raw' );
943
944
		// Create the plugin upgrader with our custom skin.
945
		$installer = new Plugin_Upgrader( new FrmInstallerSkin() );
946
		$installer->install( $download_url );
947
948
		// Flush the cache and return the newly installed plugin basename.
949
		wp_cache_flush();
950
951
		$plugin = $installer->plugin_info();
952
		if ( empty( $plugin ) ) {
953
			return array(
954
				'message' => 'Plugin was not installed. ' . $installer->result,
955
				'success' => false,
956
			);
957
		}
958
		return $plugin;
959
	}
960
961
	/**
962
	 * @since 3.06.03
963
	 */
964
	public static function ajax_activate_addon() {
965
966
		self::install_addon_permissions();
967
968
		// Set the current screen to avoid undefined notices.
969
		global $hook_suffix;
970
		set_current_screen();
971
972
		$plugin = FrmAppHelper::get_param( 'plugin', '', 'post', 'sanitize_text_field' );
973
		self::maybe_activate_addon( $plugin );
974
975
		// Send back a response.
976
		echo json_encode( __( 'Your plugin has been activated. Please reload the page to see more options.', 'formidable' ) );
977
		wp_die();
978
	}
979
980
	/**
981
	 * @since 4.06.02
982
	 */
983
	public static function ajax_multiple_addons() {
984
		self::install_addon_permissions();
985
986
		// Set the current screen to avoid undefined notices.
987
		global $hook_suffix;
988
		set_current_screen();
989
990
		$download_urls = FrmAppHelper::get_param( 'plugin', '', 'post' );
991
		$download_urls = explode( ',', $download_urls );
992
		FrmAppHelper::sanitize_value( 'esc_url_raw', $download_urls );
993
994
		foreach ( $download_urls as $download_url ) {
995
			$_POST['plugin'] = $download_url;
996
			if ( strpos( $download_url, 'http' ) !== false ) {
997
				// Installing.
998
				self::maybe_show_cred_form();
999
1000
				$installed = self::install_addon();
1001
				self::maybe_activate_addon( $installed );
1002
			} else {
1003
				// Activating.
1004
				self::maybe_activate_addon( $download_url );
1005
			}
1006
		}
1007
1008
		echo json_encode( __( 'Your plugins have been installed and activated.', 'formidable' ) );
1009
1010
		wp_die();
1011
	}
1012
1013
	/**
1014
	 * @since 3.04.02
1015
	 * @param string $installed The plugin folder name with file name
1016
	 */
1017
	private static function maybe_activate_addon( $installed ) {
1018
		if ( ! $installed ) {
1019
			return;
1020
		}
1021
1022
		$activate = activate_plugin( $installed );
1023
		if ( is_wp_error( $activate ) ) {
1024
			// Ignore the invalid header message that shows with nested plugins.
1025
			if ( $activate->get_error_code() !== 'no_plugin_header' ) {
1026
				if ( wp_doing_ajax() ) {
1027
					echo json_encode( array( 'error' => $activate->get_error_message() ) );
1028
					wp_die();
1029
				}
1030
				return array(
1031
					'message' => $activate->get_error_message(),
1032
					'success' => false,
1033
				);
1034
			}
1035
		}
1036
	}
1037
1038
	/**
1039
	 * Run security checks before installing
1040
	 *
1041
	 * @since 3.04.02
1042
	 */
1043
	private static function install_addon_permissions() {
1044
		check_ajax_referer( 'frm_ajax', 'nonce' );
1045
1046
		if ( ! current_user_can( 'activate_plugins' ) || ! isset( $_POST['plugin'] ) ) {
1047
			echo json_encode( true );
1048
			wp_die();
1049
		}
1050
	}
1051
1052
	/**
1053
	 * @since 4.08
1054
	 */
1055
	public static function connect_link() {
1056
		$auth = get_option( 'frm_connect_token' );
1057
		if ( empty( $auth ) ) {
1058
			$auth = hash( 'sha512', wp_rand() );
1059
			update_option( 'frm_connect_token', $auth );
1060
		}
1061
		$link = FrmAppHelper::admin_upgrade_link( 'connect', 'api-connect' );
1062
		$args = array(
1063
			'v'       => 2,
1064
			'siteurl' => FrmAppHelper::site_url(),
1065
			'url'     => get_rest_url(),
1066
			'token'   => $auth,
1067
			'l'       => self::get_pro_license(),
1068
		);
1069
1070
		return add_query_arg( $args, $link );
1071
	}
1072
1073
	/**
1074
	 * Check the auth value for install permission.
1075
	 *
1076
	 * @since 4.08
1077
	 *
1078
	 * @return bool
1079
	 */
1080
	public static function can_install_addon_api() {
1081
		// Verify params present (auth & download link).
1082
		$post_auth = FrmAppHelper::get_param( 'token', '', 'request', 'sanitize_text_field' );
1083
		$post_url  = FrmAppHelper::get_param( 'file_url', '', 'request', 'sanitize_text_field' );
1084
1085
		if ( empty( $post_auth ) || empty( $post_url ) ) {
1086
			return false;
1087
		}
1088
1089
		// Verify auth.
1090
		$auth = get_option( 'frm_connect_token' );
1091
		if ( empty( $auth ) || ! hash_equals( $auth, $post_auth ) ) {
1092
			return false;
1093
		}
1094
1095
		return true;
1096
	}
1097
1098
	/**
1099
	 * Install and/or activate the add-on file.
1100
	 *
1101
	 * @since 4.08
1102
	 */
1103
	public static function install_addon_api() {
1104
		// Sanitize when it's used to prevent double sanitizing.
1105
		// phpcs:ignore WordPress.Security.ValidatedSanitizedInput
1106
		$_POST['plugin'] = isset( $_REQUEST['file_url'] ) ? $_REQUEST['file_url'] : ''; // Set for later use
1107
1108
		$error = esc_html__( 'Could not install an upgrade. Please download from formidableforms.com and install manually.', 'formidable' );
0 ignored issues
show
Unused Code introduced by
$error is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
1109
1110
		// Delete so cannot replay.
1111
		delete_option( 'frm_connect_token' );
1112
1113
		// It's already installed and active.
1114
		$active = activate_plugin( 'formidable-pro/formidable-pro.php', false, false, true );
1115
		if ( is_wp_error( $active ) ) {
1116
			// Download plugin now.
1117
			$response = self::download_and_activate();
1118
			if ( is_array( $response ) && isset( $response['success'] ) ) {
1119
				return $response;
1120
			}
1121
		}
1122
1123
		// If empty license, save it now.
1124
		if ( empty( self::get_pro_license() ) && function_exists( 'load_formidable_pro' ) ) {
1125
			load_formidable_pro();
1126
			$license = stripslashes( FrmAppHelper::get_param( 'key', '', 'request', 'sanitize_text_field' ) );
1127
			if ( empty( $license ) ) {
1128
				return array(
1129
					'success' => false,
1130
					'error'   => 'That site does not have a valid license key.',
1131
				);
1132
			}
1133
1134
			$response = FrmAddon::activate_license_for_plugin( $license, 'formidable_pro' );
1135
			if ( ! $response['success'] ) {
1136
				// Could not activate license.
1137
				return $response;
1138
			}
1139
		}
1140
1141
		return array(
1142
			'success' => true,
1143
		);
1144
	}
1145
1146
	/**
1147
	 * Render a conditional action button for a specified plugin
1148
	 *
1149
	 * @param string $plugin
1150
	 * @param array|string $upgrade_link_args
1151
	 * @since 4.09
1152
	 */
1153
	public static function conditional_action_button( $plugin, $upgrade_link_args ) {
1154
		$addon         = self::get_addon( $plugin );
1155
		$license_type  = self::get_license_type();
1156
		$plan_required = FrmFormsHelper::get_plan_required( $addon );
1157
		$upgrade_link  = FrmAppHelper::admin_upgrade_link( $upgrade_link_args );
1158
		FrmAppHelper::conditional_action_button( $addon, $license_type, $plan_required, $upgrade_link );
1159
	}
1160
1161
	/**
1162
	 * @since 3.04.03
1163
	 * @deprecated 3.06
1164
	 * @codeCoverageIgnore
1165
	 * @return array
1166
	 */
1167
	public static function error_for_license( $license ) {
1168
		return FrmDeprecated::error_for_license( $license );
1169
	}
1170
1171
	/**
1172
	 * @since 3.04.03
1173
	 * @deprecated 3.06
1174
	 * @codeCoverageIgnore
1175
	 */
1176
	public static function get_pro_updater() {
1177
		return FrmDeprecated::get_pro_updater();
1178
	}
1179
1180
	/**
1181
	 * @since 3.04.03
1182
	 * @deprecated 3.06
1183
	 * @codeCoverageIgnore
1184
	 *
1185
	 * @return array
1186
	 */
1187
	public static function get_addon_info( $license = '' ) {
1188
		return FrmDeprecated::get_addon_info( $license );
1189
	}
1190
1191
	/**
1192
	 * @since 3.04.03
1193
	 * @deprecated 3.06
1194
	 * @codeCoverageIgnore
1195
	 *
1196
	 * @return string
1197
	 */
1198
	public static function get_cache_key( $license ) {
1199
		return FrmDeprecated::get_cache_key( $license );
1200
	}
1201
1202
	/**
1203
	 * @since 3.04.03
1204
	 * @deprecated 3.06
1205
	 * @codeCoverageIgnore
1206
	 */
1207
	public static function reset_cached_addons( $license = '' ) {
1208
		FrmDeprecated::reset_cached_addons( $license );
1209
	}
1210
1211
	/**
1212
	 * @since 2.03.08
1213
	 * @deprecated 3.04.03
1214
	 * @codeCoverageIgnore
1215
	 *
1216
	 * @param boolean $return
1217
	 * @param string $package
1218
	 *
1219
	 * @return boolean
1220
	 */
1221
	public static function add_shorten_edd_filename_filter( $return, $package ) {
1222
		return FrmDeprecated::add_shorten_edd_filename_filter( $return, $package );
1223
	}
1224
1225
	/**
1226
	 * @since 2.03.08
1227
	 * @deprecated 3.04.03
1228
	 * @codeCoverageIgnore
1229
	 *
1230
	 * @param string $filename
1231
	 * @param string $ext
1232
	 *
1233
	 * @return string
1234
	 */
1235
	public static function shorten_edd_filename( $filename, $ext ) {
1236
		return FrmDeprecated::shorten_edd_filename( $filename, $ext );
1237
	}
1238
1239
	/**
1240
	 * @deprecated 3.04.03
1241
	 * @codeCoverageIgnore
1242
	 */
1243
	public static function get_licenses() {
1244
		FrmDeprecated::get_licenses();
1245
	}
1246
}
1247