Completed
Push — master ( 2cfa6f...8927a4 )
by Zack
10:00 queued 06:05
created

includes/class-gravityview-settings.php (20 issues)

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

1
<?php
2
3
if( ! class_exists('GFAddOn') ) {
4
	return;
5
}
6
7
/**
8
 * GravityView Settings class (get/set/license validation) using the Gravity Forms App framework
9
 * @since 1.7.4 (Before, used the Redux Framework)
10
 */
11
class GravityView_Settings extends GFAddOn {
12
13
	/**
14
	 * @var string Version number of the Add-On
15
	 */
16
	protected $_version = GravityView_Plugin::version;
17
	/**
18
	 * @var string Gravity Forms minimum version requirement
19
	 */
20
	protected $_min_gravityforms_version = GV_MIN_GF_VERSION;
21
22
	/**
23
	 * @var string Title of the plugin to be used on the settings page, form settings and plugins page. Example: 'Gravity Forms MailChimp Add-On'
24
	 */
25
	protected $_title = 'GravityView';
26
27
	/**
28
	 * @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'
29
	 */
30
	protected  $_short_title = 'GravityView';
31
32
	/**
33
	 * @var string URL-friendly identifier used for form settings, add-on settings, text domain localization...
34
	 */
35
	protected $_slug = 'gravityview';
36
37
	/**
38
	 * @var string|array A string or an array of capabilities or roles that can uninstall the plugin
39
	 */
40
	protected $_capabilities_uninstall = 'gravityview_uninstall';
41
42
	/**
43
	 * @var string|array A string or an array of capabilities or roles that have access to the settings page
44
	 */
45
	protected $_capabilities_app_settings = 'gravityview_view_settings';
46
47
	/**
48
	 * @var string|array A string or an array of capabilities or roles that have access to the settings page
49
	 */
50
	protected $_capabilities_app_menu = 'gravityview_view_settings';
51
52
	/**
53
	 * @var string The hook suffix for the app menu
54
	 */
55
	public  $app_hook_suffix = 'gravityview';
56
57
	/**
58
	 * @var GV_License_Handler Process license validation
59
	 */
60
	private $License_Handler;
61
62
	/**
63
	 * @var GravityView_Settings
64
	 */
65
	private static $instance;
66
67
	/**
68
	 * We're not able to set the __construct() method to private because we're extending the GFAddon class, so
69
	 * we fake it. When called using `new GravityView_Settings`, it will return get_instance() instead. We pass
70
	 * 'get_instance' as a test string.
71
	 *
72
	 * @see get_instance()
73
	 *
74
	 * @param string $prevent_multiple_instances
75
	 */
76
	public function __construct( $prevent_multiple_instances = '' ) {
77
78
		if( $prevent_multiple_instances === 'get_instance' ) {
79
			return parent::__construct();
80
		}
81
82
		return self::get_instance();
83
	}
84
85
	/**
86
	 * @return GravityView_Settings
87
	 */
88
	public static function get_instance() {
89
90
		if( empty( self::$instance ) ) {
91
			self::$instance = new self( 'get_instance' );
92
		}
93
94
		return self::$instance;
95
	}
96
97
	/**
98
	 * Prevent uninstall tab from being shown by returning false for the uninstall capability check. Otherwise:
99
	 * @inheritDoc
100
	 *
101
	 * @hack
102
	 *
103
	 * @param array|string $caps
104
	 *
105
	 * @return bool
106
	 */
107
	public function current_user_can_any( $caps ) {
108
109
		if( empty( $caps ) ) {
110
			$caps = array( 'gravityview_full_access' );
111
		}
112
113
		return GVCommon::has_cap( $caps );
114
	}
115
116
	public function uninstall_warning_message() {
117
118
		$heading = esc_html__( 'If you delete then re-install GravityView, it will be like installing GravityView for the first time.', 'gravityview' );
119
		$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' );
120
121
		return sprintf( '<h4>%s</h4><p>%s</p>', $heading, $message );
122
	}
123
124
	/**
125
     * Uninstall all traces of GravityView
126
     *
127
     * Note: method is public because parent method is public
128
     *
129
	 * @return bool
130
	 */
131
	public function uninstall() {
132
133
		include_once( GRAVITYVIEW_DIR . 'includes/class-gravityview-uninstall.php' );
134
135
		$uninstaller = new GravityView_Uninstall();
136
137
		$uninstaller->fire_everything();
138
139
		/**
140
         * Set the path so that Gravity Forms can de-activate GravityView
141
         * @see GFAddOn::uninstall_addon
142
         * @uses deactivate_plugins()
143
         */
144
		$this->_path = GRAVITYVIEW_FILE;
145
146
		return true;
147
	}
148
149
	/**
150
     * Get an array of reasons why the plugin might be uninstalled
151
     *
152
     * @since 1.17.5
153
     *
154
	 * @return array Array of reasons with the label and followup questions for each uninstall reason
155
	 */
156
	private function get_uninstall_reasons() {
157
158
		$reasons = array(
159
			'will-continue' => array(
160
                'label' => esc_html__( 'I am going to continue using GravityView', 'gravityview' ),
161
            ),
162
			'no-longer-need' => array(
163
                'label' => esc_html__( 'I no longer need GravityView', 'gravityview' ),
164
            ),
165
			'doesnt-work' => array(
166
                'label' => esc_html__( 'The plugin doesn\'t work', 'gravityview' ),
167
            ),
168
			'found-other' => array(
169
                'label' => esc_html__( 'I found a better plugin', 'gravityview' ),
170
                'followup' => esc_attr__('What plugin you are using, and why?', 'gravityview'),
0 ignored issues
show
Expected 1 spaces after opening bracket; 0 found
Loading history...
Expected 1 spaces before closing bracket; 0 found
Loading history...
171
            ),
172
			'other' => array(
173
                'label' => esc_html__( 'Other', 'gravityview' ),
174
            ),
175
		);
176
177
		shuffle( $reasons );
178
179
		return $reasons;
180
    }
181
182
	/**
183
     * Display a feedback form when the plugin is uninstalled
184
     *
185
     * @since 1.17.5
186
     *
187
	 * @return string HTML of the uninstallation form
188
	 */
189
	public function uninstall_form() {
190
		ob_start();
191
192
		$user = wp_get_current_user();
193
		?>
194
    <style>
195
        #gv-reason-details {
196
            min-height: 100px;
197
        }
198
        .number-scale label {
199
            border: 1px solid #cccccc;
200
            padding: .5em .75em;
201
            margin: .1em;
202
        }
203
        #gv-uninstall-thanks p {
204
            font-size: 1.2em;
205
        }
