Completed
Push — master ( 1faf52...225e8c )
by Stephanie
02:40
created

FrmAddonsController::set_addon_status()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 18

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 3
nc 3
nop 1
dl 0
loc 18
rs 9.6666
c 0
b 0
f 0
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 to Pro', 'formidable' ),
20
				'<span style="color:#fe5a1d">' . __( 'Upgrade to Pro', '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 Pro',
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.0.01
196
	 */
197
	public static function is_license_expired() {
198
		$installed_addons = apply_filters( 'frm_installed_addons', array() );
199
		if ( empty( $installed_addons ) || ! isset( $installed_addons['formidable_pro'] ) ) {
200
			return false;
201
		}
202
		$installed_addons = array(
203
			'formidable_pro' => $installed_addons['formidable_pro'],
204
		);
205
206
		$version_info = self::fill_update_addon_info( $installed_addons );
207
		if ( ! isset( $version_info['error'] ) ) {
208
			return false;
209
		}
210
211
		return $version_info['error'];
212
	}
213
214
	/**
215
	 * @since 3.04.03
216
	 */
217
	public static function check_update( $transient ) {
218
		if ( ! is_object( $transient ) ) {
219
			$transient = new stdClass();
220
		}
221
222
		$installed_addons = apply_filters( 'frm_installed_addons', array() );
223
		if ( empty( $installed_addons ) ) {
224
			return $transient;
225
		}
226
227
		$version_info = self::fill_update_addon_info( $installed_addons );
228
229
		$transient->last_checked = time();
230
231
		if ( ! function_exists( 'get_plugins' ) ) {
232
			require_once ABSPATH . 'wp-admin/includes/plugin.php';
233
		}
234
		$wp_plugins = get_plugins();
235
236
		foreach ( $version_info as $id => $plugin ) {
237
			$plugin = (object) $plugin;
238
239
			if ( ! isset( $plugin->new_version ) || ! isset( $plugin->package ) ) {
240
				continue;
241
			}
242
243
			$folder = $plugin->plugin;
244
			if ( empty( $folder ) ) {
245
				continue;
246
			}
247
248
			if ( ! self::is_installed( $folder ) ) {
249
				// don't show an update if the plugin isn't installed
250
				continue;
251
			}
252
253
			$wp_plugin  = isset( $wp_plugins[ $folder ] ) ? $wp_plugins[ $folder ] : array();
254
			$wp_version = isset( $wp_plugin['Version'] ) ? $wp_plugin['Version'] : '1.0';
255
256
			if ( version_compare( $wp_version, $plugin->new_version, '<' ) ) {
257
				$slug                           = explode( '/', $folder );
258
				$plugin->slug                   = $slug[0];
259
				$transient->response[ $folder ] = $plugin;
260
			}
261
262
			$transient->checked[ $folder ] = $wp_version;
263
264
		}
265
266
		return $transient;
267
	}
268
269
	/**
270
	 * Check if a plugin is installed before showing an update for it
271
	 *
272
	 * @since 3.05
273
	 *
274
	 * @param string $plugin - the folder/filename.php for a plugin
275
	 *
276
	 * @return bool - True if installed
277
	 */
278
	private static function is_installed( $plugin ) {
279
		if ( ! function_exists( 'get_plugins' ) ) {
280
			require_once ABSPATH . 'wp-admin/includes/plugin.php';
281
		}
282
283
		$all_plugins = get_plugins();
284
285
		return isset( $all_plugins[ $plugin ] );
286
	}
287
288
	/**
289
	 * @since 3.04.03
290
	 *
291
	 * @param array $installed_addons
292
	 *
293
	 * @return array
294
	 */
295
	private static function fill_update_addon_info( $installed_addons ) {
296
		$checked_licenses = array();
297
		$version_info     = array();
298
299
		foreach ( $installed_addons as $addon ) {
300
			if ( $addon->store_url !== 'https://formidableforms.com' ) {
301
				// check if this is a third-party addon
302
				continue;
303
			}
304
305
			$new_license = $addon->license;
306
			if ( empty( $new_license ) || in_array( $new_license, $checked_licenses ) ) {
307
				continue;
308
			}
309
310
			$checked_licenses[] = $new_license;
311
312
			$api = new FrmFormApi( $new_license );
313
			if ( empty( $version_info ) ) {
314
				$version_info = $api->get_api_info();
315
				continue;
316
			}
317
318
			$plugin = $api->get_addon_for_license( $addon, $version_info );
319
			if ( empty( $plugin ) ) {
320
				continue;
321
			}
322
323
			$download_id = isset( $plugin['id'] ) ? $plugin['id'] : 0;
324
			if ( ! empty( $download_id ) && ! isset( $version_info[ $download_id ]['package'] ) ) {
325
				// if this addon is using its own license, get the update url
326
				$addon_info = $api->get_api_info();
327
328
				$version_info[ $download_id ] = $addon_info[ $download_id ];
329
				if ( isset( $addon_info['error'] ) ) {
330
					$version_info[ $download_id ]['error'] = array(
331
						'message' => $addon_info['error']['message'],
332
						'code'    => $addon_info['error']['code'],
333
					);
334
				}
335
			}
336
		}
337
338
		return $version_info;
339
	}
340
341
	/**
342
	 * Get the action link for an addon that isn't active.
343
	 *
344
	 * @since 3.06.03
345
	 * @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...
346
	 * @return array
347
	 */
348
	public static function install_link( $plugin ) {
349
		$link    = array();
350
		$addons = self::get_api_addons();
351
		self::prepare_addons( $addons );
352
353
		foreach ( $addons as $addon ) {
354
			$slug = explode( '/', $addon['plugin'] );
355
			if ( $slug[0] !== 'formidable-' . $plugin ) {
356
				continue;
357
			}
358
359
			if ( $addon['status']['type'] === 'installed' && ! empty( $addon['activate_url'] ) ) {
360
				$link = array(
361
					'url'   => $addon['plugin'],
362
					'class' => 'frm-activate-addon',
363
				);
364
			} elseif ( isset( $addon['url'] ) && ! empty( $addon['url'] ) ) {
365
				$link = array(
366
					'url'   => $addon['url'],
367
					'class' => 'frm-install-addon',
368
				);
369
			} elseif ( isset( $addon['categories'] ) && ! empty( $addon['categories'] ) ) {
370
				$link = array(
371
					'categories' => $addon['categories'],
372
				);
373
			}
374
375
			return $link;
376
		}
377
	}
378
379
	/**
380
	 * @since 3.04.03
381
	 *
382
	 * @param array $addons
383
	 * @param object $license The FrmAddon object
384
	 *
385
	 * @return array
386
	 */
387
	public static function get_addon_for_license( $addons, $license ) {
388
		$download_id = $license->download_id;
389
		$plugin      = array();
390 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...
391
			foreach ( $addons as $addon ) {
392
				if ( strtolower( $license->plugin_name ) == strtolower( $addon['title'] ) ) {
393
					return $addon;
394
				}
395
			}
396
		} elseif ( isset( $addons[ $download_id ] ) ) {
397
			$plugin = $addons[ $download_id ];
398
		}
399
400
		return $plugin;
401
	}
