Completed
Pull Request — develop (#1505)
by Zack
21:14 queued 01:15
created

Addon_Settings::body_class()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 12

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 1
CRAP Score 3

Importance

Changes 0
Metric Value
cc 3
nc 3
nop 1
dl 0
loc 12
ccs 1
cts 1
cp 1
crap 3
rs 9.8666
c 0
b 0
f 0
1
<?php
2
3
namespace GV;
4
5
use GV\Shortcodes\gravityview;
6
7
/** If this file is called directly, abort. */
8
if ( ! defined( 'GRAVITYVIEW_DIR' ) ) {
9
	die();
10
}
11
12
if ( ! class_exists( '\GFAddOn' ) ) {
13
	return;
14
}
15
16
/**
17
 * The Addon Settings class.
18
 *
19
 * Uses internal GFAddOn APIs.
20
 */
21
class Addon_Settings extends \GFAddOn {
22
23
	/**
24
	 * @var string Title of the plugin to be used on the settings page, form settings and plugins page. Example: 'Gravity Forms MailChimp Add-On'
25
	 */
26
	protected $_title = 'GravityView';
27
28
	/**
29
	 * @var string Short version of the plugin title to be used on menus and other places where a less verbose string is useful. Example: 'MailChimp'
30
	 */
31
	protected $_short_title = 'GravityView';
32
33
	/**
34
	 * @var string URL-friendly identifier used for form settings, add-on settings, text domain localization...
35
	 */
36
	protected $_slug = 'gravityview';
37
38
	/**
39
	 * @var string|array A string or an array of capabilities or roles that can uninstall the plugin
40
	 */
41
	protected $_capabilities_uninstall = 'gravityview_uninstall';
42
43
	/**
44
	 * @var string|array A string or an array of capabilities or roles that have access to the settings page
45
	 */
46
	protected $_capabilities_app_settings = 'gravityview_view_settings';
47
48
	/**
49
	 * @var string|array A string or an array of capabilities or roles that have access to the settings page
50
	 */
51
	protected $_capabilities_app_menu = 'gravityview_view_settings';
52
53
	/**
54
	 * @var string The hook suffix for the app menu
55
	 */
56
	public $app_hook_suffix = 'gravityview';
57
58
	/**
59
	 * @var \GV\License_Handler Process license validation
60
	 */
61
	private $License_Handler;
62
63
	/**
64 2
	 * @var bool Whether we have initialized already or not.
65 2
	 */
66 2
	private static $initialized = false;
67
68
	public function __construct() {
69
70
		$this->_version                  = Plugin::$version;
71 2
		$this->_min_gravityforms_version = Plugin::$min_gf_version;
72
73
		/**
74
		 * Hook everywhere, but only once.
75 2
		 */
76
		if ( ! self::$initialized ) {
77
			parent::__construct();
78
			self::$initialized = true;
79
		}
80
	}
81
82
	/**
83
	 * Run actions when initializing admin.
84 1
	 *
85 1
	 * Triggers the license key notice, etc.
86
	 *
87 1
	 * @return void
88
	 */
89 1
	public function init_admin() {
90
91
		$this->_load_license_handler();
92 1
93
		add_filter( 'admin_body_class', array( $this, 'body_class' ) );
94 1
95 1
		add_action( 'admin_head', array( $this, 'license_key_notice' ) );
96
97
		add_filter( 'gform_addon_app_settings_menu_gravityview', array( $this, 'modify_app_settings_menu_title' ) );
98
99
		add_filter( 'gform_settings_save_button', array( $this, 'modify_gform_settings_save_button' ), 10, 2 );
100
101
		/** @since 1.7.6 */
102
		add_action( 'network_admin_menu', array( $this, 'add_network_menu' ) );
103
104 1
		add_filter( 'gravityview_noconflict_styles', array( $this, 'register_no_conflict' ) );
105 1
106 1
		parent::init_admin();
107
	}
108
109
	/**
110
	 * Return tabs for GV Settings page
111
	 *
112
	 * @since XXX
113
	 *
114 1
	 * @return array
115 1
	 */
116 1
	public function get_app_settings_tabs() {
117
118
		$setting_tabs = parent::get_app_settings_tabs();
119
120
		foreach ( $setting_tabs as &$tab ) {
121
			if ( 'uninstall' !== $tab['name'] ) {
122
				continue;
123 1
			}
124 1
125 1
			// Do not display uninstall tab if user is lacking permissions/this is a multisite
126
			if ( ! ( $this->current_user_can_any( $this->_capabilities_uninstall ) && ( ! function_exists( 'is_multisite' ) || ! is_multisite() || is_super_admin() ) ) ) {
127 1
				$tab = null;
128 1
				continue;
129
			}
130
131
			// Add trash can icon to resemble the look and feel of the GF Settings page
132
			$tab['icon'] = 'dashicons-trash';
133
		}
134
135 1
		return array_filter( $setting_tabs );
136
	}
137 1
138 1
	/**
139
	 * Allow GF styles to load in no-conflict mode
140
	 *
141
	 * @param array $items Styles to exclude from no-conflict
142
	 *
143
	 * @return array
144
	 */
145
	public function register_no_conflict( $items ) {
146
147
		$items[] = 'gform_settings';
148
		$items[] = 'gv-admin-edd-license';
149
150
		return $items;
151 1
	}
152 1
153
	/**
154
	 * Adds a CSS class to the <body> of the admin page if running GF 2.5 or newer
155
	 *
156
	 * @param $css_class
157
	 *
158
	 * @return string
159 1
	 */
160
	public function body_class( $css_class ) {
161 1
162
		if ( ! gravityview()->request->is_admin( '', 'settings' ) ) {
0 ignored issues
show
Unused Code introduced by
The call to Frontend_Request::is_admin() has too many arguments starting with ''.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
Unused Code introduced by
The call to Request::is_admin() has too many arguments starting with ''.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
163
			return $css_class;
164
		}
165
166
		if ( gravityview()->plugin->is_GF_25() ) {
167
			$css_class .= ' gf-2-5';
168
		}
169
170
		return $css_class;
171
	}
172
173
	/**
174 1
	 * Adds an "Uninstall" button next to the GF 2.5 Save Settings button
175 1
	 *
176
	 * @since 2.9.1
177
	 *
178 1
	 * @param string                               $html HTML of the save button.
179
	 * @param \Rocketgenius\Gravity_Forms\Settings|null $framework Current instance of the Settings Framework. Or null if < 2.5.
180
	 */
181 1
	public function modify_gform_settings_save_button( $html, $framework = null ) {
182 1
183 1
		if ( ! gravityview()->request->is_admin( '', 'settings' ) ) {
0 ignored issues
show
Unused Code introduced by
The call to Frontend_Request::is_admin() has too many arguments starting with ''.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
Unused Code introduced by
The call to Request::is_admin() has too many arguments starting with ''.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
184 1
			return $html;
185
		}
186
187
		if ( ! ( $this->current_user_can_any( $this->_capabilities_uninstall ) && ( ! function_exists( 'is_multisite' ) || ! is_multisite() || is_super_admin() ) ) ) {
188
			return $html;
189
		}
190
191
		if ( gravityview()->plugin->is_GF_25() ) {
192
			$html_class = 'button outline secondary alignright button-danger';
193
		} else {
194 1
			$html_class = 'button button-secondary button-large alignright button-danger';
195
		}
196
197 1
		$href = add_query_arg( array( 'post_type' => 'gravityview', 'page' => 'gravityview_settings', 'view' => 'uninstall' ), admin_url( 'edit.php' ) );
198
199
		$uninstall_button = '<a href="' . esc_url( $href ) . '" class="' . gravityview_sanitize_html_class( $html_class ). '">' . esc_html__( 'Uninstall GravityView', 'gravityview' ) . '</a>';
200 1
201
		$html .= $uninstall_button;
202
203 1
		return $html;
204
	}
205
206 1
	/**
207 1
	 * Roll our own "Hero" Save button with an Unsubscribe button attached
208
	 *
209
	 * @since 2.9.1
210 1
	 *
211
	 * @param array $field
212
	 * @param bool $echo
213
	 *
214 1
	 * @return string|null HTML of the button.
215
	 */
216 1
	public function settings_save( $field, $echo = true ) {
217
218
		$field['type']  = 'submit';
219
		$field['name']  = 'gform-settings-save';
220
		$field['class'] = 'button button-primary primary button-hero';
221
		$field['value'] = Utils::get( $field, 'value', __( 'Update Settings', 'gravityview' ) );
222
223
		$html = $this->as_html( $field, false );
224
225
		$html = $this->modify_gform_settings_save_button( $html );
226 1
227 1
		if ( $echo ) {
228
			echo $html;
229 1
		}
230
231 1
		return $html;
232
	}
233
234
	/**
235
	 * Change the settings page header title to "GravityView"
236
	 *
237
	 * @param $setting_tabs
238
	 *
239
	 * @return array
240
	 */
241
	public function modify_app_settings_menu_title( $setting_tabs ) {
242
243
		$setting_tabs[0]['label'] = __( 'GravityView Settings', 'gravityview' );
244
		$setting_tabs[0]['icon']  = 'dashicons-admin-settings';
245
246
		return $setting_tabs;
247
	}
248
249
	/**
250
	 * Load license handler in admin-ajax.php
251
	 *
252
	 * @return void
253
	 */
254
	public function init_ajax() {
255
256
		$this->_load_license_handler();
257
	}
258
259
	/**
260
	 * Make sure the license handler is available
261
	 *
262
	 * @return void
263
	 */
264
	private function _load_license_handler() {
265
266
		if ( ! empty( $this->License_Handler ) ) {
267
			return;
268
		}
269
		$this->License_Handler = License_Handler::get( $this );
270
	}
271
272
	/**
273
	 * Add global Settings page for Multisite
274
	 *
275
	 * @since 1.7.6
276
	 * @return void
277
	 */
278
	public function add_network_menu() {
279
280
		if ( ! gravityview()->plugin->is_network_activated() ) {
281
			return;
282
		}
283
284
		add_menu_page( __( 'Settings', 'gravityview' ), __( 'GravityView', 'gravityview' ), $this->_capabilities_app_settings, "{$this->_slug}_settings", array( $this, 'app_tab_page' ), 'none' );
285
	}
286
287
	/**
288
	 * Uninstall all traces of GravityView
289
	 *
290
	 * Note: method is public because parent method is public
291
	 *
292
	 * @return bool
293
	 */
294
	public function uninstall() {
295
296
		gravityview()->plugin->uninstall();
297
298
		/**
299
		 * Set the path so that Gravity Forms can de-activate GravityView
300
		 *
301
		 * @see  GFAddOn::uninstall_addon
302
		 * @uses deactivate_plugins()
303 1
		 */
304 1
		$this->_path = GRAVITYVIEW_FILE;
305 1
306
		return true;
307
	}
308 1
309
	/**
310
	 * Prevent uninstall tab from being shown by returning false for the uninstall capability check. Otherwise:
311
	 *
312
	 * @inheritDoc
313
	 *
314
	 * @hack
315
	 *
316
	 * @param array|string $caps
317 1
	 *
318 1
	 * @return bool
319 1
	 */
320 1
	public function current_user_can_any( $caps ) {
321
322
		if ( empty( $caps ) ) {
323 1
			$caps = array( 'gravityview_full_access' );
324
		}
325
326
		return \GVCommon::has_cap( $caps );
327
	}
328
329
	public function uninstall_warning_message() {
330
331
		$heading = esc_html__( 'If you delete then re-install GravityView, it will be like installing GravityView for the first time.', 'gravityview' );
332
		$message = esc_html__( 'Delete all Views, GravityView entry approval status, GravityView-generated entry notes (including approval and entry creator changes), and GravityView plugin settings.', 'gravityview' );
333
334
		return sprintf( '<h4>%s</h4><p>%s</p>', $heading, $message );
335
	}
336
337
	/**
338
	 * Get an array of reasons why the plugin might be uninstalled
339
	 *
340
	 * @since 1.17.5
341
	 *
342
	 * @return array Array of reasons with the label and followup questions for each uninstall reason
343 1
	 */
344
	private function get_uninstall_reasons() {
345
346
		$reasons = array(
347
				'will-continue'  => array(
348 1
						'label' => esc_html__( 'I am going to continue using GravityView', 'gravityview' ),
349
				),
350 1
				'no-longer-need' => array(
351
						'label' => esc_html__( 'I no longer need GravityView', 'gravityview' ),
352
				),
353 1
				'doesnt-work'    => array(
354 1
						'label' => esc_html__( 'The plugin doesn\'t work', 'gravityview' ),
355
				),
356
				'found-other'    => array(
357
						'label'    => esc_html__( 'I found a better plugin', 'gravityview' ),
358
						'followup' => esc_attr__( 'What plugin you are using, and why?', 'gravityview' ),
359 1
				),
360
				'other'          => array(
361
						'label' => esc_html__( 'Other', 'gravityview' ),
362
				),
363
		);
364 1
365
		shuffle( $reasons );
366
367
		return $reasons;
368
	}
369
370
	/**
371
	 * Display a feedback form when the plugin is uninstalled
372
	 *
373
	 * @since 1.17.5
374
	 *
375
	 * @return string HTML of the uninstallation form
376 1
	 */
377
	public function uninstall_form() {
378
379
		ob_start();
380 1
381
		$user = wp_get_current_user();
382
		?>
383
		<style>
384 1
			#gv-reason-details {
385
				min-height: 100px;
386
			}
387 1
388
			.number-scale label {
389
				border: 1px solid #cccccc;
390
				padding: .5em .75em;
391
				margin: .1em;
392
			}
393
394 1
			#gv-uninstall-thanks p {
395
				font-size: 1.2em;
396 1
			}
397 1
398
			.scale-description ul {
399 1
				margin-bottom: 0;
400
				padding-bottom: 0;
401
			}
402 1
403
			.scale-description p.description {
404
				margin-top: 0 !important;
405
				padding-top: 0 !important;
406
			}
407
408
			.gv-form-field-wrapper {
409 1
				margin-top: 30px;
410 1
			}
411
		</style>
412
413
		<?php
414
		if ( gravityview()->plugin->is_GF_25() ) {
415
			$uninstall_title = esc_html__( 'Uninstall GravityView', 'gravityview' );
416
417
			echo <<<HTML
418 1
<div class="gform-settings-panel">
419 1
    <header class="gform-settings-panel__header">
420
        <h4 class="gform-settings-panel__title">{$uninstall_title}</h4>
421
    </header>
422
    <div class="gform-settings-panel__content" style="padding: 0 1rem 1.25rem">
423
424
HTML;
425
		} else {
426
			echo '<div class="gv-uninstall-form-wrapper" style="font-size: 110%; padding: 15px 0;">';
427
		}
428
		?>
429
		<script>
430 1
			jQuery( function( $ ) {
431 1
				$( '#gv-uninstall-feedback' ).on( 'change', function( e ) {
432
433
					if ( ! $( e.target ).is( ':input' ) ) {
434
						return;
435
					}
436
					var $textarea = $( '.gv-followup' ).find( 'textarea' );
437
					var followup_text = $( e.target ).attr( 'data-followup' );
438
					if ( ! followup_text ) {
439
						followup_text = $textarea.attr( 'data-default' );
440
					}
441
442 189
					$textarea.attr( 'placeholder', followup_text );
443
444
				} ).on( 'submit', function( e ) {
445
					e.preventDefault();
446 189
447
					$.post( $( this ).attr( 'action' ), $( this ).serialize() )
448 2
							.done( function( data ) {
449 2
								if ( 'success' !== data.status ) {
450 2
									gv_feedback_append_error_message();
451
								} else {
452
									$( '#gv-uninstall-thanks' ).fadeIn();
453
								}
454 189
							} )
455
							.fail( function( data ) {
456
								gv_feedback_append_error_message();
457
							} )
458 189
							.always( function() {
459
								$( e.target ).remove();
460
							} );
461
462
					return false;
463
				} );
464
465
				function gv_feedback_append_error_message() {
466
					$( '#gv-uninstall-thanks' ).append( '<div class="notice error">' + <?php echo json_encode( esc_html( __( 'There was an error sharing your feedback. Sorry! Please email us at [email protected]', 'gravityview' ) ) ) ?> +'</div>' );
467
				}
468
			} );
469 1
		</script>
470 1
471 1
		<form id="gv-uninstall-feedback" method="post" action="https://hooks.zapier.com/hooks/catch/28670/6haevn/">
472
			<h2><?php esc_html_e( 'Why did you uninstall GravityView?', 'gravityview' ); ?></h2>
473
			<ul>
474
				<?php
475
				$reasons = $this->get_uninstall_reasons();
476
				foreach ( $reasons as $reason ) {
477
					printf( '<li><label><input name="reason" type="radio" value="other" data-followup="%s"> %s</label></li>', Utils::get( $reason, 'followup' ), Utils::get( $reason, 'label' ) );
478
				}
479
				?>
480
			</ul>
481
			<div class="gv-followup widefat">
482 1
				<p><strong><label for="gv-reason-details"><?php esc_html_e( 'Comments', 'gravityview' ); ?></label></strong></p>
483 1
				<textarea id="gv-reason-details" name="reason_details" data-default="<?php esc_attr_e( 'Please share your thoughts about GravityView', 'gravityview' ) ?>" placeholder="<?php esc_attr_e( 'Please share your thoughts about GravityView', 'gravityview' ); ?>" class="large-text"></textarea>
484
			</div>
485
			<div class="scale-description">
486
				<p><strong><?php esc_html_e( 'How likely are you to recommend GravityView?', 'gravityview' ); ?></strong></p>
487
				<ul class="inline">
488
					<?php
489
					$i = 0;
490
					while ( $i < 11 ) {
491 189
						echo '<li class="inline number-scale"><label><input name="likely_to_refer" id="likely_to_refer_' . $i . '" value="' . $i . '" type="radio"> ' . $i . '</label></li>';
492
						$i ++;
493 189
					}
494
					?>
495 189
				</ul>
496 189
				<p class="description"><?php printf( esc_html_x( '%s ("Not at all likely") to %s ("Extremely likely")', 'A scale from 0 (bad) to 10 (good)', 'gravityview' ), '<label for="likely_to_refer_0"><code>0</code></label>', '<label for="likely_to_refer_10"><code>10</code></label>' ); ?></p>
497 189
			</div>
498
499
			<div class="gv-form-field-wrapper">
500
				<label><input type="checkbox" class="checkbox" name="follow_up_with_me" value="1" /> <?php esc_html_e( 'Please follow up with me about my feedback', 'gravityview' ); ?></label>
501
			</div>
502
503 189
			<div class="submit">
504
				<input type="hidden" name="siteurl" value="<?php echo esc_url( get_bloginfo( 'url' ) ); ?>" />
505
				<input type="hidden" name="email" value="<?php echo esc_attr( $user->user_email ); ?>" />
506
				<input type="hidden" name="display_name" value="<?php echo esc_attr( $user->display_name ); ?>" />
507
				<input type="submit" value="<?php esc_html_e( 'Send Us Your Feedback', 'gravityview' ); ?>" class="button button-primary primary button-hero" />
508
			</div>
509
		</form>
510
511
		<div id="gv-uninstall-thanks" class="<?php echo ( gravityview()->plugin->is_GF_25() ) ? 'notice-large' : 'notice notice-large notice-updated below-h2'; ?>" style="display:none;">
512
			<h3 class="notice-title"><?php esc_html_e( 'Thank you for using GravityView!', 'gravityview' ); ?></h3>
513 1
			<p><?php echo gravityview_get_floaty(); ?>
514 1
				<?php echo make_clickable( esc_html__( 'Your feedback helps us improve GravityView. If you have any questions or comments, email us: [email protected]', 'gravityview' ) ); ?>
515
			</p>
516
			<div class="wp-clearfix"></div>
517
		</div>
518
		</div>
519
		<?php
520
		if ( gravityview()->plugin->is_GF_25() ) {
521
			echo '</div>';
522 189
		}
523
524
		$form = ob_get_clean();
525 189
526 189
		return $form;
527 189
	}