206
        .scale-description ul {
207
            margin-bottom: 0;
208
            padding-bottom: 0;
209
        }
210
        .scale-description p.description {
211
            margin-top: 0!important;
212
            padding-top: 0!important;
213
        }
214
        .gv-form-field-wrapper {
215
            margin-top: 30px;
216
        }
217
    </style>
218
219
    <div class="gv-uninstall-form-wrapper" style="font-size: 110%; padding: 15px 0;">
220
        <script>
221
            jQuery(function( $ ) {
222
                $('#gv-uninstall-feedback').on( 'change', function( e ) {
223
224
                    if( ! $( e.target ).is(':input') ) {
225
                        return;
226
                    }
227
                    var $textarea = $('.gv-followup').find('textarea');
228
                    var followup_text = $( e.target ).attr( 'data-followup' );
229
                    if( ! followup_text ) {
230
                        followup_text = $textarea.attr('data-default');
231
                    }
232
233
                    $textarea.attr( 'placeholder', followup_text );
234
235
                }).on( 'submit', function( e ) {
236
                    e.preventDefault();
237
238
                    $.post( $( this ).attr( 'action' ), $( this ).serialize() )
239
                        .done( function( data ) {
240
                            if( 'success' !== data.status ) {
241
                                gv_feedback_append_error_message();
242
                            } else {
243
                                $( '#gv-uninstall-thanks' ).fadeIn();
244
                            }
245
                        })
246
                        .fail( function( data ) {
247
                            gv_feedback_append_error_message();
248
                        })
249
                        .always( function() {
250
                            $( e.target ).remove();
251
                        });
252
253
                    return false;
254
                });
255
256
                function gv_feedback_append_error_message() {
257
                    $('#gv-uninstall-thanks').append('<div class="notice error"><?php echo esc_js( __('There was an error sharing your feedback. Sorry! Please email us at [email protected]', 'gravityview' ) ) ?></div>');
0 ignored issues
show
Expected 1 spaces after opening bracket; 0 found
Loading history...
258
                }
259
            });
260
        </script>
261
262
        <form id="gv-uninstall-feedback" method="post" action="https://hooks.zapier.com/hooks/catch/28670/6haevn/">
263
            <h2><?php esc_html_e( 'Why did you uninstall GravityView?', 'gravityview' ); ?></h2>
264
            <ul>
265
				<?php
266
                $reasons = $this->get_uninstall_reasons();
267
				foreach ( $reasons as $reason ) {
268
					printf( '<li><label><input name="reason" type="radio" value="other" data-followup="%s"> %s</label></li>', rgar( $reason, 'followup' ), rgar( $reason, 'label' ) );
269
				}
270
				?>
271
            </ul>
272
            <div class="gv-followup widefat">
273
                <p><strong><label for="gv-reason-details"><?php esc_html_e( 'Comments', 'gravityview' ); ?></label></strong></p>
