Completed
Push — develop ( 909f09...da0095 )
by Zack
07:59
created

Addon_Settings::get_license_handler()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
nc 1
nop 0
dl 0
loc 3
ccs 2
cts 2
cp 1
crap 1
rs 10
c 0
b 0
f 0
1
<?php
2
namespace GV;
3
4
/** If this file is called directly, abort. */
5
if ( ! defined( 'GRAVITYVIEW_DIR' ) ) {
6
	die();
7
}
8
9
if ( ! class_exists( '\GFAddOn' ) ) {
10
	return;
11
}
12
13
/**
14
 * The Addon Settings class.
15
 *
16
 * Uses internal GFAddOn APIs.
17
 */
18
class Addon_Settings extends \GFAddOn {
19
	/**
20
	 * @var string Title of the plugin to be used on the settings page, form settings and plugins page. Example: 'Gravity Forms MailChimp Add-On'
21
	 */
22
	protected $_title = 'GravityView';
23
24
	/**
25
	 * @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'
26
	 */
27
	protected  $_short_title = 'GravityView';
28
29
	/**
30
	 * @var string URL-friendly identifier used for form settings, add-on settings, text domain localization...
31
	 */
32
	protected $_slug = 'gravityview';
33
34
	/**
35
	 * @var string|array A string or an array of capabilities or roles that can uninstall the plugin
36
	 */
37
	protected $_capabilities_uninstall = 'gravityview_uninstall';
38
39
	/**
40
	 * @var string|array A string or an array of capabilities or roles that have access to the settings page
41
	 */
42
	protected $_capabilities_app_settings = 'gravityview_view_settings';
43
44
	/**
45
	 * @var string|array A string or an array of capabilities or roles that have access to the settings page
46
	 */
47
	protected $_capabilities_app_menu = 'gravityview_view_settings';
48
49
	/**
50
	 * @var string The hook suffix for the app menu
51
	 */
52
	public $app_hook_suffix = 'gravityview';
53
54
	/**
55
	 * @var \GV\License_Handler Process license validation
56
	 */
57
	private $License_Handler;
58
59
	/**
60
	 * @var bool Whether we have initialized already or not.
61
	 */
62
	private static $initialized = false;
63
64 2
	public function __construct() {
65 2
		$this->_version = Plugin::$version;
66 2
		$this->_min_gravityforms_version = Plugin::$min_gf_version;
67
68
		/**
69
		 * Hook everywhere, but only once.
70
		 */
71 2
		if ( ! self::$initialized ) {
72
			parent::__construct();
73
			self::$initialized = true;
74
		}
75 2
	}
76
77
	/**
78
	 * Run actions when initializing admin.
79
	 *
80
	 * Triggers the license key notice, et.c
81
	 *
82
	 * @return void
83
	 */
84 1
	public function init_admin() {
85 1
		$this->_load_license_handler();
86
87 1
		add_action( 'admin_head', array( $this, 'license_key_notice' ) );
88
89 1
		add_filter( 'gform_addon_app_settings_menu_gravityview', array( $this, 'modify_app_settings_menu_title' ) );
90
91
		/** @since 1.7.6 */
92 1
		add_action( 'network_admin_menu', array( $this, 'add_network_menu' ) );
93
94 1
		parent::init_admin();
95 1
	}
96
97
	/**
98
	 * Change the settings page header title to "GravityView"
99
	 *
100
	 * @param $setting_tabs
101
	 *
102
	 * @return array
103
	 */
104 1
	public function modify_app_settings_menu_title( $setting_tabs ) {
105 1
		$setting_tabs[0]['label'] = __( 'GravityView Settings', 'gravityview' );
106 1
		return $setting_tabs;
107
	}
108
109
	/**
110
	 * Load license handler in admin-ajax.php
111
	 *
112
	 * @return void
113
	 */
114 1
	public function init_ajax() {
115 1
		$this->_load_license_handler();
116 1
	}
117
118
	/**
119
	 * Make sure the license handler is available
120
	 *
121
	 * @return void
122
	 */
123 1
	private function _load_license_handler() {
124 1
		if ( ! empty( $this->License_Handler ) ) {
125 1
			return;
126
		}
127 1
		$this->License_Handler = License_Handler::get( $this );
128 1
	}
129
130
	/**
131
	 * Add global Settings page for Multisite
132
	 * @since 1.7.6
133
	 * @return void
134
	 */
135 1
	public function add_network_menu() {
136
137 1
	    if ( ! gravityview()->plugin->is_network_activated() ) {
138 1
			return;
139
		}
140
141
        add_menu_page( __( 'Settings', 'gravityview' ), __( 'GravityView', 'gravityview' ), $this->_capabilities_app_settings, "{$this->_slug}_settings", array( $this, 'app_tab_page' ), 'none' );
142
	}
143
144
	/**
145
     * Uninstall all traces of GravityView
146
     *
147
     * Note: method is public because parent method is public
148
     *
149
	 * @return bool
150
	 */
151 1
	public function uninstall() {
152 1
		gravityview()->plugin->uninstall();
153
154
		/**
155
         * Set the path so that Gravity Forms can de-activate GravityView
156
         * @see GFAddOn::uninstall_addon
157
         * @uses deactivate_plugins()
158
         */
159 1
		$this->_path = GRAVITYVIEW_FILE;
160
161 1
		return true;
162
	}
163
164
	/**
165
	 * Prevent uninstall tab from being shown by returning false for the uninstall capability check. Otherwise:
166
	 * @inheritDoc
167
	 *
168
	 * @hack
169
	 *
170
	 * @param array|string $caps
171
	 *
172
	 * @return bool
173
	 */
174 1
	public function current_user_can_any( $caps ) {
175 1
		if ( empty( $caps ) ) {
176
			$caps = array( 'gravityview_full_access' );
177
		}
178 1
		return \GVCommon::has_cap( $caps );
179
	}
180
181 1
	public function uninstall_warning_message() {
182 1
		$heading = esc_html__( 'If you delete then re-install GravityView, it will be like installing GravityView for the first time.', 'gravityview' );
183 1
		$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' );
184 1
		return sprintf( '<h4>%s</h4><p>%s</p>', $heading, $message );
185
	}
186
187
	/**
188
     * Get an array of reasons why the plugin might be uninstalled
189
     *
190
     * @since 1.17.5
191
     *
192
	 * @return array Array of reasons with the label and followup questions for each uninstall reason
193
	 */
194 1
	private function get_uninstall_reasons() {
195
		$reasons = array(
196
			'will-continue' => array(
197 1
                'label' => esc_html__( 'I am going to continue using GravityView', 'gravityview' ),
198
            ),
199
			'no-longer-need' => array(
200 1
                'label' => esc_html__( 'I no longer need GravityView', 'gravityview' ),
201
            ),
202
			'doesnt-work' => array(
203 1
                'label' => esc_html__( 'The plugin doesn\'t work', 'gravityview' ),
204
            ),
205
			'found-other' => array(
206 1
                'label' => esc_html__( 'I found a better plugin', 'gravityview' ),
207 1
                'followup' => esc_attr__( 'What plugin you are using, and why?', 'gravityview' ),
208
            ),
209
			'other' => array(
210 1
                'label' => esc_html__( 'Other', 'gravityview' ),
211
            ),
212
		);
213
214 1
		shuffle( $reasons );
215
216 1
		return $reasons;
217
    }
218
219
	/**
220
     * Display a feedback form when the plugin is uninstalled
221
     *
222
     * @since 1.17.5
223
     *
224
	 * @return string HTML of the uninstallation form
225
	 */
226 1
	public function uninstall_form() {
227 1
		ob_start();
228
229 1
		$user = wp_get_current_user();
230
		?>
231 1
    <style>
232
        #gv-reason-details {
233
            min-height: 100px;
234
        }
235
        .number-scale label {
236
            border: 1px solid #cccccc;
237
            padding: .5em .75em;
238
            margin: .1em;
239
        }
240
        #gv-uninstall-thanks p {
241
            font-size: 1.2em;
242
        }