528 189
529 189
	public function app_settings_tab() {
530 189
531 189
		parent::app_settings_tab();
532 189
533 189
		if ( $this->maybe_uninstall() ) {
534
			echo $this->uninstall_form();
535
		}
536
	}
537
538
	/**
539
	 * The Settings title
540 189
	 *
541
	 * @return string
542
	 */
543
	public function app_settings_title() {
544
545
		return null;
546
	}
547
548
	/**
549
	 * Prevent displaying of any icon
550
	 *
551 2
	 * @return string
552 2
	 */
553
	public function app_settings_icon() {
554 2
555 2
		return '&nbsp;';
556 2
	}
557
558
	/**
559 2
	 * Retrieve a setting.
560 2
	 *
561
	 * @param string $setting_name The setting key.
562 2
	 *
563 2
	 * @return mixed The setting or null
564
	 * @deprecated Use \GV\Addon_Settings::get
565
	 */
566 2
	public function get_app_setting( $setting_name ) {
567
568
		return $this->get( $setting_name );
569 2
	}
570 2
571 2
	/**
572 2
	 * Retrieve a setting.
573 2
	 *
574
	 * @param string $key     The setting key.
575 2
	 * @param string $default A default if not found.
576
	 *
577
	 * @return mixed The setting value.
578
	 */