274
                <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>
0 ignored issues
show
Expected 1 spaces after opening bracket; 0 found
Loading history...
Expected 1 spaces before closing bracket; 0 found
Loading history...
275
            </div>
276
            <div class="scale-description">
277
                <p><strong><?php esc_html_e('How likely are you to recommend GravityView?', 'gravityview' ); ?></strong></p>
0 ignored issues
show
Expected 1 spaces after opening bracket; 0 found
Loading history...
278
                <ul class="inline">
279
					<?php
280
					$i = 0;
281
					while( $i < 11 ) {
282
						echo '<li class="inline number-scale"><label><input name="likely_to_refer" id="likely_to_refer_'.$i.'" value="'.$i.'" type="radio"> '.$i.'</label></li>';
0 ignored issues
show
Expected next thing to be a escaping function, not '$i'
Loading history...
283
						$i++;
284
					}
285
					?>
286
                </ul>
287
                <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>
288
            </div>
289
290
            <div class="gv-form-field-wrapper">
291
                <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>
0 ignored issues
show
Expected 1 spaces after opening bracket; 0 found
Loading history...
Expected 1 spaces before closing bracket; 0 found
Loading history...
292
            </div>
293
294
            <div class="submit">
295
                <input type="hidden" name="siteurl" value="<?php echo esc_url( get_bloginfo( 'siteurl' ) ); ?>" />
296
                <input type="hidden" name="email" value="<?php echo esc_attr( $user->user_email ); ?>" />
297
                <input type="hidden" name="display_name" value="<?php echo esc_attr( $user->display_name ); ?>" />
298
                <input type="submit" value="<?php esc_html_e( 'Send Us Your Feedback', 'gravityview' ); ?>" class="button button-primary button-hero" />
299
            </div>
300
        </form>
301
302
        <div id="gv-uninstall-thanks" class="notice notice-large notice-updated below-h2" style="display:none;">
303
            <h3 class="notice-title"><?php esc_html_e( 'Thank you for using GravityView!', 'gravityview' ); ?></h3>
304
            <p><?php echo gravityview_get_floaty(); ?>
0 ignored issues
show
Expected a sanitizing function (see Codex for 'Data Validation'), but instead saw 'gravityview_get_floaty'
Loading history...
305
				<?php echo make_clickable( esc_html__('Your feedback helps us improve GravityView. If you have any questions or comments, email us: [email protected]', 'gravityview' ) ); ?>
0 ignored issues
show
Expected a sanitizing function (see Codex for 'Data Validation'), but instead saw 'make_clickable'
Loading history...
Expected 1 spaces after opening bracket; 0 found
Loading history...
306
            </p>
307
            <div class="wp-clearfix"></div>
308
        </div>
309
    </div>
310
		<?php
311
		$form = ob_get_clean();
312
313
		return $form;
314
	}
315
316
317
	public function app_settings_uninstall_tab() {
318
319
		if ( $this->maybe_uninstall() ) {
320
321
			parent::app_settings_uninstall_tab();
322
323
			return;
324
		}
325
326
		if ( ! ( $this->current_user_can_any( $this->_capabilities_uninstall ) && ( ! function_exists( 'is_multisite' ) || ! is_multisite() || is_super_admin() ) ) ) {
327
			return;
328
		}
329
330
		?>
331
		<script>
332
			jQuery(document).on('click', 'a[rel="gv-uninstall-wrapper"]', function( e ) {
333
				e.preventDefault();
334
				jQuery( '#gv-uninstall-wrapper' ).slideToggle();
335
			});
336
		</script>
337
338
		<a rel="gv-uninstall-wrapper" href="#gv-uninstall-wrapper" class="button button-large alignright button-danger">Uninstall GravityView</a>
339
340
		<div id="gv-uninstall-wrapper">
341
			<form action="" method="post">
342
				<?php wp_nonce_field( 'uninstall', 'gf_addon_uninstall' ) ?>
343
				<div class="delete-alert alert_red">
344
345
					<h3>
346
						<i class="fa fa-exclamation-triangle gf_invalid"></i> <?php esc_html_e( 'Delete all GravityView content and settings', 'gravityview' ); ?>
347
					</h3>
348
349
					<div class="gf_delete_notice">
350
						<?php echo $this->uninstall_warning_message() ?>
0 ignored issues
show
Expected next thing to be a escaping function, not '$this'
Loading history...
351
					</div>
352
353
					<?php
354
					echo '<input type="submit" name="uninstall" value="' . sprintf( esc_attr__( 'Uninstall %s', 'gravityview' ), $this->get_short_title() ) . '" class="button button-hero" onclick="return confirm(\'' . esc_js( $this->uninstall_confirm_message() ) . '\');" onkeypress="return confirm(\'' . esc_js( $this->uninstall_confirm_message() ) . '\');"/>';
0 ignored issues
show
Expected a sanitizing function (see Codex for 'Data Validation'), but instead saw 'sprintf'
Loading history...
355
					?>
356
357
				</div>
358
			</form>
359
		</div>
360
	<?php
361
	}
