Completed
Pull Request — master (#200)
by Stephanie
02:17
created

FrmAddonsController::get_pro_download_url()   B

Complexity

Conditions 10
Paths 20

Size

Total Lines 29

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 10
nc 20
nop 0
dl 0
loc 29
rs 7.6666
c 0
b 0
f 0

How to fix   Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
class FrmAddonsController {
4
5
	public static function menu() {
6
		if ( ! current_user_can( 'activate_plugins' ) ) {
7
			return;
8
		}
9
10
		$label = __( 'Add-Ons', 'formidable' );
11
		if ( FrmAppHelper::pro_is_installed() ) {
12
			$label = '<span style="color:#fe5a1d">' . $label . '</span>';
13
		}
14
		add_submenu_page( 'formidable', 'Formidable | ' . __( 'Add-Ons', 'formidable' ), $label, 'frm_view_forms', 'formidable-addons', 'FrmAddonsController::list_addons' );
15
16
		if ( ! FrmAppHelper::pro_is_installed() ) {
17
			add_submenu_page(
18
				'formidable',
19
				'Formidable | ' . __( 'Upgrade', 'formidable' ),
20
				'<span style="color:#fe5a1d">' . __( 'Upgrade', 'formidable' ) . '</span>',
21
				'frm_view_forms',
22
				'formidable-pro-upgrade',
23
				'FrmAddonsController::upgrade_to_pro'
24
			);
25
		}
26
	}
27
28
	public static function list_addons() {
29
		FrmAppHelper::include_svg();
30
		$installed_addons = apply_filters( 'frm_installed_addons', array() );
31
		$license_type     = '';
32
33
		$addons = self::get_api_addons();
34
		$errors = array();
35
36
		if ( isset( $addons['error'] ) ) {
37
			$api    = new FrmFormApi();
38
			$errors = $api->get_error_from_response( $addons );
39
			$license_type = isset( $addons['error']['type'] ) ? $addons['error']['type'] : '';
40
			unset( $addons['error'] );
41
		}
42
		self::prepare_addons( $addons );
43
44
		$pricing = FrmAppHelper::admin_upgrade_link( 'addons' );
45
46
		include( FrmAppHelper::plugin_path() . '/classes/views/addons/list.php' );
47
	}
48
49
	public static function license_settings() {
50
		$plugins = apply_filters( 'frm_installed_addons', array() );
51
		if ( empty( $plugins ) ) {
52
			esc_html_e( 'There are no plugins on your site that require a license', 'formidable' );
53
54
			return;
55
		}
56
57
		ksort( $plugins );
58
59
		include( FrmAppHelper::plugin_path() . '/classes/views/addons/settings.php' );
60
	}
61
62
	private static function get_api_addons() {
63
		$api    = new FrmFormApi();
64
		$addons = $api->get_api_info();
65
66
		if ( empty( $addons ) ) {
67
			$addons = self::fallback_plugin_list();
68
		} else {
69
			foreach ( $addons as $k => $addon ) {
70
				if ( empty( $addon['excerpt'] ) && $k !== 'error' ) {
71
					unset( $addons[ $k ] );
72
				}
73
			}
74
		}
75
76
		return $addons;
77
	}
78
79
	/**
80
	 * If the API is unable to connect, show something on the addons page
81
	 *
82
	 * @since 3.04.03
83
	 * @return array
84
	 */
85
	private static function fallback_plugin_list() {
86
		return array(
87
			'formidable-pro' => array(
88
				'title'   => 'Formidable Forms',
89
				'link'    => 'pricing/',
90
				'docs'    => '',
91
				'excerpt' => 'Enhance your basic Formidable forms with a plethora of Pro field types and features. Create advanced forms and data-driven applications in minutes.',
92
			),
93
			'mailchimp'      => array(
94
				'title'   => 'MailChimp Forms',
95
				'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.',
96
			),
97
			'registration'   => array(
98
				'title'   => 'User Registration Forms',
99
				'link'    => 'downloads/user-registration/',
100
				'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.',
101
			),
102
			'paypal'         => array(
103
				'title'   => 'PayPal Standard Forms',
104
				'link'    => 'downloads/paypal-standard/',
105
				'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.',
106
			),
107
			'stripe'         => array(
108
				'title'   => 'Stripe Forms',
109
				'docs'    => 'knowledgebase/stripe/',
110
				'excerpt' => 'Any Formidable forms on your site can accept credit card payments without users ever leaving your site.',
111
			),
112
			'authorize-net'  => array(
113
				'title'   => 'Authorize.net AIM Forms',
114
				'link'    => 'downloads/authorize-net-aim/',
115
				'docs'    => 'knowledgebase/authorize-net-aim/',
116
				'excerpt' => 'Accept one-time payments directly on your site, using Authorize.net AIM.',
117
			),
118
			'woocommerce'    => array(
119
				'title'   => 'WooCommerce Forms',
120
				'excerpt' => 'Use a Formidable form on your WooCommerce product pages.',
121
			),
122
			'autoresponder'  => array(
123
				'title'   => 'Form Action Automation',
124
				'docs'    => 'knowledgebase/schedule-autoresponder/',
125
				'excerpt' => 'Schedule email notifications, SMS messages, and API actions.',
126
			),
127
			'modal'          => array(
128
				'title'   => 'Bootstrap Modal Forms',
129
				'link'    => 'downloads/bootstrap-modal/',
130
				'docs'    => 'knowledgebase/bootstrap-modal/',
131
				'excerpt' => 'Open a view or form in a Bootstrap popup.',
132
			),
133
			'bootstrap'      => array(
134
				'title'   => 'Bootstrap Style Forms',
135
				'excerpt' => 'Instantly add Bootstrap styling to all your Formidable forms.',
136
			),
137
			'zapier'         => array(
138
				'title'   => 'Zapier Forms',
139
				'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.',
140
			),
141
			'signature'      => array(
142
				'title'   => 'Digital Signature Forms',
143
				'excerpt' => 'Add a signature field to your form. The user may write their signature with a trackpad/mouse or just type it.',
144
			),
145
			'api'            => array(
146
				'title'   => 'Formidable Forms API',
147
				'link'    => 'downloads/formidable-api/',
148
				'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.',
149
			),
150
			'twilio'         => array(
151
				'title'   => 'Twilio SMS Forms',
152
				'docs'    => 'knowledgebase/twilio-add-on/',
153
				'excerpt' => 'Allow users to text their votes for polls created by Formidable Forms, or send SMS notifications when entries are submitted or updated.',
154
			),
155
		);
156
	}
157
158
	/**
159
	 * If Pro is missing but has been authenticated, include a download URL
160
	 *
161
	 * @since 3.04.03
162
	 * @return string
163
	 */
164
	public static function get_pro_download_url() {
165
		$pro_cred_store = 'frmpro-credentials';
166
		$pro_wpmu_store = 'frmpro-wpmu-sitewide';
167
		if ( is_multisite() && get_site_option( $pro_wpmu_store ) ) {
168
			$creds = get_site_option( $pro_cred_store );
169
		} else {
170
			$creds = get_option( $pro_cred_store );
171
		}
172
173
		if ( empty( $creds ) || ! is_array( $creds ) || ! isset( $creds['license'] ) ) {
174
			return '';
175
		}
176
177
		$license = $creds['license'];
178
		if ( empty( $license ) ) {
179
			return '';
180
		}
181
182
		if ( strpos( $license, '-' ) ) {
183
			// this is a fix for licenses saved in the past
184
			$license = strtoupper( $license );
185
		}
186
187
		$api       = new FrmFormApi( $license );
188
		$downloads = $api->get_api_info();
189
		$pro       = isset( $downloads['93790'] ) ? $downloads['93790'] : array();
190
191
		return isset( $pro['url'] ) ? $pro['url'] : '';
192
	}
193
194
	/**
195
	 * @since 4.06
196
	 */
197
	public static function license_type() {
198
		$api     = new FrmFormApi();
199
		$addons  = $api->get_api_info();
200
		$type    = 'free';
201
202
		if ( isset( $addons['error'] ) ) {
203
			if ( isset( $addons['error']['code'] ) && $addons['error']['code'] === 'expired' ) {
204
				return $addons['error']['code'];
205
			}
206
			$type = isset( $addons['error']['type'] ) ? $addons['error']['type'] : $type;
207
		}
208
209
		$pro = isset( $addons['93790'] ) ? $addons['93790'] : array();
210
		if ( $type === 'free' ) {
211
			$type = isset( $pro['type'] ) ? $pro['type'] : $type;
212
			if ( $type === 'free' ) {
213
				return $type;
214
			}
215
		}
216
217
		if ( isset( $pro['code'] ) && $pro['code'] === 'grandfathered' ) {
218
			return $pro['code'];
219
		}
220
221
		$expires = isset( $pro['expires'] ) ? $pro['expires'] : '';
222
		$expired = $expires ? $expires < time() : false;
223
		return $expired ? 'expired' : strtolower( $type );
224
	}
225
226
	/**
227
	 * @since 4.0.01
228
	 */
229
	public static function is_license_expired() {
230
		$installed_addons = apply_filters( 'frm_installed_addons', array() );
231
		if ( empty( $installed_addons ) || ! isset( $installed_addons['formidable_pro'] ) ) {
232
			return false;
233
		}
234
		$installed_addons = array(
235
			'formidable_pro' => $installed_addons['formidable_pro'],
236
		);
237
238
		$version_info = self::fill_update_addon_info( $installed_addons );
239
		if ( ! isset( $version_info['error'] ) ) {
240
			return false;
241
		}
242
243
		return $version_info['error'];
244
	}
245
246
	/**
247
	 * @since 3.04.03
248
	 */
249
	public static function check_update( $transient ) {
250
		if ( ! is_object( $transient ) ) {
251
			$transient = new stdClass();
252
		}
253
254
		$installed_addons = apply_filters( 'frm_installed_addons', array() );
255
		if ( empty( $installed_addons ) ) {
256
			return $transient;
257
		}
258
259
		$version_info = self::fill_update_addon_info( $installed_addons );
260
261
		$transient->last_checked = time();
262
263
		if ( ! function_exists( 'get_plugins' ) ) {
264
			require_once ABSPATH . 'wp-admin/includes/plugin.php';
265
		}
266
		$wp_plugins = get_plugins();
267
268
		foreach ( $version_info as $id => $plugin ) {
269
			$plugin = (object) $plugin;
270
271
			if ( ! isset( $plugin->new_version ) || ! isset( $plugin->package ) ) {
272
				continue;
273
			}
274
275
			$folder = $plugin->plugin;
276
			if ( empty( $folder ) ) {
277
				continue;
278
			}
279
280
			if ( ! self::is_installed( $folder ) ) {
281
				// don't show an update if the plugin isn't installed
282
				continue;
283
			}
284
285
			$wp_plugin  = isset( $wp_plugins[ $folder ] ) ? $wp_plugins[ $folder ] : array();
286
			$wp_version = isset( $wp_plugin['Version'] ) ? $wp_plugin['Version'] : '1.0';
287
288
			if ( version_compare( $wp_version, $plugin->new_version, '<' ) ) {
289
				$slug                           = explode( '/', $folder );
290
				$plugin->slug                   = $slug[0];
291
				$transient->response[ $folder ] = $plugin;
292
			}
293
294
			$transient->checked[ $folder ] = $wp_version;
295
296
		}
297
298
		return $transient;
299
	}
300
301
	/**
302
	 * Check if a plugin is installed before showing an update for it
303
	 *
304
	 * @since 3.05
305
	 *
306
	 * @param string $plugin - the folder/filename.php for a plugin
307
	 *
308
	 * @return bool - True if installed
309
	 */
310
	private static function is_installed( $plugin ) {
311
		if ( ! function_exists( 'get_plugins' ) ) {
312
			require_once ABSPATH . 'wp-admin/includes/plugin.php';
313
		}
314
315
		$all_plugins = get_plugins();
316
317
		return isset( $all_plugins[ $plugin ] );
318
	}
319
320
	/**
321
	 * @since 3.04.03
322
	 *
323
	 * @param array $installed_addons
324
	 *
325
	 * @return array
326
	 */
327
	private static function fill_update_addon_info( $installed_addons ) {
328
		$checked_licenses = array();
329
		$version_info     = array();
330
331
		foreach ( $installed_addons as $addon ) {
332
			if ( $addon->store_url !== 'https://formidableforms.com' ) {
333
				// check if this is a third-party addon
334
				continue;
335
			}
336
337
			$new_license = $addon->license;
338
			if ( empty( $new_license ) || in_array( $new_license, $checked_licenses ) ) {
339
				continue;
340
			}
341
342
			$checked_licenses[] = $new_license;
343
344
			$api = new FrmFormApi( $new_license );
345
			if ( empty( $version_info ) ) {
346
				$version_info = $api->get_api_info();
347
				continue;
348
			}
349
350
			$plugin = $api->get_addon_for_license( $addon, $version_info );
351
			if ( empty( $plugin ) ) {
352
				continue;
353
			}
354
355
			$download_id = isset( $plugin['id'] ) ? $plugin['id'] : 0;
356
			if ( ! empty( $download_id ) && ! isset( $version_info[ $download_id ]['package'] ) ) {
357
				// if this addon is using its own license, get the update url
358
				$addon_info = $api->get_api_info();
359
360
				$version_info[ $download_id ] = $addon_info[ $download_id ];
361
				if ( isset( $addon_info['error'] ) ) {
362
					$version_info[ $download_id ]['error'] = array(
363
						'message' => $addon_info['error']['message'],
364
						'code'    => $addon_info['error']['code'],
365
					);
366
				}
367
			}
368
		}
369
370
		return $version_info;
371
	}
372
373
	/**
374
	 * Get the action link for an addon that isn't active.
375
	 *
376
	 * @since 3.06.03
377
	 * @param string $addon The plugin slug
0 ignored issues
show
Bug introduced by
There is no parameter named $addon. Was it maybe removed?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function.

Consider the following example. The parameter $italy is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $island
 * @param array $italy
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was removed, but the annotation was not.

Loading history...
378
	 * @return array
379
	 */
380
	public static function install_link( $plugin ) {
381
		$link    = array();
382
		$addons = self::get_api_addons();
383
		self::prepare_addons( $addons );
384
385
		foreach ( $addons as $addon ) {
386
			$slug = explode( '/', $addon['plugin'] );
387
			if ( $slug[0] !== 'formidable-' . $plugin ) {
388
				continue;
389
			}
390
391
			if ( $addon['status']['type'] === 'installed' && ! empty( $addon['activate_url'] ) ) {
392
				$link = array(
393
					'url'   => $addon['plugin'],
394
					'class' => 'frm-activate-addon',
395
				);
396
			} elseif ( isset( $addon['url'] ) && ! empty( $addon['url'] ) ) {
397
				$link = array(
398
					'url'   => $addon['url'],
399
					'class' => 'frm-install-addon',
400
				);
401
			} elseif ( isset( $addon['categories'] ) && ! empty( $addon['categories'] ) ) {
402
				$link = array(
403
					'categories' => $addon['categories'],
404
				);
405
			}
406
407
			if ( ! empty( $link ) ) {
408
				$link['status'] = $addon['status']['type'];
409
			}
410
411
			return $link;
412
		}
413
	}
414
415
	/**
416
	 * @since 3.04.03
417
	 *
418
	 * @param array $addons
419
	 * @param object $license The FrmAddon object
420
	 *
421
	 * @return array
422
	 */
423
	public static function get_addon_for_license( $addons, $license ) {
424
		$download_id = $license->download_id;
425
		$plugin      = array();
426 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...
427
			foreach ( $addons as $addon ) {
428
				if ( strtolower( $license->plugin_name ) == strtolower( $addon['title'] ) ) {
429
					return $addon;
430
				}
431
			}
432
		} elseif ( isset( $addons[ $download_id ] ) ) {
433
			$plugin = $addons[ $download_id ];
434
		}
435
436
		return $plugin;
437
	}
438
439
	private static function prepare_addons( &$addons ) {
440
		$activate_url = '';
441
		if ( current_user_can( 'activate_plugins' ) ) {
442
			$activate_url = add_query_arg( array( 'action' => 'activate' ), admin_url( 'plugins.php' ) );
443
		}
444
445
		$loop_addons = $addons;
446
		foreach ( $loop_addons as $id => $addon ) {
447
			if ( is_numeric( $id ) ) {
448
				$slug      = str_replace( array( '-wordpress-plugin', '-wordpress' ), '', $addon['slug'] );
449
				$file_name = $addon['plugin'];
450
			} else {
451
				$slug = $id;
452
				if ( isset( $addon['file'] ) ) {
453
					$base_file = $addon['file'];
454
				} else {
455
					$base_file = 'formidable-' . $slug;
456
				}
457
				$file_name = $base_file . '/' . $base_file . '.php';
458
			}
459
460
			$addon['installed']    = self::is_installed( $file_name );
461
			$addon['activate_url'] = '';
462
463
			if ( $addon['installed'] && ! empty( $activate_url ) && ! is_plugin_active( $file_name ) ) {
464
				$addon['activate_url'] = add_query_arg(
465
					array(
466
						'_wpnonce' => wp_create_nonce( 'activate-plugin_' . $file_name ),
467
						'plugin'   => $file_name,
468
					),
469
					$activate_url
470
				);
471
			}
472
473
			if ( ! isset( $addon['docs'] ) ) {
474
				$addon['docs'] = 'knowledgebase/formidable-' . $slug . '/';
475
			}
476
			self::prepare_addon_link( $addon['docs'] );
477
478
			if ( ! isset( $addon['link'] ) ) {
479
				$addon['link'] = 'downloads/' . $slug . '/';
480
			}
481
			self::prepare_addon_link( $addon['link'] );
482
483
			self::set_addon_status( $addon );
484
			$addons[ $id ] = $addon;
485
		}
486
	}
487
488
	/**
489
	 * @since 3.04.02
490
	 */
491
	private static function prepare_addon_link( &$link ) {
492
		$site_url = 'https://formidableforms.com/';
493
		if ( strpos( $link, 'http' ) !== 0 ) {
494
			$link = $site_url . $link;
495
		}
496
		$link       = FrmAppHelper::make_affiliate_url( $link );
497
		$query_args = array(
498
			'utm_source'   => 'WordPress',
499
			'utm_medium'   => 'addons',
500
			'utm_campaign' => 'liteplugin',
501
		);
502
		$link       = add_query_arg( $query_args, $link );
503
	}
504
505
	/**
506
	 * Add the status to the addon array. Status options are:
507
	 * installed, active, not installed
508
	 *
509
	 * @since 3.04.02
510
	 */
511
	private static function set_addon_status( &$addon ) {
512
		if ( ! empty( $addon['activate_url'] ) ) {
513
			$addon['status'] = array(
514
				'type'  => 'installed',
515
				'label' => __( 'Installed', 'formidable' ),
516
			);
517
		} elseif ( $addon['installed'] ) {
518
			$addon['status'] = array(
519
				'type'  => 'active',
520
				'label' => __( 'Active', 'formidable' ),
521
			);
522
		} else {
523
			$addon['status'] = array(
524
				'type'  => 'not-installed',
525
				'label' => __( 'Not Installed', 'formidable' ),
526
			);
527
		}
528
	}
529
530
	public static function upgrade_to_pro() {
531
		FrmAppHelper::include_svg();
532
533
		$link_parts = array(
534
			'medium'  => 'upgrade',
535
			'content' => 'button',
536
		);
537
538
		$features = array(
539
			'Display Entries' => array(
540
				array(
541
					'label' => 'Display form data with virtually limitless views',
542
					'link'  => array(
543
						'content' => 'views',
544
						'param'   => 'views-display-form-data',
545
					),
546
					'lite'  => false,
547
				),
548
				array(
549
					'label' => 'Generate graphs and stats based on your submitted data',
550
					'link'  => array(
551
						'content' => 'graphs',
552
						'param'   => 'statistics-graphs-wordpress-forms',
553
					),
554
					'lite'  => false,
555
				),
556
			),
557
			'Entry Management' => array(
558
				array(
559
					'label' => 'Import entries from a CSV',
560
					'link'  => array(
561
						'content' => 'import-entries',
562
						'param'   => 'importing-exporting-wordpress-forms',
563
					),
564
					'lite'  => false,
565
				),
566
				array(
567
					'label' => 'Logged-in users can save drafts and return later',
568
					'link'  => array(
569
						'content' => 'save-drafts',
570
						'param'   => 'save-drafts-wordpress-form',
571
					),
572
					'lite'  => false,
573
				),
574
				array(
575
					'label' => 'Flexibly and powerfully view, edit, and delete entries from anywhere on your site',
576
					'link'  => array(
577
						'content' => 'front-edit',
578
						'param'   => 'wordpress-front-end-editing',
579
					),
580
					'lite'  => false,
581
				),
582
				array(
583
					'label' => 'View form submissions from the back-end',
584
					'lite'  => true,
585
				),
586
				array(
587
					'label' => 'Export your entries to a CSV',
588
					'lite'  => true,
589
				),
590
			),
591
			'Form Building' => array(
592
				array(
593
					'label' => 'Save a calculated value into a field',
594
					'link'  => array(
595
						'content' => 'calculations',
596
						'param'   => 'field-calculations-wordpress-form',
597
					),
598
					'lite'  => false,
599
				),
600
				array(
601
					'label' => 'Allow multiple file uploads',
602
					'link'  => array(
603
						'content' => 'file-uploads',
604
						'param'   => 'wordpress-multi-file-upload-fields',
605
					),
606
					'lite'  => false,
607
				),
608
				array(
609
					'label' => 'Repeat sections of fields',
610
					'link'  => array(
611
						'content' => 'repeaters',
612
						'param'   => 'repeatable-sections-forms',
613
					),
614
					'lite'  => false,
615
				),
616
				array(
617
					'label' => 'Hide and show fields conditionally based on other fields or the user\'s role',
618
					'link'  => array(
619
						'content' => 'conditional-logic',
620
						'param'   => 'conditional-logic-wordpress-forms',
621
					),
622
					'lite'  => false,
623
				),
624
				array(
625
					'label' => 'Confirmation fields',
626
					'link'  => array(
627
						'content' => 'confirmation-fields',
628
						'param'   => 'confirmation-fields-wordpress-forms',
629
					),
630
					'lite'  => false,
631
				),
632
				array(
633
					'label' => 'Multi-paged forms',
634
					'link'  => array(
635
						'content' => 'page-breaks',
636
						'param'   => 'wordpress-multi-page-forms',
637
					),
638
					'lite'  => false,
639
				),
640
				array(
641
					'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.',
642
					'lite'  => false,
643
				),
644
				array(
645
					'label' => 'Include text, email, url, paragraph text, radio, checkbox, dropdown fields, hidden fields, user ID fields, and HTML blocks in your form.',
646
					'lite'  => true,
647
				),
648
				array(
649
					'label' => 'Drag & Drop Form building',
650
					'link'  => array(
651
						'content' => 'drag-drop',
652
						'param'   => 'drag-drop-forms',
653
					),
654
					'lite'  => true,
655
				),
656
				array(
657
					'label' => 'Create forms from Templates',
658
					'link'  => array(
659
						'content' => 'form-templates',
660
						'param'   => 'wordpress-form-templates',
661
					),
662
					'lite'  => true,
663
				),
664
				array(
665
					'label' => 'Import and export forms with XML',
666
					'link'  => array(
667
						'content' => 'import',
668
						'param'   => 'importing-exporting-wordpress-forms',
669
					),
670
					'lite'  => true,
671
				),
672
				array(
673
					'label' => 'Use input placeholder text in your fields that clear when typing starts.',
674
					'lite'  => true,
675
				),
676
			),
677
			'Form Actions' => array(
678
				array(
679
					'label' => 'Conditionally send your email notifications based on values in your form',
680
					'link'  => array(
681
						'content' => 'conditional-emails',
682
					),
683
					'lite'  => false,
684
				),
685
				array(
686
					'label' => 'Create and edit WordPress posts or custom posts from the front-end',
687
					'link'  => array(
688
						'content' => 'create-posts',
689
						'param'   => 'create-posts-pages-wordpress-forms',
690
					),
691
					'lite'  => false,
692
				),
693
				array(
694
					'label' => 'Send multiple emails and autoresponders',
695
					'link'  => array(
696
						'content' => 'multiple-emails',
697
						'param'   => 'virtually-unlimited-emails',
698
					),
699
					'lite'  => true,
700
				),
701
			),
702
			'Form Appearance' => array(
703
				array(
704
					'label' => 'Create Multiple styles for different forms',
705
					'link'  => array(
706
						'content' => 'multiple-styles',
707
						'param'   => 'wordpress-visual-form-styler',
708
					),
709
					'lite'  => false,
710
				),
711
				array(
712
					'label' => 'Customizable layout with CSS classes',
713
					'link'  => array(
714
						'content' => 'form-layout',
715
						'param'   => 'wordpress-mobile-friendly-forms',
716
					),
717
					'lite'  => true,
718
				),
719
				array(
720
					'label' => 'Customize the HTML for your forms',
721
					'link'  => array(
722
						'content' => 'custom-html',
723
						'param'   => 'customizable-html-wordpress-form',
724
					),
725
					'lite'  => true,
726
				),
727
				array(
728
					'label' => 'Style your form with the Visual Form Styler',
729
					'lite'  => true,
730
				),
731
			),
732
		);
733
734
		include( FrmAppHelper::plugin_path() . '/classes/views/addons/upgrade_to_pro.php' );
735
	}
736
737
	/**
738
	 * Install Pro after connection with Formidable.
739
	 *
740
	 * @since 4.02.05
741
	 */
742
	public static function connect_pro() {
743
		FrmAppHelper::permission_check( 'install_plugins' );
744
		check_ajax_referer( 'frm_ajax', 'nonce' );
745
746
		$url = FrmAppHelper::get_post_param( 'plugin', '', 'sanitize_text_field' );
747
		if ( FrmAppHelper::pro_is_installed() || empty( $url ) ) {
748
			wp_die();
749
		}
750
751
		$response = array();
752
753
		// It's already installed and active.
754
		$active = activate_plugin( 'formidable-pro/formidable-pro.php', false, false, true );
755
		if ( is_wp_error( $active ) ) {
756
			// The plugin was installed, but not active. Download it now.
757
			self::ajax_install_addon();
758
		} else {
759
			$response['active'] = true;
760
		}
761
762
		echo json_encode( $response );
763
		wp_die();
764
	}
765
766
	/**
767
	 * @since 3.04.02
768
	 */
769
	public static function ajax_install_addon() {
770
771
		self::install_addon_permissions();
772
773
		// Set the current screen to avoid undefined notices.
774
		global $hook_suffix;
775
		set_current_screen();
776
777
		self::maybe_show_cred_form();
778
779
		$installed = self::install_addon();
780
		self::maybe_activate_addon( $installed );
781
782
		// Send back a response.
783
		echo json_encode( __( 'Your plugin has been installed. Please reload the page to see more options.', 'formidable' ) );
784
		wp_die();
785
	}
786
787
	/**
788
	 * @since 3.04.02
789
	 */
790
	private static function maybe_show_cred_form() {
791
		// Start output bufferring to catch the filesystem form if credentials are needed.
792
		ob_start();
793
794
		$show_form = false;
795
		$method    = '';
796
		$url       = add_query_arg( array( 'page' => 'formidable-settings' ), admin_url( 'admin.php' ) );
797
		$url       = esc_url_raw( $url );
798
		$creds     = request_filesystem_credentials( $url, $method, false, false, null );
799
800
		if ( false === $creds ) {
801
			$show_form = true;
802
		} elseif ( ! WP_Filesystem( $creds ) ) {
803
			request_filesystem_credentials( $url, $method, true, false, null );
804
			$show_form = true;
805
		}
806
807
		if ( $show_form ) {
808
			//$form = ob_get_clean();
809
			//TODO: test this: echo json_encode( array( 'form' => $form ) );
810
			echo json_encode( array( 'form' => __( 'Sorry, you\'re site requires FTP authentication. Please install plugins manaully.', 'formidable' ) ) );
811
			wp_die();
812
		}
813
814
		ob_end_clean();
815
	}
816
817
	/**
818
	 * We do not need any extra credentials if we have gotten this far,
819
	 * so let's install the plugin.
820
	 *
821
	 * @since 3.04.02
822
	 */
823
	private static function install_addon() {
824
		require_once( ABSPATH . 'wp-admin/includes/class-wp-upgrader.php' );
825
826
		$download_url = FrmAppHelper::get_param( 'plugin', '', 'post', 'esc_url_raw' );
827
828
		// Create the plugin upgrader with our custom skin.
829
		$installer = new Plugin_Upgrader( new FrmInstallerSkin() );
830
		$installer->install( $download_url );
831
832
		// Flush the cache and return the newly installed plugin basename.
833
		wp_cache_flush();
834
835
		return $installer->plugin_info();
836
	}
837
838
	/**
839
	 * @since 3.06.03
840
	 */
841
	public static function ajax_activate_addon() {
842
843
		self::install_addon_permissions();
844
845
		// Set the current screen to avoid undefined notices.
846
		global $hook_suffix;
847
		set_current_screen();
848
849
		$plugin = FrmAppHelper::get_param( 'plugin', '', 'post', 'sanitize_text_field' );
850
		self::maybe_activate_addon( $plugin );
851
852
		// Send back a response.
853
		echo json_encode( __( 'Your plugin has been activated. Please reload the page to see more options.', 'formidable' ) );
854
		wp_die();
855
	}
856
857
	/**
858
	 * @since 4.06.02
859
	 */
860
	public static function ajax_multiple_addons() {
861
		self::install_addon_permissions();
862
863
		// Set the current screen to avoid undefined notices.
864
		global $hook_suffix;
865
		set_current_screen();
866
867
		$download_urls = FrmAppHelper::get_param( 'plugin', '', 'post' );
868
		$download_urls = explode( ',', $download_urls );
869
		FrmAppHelper::sanitize_value( 'esc_url_raw', $download_urls );
870
871
		foreach ( $download_urls as $download_url ) {
872
			$_POST['plugin'] = $download_url;
873
			if ( strpos( $download_url, 'http' ) !== false ) {
874
				// Installing.
875
				self::maybe_show_cred_form();
876
877
				$installed = self::install_addon();
878
				self::maybe_activate_addon( $installed );
879
			} else {
880
				// Activating.
881
				self::maybe_activate_addon( $download_url );
882
			}
883
		}
884
885
		echo json_encode( __( 'Your plugins have been installed and activated.', 'formidable' ) );
886
887
		wp_die();
888
	}
889
890
	/**
891
	 * @since 3.04.02
892
	 * @param string $installed The plugin folder name with file name
893
	 */
894
	private static function maybe_activate_addon( $installed ) {
895
		if ( ! $installed ) {
896
			return;
897
		}
898
899
		$activate = activate_plugin( $installed );
900
		if ( is_wp_error( $activate ) ) {
901
			// Ignore the invalid header message that shows with nested plugins.
902
			if ( $activate->get_error_code() !== 'no_plugin_header' ) {
903
				echo json_encode( array( 'error' => $activate->get_error_message() ) );
904
				wp_die();
905
			}
906
		}
907
	}
908
909
	/**
910
	 * Run security checks before installing
911
	 *
912
	 * @since 3.04.02
913
	 */
914
	private static function install_addon_permissions() {
915
		check_ajax_referer( 'frm_ajax', 'nonce' );
916
917
		if ( ! current_user_can( 'activate_plugins' ) || ! isset( $_POST['plugin'] ) ) {
918
			echo json_encode( true );
919
			wp_die();
920
		}
921
	}
922
923
	/**
924
	 * @since 3.04.03
925
	 * @deprecated 3.06
926
	 * @codeCoverageIgnore
927
	 * @return array
928
	 */
929
	public static function error_for_license( $license ) {
930
		return FrmDeprecated::error_for_license( $license );
931
	}
932
933
	/**
934
	 * @since 3.04.03
935
	 * @deprecated 3.06
936
	 * @codeCoverageIgnore
937
	 */
938
	public static function get_pro_updater() {
939
		return FrmDeprecated::get_pro_updater();
940
	}
941
942
	/**
943
	 * @since 3.04.03
944
	 * @deprecated 3.06
945
	 * @codeCoverageIgnore
946
	 *
947
	 * @return array
948
	 */
949
	public static function get_addon_info( $license = '' ) {
950
		return FrmDeprecated::get_addon_info( $license );
951
	}
952
953
	/**
954
	 * @since 3.04.03
955
	 * @deprecated 3.06
956
	 * @codeCoverageIgnore
957
	 *
958
	 * @return string
959
	 */
960
	public static function get_cache_key( $license ) {
961
		return FrmDeprecated::get_cache_key( $license );
962
	}
963
964
	/**
965
	 * @since 3.04.03
966
	 * @deprecated 3.06
967
	 * @codeCoverageIgnore
968
	 */
969
	public static function reset_cached_addons( $license = '' ) {
970
		FrmDeprecated::reset_cached_addons( $license );
971
	}
972
973
	/**
974
	 * @since 2.03.08
975
	 * @deprecated 3.04.03
976
	 * @codeCoverageIgnore
977
	 *
978
	 * @param boolean $return
979
	 * @param string $package
980
	 *
981
	 * @return boolean
982
	 */
983
	public static function add_shorten_edd_filename_filter( $return, $package ) {
984
		return FrmDeprecated::add_shorten_edd_filename_filter( $return, $package );
985
	}
986
987
	/**
988
	 * @since 2.03.08
989
	 * @deprecated 3.04.03
990
	 * @codeCoverageIgnore
991
	 *
992
	 * @param string $filename
993
	 * @param string $ext
994
	 *
995
	 * @return string
996
	 */
997
	public static function shorten_edd_filename( $filename, $ext ) {
998
		return FrmDeprecated::shorten_edd_filename( $filename, $ext );
999
	}
1000
1001
	/**
1002
	 * @deprecated 3.04.03
1003
	 * @codeCoverageIgnore
1004
	 */
1005
	public static function get_licenses() {
1006
		FrmDeprecated::get_licenses();
1007
	}
1008
}
1009