579 2
	public function get( $key, $default = null ) {
580
581
		/**
582
		 * Backward compatibility with Redux
583
		 */
584
		if ( $key === 'license' ) {
585 1
			return array(
586 1
					'license'  => $this->get( 'license_key' ),
587 1
					'status'   => $this->get( 'license_key_status' ),
588
					'response' => $this->get( 'license_key_response' ),
589
			);
590
		}
591
592
		if ( 'license_key' === $key && defined( 'GRAVITYVIEW_LICENSE_KEY' ) ) {
593
			return GRAVITYVIEW_LICENSE_KEY;
594
		}
595
596
		return Utils::get( $this->all(), $key, $default );
597
	}
598
599 1
	/**
600 1
	 * Get the setting for GravityView by name
601
	 *
602
	 * @param string $key Option key to fetch
603
	 *
604
	 * @return mixed
605
	 * @deprecated Use gravityview()->plugin->settings->get()
606
	 */
607
	static public function getSetting( $key ) {
608
609
		if ( gravityview()->plugin->settings instanceof Addon_Settings ) {
610
			return gravityview()->plugin->settings->get( $key );
611
		}
612
	}
613
614
	/**
615
	 * Get all settings.
616
	 *
617
	 * @return array The settings.
618
	 * @deprecated Use \GV\Addon_Settings::all() or \GV\Addon_Settings::get()
619
	 *
620
	 */