362
363
	/**
364
	 * Run actions when initializing admin
365
	 *
366
	 * Triggers the license key notice
367
	 *
368
	 * @return void
369
	 */
370
	function init_admin() {
371
372
		$this->_load_license_handler();
373
374
		$this->license_key_notice();
375
376
		add_filter( 'gform_addon_app_settings_menu_gravityview', array( $this, 'modify_app_settings_menu_title' ) );
377
378
		/** @since 1.7.6 */
379
		add_action('network_admin_menu', array( $this, 'add_network_menu' ) );
380
381
		parent::init_admin();
382
	}
383
384
	/**
385
	 * Change the settings page header title to "GravityView"
386
	 *
387
	 * @param $setting_tabs
388
	 *
389
	 * @return array
390
	 */
391
	public function modify_app_settings_menu_title( $setting_tabs ) {
392
393
		$setting_tabs[0]['label'] = __( 'GravityView Settings', 'gravityview');
394
395
		return $setting_tabs;
396
	}
397
398
	/**
399
	 * Load license handler in admin-ajax.php
400
	 */
401
	public function init_ajax() {
402
		$this->_load_license_handler();
403
	}
404
405
	/**
406
	 * Make sure the license handler is available
407
	 */
408
	private function _load_license_handler() {
409
410
		if( !empty( $this->License_Handler ) ) {
411
			return;
412
		}
413
414
		require_once( GRAVITYVIEW_DIR . 'includes/class-gv-license-handler.php');
415
416
		$this->License_Handler = GV_License_Handler::get_instance( $this );
417
	}
418
419
	/**
420
	 * Display a notice if the plugin is inactive.
421
	 * @return void
422
	 */
423
	function license_key_notice() {
424
425
		// Only show on GravityView pages
426
		if( ! gravityview_is_admin_page() ) {
427
			return;
428
		}
429
430
		$license_status = self::getSetting('license_key_status');
431
		$license_key = self::getSetting('license_key');
0 ignored issues
show
Expected 1 spaces after opening bracket; 0 found
Loading history...
Expected 1 spaces before closing bracket; 0 found
Loading history...
432
		if( '' === $license_key ) {
433
			$license_status = 'inactive';
434
        }
435
		$license_id = empty( $license_key ) ? 'license' : $license_key;
436
437
		$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');
438
439
		/**
440
		 * I wanted to remove the period from after the buttons in the string,
441
		 * but didn't want to mess up the translation strings for the translators.
442
		 */
443
		$message = mb_substr( $message, 0, mb_strlen( $message ) - 1 );
444
		$title = __('Inactive License', 'gravityview');
445
		$status = '';
446
		$update_below = false;
447
		$primary_button_link = admin_url( 'edit.php?post_type=gravityview&amp;page=gravityview_settings' );
448
		switch ( $license_status ) {
449
			/** @since 1.17 */
450
			case 'expired':
451
				$title = __('Expired License', 'gravityview');
452
				$status = 'expired';
453
				$message = $this->get_license_handler()->strings( 'expired', self::getSetting('license_key_response') );
454
				break;
455
			case 'invalid':
456
				$title = __('Invalid License', 'gravityview');
457
				$status = __('is invalid', 'gravityview');
458
				break;
459
			case 'deactivated':
460
				$status = __('is inactive', 'gravityview');
461
				$update_below = __('Activate your license key below.', 'gravityview');
462
				break;
463
			/** @noinspection PhpMissingBreakStatementInspection */
464
			case '':
465
				$license_status = 'site_inactive';
466
				// break intentionally left blank
467
			case 'inactive':
468
			case 'site_inactive':
469
				$status = __('has not been activated', 'gravityview');
470
				$update_below = __('Activate your license key below.', 'gravityview');
471
				break;
472
		}
473
		$url = 'https://gravityview.co/pricing/?utm_source=admin_notice&utm_medium=admin&utm_content='.$license_status.'&utm_campaign=Admin%20Notice';
474
475
		// Show a different notice on settings page for inactive licenses (hide the buttons)
476
		if( $update_below && gravityview_is_admin_page( '', 'settings' ) ) {
477
			$message = sprintf( $message, $status, '<div class="hidden">', '', '', '</div><a href="#" onclick="jQuery(\'#license_key\').focus(); return false;">' . $update_below . '</a>' );
478
		} else {
479
			$message = sprintf( $message, $status, "\n\n" . '<a href="' . esc_url( $primary_button_link ) . '" class="button button-primary">', '</a>', '<a href="' . esc_url( $url ) . '" class="button button-secondary">', '</a>' );
480
		}
481
482
		if( !empty( $status ) ) {
483
			GravityView_Admin_Notices::add_notice( array(
484
				'message' => $message,
485
				'class'	=> 'updated',
486
				'title' => $title,
487
				'cap' => 'gravityview_edit_settings',
488
				'dismiss' => sha1( $license_status.'_'.$license_id ),
489
			));
490
		}
491
	}