243
        .scale-description ul {
244
            margin-bottom: 0;
245
            padding-bottom: 0;
246
        }
247
        .scale-description p.description {
248
            margin-top: 0!important;
249
            padding-top: 0!important;
250
        }
251
        .gv-form-field-wrapper {
252
            margin-top: 30px;
253
        }
254
    </style>
255
256
    <div class="gv-uninstall-form-wrapper" style="font-size: 110%; padding: 15px 0;">
257
        <script>
258
            jQuery( function( $ ) {
259
                $( '#gv-uninstall-feedback' ).on( 'change', function( e ) {
260
261
                    if ( ! $( e.target ).is( ':input' ) ) {
262
                        return;
263
                    }
264
                    var $textarea = $( '.gv-followup' ).find( 'textarea' );
265
                    var followup_text = $( e.target ).attr( 'data-followup' );
266
                    if( ! followup_text ) {
267
                        followup_text = $textarea.attr( 'data-default' );
268
                    }
269
270
                    $textarea.attr( 'placeholder', followup_text );
271
272
                } ).on( 'submit', function( e ) {
273
                    e.preventDefault();
274
275
                    $.post( $( this ).attr( 'action' ), $( this ).serialize() )
276
                        .done( function( data ) {
277
                            if ( 'success' !== data.status ) {
278
                                gv_feedback_append_error_message();
279
                            } else {
280
                                $( '#gv-uninstall-thanks' ).fadeIn();
281
                            }
282
                        })
283
                        .fail( function( data ) {
284
                            gv_feedback_append_error_message();
285
                        } )
286
                        .always( function() {
287
                            $( e.target ).remove();
288
                        } );
289
290
                    return false;
291
                });
292
293
                function gv_feedback_append_error_message() {
294
                    $( '#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>' );
295
                }
296
            });
297
        </script>
298
299
        <form id="gv-uninstall-feedback" method="post" action="https://hooks.zapier.com/hooks/catch/28670/6haevn/">
300
            <h2><?php esc_html_e( 'Why did you uninstall GravityView?', 'gravityview' ); ?></h2>
301
            <ul>
302
				<?php
303 1
                $reasons = $this->get_uninstall_reasons();
304 1
				foreach ( $reasons as $reason ) {
305 1
					printf( '<li><label><input name="reason" type="radio" value="other" data-followup="%s"> %s</label></li>', Utils::get( $reason, 'followup' ), Utils::get( $reason, 'label' ) );
306
				}
307
				?>
308 1
            </ul>
309
            <div class="gv-followup widefat">
310
                <p><strong><label for="gv-reason-details"><?php esc_html_e( 'Comments', 'gravityview' ); ?></label></strong></p>
311
                <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>
312
            </div>
313
            <div class="scale-description">
314
                <p><strong><?php esc_html_e( 'How likely are you to recommend GravityView?', 'gravityview' ); ?></strong></p>
315
                <ul class="inline">
316
					<?php
317 1
					$i = 0;
318 1
					while( $i < 11 ) {
319 1
						echo '<li class="inline number-scale"><label><input name="likely_to_refer" id="likely_to_refer_'.$i.'" value="'.$i.'" type="radio"> '.$i.'</label></li>';
320 1
						$i++;
321
					}
322
					?>
323 1
                </ul>
324
                <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>
325
            </div>
326
327
            <div class="gv-form-field-wrapper">
328
                <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>
329
            </div>
330
331
            <div class="submit">