621
	public function get_app_settings() {
622
623
		return $this->all();
624
	}
625
626
	/**
627
	 * Get all the settings.
628
	 *
629
	 * @return array The settings.
630
	 */
631
	public function all() {
632
633
		$option_name = 'gravityformsaddon_' . $this->_slug . '_app_settings';
634
635
		if ( $this->has_site_settings() ) {
636
			$defaults     = $this->defaults();
637
			$option_value = get_option( $option_name, array() );
638
		} else {
639
			$defaults     = get_blog_option( get_main_site_id(), $option_name );
640
			$option_value = get_blog_option( get_main_site_id(), $option_name );
641
		}
642
643
		return wp_parse_args( $option_value, $defaults );
644
	}
645
646
	/**
647
	 * Default settings.
648
	 *
649
	 * @return array The defaults.
650
	 * @deprecated Use \GV\Addon_Settings::defaults()
651
	 *
652
	 */
653
	public function get_default_settings() {
654
655
		return $this->defaults();
656
	}
657
658
	/**
659
	 * Default settings.
660
	 *
661
	 * @return array The defaults.
662
	 */
663
	private function defaults() {
664
665
		$defaults = array(
666
			// Set the default license in wp-config.php
667
			'license_key'          => defined( 'GRAVITYVIEW_LICENSE_KEY' ) ? GRAVITYVIEW_LICENSE_KEY : '',
668
			'license_key_response' => '',
669
			'license_key_status'   => '',
670
			'support-email'        => get_bloginfo( 'admin_email' ),
671
			'no-conflict-mode'     => '1',
672
			'support_port'         => '1',
673
			'flexbox_search'       => '1',
674
			'rest_api'             => '0',
675
			'beta'                 => '0',
676
		);
677
678
		/**
679
		 * @filter `gravityview/settings/default` Filter default global settings.
680
		 * @param  [in,out] array The defaults.
681
		 */
682
		return apply_filters( 'gravityview/settings/defaults', $defaults );
683
	}
684
685
	/***
686
	 * Renders the save button for settings pages
687
	 *
688
	 * @param array $field - Field array containing the configuration options of this field
689 1
	 * @param bool  $echo  = true - true to echo the output to the screen, false to simply return the contents as a string
690 1
	 *
691
	 * @return string The HTML
692
	 */
693
	public function as_html( $field, $echo = true ) {
694
695
		$field['type'] = ( isset( $field['type'] ) && in_array( $field['type'], array( 'submit', 'reset', 'button' ) ) ) ? $field['type'] : 'submit';
696
697
		$attributes    = $this->get_field_attributes( $field );
698
		$default_value = Utils::get( $field, 'value', Utils::get( $field, 'default_value' ) );
699
		$value         = $this->get( $field['name'], $default_value );
700
701
		$attributes['class'] = isset( $attributes['class'] ) ? esc_attr( $attributes['class'] ) : 'button-primary primary gfbutton';
702 23
		$name                = ( $field['name'] === 'gform-settings-save' ) ? $field['name'] : '_gaddon_setting_' . $field['name'];
703 23
704
		if ( empty( $value ) ) {
705 23
			$value = __( 'Update Settings', 'gravityview' );
706
		}
707
708
		$attributes = $this->get_field_attributes( $field );
709
710
		$html = '<input
711
                    type="' . $field['type'] . '"
712
                    name="' . esc_attr( $name ) . '"
713
                    value="' . $value . '" ' .
714 23
				implode( ' ', $attributes ) .
715
				' />';
716
717
		if ( $echo ) {
718
			echo $html;
719
		}
720
721 23
		return $html;
722 23
	}
723
724 23
	/**
725 23
	 * @deprecated Use \GV\Addon_Settings::as_html
726 23
	 */
727 23
	public function settings_submit( $field, $echo = true ) {
728
729
		gravityview()->log->warning( '\GV\Addon_Settings::settings_submit has been deprecated for \GV\Addon_Settings::as_html' );
730
731
		return $this->as_html( $field, $echo );
732
	}