492
493
	/**
494
	 * Register styles in the app admin page
495
	 * @return array
496
	 */
497
	public function styles() {
498
499
		$styles = parent::styles();
500
501
		$styles[] = array(
502
			'handle'  => 'gravityview_settings',
503
			'src'     => plugins_url( 'assets/css/admin-settings.css', GRAVITYVIEW_FILE ),
504
			'version' => GravityView_Plugin::version,
505
			"deps" => array(
506
				'gaddon_form_settings_css'
507
			),
508
			'enqueue' => array(
509
				array( 'admin_page' => array(
510
					'app_settings'
511
				) ),
512
			)
513
		);
514
515
		return $styles;
516
	}
517
518
	/**
519
	 * Add global Settings page for Multisite
520
	 * @since 1.7.6
521
	 * @return void
522
	 */
523
	public function add_network_menu() {
524
		if( GravityView_Plugin::is_network_activated() ) {
525
			add_menu_page( __( 'Settings', 'gravityview' ), __( 'GravityView', 'gravityview' ), $this->_capabilities_app_settings, "{$this->_slug}_settings", array( $this, 'app_tab_page' ), 'none' );
526
		}
527
	}
528
529
	/**
530
	 * Add Settings link to GravityView menu
531
	 * @return void
532
	 */
533
	public function create_app_menu() {
534
535
		/**
536
		 * If not multisite, always show.
537
		 * If multisite and the plugin is network activated, show; we need to register the submenu page for the Network Admin settings to work.
538
		 * If multisite and not network admin, we don't want the settings to show.
539
		 * @since 1.7.6
540
		 */
541
		$show_submenu = !is_multisite() ||  is_main_site() || !GravityView_Plugin::is_network_activated() || ( is_network_admin() && GravityView_Plugin::is_network_activated() );
542
543
		/**
544
		 * Override whether to show the Settings menu on a per-blog basis.
545
		 * @since 1.7.6
546
		 * @param bool $hide_if_network_activated Default: true
547
		 */
548
		$show_submenu = apply_filters( 'gravityview/show-settings-menu', $show_submenu );
549
550
		if( $show_submenu ) {
551
			add_submenu_page( 'edit.php?post_type=gravityview', __( 'Settings', 'gravityview' ), __( 'Settings', 'gravityview' ), $this->_capabilities_app_settings, $this->_slug . '_settings', array( $this, 'app_tab_page' ) );
552
		}
553
	}
554
555
	/**
556
	 * The Settings title
557
	 * @return string
558
	 */
559
	public function app_settings_title() {
560
		return null;
561
	}
562
563
	/**
564
	 * Prevent displaying of any icon
565
	 * @return string
566
	 */
567
	public function app_settings_icon() {
568
		return '&nbsp;';
569
	}
570
571
	public function app_settings_tab() {
572
	    parent::app_settings_tab();
573
574
		if ( $this->maybe_uninstall() ) {
575
            echo $this->uninstall_form();
0 ignored issues
show
Expected next thing to be a escaping function, not '$this'
Loading history...
576
		}
577
    }
578
579
	/**
580
	 * Make protected public
581
	 * @inheritDoc
582
	 * @access public
583
	 */
584
	public function get_app_setting( $setting_name ) {
585
586
		/**
587
		 * Backward compatibility with Redux
588
		 */
589
		if( $setting_name === 'license' ) {
590
			return array(
591
				'license' => parent::get_app_setting( 'license_key' ),
592
				'status' => parent::get_app_setting( 'license_key_status' ),
593
				'response' => parent::get_app_setting( 'license_key_response' ),
594
			);
595
		}
596
597
		return parent::get_app_setting( $setting_name );
598
	}
599
600
	/**
601
	 * Returns the currently saved plugin settings
602
	 *
603
	 * Different from GFAddon in two ways:
604
	 * 1. Makes protected method public
605
	 * 2. Use default settings if the original settings don't exist
606
	 *
607
	 * @access public
608
	 *
609
	 * @return array
610
	 */
611
	public function get_app_settings() {
612
		return get_option( 'gravityformsaddon_' . $this->_slug . '_app_settings', $this->get_default_settings() );
613
	}
614
615
616
	/**
617
	 * Updates app settings with the provided settings
618
	 *
619
	 * Same as the GVAddon, except it returns the value from update_option()
620
	 *
621
	 * @param array $settings - App settings to be saved
622
	 *
623
	 * @return boolean False if value was not updated and true if value was updated.
624
	 */