332
                <input type="hidden" name="siteurl" value="<?php echo esc_url( get_bloginfo( 'url' ) ); ?>" />
333
                <input type="hidden" name="email" value="<?php echo esc_attr( $user->user_email ); ?>" />
334
                <input type="hidden" name="display_name" value="<?php echo esc_attr( $user->display_name ); ?>" />
335
                <input type="submit" value="<?php esc_html_e( 'Send Us Your Feedback', 'gravityview' ); ?>" class="button button-primary button-hero" />
336
            </div>
337
        </form>
338
339
        <div id="gv-uninstall-thanks" class="notice notice-large notice-updated below-h2" style="display:none;">
340
            <h3 class="notice-title"><?php esc_html_e( 'Thank you for using GravityView!', 'gravityview' ); ?></h3>
341
            <p><?php echo gravityview_get_floaty(); ?>
342
				<?php echo make_clickable( esc_html__( 'Your feedback helps us improve GravityView. If you have any questions or comments, email us: [email protected]', 'gravityview' ) ); ?>
343 1
            </p>
344
            <div class="wp-clearfix"></div>
345
        </div>
346
    </div>
347
		<?php
348 1
		$form = ob_get_clean();
349
350 1
		return $form;
351
	}
352
353 1
	public function app_settings_uninstall_tab() {
354 1
		if ( $this->maybe_uninstall() ) {
355
			parent::app_settings_uninstall_tab();
356
			return;
357
		}
358
359 1
		if ( ! ( $this->current_user_can_any( $this->_capabilities_uninstall ) && ( ! function_exists( 'is_multisite' ) || ! is_multisite() || is_super_admin() ) ) ) {
360
			return;
361
		}
362
363
		?>
364 1
		<script>
365
			jQuery( document ).on( 'click', 'a[rel="gv-uninstall-wrapper"]', function( e ) {
366
				e.preventDefault();
367
				jQuery( '#gv-uninstall-wrapper' ).slideToggle();
368
			} );
369
		</script>
370
371
		<a rel="gv-uninstall-wrapper" href="#gv-uninstall-wrapper" class="button button-large alignright button-danger">Uninstall GravityView</a>
372
373
		<div id="gv-uninstall-wrapper">
374
			<form action="" method="post">
375
				<?php wp_nonce_field( 'uninstall', 'gf_addon_uninstall' ) ?>
376 1
				<div class="delete-alert alert_red">
377
378
					<h3>
379
						<i class="fa fa-exclamation-triangle gf_invalid"></i> <?php esc_html_e( 'Delete all GravityView content and settings', 'gravityview' ); ?>
380 1
					</h3>
381
382
					<div class="gf_delete_notice">
383
						<?php echo $this->uninstall_warning_message() ?>
384 1
					</div>
385
386
					<?php
387 1
					echo '<input type="submit" name="uninstall" value="' . sprintf( esc_attr__( 'Uninstall %s', 'gravityview' ), $this->get_short_title() ) . '" class="button button-hero" onclick="return confirm( ' . json_encode( $this->uninstall_confirm_message() ) . ' );" onkeypress="return confirm( ' . json_encode( $this->uninstall_confirm_message() ) . ' );"/>';
388
					?>
389
390
				</div>
391
			</form>
392
		</div>
393
	<?php
394 1
	}
395
396 1
	public function app_settings_tab() {
397 1
	    parent::app_settings_tab();
398
399 1
		if ( $this->maybe_uninstall() ) {
400
            echo $this->uninstall_form();
401
		}
402 1
    }
403
404
	/**
405
	 * The Settings title
406
	 *
407
	 * @return string
408
	 */
409 1
	public function app_settings_title() {
410 1
		return null;
411
	}
412
413
	/**
414
	 * Prevent displaying of any icon
415
	 *
416
	 * @return string
417
	 */
418 1
	public function app_settings_icon() {
419 1
		return '&nbsp;';
420
	}
421
422
	/**
423
	 * Retrieve a setting.
424
	 *
425
	 * @deprecated Use \GV\Addon_Settings::get
426
	 * @param string $setting_name The setting key.
427
	 *
428
	 * @return mixed The setting or null
429
	 */
430 1
	public function get_app_setting( $setting_name ) {
431 1
		return $this->get( $setting_name );
432
	}
433
434
	/**
435
	 * Retrieve a setting.
436
	 *
437
	 * @param string $key The setting key.
438
	 * @param string $default A default if not found.
439
	 *
440
	 * @return mixed The setting value.
441
	 */
442 188
	public function get( $key, $default = null ) {
443
		/**
444
		 * Backward compatibility with Redux
445
		 */
446 188
		if ( $key === 'license' ) {
447
			return array(
448 2
				'license' => $this->get( 'license_key' ),
449 2
				'status' => $this->get( 'license_key_status' ),
450 2
				'response' => $this->get( 'license_key_response' ),
451
			);
452
		}
453
454 188
		if ( 'license_key' === $key && defined( 'GRAVITYVIEW_LICENSE_KEY' ) ) {
455
			return GRAVITYVIEW_LICENSE_KEY;
456
		}
457
458 188
		return Utils::get( $this->all(), $key, $default );
459
	}
460
461
	/**
462
	 * Get the setting for GravityView by name
463
	 *
464
	 * @deprecated Use gravityview()->plugin->settings->get()
465
	 * @param  string $key     Option key to fetch
466
	 *
467
	 * @return mixed
468
	 */
469 1
	static public function getSetting( $key ) {
470 1
		if ( gravityview()->plugin->settings instanceof Addon_Settings ) {
471 1
			return gravityview()->plugin->settings->get( $key );
472
		}
473
	}
474
475
	/**
476
	 * Get all settings.
477
	 *
478
	 * @deprecated Use \GV\Addon_Settings::all() or \GV\Addon_Settings::get()
479
	 *
480
	 * @return array The settings.
481
	 */