733
734
	/**
735
	 * Check whether GravityView is being saved
736
	 *
737
	 * The generic is_save_postback() is true for all addons
738
	 *
739
	 * @since 2.0.8
740
	 *
741 23
	 * @return bool
742
	 */
743
	public function is_save_postback() {
744
745
		return isset( $_POST['gform-settings-save'] ) && isset( $_POST['_gravityview_save_settings_nonce'] );
746
	}
747
748
	/**
749
	 * Display a notice if the plugin is inactive.
750
	 *
751
	 * @return void
752
	 */
753
	public function license_key_notice() {
754
755 189
		if ( 'uninstall' === rgget( 'view' ) ) {
756 189
			return; // Do not display license notice on the uninstall page in GF 2.5
757
		}
758
759
		if ( $this->is_save_postback() ) {
760
			$settings       = $this->get_posted_settings();
761
			$license_key    = defined( 'GRAVITYVIEW_LICENSE_KEY' ) ? GRAVITYVIEW_LICENSE_KEY : \GV\Utils::get( $settings, 'license_key' );
762
			$license_status = \GV\Utils::get( $settings, 'license_key_status', 'inactive' );
763 1
		} else {
764
			$license_status = $this->get( 'license_key_status', 'inactive' );
765
			$license_key    = $this->get( 'license_key' );
766
		}
767
768
		$license_id = empty( $license_key ) ? 'license' : $license_key;
769
770 1
		$message = esc_html__( 'Your GravityView license %s. This means you&rsquo;re missing out on updates and support! %sActivate your license%s or %sget a license here%s.', 'gravityview' );
771
772 1
		/** @internal Do not use! Will change without notice (pun slightly intended). */
773
		$message = apply_filters( 'gravityview/settings/license-key-notice', $message );
774
775
		/**
776 1
		 * I wanted to remove the period from after the buttons in the string,
777 1
		 * but didn't want to mess up the translation strings for the translators.
778
		 */
779
		$message             = mb_substr( $message, 0, mb_strlen( $message ) - 1 );
780
		$title               = __( 'Inactive License', 'gravityview' );
781
		$status              = '';
782
		$update_below        = false;
783
		$primary_button_link = admin_url( 'edit.php?post_type=gravityview&amp;page=gravityview_settings' );
784
785
		switch ( $license_status ) {
786
			/** @since 1.17 */
787 1
			case 'expired':
788 1
				$title   = __( 'Expired License', 'gravityview' );
789
				$status  = __( 'has expired', 'gravityview' );
790
				$message = $this->get_license_handler()->strings( 'expired', $this->get( 'license_key_response' ) );
791
				break;
792
			case 'invalid':
793
				$title  = __( 'Invalid License', 'gravityview' );
794
				$status = __( 'is invalid', 'gravityview' );
795
				break;
796 1
			case 'deactivated':
797 1
				$status       = __( 'is inactive', 'gravityview' );
798
				$update_below = __( 'Activate your license key below.', 'gravityview' );
799 1
				break;
800
			/** @noinspection PhpMissingBreakStatementInspection */
801
			case '':
802
				$license_status = 'site_inactive';
803 1
			// break intentionally left blank
804
			case 'inactive':
805
			case 'site_inactive':
806
				$status       = __( 'has not been activated', 'gravityview' );
807
				$update_below = __( 'Activate your license key below.', 'gravityview' );
808 1
				break;
809 1
		}
810 1
		$url = 'https://gravityview.co/pricing/?utm_source=admin_notice&utm_medium=admin&utm_content=' . $license_status . '&utm_campaign=Admin%20Notice';
811 1
812 1
		// Show a different notice on settings page for inactive licenses (hide the buttons)
813 1
		if ( $update_below && gravityview()->request->is_admin( '', 'settings' ) ) {
0 ignored issues
show
Unused Code introduced by
The call to Frontend_Request::is_admin() has too many arguments starting with ''.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
Unused Code introduced by
The call to Request::is_admin() has too many arguments starting with ''.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
Bug Best Practice introduced by
The expression $update_below of type string|false is loosely compared to true; this is ambiguous if the string can be empty. You might want to explicitly use !== false instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
814 1
			$message = sprintf( $message, $status, '<div class="hidden">', '', '', '</div><a href="#" onclick="jQuery(\'#license_key\').focus(); return false;">' . $update_below . '</a>' );
815 1
		} else {
816 1
			$message = sprintf( $message, $status, "\n\n" . '<a href="' . esc_url( $primary_button_link ) . '" class="button button-primary primary">', '</a>', '<a href="' . esc_url( $url ) . '" class="button button-secondary">', '</a>' );
817
		}
818
819 1
		if ( empty( $status ) ) {
820 1
			return;
821 1
		}
822
823
		\GravityView_Admin_Notices::add_notice( array(
824 1
				'message' => $message,
825 1
				'class'   => 'notice notice-warning gv-license-warning',
826 1
				'title'   => $title,
827
				'cap'     => 'gravityview_edit_settings',
828
				'dismiss' => sha1( $license_status . '_' . $license_id . '_' . date( 'z' ) ), // Show every day, instead of every 8 weeks (which is the default)
829 1
		) );
830 1
	}
831 1
832 1
	/**
833 1
	 * Allow public access to the GV\License_Handler class
834 1
	 *
835 1
	 * @since 1.7.4
836
	 *
837
	 * @return \GV\License_Handler
838
	 */
839
	public function get_license_handler() {
840
841 1
		return $this->License_Handler;
842 1
	}
843 1
844 1
	/**
845 1
	 * Add tooltip script to app settings page. Not enqueued by Gravity Forms for some reason.
846
	 *
847
	 * @since 1.21.5
848 1
	 *
849 1
	 * @see   GFAddOn::scripts()
850
	 *
851
	 * @return array Array of scripts
852 1
	 */
853 1
	public function scripts() {
854
855
		$scripts = parent::scripts();
856 1
857 1
		$scripts[] = array(
858
				'handle'  => 'gform_tooltip_init',
859
				'enqueue' => array(
860 1
						array(
861 1
								'admin_page' => array( 'app_settings' ),
862 1
						),
863 1
				),
864 1
		);
865
866
		return $scripts;
867 1
	}
868 1
869
	/**
870
	 * Register styles in the app admin page
871 1
	 *
872 1
	 * @return array
873
	 */
874
	public function styles() {
875 1
876
		$styles = parent::styles();
877
878
		$styles[] = array(
879
				'handle'  => 'gravityview_settings',
880 1
				'src'     => plugins_url( 'assets/css/admin-settings.css', GRAVITYVIEW_FILE ),
881
				'version' => Plugin::$version,
882 1
				'deps'    => array(
883 1
						'gform_admin',
884 1
						'gaddon_form_settings_css',
885 1
						'gform_tooltip',
886 1
						'gform_font_awesome',
887
				),
888
				'enqueue' => array(
889 1
						array(
890 1
								'admin_page' => array(
891
										'app_settings',
892
								),
893 1
						),
894 1
				),
895
		);
896
897 1
		return $styles;
898 1
	}