402
403
	private static function prepare_addons( &$addons ) {
404
		$activate_url = '';
405
		if ( current_user_can( 'activate_plugins' ) ) {
406
			$activate_url = add_query_arg( array( 'action' => 'activate' ), admin_url( 'plugins.php' ) );
407
		}
408
409
		$loop_addons = $addons;
410
		foreach ( $loop_addons as $id => $addon ) {
411
			if ( is_numeric( $id ) ) {
412
				$slug      = str_replace( array( '-wordpress-plugin', '-wordpress' ), '', $addon['slug'] );
413
				$file_name = $addon['plugin'];
414
			} else {
415
				$slug = $id;
416
				if ( isset( $addon['file'] ) ) {
417
					$base_file = $addon['file'];
418
				} else {
419
					$base_file = 'formidable-' . $slug;
420
				}
421
				$file_name = $base_file . '/' . $base_file . '.php';
422
			}
423
424
			$addon['installed']    = self::is_installed( $file_name );
425
			$addon['activate_url'] = '';
426
427
			if ( $addon['installed'] && ! empty( $activate_url ) && ! is_plugin_active( $file_name ) ) {
428
				$addon['activate_url'] = add_query_arg(
429
					array(
430
						'_wpnonce' => wp_create_nonce( 'activate-plugin_' . $file_name ),
431
						'plugin'   => $file_name,
432
					),
433
					$activate_url
434
				);
435
			}
436
437
			if ( ! isset( $addon['docs'] ) ) {
438
				$addon['docs'] = 'knowledgebase/formidable-' . $slug . '/';
439
			}
440
			self::prepare_addon_link( $addon['docs'] );
441
442
			if ( ! isset( $addon['link'] ) ) {
443
				$addon['link'] = 'downloads/' . $slug . '/';
444
			}
445
			self::prepare_addon_link( $addon['link'] );
446
447
			self::set_addon_status( $addon );
448
			$addons[ $id ] = $addon;
449
		}
450
	}