482 1
	public function get_app_settings() {
483 1
		return $this->all();
484
	}
485
486
	/**
487
	 * Get all the settings.
488
	 *
489
	 * @return array The settings.
490
	 */
491 188
	public function all() {
492 188
		$option_name  = 'gravityformsaddon_' . $this->_slug . '_app_settings';
493
494 188
		$option_value = get_option( $option_name, array() );
495
496 188
		return wp_parse_args( $option_value, $this->defaults() );
497
	}
498
499
	/**
500
	 * Default settings.
501
	 *
502
	 * @deprecated Use \GV\Addon_Settings::defaults()
503
	 *
504
	 * @return array The defaults.
505
	 */
506 1
	public function get_default_settings() {
507 1
		return $this->defaults();
508
	}
509
510
	/**
511
	 * Default settings.
512
	 *
513
	 * @return array The defaults.
514
	 */
515 188
	private function defaults() {
516
		$defaults = array(
517
			// Set the default license in wp-config.php
518 188
			'license_key'          => defined( 'GRAVITYVIEW_LICENSE_KEY' ) ? GRAVITYVIEW_LICENSE_KEY : '',
519 188
			'license_key_response' => '',
520 188
			'license_key_status'   => '',
521 188
			'support-email'        => get_bloginfo( 'admin_email' ),
522 188
			'no-conflict-mode'     => '1',
523 188
			'support_port'         => '1',
524 188
			'flexbox_search'       => '1',
525 188
			'rest_api'             => '0',
526 188
			'beta'                 => '0',
527
		);
528
529
		/**
530
		 * @filter `gravityview/settings/default` Filter default global settings.
531
		 * @param[in,out] array The defaults.
532
		 */
533 188
		return apply_filters( 'gravityview/settings/defaults', $defaults );
534
	}
535
536
	/***
537
	 * Renders the save button for settings pages
538
	 *
539
	 * @param array $field - Field array containing the configuration options of this field
540
	 * @param bool  $echo  = true - true to echo the output to the screen, false to simply return the contents as a string
541
	 *
542
	 * @return string The HTML
543
	 */
544 2
	public function as_html( $field, $echo = true ) {
545 2
		$field['type']  = ( isset( $field['type'] ) && in_array( $field['type'], array( 'submit','reset','button' ) ) ) ? $field['type'] : 'submit';
546
547 2
		$attributes    = $this->get_field_attributes( $field );
548 2
		$default_value = Utils::get( $field, 'value', Utils::get( $field, 'default_value' ) );
549 2
		$value         = $this->get( $field['name'], $default_value );
550
551
552 2
		$attributes['class'] = isset( $attributes['class'] ) ? esc_attr( $attributes['class'] ) : 'button-primary gfbutton';
553 2
		$name    = ( $field['name'] === 'gform-settings-save' ) ? $field['name'] : '_gaddon_setting_' . $field['name'];
554
555 2
		if ( empty( $value ) ) {
556 2
			$value = __( 'Update Settings', 'gravityview' );
557
		}
558
559 2
		$attributes = $this->get_field_attributes( $field );
560
561
		$html = '<input
562 2
                    type="' . $field['type'] . '"
563 2
                    name="' . esc_attr( $name ) . '"
564 2
                    value="' . $value . '" ' .
565 2
		        implode( ' ', $attributes ) .
566 2
		        ' />';
567
568 2
		if ( $echo ) {
569
			echo $html;
570
		}
571
572 2
		return $html;
573
	}
574
575
	/**
576
	 * @deprecated Use \GV\Addon_Settings::as_html
577
	 */
578 1
	public function settings_submit( $field, $echo = true ) {
579 1
		gravityview()->log->warning( '\GV\Addon_Settings::settings_submit has been deprecated for \GV\Addon_Settings::as_html' );
580 1
		return $this->as_html( $field, $echo );
581
	}
582
583
	/**
584
     * Check whether GravityView is being saved
585
     *
586
     * The generic is_save_postback() is true for all addons
587
     *
588
     * @since 2.0.8
589
     *
590
	 * @return bool
591
	 */
592 1
	public function is_save_postback() {
593 1
		return isset( $_POST['gform-settings-save'] ) && isset( $_POST['_gravityview_save_settings_nonce'] );
594
	}
595
596
	/**
597
	 * Display a notice if the plugin is inactive.
598
	 *
599
	 * @return void
600
	 */