899
900
	/**
901 1
	 * Does the current site have its own settings?
902 1
	 *
903 1
	 * - If not multisite, returns true.
904 1
	 * - If multisite and the plugin is network activated, returns true; we need to register the submenu page for the Network Admin settings to work.
905 1
	 * - If multisite and not network admin, return false.
906
	 *
907
	 * @since 2.8.2
908 1
	 *
909 1
	 * @return bool
910 1
	 */
911
	private function has_site_settings() {
912
913 1
		return ( ! is_multisite() ) || is_main_site() || ( ! gravityview()->plugin->is_network_activated() ) || ( is_network_admin() && gravityview()->plugin->is_network_activated() );
914
	}
915
916
	/**
917 1
	 * Add Settings link to GravityView menu
918
	 *
919
	 * @return void
920
	 */
921
	public function create_app_menu() {
922
923
		/**
924 1
		 * Override whether to show the Settings menu on a per-blog basis.
925
		 *
926
		 * @since 1.7.6
927
		 * @param bool $hide_if_network_activated Default: true
928
		 */
929
		$show_submenu = apply_filters( 'gravityview/show-settings-menu', $this->has_site_settings() );
930 1
931
		if ( ! $show_submenu ) {
932
			return;
933
		}
934
935
		add_submenu_page( 'edit.php?post_type=gravityview', __( 'Settings', 'gravityview' ), __( 'Settings', 'gravityview' ), $this->_capabilities_app_settings, $this->_slug . '_settings', array( $this, 'app_tab_page' ) );
936 1
	}
937 1
938 1
	/**
939 1
	 * Gets the required indicator
940 1
	 * Gets the markup of the required indicator symbol to highlight fields that are required
941
	 *
942 1
	 * @param $field - The field meta.
943
	 *
944
	 * @return string - Returns markup of the required indicator symbol
945
	 */
946 1
	public function get_required_indicator( $field ) {
947 1
948
		return '<span class="required" title="' . esc_attr__( 'Required', 'gravityview' ) . '">*</span>';
949
	}
950
951
	/**
952
	 * Specify the settings fields to be rendered on the plugin settings page
953 1
	 *
954 1
	 * @return array
955
	 */