451
452
	/**
453
	 * @since 3.04.02
454
	 */
455
	private static function prepare_addon_link( &$link ) {
456
		$site_url = 'https://formidableforms.com/';
457
		if ( strpos( $link, 'http' ) !== 0 ) {
458
			$link = $site_url . $link;
459
		}
460
		$link       = FrmAppHelper::make_affiliate_url( $link );
461
		$query_args = array(
462
			'utm_source'   => 'WordPress',
463
			'utm_medium'   => 'addons',
464
			'utm_campaign' => 'liteplugin',
465
		);
466
		$link       = add_query_arg( $query_args, $link );
467
	}
468
469
	/**
470
	 * Add the status to the addon array. Status options are:
471
	 * installed, active, not installed
472
	 *
473
	 * @since 3.04.02
474
	 */
475
	private static function set_addon_status( &$addon ) {
476
		if ( ! empty( $addon['activate_url'] ) ) {
477
			$addon['status'] = array(
478
				'type'  => 'installed',
479
				'label' => __( 'Installed', 'formidable' ),
480
			);
481
		} elseif ( $addon['installed'] ) {
482
			$addon['status'] = array(
483
				'type'  => 'active',
484
				'label' => __( 'Active', 'formidable' ),
485
			);
486
		} else {
487
			$addon['status'] = array(
488
				'type'  => 'not-installed',
489
				'label' => __( 'Not Installed', 'formidable' ),
490
			);
491
		}
492
	}