601
	public function license_key_notice() {
602
603
	    if( $this->is_save_postback() ) {
604
		    $settings = $this->get_posted_settings();
605
		    $license_key = defined( 'GRAVITYVIEW_LICENSE_KEY' ) ? GRAVITYVIEW_LICENSE_KEY : \GV\Utils::get( $settings, 'license_key' );
606
		    $license_status = \GV\Utils::get( $settings, 'license_key_status', 'inactive' );
607
        } else {
608
		    $license_status = $this->get( 'license_key_status', 'inactive' );
609
		    $license_key    = $this->get( 'license_key' );
610
	    }
611
612
	    $license_id = empty( $license_key ) ? 'license' : $license_key;
613
614
		$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' );
615
616
		/** @internal Do not use! Will change without notice (pun slightly intended). */
617
		$message = apply_filters( 'gravityview/settings/license-key-notice', $message );
618
619
		/**
620
		 * I wanted to remove the period from after the buttons in the string,
621
		 * but didn't want to mess up the translation strings for the translators.
622
		 */
623
		$message = mb_substr( $message, 0, mb_strlen( $message ) - 1 );
624
		$title = __( 'Inactive License', 'gravityview');
625
		$status = '';
626
		$update_below = false;
627
		$primary_button_link = admin_url( 'edit.php?post_type=gravityview&amp;page=gravityview_settings' );
628
629
        switch ( $license_status ) {
630
			/** @since 1.17 */
631
			case 'expired':
632
				$title = __( 'Expired License', 'gravityview' );
633
				$status = 'expired';
634
				$message = $this->get_license_handler()->strings( 'expired', $this->get( 'license_key_response' ) );
635
				break;
636
			case 'invalid':
637
				$title = __( 'Invalid License', 'gravityview' );
638
				$status = __( 'is invalid', 'gravityview' );
639
				break;
640
			case 'deactivated':
641
				$status = __( 'is inactive', 'gravityview' );
642
				$update_below = __( 'Activate your license key below.', 'gravityview' );
643
				break;
644
			/** @noinspection PhpMissingBreakStatementInspection */
645
			case '':
646
				$license_status = 'site_inactive';
647
				// break intentionally left blank
648
			case 'inactive':
649
			case 'site_inactive':
650
				$status = __( 'has not been activated', 'gravityview' );
651
				$update_below = __( 'Activate your license key below.', 'gravityview' );
652
				break;
653
		}
654
		$url = 'https://gravityview.co/pricing/?utm_source=admin_notice&utm_medium=admin&utm_content='.$license_status.'&utm_campaign=Admin%20Notice';
655
656
		// Show a different notice on settings page for inactive licenses (hide the buttons)
657
		if ( $update_below && gravityview()->request->is_admin( '', 'settings' ) ) {
0 ignored issues
show
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...
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...
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...
658
			$message = sprintf( $message, $status, '<div class="hidden">', '', '', '</div><a href="#" onclick="jQuery(\'#license_key\').focus(); return false;">' . $update_below . '</a>' );
659
		} else {
660
			$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>' );
661
		}
662
663
		if ( empty( $status ) ) {
664
			return;
665
		}
666
667
        \GravityView_Admin_Notices::add_notice( array(
668
            'message' => $message,
669
            'class'   => 'notice notice-warning',
670
            'title'   => $title,
671
            'cap'     => 'gravityview_edit_settings',
672
            'dismiss' => sha1( $license_status . '_' . $license_id . '_' . date( 'z' ) ), // Show every day, instead of every 8 weeks (which is the default)
673
        ) );
674
	}
675
676
	/**
677
	 * Allow public access to the GV\License_Handler class
678
	 * @since 1.7.4
679
	 *
680
	 * @return \GV\License_Handler
681
	 */
682 1
	public function get_license_handler() {
683 1
		return $this->License_Handler;
684
	}
685
686
	/**
687
     * Add tooltip script to app settings page. Not enqueued by Gravity Forms for some reason.
688
     *
689
     * @since 1.21.5
690
     *
691
     * @see GFAddOn::scripts()
692
     *
693
	 * @return array Array of scripts
694
	 */
695 23
	public function scripts() {
696 23
		$scripts = parent::scripts();
697
698 23
		$scripts[] = array(
699
			'handle'  => 'gform_tooltip_init',
700
			'enqueue' => array(
701
                array(
702
			        'admin_page' => array( 'app_settings' )
703
                )
704
            )
705
		);
706
707 23
		return $scripts;
708
	}
709
710
	/**
711
	 * Register styles in the app admin page
712
	 * @return array
713
	 */
714 23
	public function styles() {
715 23
		$styles = parent::styles();
716
717 23
		$styles[] = array(
718 23
			'handle'  => 'gravityview_settings',
719 23
			'src'     => plugins_url( 'assets/css/admin-settings.css', GRAVITYVIEW_FILE ),
720 23
			'version' => Plugin::$version,
721
			'deps' => array(
722
                'gform_admin',
723
				'gaddon_form_settings_css',
724
                'gform_tooltip',
725
                'gform_font_awesome',
726
			),
727
			'enqueue' => array(
728
				array( 'admin_page' => array(
729
					'app_settings',
730
				) ),
731
			)
732
		);
733
734 23
		return $styles;
735
	}
736
737
	/**
738
	 * Add Settings link to GravityView menu
739
	 * @return void
740
	 */
741 1
	public function create_app_menu() {
742
		/**
743
		 * If not multisite, always show.
744
		 * If multisite and the plugin is network activated, show; we need to register the submenu page for the Network Admin settings to work.
745
		 * If multisite and not network admin, we don't want the settings to show.
746
		 * @since 1.7.6
747
		 */
748 1
		$show_submenu = ( ! is_multisite() ) ||  is_main_site() || ( ! gravityview()->plugin->is_network_activated() ) || ( is_network_admin() && gravityview()->plugin->is_network_activated() );
749
750
		/**
751
		 * Override whether to show the Settings menu on a per-blog basis.
752
		 * @since 1.7.6
753
		 * @param bool $hide_if_network_activated Default: true
754
		 */
755 1
		$show_submenu = apply_filters( 'gravityview/show-settings-menu', $show_submenu );
756
757 1
		if ( $show_submenu ) {
758 1
			add_submenu_page( 'edit.php?post_type=gravityview', __( 'Settings', 'gravityview' ), __( 'Settings', 'gravityview' ), $this->_capabilities_app_settings, $this->_slug . '_settings', array( $this, 'app_tab_page' ) );
759
		}
760 1
	}
761
762
	/**
763
	 * Gets the required indicator
764
	 * Gets the markup of the required indicator symbol to highlight fields that are required
765
	 *
766
	 * @param $field - The field meta.
767
	 *
768
	 * @return string - Returns markup of the required indicator symbol
769
	 */
770 1
	public function get_required_indicator( $field ) {
771 1
		return '<span class="required" title="' . esc_attr__( 'Required', 'gravityview' ) . '">*</span>';
772
	}
773
774
	/**
775
	 * Specify the settings fields to be rendered on the plugin settings page
776
	 *
777
	 * @return array
778
	 */