625
	public function update_app_settings( $settings ) {
626
		return update_option( 'gravityformsaddon_' . $this->_slug . '_app_settings', $settings );
627
	}
628
629
	/**
630
	 * Make protected public
631
	 * @inheritDoc
632
	 * @access public
633
	 */
634
	public function set_field_error( $field, $error_message = '' ) {
635
		parent::set_field_error( $field, $error_message );
636
	}
637
638
	/**
639
	 * Register the settings field for the EDD License field type
640
	 * @param array $field
641
	 * @param bool $echo Whether to echo the
642
	 *
643
	 * @return string
644
	 */
645
	protected function settings_edd_license( $field, $echo = true ) {
646
647
		$text = self::settings_text( $field, false );
648
649
		$activation = $this->License_Handler->settings_edd_license_activation( $field, false );
650
651
		$return = $text . $activation;
652
653
		if( $echo ) {
654
			echo $return;
655
		}
656
657
		return $return;
658
	}
659
660
	/**
661
	 * Allow public access to the GV_License_Handler class
662
	 * @since 1.7.4
663
	 *
664
	 * @return GV_License_Handler
665
	 */
666
	public function get_license_handler() {
667
		return $this->License_Handler;
668
	}
669
670
	/***
671
	 * Renders the save button for settings pages
672
	 *
673
	 * @param array $field - Field array containing the configuration options of this field
674
	 * @param bool  $echo  = true - true to echo the output to the screen, false to simply return the contents as a string
675
	 *
676
	 * @return string The HTML
677
	 */
678
	public function settings_submit( $field, $echo = true ) {
679
680
		$field['type']  = ( isset($field['type']) && in_array( $field['type'], array('submit','reset','button') ) ) ? $field['type'] : 'submit';
681
682
		$attributes    = $this->get_field_attributes( $field );
683
		$default_value = rgar( $field, 'value' ) ? rgar( $field, 'value' ) : rgar( $field, 'default_value' );
684
		$value         = $this->get_setting( $field['name'], $default_value );
685
0 ignored issues
show
Functions must not contain multiple empty lines in a row; found 2 empty lines
Loading history...
686
687
		$attributes['class'] = isset( $attributes['class'] ) ? esc_attr( $attributes['class'] ) : 'button-primary gfbutton';
688
		$name    = ( $field['name'] === 'gform-settings-save' ) ? $field['name'] : '_gaddon_setting_'.$field['name'];
689
690
		if ( empty( $value ) ) {
691
			$value = __( 'Update Settings', 'gravityview' );
692
		}
693
694
		$attributes = $this->get_field_attributes( $field );
695
696
		$html = '<input
697
                    type="' . $field['type'] . '"
698
                    name="' . esc_attr( $name ) . '"
699
                    value="' . $value . '" ' .
700
		        implode( ' ', $attributes ) .
701
		        ' />';
702
703
		if ( $echo ) {
704
			echo $html;
705
		}
706
707
		return $html;
708
	}
709
710
	/**
711
	 * Allow customizing the Save field parameters
712
	 *
713
	 * @param array $field
714
	 * @param bool $echo
715
	 *
716
	 * @return string
717
	 */
718
	public function settings_save( $field, $echo = true ) {
719
		$field['type']  = 'submit';
720
		$field['name']  = 'gform-settings-save';
721
		$field['class'] = isset( $field['class'] ) ? $field['class'] : 'button-primary gfbutton';
722
723
		if ( ! rgar( $field, 'value' ) ) {
724
			$field['value'] = __( 'Update Settings', 'gravityview' );
725
		}
726
727
		$output = $this->settings_submit( $field, false );
728
729
		ob_start();
730
		$this->app_settings_uninstall_tab();
731
		$output .= ob_get_clean();
732
733
		if( $echo ) {
734
			echo $output;
735
		}
736
737
		return $output;
738
	}
739
740
741
	/**
742
	 * The same as the parent, except added support for field descriptions
743
	 * @inheritDoc
744
	 * @param $field array
745
	 */
746
	public function single_setting_label( $field ) {
747
748
		parent::single_setting_label( $field );
749
750
		// Added by GravityView
751
		if ( isset( $field['description'] ) ) {
752
			echo '<span class="description">'. $field['description'] .'</span>';
753
		}
754
755
	}
756
757
	/**
758
	 * Get the default settings for the plugin
759
	 *
760
	 * Merges previous settings created when using the Redux Framework
761
	 *
762
	 * @return array Settings with defaults set
763
	 */