493
494
	public static function upgrade_to_pro() {
495
		FrmAppHelper::include_svg();
496
497
		$link_parts = array(
498
			'medium'  => 'upgrade',
499
			'content' => 'button',
500
		);
501
502
		$features = array(
503
			'Display Entries' => array(
504
				array(
505
					'label' => 'Display form data with virtually limitless views',
506
					'link'  => array(
507
						'content' => 'views',
508
						'param'   => 'views-display-form-data',
509
					),
510
					'lite'  => false,
511
				),
512
				array(
513
					'label' => 'Generate graphs and stats based on your submitted data',
514
					'link'  => array(
515
						'content' => 'graphs',
516
						'param'   => 'statistics-graphs-wordpress-forms',
517
					),
518
					'lite'  => false,
519
				),
520
			),
521
			'Entry Management' => array(
522
				array(
523
					'label' => 'Import entries from a CSV',
524
					'link'  => array(
525
						'content' => 'import-entries',
526
						'param'   => 'importing-exporting-wordpress-forms',
527
					),
528
					'lite'  => false,
529
				),
530
				array(
531
					'label' => 'Logged-in users can save drafts and return later',
532
					'link'  => array(
533
						'content' => 'save-drafts',
534
						'param'   => 'save-drafts-wordpress-form',
535
					),
536
					'lite'  => false,
537
				),
538
				array(
539
					'label' => 'Flexibly and powerfully view, edit, and delete entries from anywhere on your site',
540
					'link'  => array(
541
						'content' => 'front-edit',
542
						'param'   => 'wordpress-front-end-editing',
543
					),
544
					'lite'  => false,
545
				),
546
				array(
547
					'label' => 'View form submissions from the back-end',
548
					'lite'  => true,
549
				),
550
				array(
551
					'label' => 'Export your entries to a CSV',
552
					'lite'  => true,
553
				),
554
			),
555
			'Form Building' => array(
556
				array(
557
					'label' => 'Save a calculated value into a field',
558
					'link'  => array(
559
						'content' => 'calculations',
560
						'param'   => 'field-calculations-wordpress-form',
561
					),
562
					'lite'  => false,
563
				),
564
				array(
565
					'label' => 'Allow multiple file uploads',
566
					'link'  => array(
567
						'content' => 'file-uploads',
568
						'param'   => 'wordpress-multi-file-upload-fields',
569
					),
570
					'lite'  => false,
571
				),
572
				array(
573
					'label' => 'Repeat sections of fields',
574
					'link'  => array(
575
						'content' => 'repeaters',
576
						'param'   => 'repeatable-sections-forms',
577
					),
578
					'lite'  => false,
579
				),
580
				array(
581
					'label' => 'Hide and show fields conditionally based on other fields or the user\'s role',
582
					'link'  => array(
583
						'content' => 'conditional-logic',
584
						'param'   => 'conditional-logic-wordpress-forms',
585
					),
586
					'lite'  => false,
587
				),
588
				array(
589
					'label' => 'Confirmation fields',
590
					'link'  => array(
591
						'content' => 'confirmation-fields',
592
						'param'   => 'confirmation-fields-wordpress-forms',
593
					),
594
					'lite'  => false,
595
				),
596
				array(
597
					'label' => 'Multi-paged forms',
598
					'link'  => array(
599
						'content' => 'page-breaks',
600
						'param'   => 'wordpress-multi-page-forms',
601
					),
602
					'lite'  => false,
603
				),
604
				array(
605
					'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.',
606
					'lite'  => false,
607
				),
608
				array(
609
					'label' => 'Include text, email, url, paragraph text, radio, checkbox, dropdown fields, hidden fields, user ID fields, and HTML blocks in your form.',
610
					'lite'  => true,
611
				),
612
				array(
613
					'label' => 'Drag & Drop Form building',
614
					'link'  => array(
615
						'content' => 'drag-drop',
616
						'param'   => 'drag-drop-forms',
617
					),
618
					'lite'  => true,
619
				),
620
				array(
621
					'label' => 'Create forms from Templates',
622
					'link'  => array(
623
						'content' => 'form-templates',
624
						'param'   => 'wordpress-form-templates',
625
					),
626
					'lite'  => true,
627
				),
628
				array(
629
					'label' => 'Import and export forms with XML',
630
					'link'  => array(
631
						'content' => 'import',
632
						'param'   => 'importing-exporting-wordpress-forms',
633
					),
634
					'lite'  => true,
635
				),
636
				array(
637
					'label' => 'Use input placeholder text in your fields that clear when typing starts.',
638
					'lite'  => true,
639
				),
640
			),
641
			'Form Actions' => array(
642
				array(
643
					'label' => 'Conditionally send your email notifications based on values in your form',
644
					'link'  => array(
645
						'content' => 'conditional-emails',
646
					),
647
					'lite'  => false,
648
				),
649
				array(
650
					'label' => 'Create and edit WordPress posts or custom posts from the front-end',
651
					'link'  => array(
652
						'content' => 'create-posts',
653
						'param'   => 'create-posts-pages-wordpress-forms',
654
					),
655
					'lite'  => false,
656
				),
657
				array(
658
					'label' => 'Send multiple emails and autoresponders',
659
					'link'  => array(
660
						'content' => 'multiple-emails',
661
						'param'   => 'virtually-unlimited-emails',
662
					),
663
					'lite'  => true,
664
				),
665
			),
666
			'Form Appearance' => array(
667
				array(
668
					'label' => 'Create Multiple styles for different forms',
669
					'link'  => array(
670
						'content' => 'multiple-styles',
671
						'param'   => 'wordpress-visual-form-styler',
672
					),
673
					'lite'  => false,
674
				),
675
				array(
676
					'label' => 'Customizable layout with CSS classes',
677
					'link'  => array(
678
						'content' => 'form-layout',
679
						'param'   => 'wordpress-mobile-friendly-forms',
680
					),
681
					'lite'  => true,
682
				),
683
				array(
684
					'label' => 'Customize the HTML for your forms',
685
					'link'  => array(
686
						'content' => 'custom-html',
687
						'param'   => 'customizable-html-wordpress-form',
688
					),
689
					'lite'  => true,
690
				),
691
				array(
692
					'label' => 'Style your form with the Visual Form Styler',
693
					'lite'  => true,
694
				),
695
			),
696
		);
697
698
		include( FrmAppHelper::plugin_path() . '/classes/views/addons/upgrade_to_pro.php' );
699
	}