956
	public function app_settings_fields() {
957
958
		$default_settings = $this->defaults();
959
960 1
		$disabled_attribute = \GVCommon::has_cap( 'gravityview_edit_settings' ) ? false : 'disabled';
961
962
		$fields = array(
963
				array(
964 1
						'name'          => 'support-email',
965
						'type'          => 'text',
966
						'validate'      => 'email',
967
						'default_value' => $default_settings['support-email'],
968
						'label'         => __( 'Support Email', 'gravityview' ),
969
						'description'   => __( 'In order to provide responses to your support requests, please provide your email address.', 'gravityview' ),
970
						'class'         => 'code regular-text',
971
				),
972
				/**
973
				 * @since 1.15 Added Support Port support
974
				 */
975
				array(
976
						'name'          => 'support_port',
977
						'type'          => 'radio',
978
						'label'         => __( 'Show Support Port?', 'gravityview' ),
979 1
						'default_value' => $default_settings['support_port'],
980
						'horizontal'    => 1,
981
						'choices'       => array(
982 1
								array(
983
										'label' => _x( 'Show', 'Setting: Show or Hide', 'gravityview' ),
984
										'value' => '1',
985
								),
986
								array(
987
										'label' => _x( 'Hide', 'Setting: Show or Hide', 'gravityview' ),
988
										'value' => '0',
989
								),
990
						),
991
						'tooltip' => '<p>' . esc_html__( 'The Support Port provides quick access to how-to articles and tutorials. For administrators, it also makes it easy to contact support.', 'gravityview' ) . '<img src="' . esc_url_raw( plugins_url( 'assets/images/beacon.png', GRAVITYVIEW_FILE ) ) . '" alt="' . esc_attr__( 'The Support Port looks like this.', 'gravityview' ) . '" class="aligncenter" style="display: block; max-width:100%; margin:1em auto;" /></p>',
992
						'description' => __( 'Show the Support Port on GravityView pages?', 'gravityview' ),
993
				),
994
				array(
995
						'name'          => 'no-conflict-mode',
996
						'type'          => 'radio',
997 1
						'label'         => __( 'No-Conflict Mode', 'gravityview' ),
998
						'default_value' => $default_settings['no-conflict-mode'],
999
						'horizontal'    => 1,
1000 1
						'choices'       => array(
1001
								array(
1002
										'label' => _x( 'On', 'Setting: On or off', 'gravityview' ),
1003
										'value' => '1',
1004
								),
1005
								array(
1006
										'label' => _x( 'Off', 'Setting: On or off', 'gravityview' ),
1007
										'value' => '0',
1008
								),
1009
						),
1010
						'description'   => __( 'Set this to ON to prevent extraneous scripts and styles from being printed on GravityView admin pages, reducing conflicts with other plugins and themes.', 'gravityview' ) . ' ' . __( 'If your Edit View tabs are ugly, enable this setting.', 'gravityview' ),
1011
				),
1012
				/**
1013
				 * @since 2.0 Added REST API
1014
				 */
1015
				gravityview()->plugin->supports( Plugin::FEATURE_REST ) ?
1016
						array(
1017
								'name'          => 'rest_api',
1018
								'type'          => 'radio',
1019
								'label'         => __( 'REST API', 'gravityview' ),
1020
								'default_value' => $default_settings['rest_api'],
1021
								'horizontal'    => 1,
1022
								'choices'       => array(
1023
										array(
1024 4
												'label' => _x( 'Enable', 'Setting: Enable or Disable', 'gravityview' ),
1025 4
												'value' => '1',
1026 2
										),
1027
										array(
1028 4
												'label' => _x( 'Disable', 'Setting: Enable or Disable', 'gravityview' ),
1029 4
												'value' => '0',
1030
										),
1031
								),
1032
								'description'   => __( 'Enable View and Entry access via the REST API? Regular per-View restrictions apply (private, password protected, etc.).', 'gravityview' ),
1033
								'tooltip'       => '<p>' . esc_html__( 'If you are unsure, choose the Disable setting.', 'gravityview' ) . '</p>',
1034
						) : array(),
1035
				array(
1036
						'name'          => 'beta',
1037
						'type'          => 'checkbox',
1038
						'label'         => __( 'Become a Beta Tester', 'gravityview' ),
1039 1
						'default_value' => $default_settings['beta'],
1040 1
						'horizontal'    => 1,
1041
						'choices'       => array(
1042
								array(
1043
										'label' => esc_html__( 'Show me beta versions if they are available.', 'gravityview' ),
1044
										'value' => '1',
1045
										'name'  => 'beta',
1046
								),
1047
						),
1048
						'description'   => __( 'You will have early access to the latest GravityView features and improvements. There may be bugs! If you encounter an issue, help make GravityView better by reporting it!', 'gravityview' ),
1049
				),
1050 1
		);
1051
1052 1
		$fields = array_filter( $fields, 'count' );
1053
1054
		/**
1055
		 * @filter     `gravityview_settings_fields` Filter the settings fields.
1056 1
		 * @param array $fields The fields to filter.
1057
		 * @deprecated Use `gravityview/settings/fields`.
1058 1
		 */
1059
		$fields = apply_filters( 'gravityview_settings_fields', $fields );
1060 1
1061
		/**
1062 1
		 * @filter `gravityview/settings/fields` Filter the settings fields.
1063 1
		 * @param array $fields The fields to filter.
1064
		 */
1065
		$fields = apply_filters( 'gravityview/settings/fields', $fields );
1066 1
1067
		/**
1068
		 * Redux backward compatibility
1069
		 *
1070
		 * @since 1.7.4
1071
		 */
1072
		foreach ( $fields as &$field ) {
1073
			$field['name']          = isset( $field['name'] ) ? $field['name'] : Utils::get( $field, 'id' );
1074
			$field['label']         = isset( $field['label'] ) ? $field['label'] : Utils::get( $field, 'title' );
1075
			$field['default_value'] = isset( $field['default_value'] ) ? $field['default_value'] : Utils::get( $field, 'default' );
1076
			$field['description']   = isset( $field['description'] ) ? $field['description'] : Utils::get( $field, 'subtitle' );
1077
1078
			if ( $disabled_attribute ) {
1079 1
				$field['disabled'] = $disabled_attribute;
1080
			}
1081 1
1082
			if ( empty( $field['disabled'] ) ) {
1083 1
				unset( $field['disabled'] );
1084 1
			}
1085
		}
1086
1087 1
		$license_fields = array(
1088
			array(
1089
					'name' => 'license_key',
1090
					'required' => ! defined( 'GRAVITYVIEW_LICENSE_KEY' ) || ! GRAVITYVIEW_LICENSE_KEY,
1091
					'label' => __( 'License Key', 'gravityview' ),
1092
					'description' => __( 'Enter the license key that was sent to you on purchase. This enables plugin updates &amp; support.', 'gravityview' ),
1093
					'type' => 'edd_license',
1094
					'disabled' => ( defined( 'GRAVITYVIEW_LICENSE_KEY' ) && GRAVITYVIEW_LICENSE_KEY ),
1095
					'title' => __( 'The license key is defined by your site\'s configuration file.', 'gravityview' ),
1096
					'data-pending-text' => __( 'Verifying license&hellip;', 'gravityview' ),
1097
					'default_value' => $default_settings['license_key'],
1098
					'class' => ( '' == $this->get( 'license_key' ) ) ? 'activate code regular-text edd-license-key' : 'deactivate code regular-text edd-license-key',
1099 1
			),
1100
			array(
1101
					'name' => 'license_key_response',
1102
					'default_value' => $default_settings['license_key_response'],
1103
					'type' => 'hidden',
1104
			),
1105 1
			array(
1106
					'name' => 'license_key_status',
1107
					'default_value' => $default_settings['license_key_status'],
1108
					'type' => 'hidden',
1109 1
			),
1110
		);
1111
1112
		$sections = array();
1113
		$version_info = '<span class="gv-version-info" title="' . sprintf( __( 'You are running GravityView version %s', 'gravityview' ), Plugin::$version ) . '">Version ' . esc_html( Plugin::$version ) . '</span>';
1114
1115
		if ( \gravityview()->plugin->is_GF_25() ) {
1116
1117
			$sections[] = array(
1118
					'title'       => __( 'GravityView License', 'gravityview' ),
1119 1
					'class'       => 'gform-settings-panel--full gv-settings-panel--license',
1120 1
					'description' => $version_info,
1121 1
					'fields'      => $license_fields,
1122 1
			);
1123 1
1124
		} else {
1125 1
1126
			$fields = array_merge( $license_fields, $fields );
1127 1
1128 1
			array_unshift( $fields, array(
1129 1
					'name'  => 'gv_header',
1130
					'value' => $version_info,
1131 1
					'type'  => 'html',
1132 1
			) );
1133
		}
1134
1135 1
		$sections[] = array(
1136
			'title' => ( gravityview()->plugin->is_GF_25() ? __( 'GravityView Settings', 'gravityview' ) : null ),
1137
			'class' => 'gform-settings-panel--full gv-settings-panel--core',
1138
			'fields'      => $fields,
1139
		);
1140
1141
		/**
1142
		 * @filter `gravityview/settings/extension/sections` Modify the GravityView settings page
1143
		 * Extensions can tap in here to insert their own section and settings.
1144
		 * <code>
1145
		 *   $sections[] = array(
1146
		 *      'title' => __( 'GravityView My Extension Settings', 'gravityview' ),
1147
		 *      'fields' => $settings,
1148
		 *   );
1149
		 * </code>
1150
		 * @param array $extension_settings Empty array, ready for extension settings!
1151
		 */
1152
		$extension_sections = apply_filters( 'gravityview/settings/extension/sections', array() );
1153 1
1154 1
		// If there are extensions, add a section for them
1155 1
		if ( ! empty( $extension_sections ) ) {
1156 1
1157 1
			if ( $disabled_attribute ) {
1158
				foreach ( $extension_sections as &$section ) {
1159
					foreach ( $section['fields'] as &$field ) {
1160
						$field['disabled'] = $disabled_attribute;
1161
					}
1162
				}
1163
			}
1164 1
1165 1
			$sections = array_merge( $sections, $extension_sections );
1166 1
		}
1167 1
1168
		return $sections;
1169 1
	}
1170
1171
	/**
1172
	 * Updates app settings with the provided settings
1173
	 *
1174
	 * Same as the GFAddon, except it returns the value from update_option()
1175
	 *
1176
	 * @param array $settings - App settings to be saved
1177
	 *
1178 1
	 * @return boolean False if value was not updated and true if value was updated.
1179
	 * @deprecated Use \GV\Addon_Settings::set or \GV\Addon_Settings::update
1180 1
	 *
1181
	 */
1182
	public function update_app_settings( $settings ) {
1183
1184
		return $this->update( $settings );
1185
	}