779 1
	public function app_settings_fields() {
780 1
		$default_settings = $this->defaults();
781
782 1
		$disabled_attribute = \GVCommon::has_cap( 'gravityview_edit_settings' ) ? false : 'disabled';
783
784
		$fields = array(
785
			array(
786 1
				'name' => 'gv_header',
787
				'value' => '',
788
				'type' => 'html',
789
			),
790
			array(
791 1
				'name' => 'license_key',
792 1
				'required' => ! defined( 'GRAVITYVIEW_LICENSE_KEY' ) || ! GRAVITYVIEW_LICENSE_KEY,
793 1
				'label' => __( 'License Key', 'gravityview' ),
794 1
				'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' ) ),
0 ignored issues
show
Deprecated Code introduced by
The method GV\Addon_Settings::get_app_setting() has been deprecated with message: Use \GV\Addon_Settings::get

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
795 1
				'type' => 'edd_license',
796 1
				'disabled' => ( defined( 'GRAVITYVIEW_LICENSE_KEY' )  && GRAVITYVIEW_LICENSE_KEY ),
797 1
				'data-pending-text' => __( 'Verifying license&hellip;', 'gravityview' ),
798 1
				'default_value' => $default_settings['license_key'],
799 1
				'class' => ( '' == $this->get( 'license_key' ) ) ? 'activate code regular-text edd-license-key' : 'deactivate code regular-text edd-license-key',
800
			),
801
			array(
802 1
				'name' => 'license_key_response',
803 1
				'default_value' => $default_settings['license_key_response'],
804 1
				'type' => 'hidden',
805
			),
806
			array(
807 1
				'name' => 'license_key_status',
808 1
				'default_value' => $default_settings['license_key_status'],
809 1
				'type' => 'hidden',
810
			),
811
			array(
812 1
				'name' => 'support-email',
813 1
				'type' => 'text',
814 1
				'validate' => 'email',
815 1
				'default_value' => $default_settings['support-email'],
816 1
				'label' => __( 'Support Email', 'gravityview' ),
817 1
				'description' => __( 'In order to provide responses to your support requests, please provide your email address.', 'gravityview' ),
818 1
				'class' => 'code regular-text',
819
			),
820
			/**
821
			 * @since 1.15 Added Support Port support
822
			 */
823
			array(
824 1
				'name' => 'support_port',
825 1
				'type' => 'radio',
826 1
				'label' => __( 'Show Support Port?', 'gravityview' ),
827 1
				'default_value' => $default_settings['support_port'],
828 1
				'horizontal' => 1,
829
				'choices' => array(
830
					array(
831 1
						'label' => _x( 'Show', 'Setting: Show or Hide', 'gravityview' ),
832 1
						'value' => '1',
833
					),
834
					array(
835 1
						'label' => _x( 'Hide', 'Setting: Show or Hide', 'gravityview' ),
836 1
						'value' => '0',
837
					),
838
				),
839 1
				'tooltip' => '<p><img src="' . esc_url_raw( plugins_url( 'assets/images/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>',
840 1
				'description' => __( 'Show the Support Port on GravityView pages?', 'gravityview' ),
841
			),
842
			array(
843 1
				'name' => 'no-conflict-mode',
844 1
				'type' => 'radio',
845 1
				'label' => __( 'No-Conflict Mode', 'gravityview' ),
846 1
				'default_value' => $default_settings['no-conflict-mode'],
847 1
				'horizontal' => 1,
848
				'choices' => array(
849
					array(
850 1
						'label' => _x( 'On', 'Setting: On or off', 'gravityview' ),
851 1
						'value' => '1',
852
					),
853
					array(
854 1
						'label' => _x( 'Off', 'Setting: On or off', 'gravityview' ),
855 1
						'value' => '0',
856
					),
857
				),
858 1
				'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' ),
859
			),
860
			/**
861
			 * @since 2.0 Added REST API
862
			 */
863 1
			gravityview()->plugin->supports( Plugin::FEATURE_REST ) ?
864
				array(
865 1
					'name' => 'rest_api',
866 1
					'type' => 'radio',
867 1
					'label' => __( 'REST API', 'gravityview' ),
868 1
					'default_value' => $default_settings['rest_api'],
869 1
					'horizontal' => 1,
870
					'choices' => array(
871
						array(
872 1
							'label' => _x( 'Enable', 'Setting: Enable or Disable', 'gravityview' ),
873 1
							'value' => '1',
874
						),
875
						array(
876 1
							'label' => _x( 'Disable', 'Setting: Enable or Disable', 'gravityview' ),
877 1
							'value' => '0',
878
						),
879
					),
880 1
					'description' => __( 'Enable View and Entry access via the REST API? Regular per-View restrictions apply (private, password protected, etc.).', 'gravityview' ),
881 1
					'tooltip' => '<p>' . esc_html__( 'If you are unsure, choose the Disable setting.', 'gravityview' ) . '</p>',
882
				) : array(),
883
			array(
884 1
				'name' => 'beta',
885 1
				'type' => 'checkbox',
886 1
				'label' => __( 'Become a Beta Tester', 'gravityview' ),
887 1
				'default_value' => $default_settings['beta'],
888 1
				'horizontal' => 1,
889
				'choices' => array(
890
					array(
891 1
						'label' => esc_html__( 'Show me beta versions if they are available.', 'gravityview' ),
892 1
						'value' => '1',
893 1
                        'name'  => 'beta',
894
					),
895
				),
896 1
				'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' ),
897
			),
898
		);
899
900 1
		$fields = array_filter( $fields, 'count' );
901
902
		/**
903
		 * @filter `gravityview_settings_fields` Filter the settings fields.
904
		 * @param array $fields The fields to filter.
905
		 * @deprecated Use `gravityview/settings/fields`.
906
		 */