700
701
	/**
702
	 * Install Pro after connection with Formidable.
703
	 *
704
	 * @since 4.02.05
705
	 */
706
	public static function connect_pro() {
707
		FrmAppHelper::permission_check( 'install_plugins' );
708
		check_ajax_referer( 'frm_ajax', 'nonce' );
709
710
		$url = FrmAppHelper::get_post_param( 'plugin', '', 'sanitize_text_field' );
711
		if ( FrmAppHelper::pro_is_installed() || empty( $url ) ) {
712
			wp_die();
713
		}
714
715
		$response = array();
716
717
		// It's already installed and active.
718
		$active = activate_plugin( 'formidable-pro/formidable-pro.php', false, false, true );
719
		if ( is_wp_error( $active ) ) {
720
			// The plugin was installed, but not active. Download it now.
721
			self::ajax_install_addon();
722
		} else {
723
			$response['active'] = true;
724
		}
725
726
		echo json_encode( $response );
727
		wp_die();
728
	}
729
730
	/**
731
	 * @since 3.04.02
732
	 */
733
	public static function ajax_install_addon() {
734
735
		self::install_addon_permissions();
736
737
		// Set the current screen to avoid undefined notices.
738
		global $hook_suffix;
739
		set_current_screen();
740
741
		self::maybe_show_cred_form();
742
743
		$installed = self::install_addon();
744
		self::maybe_activate_addon( $installed );
745
746
		// Send back a response.
747
		echo json_encode( __( 'Your plugin has been installed. Please reload the page to see more options.', 'formidable' ) );
748
		wp_die();
749
	}
750
751
	/**
752
	 * @since 3.04.02
753
	 */
754
	private static function maybe_show_cred_form() {
755
		// Start output bufferring to catch the filesystem form if credentials are needed.
756
		ob_start();
757
758
		$show_form = false;
759
		$method    = '';
760
		$url       = add_query_arg( array( 'page' => 'formidable-settings' ), admin_url( 'admin.php' ) );
761
		$url       = esc_url_raw( $url );
762
		$creds     = request_filesystem_credentials( $url, $method, false, false, null );
763
764
		if ( false === $creds ) {
765
			$show_form = true;
766
		} elseif ( ! WP_Filesystem( $creds ) ) {
767
			request_filesystem_credentials( $url, $method, true, false, null );
768
			$show_form = true;
769
		}
770
771
		if ( $show_form ) {
772
			//$form = ob_get_clean();
773
			//TODO: test this: echo json_encode( array( 'form' => $form ) );
774
			echo json_encode( array( 'form' => __( 'Sorry, you\'re site requires FTP authentication. Please install plugins manaully.', 'formidable' ) ) );
775
			wp_die();
776
		}
777
778
		ob_end_clean();
779
	}
780
781
	/**
782
	 * We do not need any extra credentials if we have gotten this far,
783
	 * so let's install the plugin.
784
	 *
785
	 * @since 3.04.02
786
	 */
787
	private static function install_addon() {
788
		require_once( ABSPATH . 'wp-admin/includes/class-wp-upgrader.php' );
789
790
		$download_url = FrmAppHelper::get_param( 'plugin', '', 'post', 'esc_url_raw' );
791
792
		// Create the plugin upgrader with our custom skin.
793
		$installer = new Plugin_Upgrader( new FrmInstallerSkin() );
794
		$installer->install( $download_url );
795
796
		// Flush the cache and return the newly installed plugin basename.
797
		wp_cache_flush();
798
799
		return $installer->plugin_info();
800
	}
801
802
	/**
803
	 * @since 3.06.03
804
	 */