1186
1187 1
	/**
1188 1
	 * Sets a subset of settings.
1189
	 *
1190
	 * @param array|string An array of settings to update, or string (key) and $value to update one setting.
1191
	 * @param mixed $value A value if $settings is string (key). Default: null.
1192
	 */
1193
	public function set( $settings, $value = null ) {
1194
1195 1
		if ( is_string( $settings ) ) {
1196 1
			$settings = array( $settings => $value );
1197
		}
1198 1
		$settings = wp_parse_args( $settings, $this->all() );
1199
1200 1
		return update_option( 'gravityformsaddon_' . $this->_slug . '_app_settings', $settings );
1201
	}
1202
1203
	/**
1204 1
	 * Updates settings.
1205
	 *
1206 1
	 * @param array $settings The settings array.
1207
	 *
1208
	 * @return boolean False if value was not updated and true if value was updated.
1209
	 */
1210 1
	public function update( $settings ) {
1211
1212
		return update_option( 'gravityformsaddon_' . $this->_slug . '_app_settings', $settings );
1213
	}
1214
1215
	/**
1216
	 * Register the settings field for the EDD License field type
1217
	 *
1218
	 * @param array $field
1219 1
	 * @param bool  $echo Whether to echo the
1220
	 *
1221
	 * @return string
1222
	 */
1223
	public function settings_edd_license( $field, $echo = true ) {
1224
1225
		if ( defined( 'GRAVITYVIEW_LICENSE_KEY' ) && GRAVITYVIEW_LICENSE_KEY ) {
1226
			$field['input_type'] = 'password';
1227
		}
1228
1229
		$text = $this->settings_text( $field, false );
1230
1231
		$activation = $this->License_Handler->settings_edd_license_activation( $field, false );
1232
1233
		$return = $text . $activation;
1234
1235
		$return .= $this->get_license_handler()->license_details( \GV\Addon_Settings::get( 'license_key_response' ) );
1236
1237
		if ( $echo ) {
1238
			echo $return;
1239
		}
1240
1241
		return $return;
1242
	}
1243
1244
	/**
1245
	 * Allow pure HTML settings row
1246
	 *
1247
	 * @since 2.0.6
1248
	 *
1249
	 * @param array $field
1250
	 * @param bool  $echo Whether to echo the
1251
	 *
1252
	 * @return string
1253
	 */
1254
	protected function settings_html( $field, $echo = true ) {
1255
1256
		$return = \GV\Utils::get( $field, 'value', '' );
1257
1258
		if ( $echo ) {
1259
			echo $return;
1260
		}
1261
1262
		return $return;
1263
	}
1264
1265
	/**
1266
	 * No <th> needed for pure HTML settings row
1267
	 *
1268
	 * @since 2.0.6
1269
	 *
1270
	 * @param array $field
1271
	 *
1272
	 * @return void
1273
	 */
1274
	public function single_setting_row_html( $field ) {
1275
1276
		?>
1277
1278
		<tr id="gaddon-setting-row-<?php echo esc_attr( $field['name'] ); ?>">
1279
			<td colspan="2">
1280
				<?php $this->single_setting( $field ); ?>
1281
			</td>
1282
		</tr>
1283
1284
		<?php
1285
	}
1286
1287
	/**
1288
	 * Keep GravityView styling for `$field['description']`, even though Gravity Forms added support for it
1289
	 *
1290
	 * Converts `$field['description']` to `$field['gv_description']`
1291
	 * Converts `$field['subtitle']` to `$field['description']`
1292
	 *
1293
	 * @since 1.21.5.2
1294
	 *
1295
	 * @see   http://share.gravityview.co/P28uGp/2OIRKxog for image that shows subtitle vs description
1296
	 *
1297
	 * @see   \GV\Addon_Settings::single_setting_label Converts `gv_description` back to `description`
1298
	 * @param array $field
1299
	 *
1300
	 * @return void
1301
	 */
1302
	public function single_setting_row( $field ) {
1303
1304
		$field['gv_description'] = Utils::get( $field, 'description' );
1305
		$field['description']    = Utils::get( $field, 'subtitle' );
1306
		parent::single_setting_row( $field );
1307
	}
1308
1309
	/**
1310
	 * The same as the parent, except added support for field descriptions
1311
	 *
1312
	 * @inheritDoc
1313
	 * @param $field array
1314
	 */
1315
	public function single_setting_label( $field ) {
1316
1317
		parent::single_setting_label( $field );
1318
		if ( $description = Utils::get( $field, 'gv_description' ) ) {
1319
			echo '<span class="description">' . $description . '</span>';
1320
		}
1321
	}
1322
1323
	/**
1324
	 * Check for the `gravityview_edit_settings` capability before saving plugin settings.
1325
	 * Gravity Forms says you're able to edit if you're able to view settings. GravityView allows two different permissions.
1326
	 *
1327
	 * @since 1.15
1328
	 * @return void
1329
	 */
1330
	public function maybe_save_app_settings() {
1331
1332
		if ( $this->is_save_postback() ) {
1333
			if ( ! \GVCommon::has_cap( 'gravityview_edit_settings' ) ) {
1334
				$_POST = array(); // If you don't reset the $_POST array, it *looks* like the settings were changed, but they weren't
1335
				\GFCommon::add_error_message( __( 'You don\'t have the ability to edit plugin settings.', 'gravityview' ) );
1336
1337
				return;
1338
			}
1339
		}
1340
		parent::maybe_save_app_settings();
1341
	}
1342
1343
	/**
1344
	 * When the settings are saved, make sure the license key matches the previously activated key
1345
	 *
1346
	 * @return array settings from parent::get_posted_settings(), with `license_key_response` and `license_key_status` potentially unset
1347
	 */
1348
	public function get_posted_settings() {
1349
1350
		$posted_settings = parent::get_posted_settings();
1351
1352
		$local_key = Utils::get( $posted_settings, 'license_key' );
1353
1354
		if ( ! $local_key && defined( 'GRAVITYVIEW_LICENSE_KEY' ) ) {
1355
			$local_key = GRAVITYVIEW_LICENSE_KEY;
1356
		}
1357
1358
		$response_key = Utils::get( $posted_settings, 'license_key_response/license_key' );
1359
1360
		static $added_message = false;
1361
1362
		// If the posted key doesn't match the activated/deactivated key (set using the Activate License button, AJAX response),
1363
		// then we assume it's changed. If it's changed, unset the status and the previous response.
1364
		if ( ! $added_message && ( $local_key !== $response_key ) ) {
1365
1366
			unset( $posted_settings['license_key_response'] );
1367
			unset( $posted_settings['license_key_status'] );
1368
1369
			\GFCommon::add_error_message( __( 'The license key you entered has been saved, but not activated. Please activate the license.', 'gravityview' ) );
1370
1371
			$added_message = true;
1372
		}
1373
1374
		return $posted_settings;
1375
	}
1376
}
1377