907 1
		$fields = apply_filters( 'gravityview_settings_fields', $fields );
908
909
		/**
910
		 * @filter `gravityview/settings/fields` Filter the settings fields.
911
		 * @param array $fields The fields to filter.
912
		 */
913 1
		$fields = apply_filters( 'gravityview/settings/fields', $fields );
914
915
		/**
916
		 * Redux backward compatibility
917
		 * @since 1.7.4
918
		 */
919 1
		foreach ( $fields as &$field ) {
920 1
			$field['name']          = isset( $field['name'] ) ? $field['name'] : Utils::get( $field, 'id' );
921 1
			$field['label']         = isset( $field['label'] ) ? $field['label'] : Utils::get( $field, 'title' );
922 1
			$field['default_value'] = isset( $field['default_value'] ) ? $field['default_value'] : Utils::get( $field, 'default' );
923 1
			$field['description']   = isset( $field['description'] ) ? $field['description'] : Utils::get( $field, 'subtitle' );
924
925 1
			if ( $disabled_attribute ) {
926
				$field['disabled']  = $disabled_attribute;
927
			}
928
929 1
			if ( empty( $field['disabled'] ) ) {
930 1
				unset( $field['disabled'] );
931
            }
932
		}
933
934
        $sections = array(
935
            array(
936 1
                'description' => sprintf( '<span class="version-info description">%s</span>', sprintf( __( 'You are running GravityView version %s', 'gravityview' ), Plugin::$version ) ),
937 1
                'fields'      => $fields,
938
            )
939
        );
940
941
        // custom 'update settings' button
942
        $button = array(
943 1
            'class' => 'button button-primary button-hero',
944
            'type' => 'save',
945
        );
946
947 1
		if ( $disabled_attribute ) {
948
			$button['disabled'] = $disabled_attribute;
949
		}
950
951
        /**
952
         * @filter `gravityview/settings/extension/sections` Modify the GravityView settings page
953
         * Extensions can tap in here to insert their own section and settings.
954
         * <code>
955
         *   $sections[] = array(
956
         *      'title' => __( 'GravityView My Extension Settings', 'gravityview' ),
957
         *      'fields' => $settings,
958
         *   );
959
         * </code>
960
         * @param array $extension_settings Empty array, ready for extension settings!
961
         */
962 1
        $extension_sections = apply_filters( 'gravityview/settings/extension/sections', array() );
963
964
		// If there are extensions, add a section for them
965 1
		if ( ! empty( $extension_sections ) ) {
966
967
			if( $disabled_attribute ) {
968
				foreach ( $extension_sections as &$section ) {
969
					foreach ( $section['fields'] as &$field ) {
970
						$field['disabled'] = $disabled_attribute;
971
					}
972
				}
973
			}
974
975
            $k = count( $extension_sections ) - 1 ;
976
            $extension_sections[ $k ]['fields'][] = $button;
977
			$sections = array_merge( $sections, $extension_sections );
978
		} else {
979
            // add the 'update settings' button to the general section
980 1
            $sections[0]['fields'][] = $button;
981
        }
982
983 1
		return $sections;
984
	}
985
986
	/**
987
	 * Updates app settings with the provided settings
988
	 *
989
	 * Same as the GFAddon, except it returns the value from update_option()
990
	 *
991
	 * @param array $settings - App settings to be saved
992
	 *
993
	 * @deprecated Use \GV\Addon_Settings::set or \GV\Addon_Settings::update
994
	 *
995
	 * @return boolean False if value was not updated and true if value was updated.
996
	 */
997
	public function update_app_settings( $settings ) {
998
		return $this->update( $settings );
999
	}
1000
1001
	/**
1002
	 * Sets a subset of settings.
1003
	 *
1004
	 * @param array|string An array of settings to update, or string (key) and $value to update one setting.
1005
	 * @param mixed $value A value if $settings is string (key). Default: null.
1006
	 */
1007 4
	public function set( $settings, $value = null ) {
1008 4
		if ( is_string( $settings ) ) {
1009 2
			$settings = array( $settings => $value );
1010
		}
1011 4
		$settings = wp_parse_args( $settings, $this->all() );
1012 4
		return update_option( 'gravityformsaddon_' . $this->_slug . '_app_settings', $settings );
1013
	}
1014
1015
	/**
1016
	 * Updates settings.
1017
	 *
1018
	 * @param array $settings The settings array.
1019
	 *
1020
	 * @return boolean False if value was not updated and true if value was updated.
1021
	 */
1022 1
	public function update( $settings ) {
1023 1
		return update_option( 'gravityformsaddon_' . $this->_slug . '_app_settings', $settings );
1024
	}
1025
1026
	/**
1027
	 * Register the settings field for the EDD License field type
1028
	 * @param array $field
1029
	 * @param bool $echo Whether to echo the
1030
	 *
1031
	 * @return string
1032
	 */
1033 1
	protected function settings_edd_license( $field, $echo = true ) {
1034
1035 1
	    if ( defined( 'GRAVITYVIEW_LICENSE_KEY' ) && GRAVITYVIEW_LICENSE_KEY ) {
1036
		    $field['input_type'] = 'password';
1037
        }
1038
1039 1
		$text = $this->settings_text( $field, false );
1040
1041 1
		$activation = $this->License_Handler->settings_edd_license_activation( $field, false );
1042
1043 1
		$return = $text . $activation;
1044
1045 1
		if ( $echo ) {
1046 1
			echo $return;
1047
		}
1048
1049 1
		return $return;
1050
	}
1051
1052
	/**
1053
	 * Allow pure HTML settings row
1054
     *
1055
     * @since 2.0.6
1056
     *
1057
	 * @param array $field
1058
	 * @param bool $echo Whether to echo the
1059
	 *
1060
	 * @return string
1061
	 */