805
	public static function ajax_activate_addon() {
806
807
		self::install_addon_permissions();
808
809
		// Set the current screen to avoid undefined notices.
810
		global $hook_suffix;
811
		set_current_screen();
812
813
		$plugin = FrmAppHelper::get_param( 'plugin', '', 'post', 'sanitize_text_field' );
814
		self::maybe_activate_addon( $plugin );
815
816
		// Send back a response.
817
		echo json_encode( __( 'Your plugin has been activated. Please reload the page to see more options.', 'formidable' ) );
818
		wp_die();
819
	}
820
821
	/**
822
	 * @since 3.04.02
823
	 * @param string $installed The plugin folder name with file name
824
	 */
825
	private static function maybe_activate_addon( $installed ) {
826
		if ( ! $installed ) {
827
			return;
828
		}
829
830
		$activate = activate_plugin( $installed );
831
		if ( is_wp_error( $activate ) ) {
832
			// Ignore the invalid header message that shows with nested plugins.
833
			if ( $activate->get_error_code() !== 'no_plugin_header' ) {
834
				echo json_encode( array( 'error' => $activate->get_error_message() ) );
835
				wp_die();
836
			}
837
		}
838
	}
839
840
	/**
841
	 * Run security checks before installing
842
	 *
843
	 * @since 3.04.02
844
	 */
845
	private static function install_addon_permissions() {
846
		check_ajax_referer( 'frm_ajax', 'nonce' );
847
848
		if ( ! current_user_can( 'activate_plugins' ) || ! isset( $_POST['plugin'] ) ) {
849
			echo json_encode( true );
850
			wp_die();
851
		}
852
	}
853
854
	/**
855
	 * @since 3.04.03
856
	 * @deprecated 3.06
857
	 * @codeCoverageIgnore
858
	 * @return array
859
	 */
860
	public static function error_for_license( $license ) {
861
		return FrmDeprecated::error_for_license( $license );
862
	}
863
864
	/**
865
	 * @since 3.04.03
866
	 * @deprecated 3.06
867
	 * @codeCoverageIgnore
868
	 */
869
	public static function get_pro_updater() {
870
		return FrmDeprecated::get_pro_updater();
871
	}
872
873
	/**
874
	 * @since 3.04.03
875
	 * @deprecated 3.06
876
	 * @codeCoverageIgnore
877
	 *
878
	 * @return array
879
	 */
880
	public static function get_addon_info( $license = '' ) {
881
		return FrmDeprecated::get_addon_info( $license );
882
	}
883
884
	/**
885
	 * @since 3.04.03
886
	 * @deprecated 3.06
887
	 * @codeCoverageIgnore
888
	 *
889
	 * @return string
890
	 */
891
	public static function get_cache_key( $license ) {
892
		return FrmDeprecated::get_cache_key( $license );
893
	}
894
895
	/**
896
	 * @since 3.04.03
897
	 * @deprecated 3.06
898
	 * @codeCoverageIgnore
899
	 */
900
	public static function reset_cached_addons( $license = '' ) {
901
		FrmDeprecated::reset_cached_addons( $license );
902
	}
903
904
	/**
905
	 * @since 2.03.08
906
	 * @deprecated 3.04.03
907
	 * @codeCoverageIgnore
908
	 *
909
	 * @param boolean $return
910
	 * @param string $package
911
	 *
912
	 * @return boolean
913
	 */
914
	public static function add_shorten_edd_filename_filter( $return, $package ) {
915
		return FrmDeprecated::add_shorten_edd_filename_filter( $return, $package );
916
	}
917
918
	/**
919
	 * @since 2.03.08
920
	 * @deprecated 3.04.03
921
	 * @codeCoverageIgnore
922
	 *
923
	 * @param string $filename
924
	 * @param string $ext
925
	 *
926
	 * @return string
927
	 */
928
	public static function shorten_edd_filename( $filename, $ext ) {
929
		return FrmDeprecated::shorten_edd_filename( $filename, $ext );
930
	}
931
932
	/**
933
	 * @deprecated 3.04.03
934
	 * @codeCoverageIgnore
935
	 */
936
	public static function get_licenses() {
937
		FrmDeprecated::get_licenses();
938
	}
939
}
940