764
	private function get_default_settings() {
765
766
		$defaults = array(
767
			// Set the default license in wp-config.php
768
			'license_key' => defined( 'GRAVITYVIEW_LICENSE_KEY' ) ? GRAVITYVIEW_LICENSE_KEY : '',
769
			'license_key_response' => '',
770
			'license_key_status' => '',
771
			'support-email' => get_bloginfo( 'admin_email' ),
772
			'no-conflict-mode' => '1',
773
			'support_port' => '1',
774
			'flexbox_search' => '1',
775
		);
776
777
		return $defaults;
778
	}
779
780
	/**
781
	 * Check for the `gravityview_edit_settings` capability before saving plugin settings.
782
	 * Gravity Forms says you're able to edit if you're able to view settings. GravityView allows two different permissions.
783
	 *
784
	 * @since 1.15
785
	 * @return void
786
	 */
787
	public function maybe_save_app_settings() {
788
789
		if ( $this->is_save_postback() ) {
790
			if ( ! GVCommon::has_cap( 'gravityview_edit_settings' ) ) {
791
				$_POST = array(); // If you don't reset the $_POST array, it *looks* like the settings were changed, but they weren't
792
				GFCommon::add_error_message( __( 'You don\'t have the ability to edit plugin settings.', 'gravityview' ) );
793
				return;
794
			}
795
		}
796
797
		parent::maybe_save_app_settings();
798
	}
799
800
	/**
801
	 * When the settings are saved, make sure the license key matches the previously activated key
802
	 *
803
	 * @return array settings from parent::get_posted_settings(), with `license_key_response` and `license_key_status` potentially unset
804
	 */
805
	public function get_posted_settings() {
806
807
		$posted_settings = parent::get_posted_settings();
808
809
		$local_key = rgar( $posted_settings, 'license_key' );
810
		$response_key = rgars( $posted_settings, 'license_key_response/license_key' );
811
812
		// If the posted key doesn't match the activated/deactivated key (set using the Activate License button, AJAX response),
813
		// then we assume it's changed. If it's changed, unset the status and the previous response.
814
		if( $local_key !== $response_key ) {
815
816
			unset( $posted_settings['license_key_response'] );
817
			unset( $posted_settings['license_key_status'] );
818
			GFCommon::add_error_message( __('The license key you entered has been saved, but not activated. Please activate the license.', 'gravityview' ) );
819
		}
820
821
		return $posted_settings;
822
	}
823
824
	/**
825
	 * Gets the required indicator
826
	 * Gets the markup of the required indicator symbol to highlight fields that are required
827
	 *
828
	 * @param $field - The field meta.
829
	 *
830
	 * @return string - Returns markup of the required indicator symbol
831
	 */
832
	public function get_required_indicator( $field ) {
833
		return '<span class="required" title="' . esc_attr__( 'Required', 'gravityview' ) . '">*</span>';
834
	}
835
836
	/**
837
	 * Specify the settings fields to be rendered on the plugin settings page
838
	 * @return array
839
	 */
840
	public function app_settings_fields() {
841
842
		$default_settings = $this->get_default_settings();
843
844
		$disabled_attribute = GVCommon::has_cap( 'gravityview_edit_settings' ) ? false : 'disabled';
845
846
		$fields = apply_filters( 'gravityview_settings_fields', array(
847
			array(
848
				'name'                => 'license_key',
849
				'required'               => true,
850
				'label'             => __( 'License Key', 'gravityview' ),
851
				'description'          => __( 'Enter the license key that was sent to you on purchase. This enables plugin updates &amp; support.', 'gravityview' ) . $this->get_license_handler()->license_details( $this->get_app_setting( 'license_key_response' ) ),
852
				'type'              => 'edd_license',
853
				'data-pending-text' => __('Verifying license&hellip;', 'gravityview'),
854
				'default_value'           => $default_settings['license_key'],
855
				'class'             => ( '' == $this->get_app_setting( 'license_key' ) ) ? 'activate code regular-text edd-license-key' : 'deactivate code regular-text edd-license-key',
856
			),
857
			array(
858
				'name'       => 'license_key_response',
859
				'default_value'  => $default_settings['license_key_response'],
860
				'type'     => 'hidden',
861
			),
862
			array(
863
				'name'       => 'license_key_status',
864
				'default_value'  => $default_settings['license_key_status'],
865
				'type'     => 'hidden',
866
			),
867
			array(
868
				'name'       => 'support-email',
869
				'type'     => 'text',
870
				'validate' => 'email',
871
				'default_value'  => $default_settings['support-email'],
872
				'label'    => __( 'Support Email', 'gravityview' ),
873
				'description' => __( 'In order to provide responses to your support requests, please provide your email address.', 'gravityview' ),
874
				'class'    => 'code regular-text',
875
			),
876
			/**
877
			 * @since 1.15 Added Support Port support
878
			 */
879
			array(
880
				'name'         => 'support_port',
881
				'type'       => 'radio',
882
				'label'      => __( 'Show Support Port?', 'gravityview' ),
883
				'default_value'    => $default_settings['support_port'],
884
				'horizontal' => 1,
885
				'choices'    => array(
886
					array(
887
						'label' => _x('Show', 'Setting: Show or Hide', 'gravityview'),
888
						'value' => '1',
889
					),
890
					array(
891
						'label' => _x('Hide', 'Setting: Show or Hide', 'gravityview'),
892
						'value' => '0',
893
					),
894
				),
895
				'tooltip' => '<p><img src="' . esc_url_raw( plugins_url('assets/images/screenshots/beacon.png', GRAVITYVIEW_FILE ) ) . '" alt="' . esc_attr__( 'The Support Port looks like this.', 'gravityview' ) . '" class="alignright" style="max-width:40px; margin:.5em;" />' . 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') . '</p>',
896
				'description'   => __( 'Show the Support Port on GravityView pages?', 'gravityview' ),
897
			),
898
			array(
899
				'name'         => 'no-conflict-mode',
900
				'type'       => 'radio',
901
				'label'      => __( 'No-Conflict Mode', 'gravityview' ),
902
				'default_value'    => $default_settings['no-conflict-mode'],
903
				'horizontal' => 1,
904
				'choices'    => array(
905
					array(
906
						'label' => _x('On', 'Setting: On or off', 'gravityview'),
907
						'value' => '1',
908
					),
909
					array(
910
						'label' => _x('Off', 'Setting: On or off', 'gravityview'),
911
						'value' => '0',
912
					),
913
				),
914
				'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'),
915
			),
916
		) );