1062 1
	protected function settings_html( $field, $echo = true ) {
1063
1064 1
		$return = \GV\Utils::get( $field, 'value', '' );
1065
1066 1
		if ( $echo ) {
1067 1
			echo $return;
1068
		}
1069
1070 1
		return $return;
1071
	}
1072
1073
	/**
1074
	 * No <th> needed for pure HTML settings row
1075
	 *
1076
	 * @since 2.0.6
1077
	 *
1078
	 * @param array $field
1079
	 *
1080
	 * @return void
1081
	 */
1082 1
	public function single_setting_row_html( $field ) {
1083
		?>
1084
1085
        <tr id="gaddon-setting-row-<?php echo esc_attr( $field['name'] ); ?>">
1086
            <td colspan="2">
1087
				<?php $this->single_setting( $field ); ?>
1088 1
            </td>
1089
        </tr>
1090
1091
		<?php
1092 1
	}
1093
1094
	/**
1095
	 * Allow customizing the Save field parameters
1096
	 *
1097
	 * @param array $field
1098
	 * @param bool $echo
1099
	 *
1100
	 * @return string
1101
	 */
1102 1
	public function settings_save( $field, $echo = true ) {
1103 1
		$field['type']  = 'submit';
1104 1
		$field['name']  = 'gform-settings-save';
1105 1
		$field['class'] = isset( $field['class'] ) ? $field['class'] : 'button-primary gfbutton';
1106 1
		$field['value'] = Utils::get( $field, 'value', __( 'Update Settings', 'gravityview' ) );
1107
1108 1
		$output = $this->settings_submit( $field, false );
0 ignored issues
show
Deprecated Code introduced by
The method GV\Addon_Settings::settings_submit() has been deprecated with message: Use \GV\Addon_Settings::as_html

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
1109
1110 1
		ob_start();
1111 1
		$this->app_settings_uninstall_tab();
1112 1
		$output .= ob_get_clean();
1113
1114 1
		if ( $echo ) {
1115 1
			echo $output;
1116
		}
1117
1118 1
		return $output;
1119
	}
1120
1121
	/**
1122
     * Keep GravityView styling for `$field['description']`, even though Gravity Forms added support for it
1123
     *
1124
     * Converts `$field['description']` to `$field['gv_description']`
1125
     * Converts `$field['subtitle']` to `$field['description']`
1126
     *
1127
     * @see \GV\Addon_Settings::single_setting_label Converts `gv_description` back to `description`
1128
     * @see http://share.gravityview.co/P28uGp/2OIRKxog for image that shows subtitle vs description
1129
     *
1130
     * @since 1.21.5.2
1131
     *
1132
	 * @param array $field
1133
     *
1134
     * @return void
1135
	 */
1136 1
	public function single_setting_row( $field ) {
1137 1
		$field['gv_description'] = Utils::get( $field, 'description' );
1138 1
		$field['description']    = Utils::get( $field, 'subtitle' );
1139 1
		parent::single_setting_row( $field );
1140 1
	}
1141
1142
	/**
1143
	 * The same as the parent, except added support for field descriptions
1144
	 * @inheritDoc
1145
	 * @param $field array
1146
	 */
1147 1
	public function single_setting_label( $field ) {
1148 1
		parent::single_setting_label( $field );
1149 1
		if ( $description = Utils::get( $field, 'gv_description' ) ) {
1150 1
			echo '<span class="description">'. $description .'</span>';
1151
		}
1152 1
	}
1153
1154
	/**
1155
	 * Check for the `gravityview_edit_settings` capability before saving plugin settings.
1156
	 * Gravity Forms says you're able to edit if you're able to view settings. GravityView allows two different permissions.
1157
	 *
1158
	 * @since 1.15
1159
	 * @return void
1160
	 */
1161 1
	public function maybe_save_app_settings() {
1162
1163 1
		if ( $this->is_save_postback() ) {
1164
			if ( ! \GVCommon::has_cap( 'gravityview_edit_settings' ) ) {
1165
				$_POST = array(); // If you don't reset the $_POST array, it *looks* like the settings were changed, but they weren't
1166
				\GFCommon::add_error_message( __( 'You don\'t have the ability to edit plugin settings.', 'gravityview' ) );
1167
				return;
1168
			}
1169
		}
1170 1
		parent::maybe_save_app_settings();
1171 1
	}
1172
1173
	/**
1174
	 * When the settings are saved, make sure the license key matches the previously activated key
1175
	 *
1176
	 * @return array settings from parent::get_posted_settings(), with `license_key_response` and `license_key_status` potentially unset
1177
	 */
1178 1
	public function get_posted_settings() {
1179 1
		$posted_settings = parent::get_posted_settings();
1180
1181 1
		$local_key = Utils::get( $posted_settings, 'license_key' );
1182
1183 1
		if ( ! $local_key && defined( 'GRAVITYVIEW_LICENSE_KEY' ) ) {
1184
			$local_key = GRAVITYVIEW_LICENSE_KEY;
1185
		}
1186
1187 1
		$response_key = Utils::get( $posted_settings, 'license_key_response/license_key' );
1188
1189 1
		static $added_message = false;
1190
1191
		// If the posted key doesn't match the activated/deactivated key (set using the Activate License button, AJAX response),
1192
		// then we assume it's changed. If it's changed, unset the status and the previous response.
1193 1
		if ( ! $added_message && ( $local_key !== $response_key ) ) {
1194
1195
			unset( $posted_settings['license_key_response'] );
1196
			unset( $posted_settings['license_key_status'] );
1197
1198
			\GFCommon::add_error_message( __('The license key you entered has been saved, but not activated. Please activate the license.', 'gravityview' ) );
1199
1200
			$added_message = true;
1201
		}
1202 1
		return $posted_settings;
1203
	}
1204
}
1205