917
918
919
920
		/**
921
		 * Redux backward compatibility
922
		 * @since 1.7.4
923
		 */
924
		foreach ( $fields as &$field ) {
925
			$field['name']          = isset( $field['name'] ) ? $field['name'] : rgget('id', $field );
926
			$field['label']         = isset( $field['label'] ) ? $field['label'] : rgget('title', $field );
927
			$field['default_value'] = isset( $field['default_value'] ) ? $field['default_value'] : rgget('default', $field );
928
			$field['description']   = isset( $field['description'] ) ? $field['description'] : rgget('subtitle', $field );
929
930
			if( $disabled_attribute ) {
931
				$field['disabled']  = $disabled_attribute;
932
			}
933
		}
934
0 ignored issues
show
Functions must not contain multiple empty lines in a row; found 2 empty lines
Loading history...
935
936
        $sections = array(
937
            array(
938
                'description' =>      sprintf( '<span class="version-info description">%s</span>', sprintf( __('You are running GravityView version %s', 'gravityview'), GravityView_Plugin::version ) ),
939
                'fields'      => $fields,
940
            )
941
        );
942
943
        // custom 'update settings' button
944
        $button = array(
945
            'class' => 'button button-primary button-hero',
946
            'type'     => 'save',
947
        );
948
949
		if( $disabled_attribute ) {
950
			$button['disabled'] = $disabled_attribute;
951
		}
952
0 ignored issues
show
Functions must not contain multiple empty lines in a row; found 2 empty lines
Loading history...
953
954
        /**
955
         * @filter `gravityview/settings/extension/sections` Modify the GravityView settings page
956
         * Extensions can tap in here to insert their own section and settings.
957
         * <code>
958
         *   $sections[] = array(
959
         *      'title' => __( 'GravityView My Extension Settings', 'gravityview' ),
960
         *      'fields' => $settings,
961
         *   );
962
         * </code>
963
         * @param array $extension_settings Empty array, ready for extension settings!
964
         */
965
        $extension_sections = apply_filters( 'gravityview/settings/extension/sections', array() );
966
967
		// If there are extensions, add a section for them
968
		if ( ! empty( $extension_sections ) ) {
969
970
			if( $disabled_attribute ) {
971
				foreach ( $extension_sections as &$section ) {
972
					foreach ( $section['fields'] as &$field ) {
973
						$field['disabled'] = $disabled_attribute;
974
					}
975
				}
976
			}
977
978
            $k = count( $extension_sections ) - 1 ;
979
            $extension_sections[ $k ]['fields'][] = $button;
980
			$sections = array_merge( $sections, $extension_sections );
981
		} else {
982
            // add the 'update settings' button to the general section
983
            $sections[0]['fields'][] = $button;
984
        }
985
986
		return $sections;
987
	}
988
989
	/**
990
	 * Get the setting for GravityView by name
991
	 *
992
	 * @param  string $key     Option key to fetch
993
	 *
994
	 * @return mixed
995
	 */
996
	static public function getSetting( $key ) {
997
		return self::get_instance()->get_app_setting( $key );
998
	}
999
1000
}
1001
1002
GravityView_Settings::get_instance();