Completed
Pull Request — develop (#1491)
by Zack
07:40
created

License_Handler::license_call()   F

Complexity

Conditions 18
Paths 312

Size

Total Lines 70

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 29
CRAP Score 18.5768

Importance

Changes 0
Metric Value
cc 18
nc 312
nop 2
dl 0
loc 70
ccs 29
cts 33
cp 0.8788
crap 18.5768
rs 2.6333
c 0
b 0
f 0

How to fix   Long Method    Complexity   

Long Method

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

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

Commonly applied refactorings include:

1
<?php
2
namespace GV;
3
4
/** If this file is called directly, abort. */
5
if ( ! defined( 'GRAVITYVIEW_DIR' ) ) {
6
	die();
7
}
8
9
/**
10
 * The \GV\License_Handler class.
11
 *
12
 * Handles everything licensing. Ka-ching!
13
 */
14
class License_Handler {
0 ignored issues
show
Coding Style introduced by
Since you have declared the constructor as private, maybe you should also declare the class as final.
Loading history...
15
	/**
16
	 * @var \GV\Addon_Settings The global addon settings binding.
17
	 */
18
	private $settings;
19
20
	const name = 'GravityView';
21
	const author = 'Katz Web Services, Inc.';
22
	const url = 'https://gravityview.co';
23
24
	/**
25
	 * Post ID on gravityview.co
26
	 * @since 1.15
27
	 */
28
	const item_id = 17;
29
30
	/**
31
	 * Name of the transient used to store license status for GV
32
	 * @since 1.17
33
	 */
34
	const status_transient_key = 'gravityview_edd-activate_valid';
35
36
	/**
37
	 * @var string Key used to store active GravityView/Gravity Forms plugin data
38
	 * @since 1.15
39
	 */
40
	const related_plugins_key = 'gravityview_related_plugins';
41
42
	/** @var \GV\EDD_SL_Plugin_Updater */
43
	private $EDD_SL_Plugin_Updater;
44
45
	/**
46
	 * @var \GV\License_Handler
47
	 */
48
	private static $__instance;
49
50 1
	private function __construct( $settings ) {
51
52 1
		$this->settings = $settings;
53
54 1
		if ( ! $this->settings instanceof Addon_Settings ) {
55
			$this->settings = gravityview()->plugin->settings;
56
		}
57
58 1
		add_action( 'admin_init', array( $this, 'setup_edd' ), 0 );
59 1
		add_action( 'wp_ajax_gravityview_license', array( $this, 'license_call' ) );
60 1
		add_action( 'admin_init', array( $this, 'refresh_license_status' ) );
61 1
		add_action( 'admin_init', array( $this, 'check_license' ) );
62 1
		add_action( 'update_option_active_plugins', array( $this, 'flush_related_plugins_transient' ) );
63 1
		add_action( 'update_option_active_sitewide_plugins', array( $this, 'flush_related_plugins_transient' ) );
64 1
	}
65
66
	/**
67
	 * @return \GV\License_Handler The global instance.
68
	 */
69 2
	public static function get( $settings = null ) {
70 2
		if ( ! self::$__instance ) {
71 1
			self::$__instance = new self( $settings );
72
		}
73 2
		return self::$__instance;
74
	}
75
76
	/**
77
	 * Generate the array of settings passed to the EDD license call
78
	 *
79
	 * @since 1.7.4
80
	 *
81
	 * @param string $action The action to send to edd, such as `check_license`
82
	 * @param string $license The license key to have passed to EDD
83
	 *
84
	 * @return array
85
	 */
86 1
	private function _get_edd_settings( $action = '', $license = '' ) {
87
88
		// retrieve our license key from the DB
89 1
		$license_key = empty( $license ) ? trim( $this->settings->get( 'license_key' ) ) : $license;
90
91
		$settings = array(
92 1
			'version'   => Plugin::$version,
93 1
			'license'   => $license_key,
94 1
			'item_name' => self::name,
95 1
			'item_id'   => self::item_id,
96 1
			'author'    => self::author,
97 1
			'language'  => get_locale(),
98 1
			'url'       => home_url(),
99 1
		    'beta'      => $this->settings->get( 'beta' ),
100
		);
101
102 1
		if ( ! empty( $action ) ) {
103 1
			$settings['edd_action'] = esc_attr( $action );
104
		}
105
106 1
		return array_map( 'urlencode', $settings );
107
	}
108
109
	/**
110
	 * Include the EDD plugin updater class, if not exists
111
	 *
112
	 * @since 1.7.4
113
	 * @since 1.21.5.3 Changed visibility of method to public
114
	 *
115
	 * @return void
116
	 */
117 1
	public function setup_edd() {
118 1
		if ( ! class_exists( '\GV\EDD_SL_Plugin_Updater' ) ) {
119 1
			require_once gravityview()->plugin->dir( 'future/lib/EDD_SL_Plugin_Updater.php' );
120
		}
121
122
		// setup the updater
123 1
		$this->EDD_SL_Plugin_Updater = new EDD_SL_Plugin_Updater(
124 1
			self::url,
125 1
			GRAVITYVIEW_FILE,
126 1
			$this->_get_edd_settings()
127
		);
128 1
	}
129
130
	/**
131
	 * Perform the call to EDD based on the AJAX call or passed data
132
	 *
133
	 * @since 1.7.4
134
	 *
135
	 * @param array $array {
136
	 * @type string $license The license key
137
	 * @type string $edd_action The EDD action to perform, like `check_license`
138
	 * @type string $field_id The ID of the field to check
139
	 * @type boolean $update Whether to update plugin settings. Prevent updating the data by setting an `update` key to false
140
	 * @type string $format If `object`, return the object of the license data. Else, return the JSON-encoded object
141
	 * }
142
	 * @param boolean $cap_check Require `gravityview_edit_settings` capability from current user.
143
	 *
144
	 * @return mixed|string|void
145
	 */
146 1
	public function license_call( $array = array(), $cap_check = true ) {
147
148 1
		$is_ajax = ( defined( 'DOING_AJAX' ) && DOING_AJAX );
149 1
		$data = empty( $array ) ? Utils::_POST( 'data', array() ) : $array;
150
151 1
		$data = wp_parse_args( $data, array(
152 1
			'license' => '',
153
			'edd_action' => '',
154
			'field_id' => '',
155
			'update' => '',
156
			'format' => 'json',
157
		) );
158
159 1
		if ( $is_ajax && empty( $data['license'] ) ) {
160
			die( -1 );
161
		}
162
163
		// If the user isn't allowed to edit settings, show an error message
164 1
		if ( $cap_check && ! \GVCommon::has_cap( 'gravityview_edit_settings' ) ) {
165 1
			$license_data = new \stdClass();
166 1
			$license_data->error = 'capability';
167 1
			$license_data->message = $this->get_license_message( $license_data );
168 1
			$json = json_encode( $license_data );
169
		} else {
170 1
			$license      = esc_attr( Utils::get( $data, 'license' ) );
171 1
			$license_data = $this->_license_get_remote_response( $data, $license );
172
173
			// Empty is returned when there's an error.
174 1
			if ( empty( $license_data ) ) {
175 1
				if ( $is_ajax ) {
176
					exit( json_encode( array() ) );
177
				} else { // Non-ajax call
178 1
					return json_encode( array() );
179
				}
180
			}
181
182 1
			$license_data->details = $this->license_details( $license_data );
183 1
			$license_data->message = $this->get_license_message( $license_data );
184
185 1
			$json = json_encode( $license_data );
186
187 1
			$update_license = Utils::get( $data, 'update' ) || 'gravityview_license' === Utils::_POST('action');
188
189 1
			$is_check_action_button = ( 'check_license' === Utils::get( $data, 'edd_action' ) && defined( 'DOING_AJAX' ) && DOING_AJAX );
190
191 1
			do_action('gravityview/admin_installer/delete_downloads_data', true );
192
193 1
			if ( $is_check_action_button ) {
194
				delete_transient( self::status_transient_key );
195
196
			// Failed is the response from trying to de-activate a license and it didn't work.
197
			// This likely happened because people entered in a different key and clicked "Deactivate",
198
			// meaning to deactivate the original key. We don't want to save this response, since it is
199
			// most likely a mistake.
200 1
			} else if ( $license_data->license !== 'failed' && $update_license ) {
201
202 1
				if ( ! empty( $data['field_id'] ) ) {
203 1
					set_transient( self::status_transient_key, $license_data, DAY_IN_SECONDS );
204
				}
205
206 1
				$this->license_call_update_settings( $license_data, $data );
207
			}
208
		}
209
210 1
		if ( $is_ajax ) {
211
			exit( $json );
212
		} else { // Non-ajax call
213 1
			return ( Utils::_GET( 'format', Utils::get( $data, 'format' ) ) === 'object' ) ? $license_data : $json;
214
		}
215
	}
216
217
	/**
218
	 * Generate the status message displayed in the license field
219
	 *
220
	 * @since 1.7.4
221
	 * @param $license_data
222
	 *
223
	 * @return string
224
	 */
225 2
	private function get_license_message( $license_data ) {
226 2
		if ( empty( $license_data ) ) {
227 2
			$message = '';
228
		} else {
229 1
			if( ! empty( $license_data->error ) ) {
230 1
				$class = 'error';
231 1
				$string_key = $license_data->error;
232 1
			} else { $class = $license_data->license;
233 1
				$string_key = $license_data->license;
234
			}
235
236 1
			$message = sprintf( '<p><strong>%s: %s</strong></p>', $this->strings( 'status' ), $this->strings( $string_key, $license_data ) );
237
238 1
			$message = $this->generate_license_box( $message, $class );
239
		}
240
241 2
		return $message;
242
	}
243
244
	/**
245
	 * Allow pure HTML in settings fields
246
	 *
247
	 * @since 1.17
248
	 *
249
	 * @param array $response License response
250
	 *
251
	 * @return string `html` key of the $field
252
	 */
253 2
	public function license_details( $response = array() ) {
254
255 2
		$response = (array) $response;
256
257 2
		$return = '';
258 2
		$wrapper = '<span class="gv-license-details" aria-live="polite" aria-busy="false">%s</span>';
259
260 2
		if ( ! empty( $response['license_key'] ) ) {
261 1
			$return .= '<h3>' . esc_html__( 'License Details:', 'gravityview' ) . '</h3>';
262
263 1
			if ( in_array( Utils::get( $response, 'license' ), array( 'invalid', 'deactivated' ) ) ) {
264 1
				$return .= $this->strings( $response['license'], $response );
265 1
			} elseif ( ! empty( $response['license_name'] ) ) {
266
				$response_keys = array(
267 1
					'license_name'   => '',
268
					'license_limit'  => '',
269
					'customer_name'  => '',
270
					'customer_email' => '',
271
					'site_count'     => '',
272
					'expires'        => '',
273
					'upgrades'       => ''
274
				);
275
276
				// Make sure all the keys are set
277 1
				$response = wp_parse_args( $response, $response_keys );
278
279 1
				$login_link    = sprintf( '<a href="%s" class="howto" rel="external">%s</a>', esc_url( sprintf( 'https://gravityview.co/wp-login.php?username=%s', $response['customer_email'] ) ), esc_html__( 'Access your GravityView account', 'gravityview' ) );
280 1
				$local_text    = ( ! empty( $response['is_local'] ) ? '<span class="howto">' . __( 'This development site does not count toward license activation limits', 'gravityview' ) . '</span>' : '' );
281 1
				$license_limit = empty( $response['license_limit'] ) ? __( 'Unlimited', 'gravityview' ) : (int) $response['license_limit'];
282
283
				$details    = array(
284 1
					'license'     => sprintf( esc_html__( 'License level: %s', 'gravityview' ), esc_html( $response['license_name'] ), esc_html( $response['license_limit'] ) ),
285 1
					'licensed_to' => sprintf( esc_html_x( 'Licensed to: %1$s (%2$s)', '1: Customer name; 2: Customer email', 'gravityview' ), esc_html__( $response['customer_name'], 'gravityview' ), esc_html__( $response['customer_email'], 'gravityview' ) ) . $login_link,
286 1
					'activations' => sprintf( esc_html__( 'Activations: %d of %s sites', 'gravityview' ), intval( $response['site_count'] ), esc_html( $license_limit ) ) . $local_text,
287 1
					'expires'     => 'lifetime' === $response['expires'] ? '' : sprintf( esc_html__( 'Renew on: %s', 'gravityview' ), date_i18n( get_option( 'date_format' ), strtotime( $response['expires'] ) - DAY_IN_SECONDS ) ),
288 1
					'upgrade'     => $this->get_upgrade_html( $response['upgrades'] ),
289
				);
290
291 1
				if ( ! empty( $response['error'] ) && 'expired' === $response['error'] ) {
292
					unset( $details['upgrade'] );
293
					$details['expires'] = '<div class="error inline"><p>' . $this->strings( 'expired', $response ) . '</p></div>';
294
				}
295
296 1
				$return .= '<ul><li>' . implode( '</li><li>', array_filter( $details ) ) . '</li></ul>';
297
			}
298
		}
299
300 2
		return sprintf( $wrapper, $return );
301
	}
302
303
	/**
304
	 * Display possible upgrades for a license
305
	 *
306
	 * @since 1.17
307
	 *
308
	 * @param array $upgrades Array of upgrade paths, returned from the GV website
309
	 *
310
	 * @return string HTML list of upgrades available for the current license
311
	 */
312 1
	private function get_upgrade_html( $upgrades ) {
313
314 1
		$output = '';
315
316 1
		if ( ! empty( $upgrades ) ) {
317
318 1
			$locale_parts = explode( '_', get_locale() );
319 1
			$is_english = ( 'en' === $locale_parts[0] );
320
321 1
			$output .= '<h4>' . esc_html__( 'Upgrades available:', 'gravityview' ) . '</h4>';
322 1
			$output .= '<ul class="ul-disc">';
323
324 1
			foreach ( $upgrades as $upgrade_id => $upgrade ) {
325 1
				$upgrade = (object) $upgrade;
326
327 1
				$anchor_text = sprintf( esc_html_x( 'Upgrade to %1$s for %2$s', '1: GravityView upgrade name, 2: Cost of upgrade', 'gravityview' ), esc_attr( $upgrade->name ), esc_attr( $upgrade->price ) );
328
329 1
				if ( $is_english && isset( $upgrade->description ) ) {
330 1
					$message = esc_html( $upgrade->description );
331
				} else {
332
					switch( $upgrade->price_id ) {
333
						// Interstellar
334
						case 1:
335
						default:
336
							$message = esc_html__( 'Get access to Extensions', 'gravityview' );
337
							break;
338
						// Galactic
339
						case 2:
0 ignored issues
show
Unused Code introduced by
case 2: $message = e...avityview'); break; does not seem to be reachable.

This check looks for unreachable code. It uses sophisticated control flow analysis techniques to find statements which will never be executed.

Unreachable code is most often the result of return, die or exit statements that have been added for debug purposes.

function fx() {
    try {
        doSomething();
        return true;
    }
    catch (\Exception $e) {
        return false;
    }

    return false;
}

In the above example, the last return false will never be executed, because a return statement has already been met in every possible execution path.

Loading history...
340
							$message = esc_html__( 'Get access to Entry Importer and other Premium plugins', 'gravityview' );
341
							break;
342
					}
343
				}
344
345 1
				$output .= sprintf( '<li><a href="%s">%s</a><span class="howto">%s</span></li>', esc_url( add_query_arg( array( 'utm_source' => 'settings', 'utm_medium' => 'admin', 'utm_content' => 'license-details', 'utm_campaign' => 'Upgrades' ), $upgrade->url ) ), $anchor_text, $message );
346
			}
347 1
			$output .= '</ul>';
348
		}
349
350 1
		return $output;
351
	}
352
353
	/**
354
	 * Generate the status message box HTML based on the current status
355
	 *
356
	 * @since 1.7.4
357
	 * @param $message
358
	 * @param string $class
359
	 *
360
	 * @return string
361
	 */
362 1
	private function generate_license_box( $message, $class = '' ) {
363 1
		$template = '<div id="gv-edd-status" aria-live="polite" aria-busy="false" class="gv-edd-message inline %s">%s</div>';
364
365 1
		$output = sprintf( $template, esc_attr( $class ), $message );
366
367 1
		return $output;
368
	}
369
370
	/**
371
	 * Override the text used in the GravityView EDD license Javascript
372
	 *
373
	 * @param  string $status Status to get. If empty, get all strings.
374
	 * @param  object|array|null $license_data Object with license data, used to generate link to license renewal URL
375
	 * @return string Modified array of content
376
	 */
377 1
	public function strings( $status = NULL, $license_data = null ) {
378
379
		$strings = array(
380 1
			'status' => esc_html__( 'Status', 'gravityview' ),
381 1
			'error' => esc_html__( 'There was an error processing the request.', 'gravityview' ),
382 1
			'failed'  => esc_html__( 'Could not deactivate the license. The license key you attempted to deactivate may not be active or valid.', 'gravityview' ),
383 1
			'site_inactive' => esc_html__( 'The license key is valid, but it has not been activated for this site.', 'gravityview' ),
384 1
			'inactive' => esc_html__( 'The license key is valid, but it has not been activated for this site.', 'gravityview' ),
385 1
			'no_activations_left' => esc_html__( 'Invalid: this license has reached its activation limit.', 'gravityview' ) . ' ' . sprintf( esc_html__( 'You can manage license activations %son your GravityView account page%s.', 'gravityview' ), '<a href="https://gravityview.co/account/#licenses">', '</a>' ),
386 1
			'deactivated' => esc_html__( 'The license has been deactivated.', 'gravityview' ),
387 1
			'valid' => esc_html__( 'The license key is valid and active.', 'gravityview' ),
388 1
			'invalid' => esc_html__( 'The license key entered is invalid.', 'gravityview' ),
389 1
			'missing' => esc_html__( 'Invalid license key.', 'gravityview' ),
390 1
			'revoked' => esc_html__( 'This license key has been revoked.', 'gravityview' ),
391 1
			'expired' => sprintf( esc_html__( 'This license key has expired. %sRenew your license on the GravityView website%s to receive updates and support.', 'gravityview' ), '<a href="'. esc_url( $this->get_license_renewal_url( $license_data ) ) .'">', '</a>' ),
392 1
			'capability' => esc_html__( 'You don\'t have the ability to edit plugin settings.', 'gravityview' ),
393
394 1
			'verifying_license' => esc_html__( 'Verifying license&hellip;', 'gravityview' ),
395 1
			'activate_license' => esc_html__( 'Activate License', 'gravityview' ),
396 1
			'deactivate_license' => esc_html__( 'Deactivate License', 'gravityview' ),
397 1
			'check_license' => esc_html__( 'Verify License', 'gravityview' ),
398
		);
399
400
		/**
401
		 * @internal Do not rely on this filter.
402
		 * @since 2.1
403
		 */
404 1
		$strings = apply_filters( 'gravityview/admin/license/strings', $strings );
405
406 1
		return Utils::get( $strings, $status, null );
407
	}
408
409
	/**
410
	 * URL to direct license renewal, or if license key is not set, then just the account page
411
	 * @since 1.13.1
412
	 * @param  object|null $license_data Object with license data
413
	 * @return string Renewal or account URL
414
	 */
415 1
	private function get_license_renewal_url( $license_data ) {
416 1
		$license_data = is_array( $license_data ) ? (object)$license_data : $license_data;
417
418 1
		if ( ! empty( $license_data->renewal_url ) ) {
419
			$renew_license_url = $license_data->renewal_url;
420 1
		} elseif( ! empty( $license_data->license_key ) ) {
421 1
			$renew_license_url = sprintf( 'https://gravityview.co/checkout/?download_id=17&edd_license_key=%s', $license_data->license_key );
422
		} else {
423 1
			$renew_license_url = 'https://gravityview.co/account/';
424
		}
425
426 1
		$renew_license_url = add_query_arg( wp_parse_args( 'utm_source=admin_notice&utm_medium=admin&utm_content=expired&utm_campaign=Activation&force_login=1' ), $renew_license_url );
427
428 1
		return $renew_license_url;
429
	}
430
431
	/**
432
	 * Perform the call
433
	 *
434
	 * @return array|\WP_Error
435
	 */
436 1
	private function _license_get_remote_response( $data, $license = '' ) {
437 1
		$api_params = $this->_get_edd_settings( $data['edd_action'], $license );
438
439 1
		$url = add_query_arg( $api_params, self::url );
440
441 1
		$response = wp_remote_get( $url, array(
442 1
			'timeout'   => 15,
443
			'sslverify' => false,
444
		) );
445
446 1
		if ( is_wp_error( $response ) ) {
447
			gravityview()->log->error( 'WP_Error response from license check. API params:', array( 'data' => $api_params ) );
448
			return array();
449
		}
450
451 1
		$license_data = json_decode( wp_remote_retrieve_body( $response ) );
452
453
		// Not JSON
454 1
		if ( empty( $license_data ) ) {
455 1
			gravityview()->log->error( 'Empty license data response from license check', array( 'data' => compact( 'response', 'url', 'api_params', 'data' ) ) );
456
457 1
			delete_transient( self::status_transient_key );
458
459
			// Change status
460 1
			return array();
461
		}
462
463
		// Store the license key inside the data array
464 1
		$license_data->license_key = $license;
465
466 1
		return $license_data;
467
	}
468
469
	/**
470
	 * Update the license after fetching it
471
	 * @param object $license_data
472
	 * @return void
473
	 */
474 1
	private function license_call_update_settings( $license_data, $data ) {
475 1
		$settings = array();
476
477 1
        $settings['license_key'] = $license_data->license_key = trim( $data['license'] );
478 1
		$settings['license_key_status'] = $license_data->license;
479 1
		$settings['license_key_response'] = (array)$license_data;
480
481 1
		$this->settings->set( $settings );
482 1
	}
483
484 2
	public function settings_edd_license_activation( $field, $echo ) {
0 ignored issues
show
Unused Code introduced by
The parameter $field is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
485 2
		$script_debug = ( defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ) ? '' : '.min';
486
487 2
		wp_enqueue_script( 'gv-admin-edd-license', GRAVITYVIEW_URL . 'assets/js/admin-edd-license' . $script_debug . '.js', array( 'jquery' ) );
488
489 2
		$status = trim( $this->settings->get( 'license_key_status' ) );
490 2
		$key = trim( $this->settings->get( 'license_key' ) );
491
492 2
		if ( ! empty( $key ) ) {
493
			$response = $this->settings->get( 'license_key_response' );
494
			$response = is_array( $response ) ? (object) $response : json_decode( $response );
495
		} else {
496 2
			$response = array();
497
		}
498
499 2
		wp_localize_script( 'gv-admin-edd-license', 'GVGlobals', array(
500 2
			'license_box' => $this->get_license_message( $response )
501
		) );
502
503
		$fields = array(
504
			array(
505 2
				'name'  => 'edd-activate',
506 2
				'value' => __( 'Activate License', 'gravityview' ),
507 2
				'data-pending_text' => __( 'Verifying license&hellip;', 'gravityview' ),
508 2
				'data-edd_action' => 'activate_license',
509 2
				'class' => 'button-primary',
510
			),
511
			array(
512 2
				'name'  => 'edd-deactivate',
513 2
				'value' => __( 'Deactivate License', 'gravityview' ),
514 2
				'data-pending_text' => __( 'Deactivating license&hellip;', 'gravityview' ),
515 2
				'data-edd_action' => 'deactivate_license',
516 2
				'class' => ( empty( $status ) ? 'button-primary hide' : 'button-primary' ),
517
			),
518
			array(
519 2
				'name'  => 'edd-check',
520 2
				'value' => __( 'Check License', 'gravityview' ),
521 2
				'data-pending_text' => __( 'Verifying license&hellip;', 'gravityview' ),
522 2
				'title' => 'Check the license before saving it',
523 2
				'data-edd_action' => 'check_license',
524 2
				'class' => 'button-secondary',
525
			),
526
		);
527
528 2
		$class = 'button gv-edd-action';
529
530 2
		$class .= ( ! empty( $key ) && $status !== 'valid' ) ? '' : ' hide';
531
532 2
		$disabled_attribute = \GVCommon::has_cap( 'gravityview_edit_settings' ) ? false : 'disabled';
533
534 2
		$submit = '<div class="gv-edd-button-wrapper">';
535 2
		foreach ( $fields as $field ) {
536 2
			$field['type'] = 'button';
537 2
			$field['class'] = isset( $field['class'] ) ? $field['class'] . ' '. $class : $class;
538 2
			$field['style'] = 'margin-left: 10px;';
539 2
			if( $disabled_attribute ) {
540 1
				$field['disabled'] = $disabled_attribute;
541
			}
542 2
			$submit .= $this->settings->as_html( $field, $echo );
543
		}
544 2
		$submit .= '</div>';
545
546 2
		return $submit;
547
	}
548
549
	/**
550
	 * When the status transient expires (or is deleted on activation), re-check the status
551
	 *
552
	 * @since 1.17
553
	 *
554
	 * @return void
555
	 */
556 1
	public function refresh_license_status() {
557 1
		if ( defined( 'DOING_AJAX' ) && DOING_AJAX ) {
558
			return;
559
		}
560
561
		// The transient is fresh; don't fetch.
562 1
		if ( $status = get_transient( self::status_transient_key ) ) {
563
			return;
564
		}
565
566
		$data = array(
567 1
			'edd_action' => 'check_license',
568 1
			'license' => trim( $this->settings->get( 'license_key' ) ),
569
			'update' => true,
570 1
			'format' => 'object',
571 1
			'field_id' => 'refresh_license_status', // Required to set the `status_transient_key` transient
572
		);
573
574 1
		$license_call = $this->license_call( $data, false );
575
576 1
		gravityview()->log->debug( 'Refreshed the license.', array( 'data' => $license_call ) );
577 1
	}
578
579
	/**
580
	 * Check the GravityView license information
581
	 *
582
	 * @since 1.19.3
583
	 * @param bool $force Whether to force checking license, even if AJAX
0 ignored issues
show
Bug introduced by
There is no parameter named $force. Was it maybe removed?

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

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

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

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

Loading history...
584
	 *
585
	 * @return void
586
	 */
587 1
	public function check_license() {
588 1
		if ( defined( 'DOING_AJAX' ) && DOING_AJAX ) {
589
			return; // Don't fire when saving settings or AJAX
590
		}
591
592 1
		if ( ! apply_filters( 'gv_send_site_data', true ) ) {
593
			return;
594
		}
595
596
		// Send checkins once per week
597 1
		$last_checked = get_option( 'gv_last_checkin', false );
598
599 1
		if ( is_numeric( $last_checked ) && $last_checked > strtotime( '-1 week', current_time( 'timestamp' ) ) ) {
600
			return; // checked within a week
601
		}
602
603 1
		$status = get_transient( 'gv_license_check' );
604
605
		// Run the license check a maximum of once per day, and not on GV website
606 1
		if ( false === $status && site_url() !== self::url ) {
607
608
			// Call the custom API.
609 1
			$response = wp_remote_post( self::url, array(
610 1
				'timeout'   => 15,
611
			    'sslverify' => false,
612
			    'body'      =>  array(
613 1
				    'edd_action' => 'check_license',
614 1
				    'license'    => trim( $this->settings->get( 'license_key' ) ),
615 1
				    'item_name'  => self::name,
616 1
				    'url'        => home_url(),
617 1
				    'site_data'  => $this->get_site_data(),
618
			    ),
619
			));
620
621
			// make sure the response came back okay
622 1
			if ( is_wp_error( $response ) ) {
623
624
				// Connection failed, try again in three hours
625
				set_transient( 'gv_license_check', 1, 3 * HOUR_IN_SECONDS );
626
627
				return;
628
			}
629
630 1
			set_transient( 'gv_license_check', 1, DAY_IN_SECONDS );
631
632 1
			update_option( 'gv_last_checkin', current_time( 'timestamp' ) );
633
		}
634 1
	}
635
636
	/**
637
	 * Retrieves site data (plugin versions, integrations, etc) to be sent along with the license check.
638
	 *
639
	 * @since 1.9
640
	 * @access public
641
	 *
642
	 * @return array
643
	 */
644 1
	public function get_site_data() {
645 1
		$data = array();
646
647 1
		$theme_data = wp_get_theme();
648 1
		$theme      = $theme_data->Name . ' ' . $theme_data->Version;
649
650 1
		$data['gv_version']  = Plugin::$version;
651 1
		$data['php_version']  = phpversion();
652 1
		$data['wp_version']   = get_bloginfo( 'version' );
653 1
		$data['gf_version']  = \GFForms::$version;
654 1
		$data['server']       = Utils::get( $_SERVER, 'SERVER_SOFTWARE' );
655 1
		$data['multisite']    = is_multisite();
656 1
		$data['theme']        = $theme;
657 1
		$data['url']          = home_url();
658 1
		$data['license_key']  = $this->settings->get( 'license_key' );
659 1
		$data['beta']         = $this->settings->get( 'beta' );
660
661
		// View Data
662 1
		$gravityview_posts = wp_count_posts( 'gravityview', 'readable' );
663
664 1
		$data['view_count'] = null;
665 1
		$data['view_first'] = null;
666 1
		$data['view_latest'] = null;
667
668 1
		if ( $gravityview_posts->publish ) {
669 1
			$data['view_count'] = $gravityview_posts->publish;
670
671 1
			$first = get_posts( 'numberposts=1&post_type=gravityview&post_status=publish&order=ASC' );
672 1
			$latest = get_posts( 'numberposts=1&post_type=gravityview&post_status=publish&order=DESC' );
673
674 1
			if ( $first = array_shift( $first ) ) {
675 1
				$data['view_first'] = $first->post_date;
676
			}
677 1
			if ( $latest = array_pop( $latest ) ) {
678 1
				$data['view_latest'] = $latest->post_date;
679
			}
680
		}
681
682
		// Form counts
683 1
		if ( class_exists( 'GFFormsModel' ) ) {
684 1
			$form_data = \GFFormsModel::get_form_count();
685 1
			$data['forms_total'] = Utils::get( $form_data, 'total', 0 );
686 1
			$data['forms_active'] = Utils::get( $form_data, 'active', 0 );
687 1
			$data['forms_inactive'] = Utils::get( $form_data, 'inactive', 0 );
688 1
			$data['forms_trash'] = Utils::get( $form_data, 'inactive', 0 );
689
		}
690
691
		// Retrieve current plugin information
692 1
		if ( ! function_exists( 'get_plugins' ) ) {
693
			include ABSPATH . '/wp-admin/includes/plugin.php';
694
		}
695
696 1
		$data['integrations']     = self::get_related_plugins_and_extensions();
697 1
		$data['active_plugins']   = get_option( 'active_plugins', array() );
698 1
		$data['inactive_plugins'] = array();
699 1
		$data['locale']           = get_locale();
700
701
		// Validate request on the GV server
702 1
		$data['hash']             = 'gv_version.url.locale:' . sha1( $data['gv_version'] . $data['url'] . $data['locale'] );
703
704 1
		return $data;
705
	}
706
707
	/**
708
	 * Get active GravityView Extensions and Gravity Forms Add-ons to help debug issues.
709
	 *
710
	 * @since 1.15
711
	 * @return string List of active extensions related to GravityView or Gravity Forms, separated by HTML line breaks
712
	 */
713 1
	static public function get_related_plugins_and_extensions( $implode = '<br />' ) {
714 1
		if ( ! function_exists( 'wp_get_active_and_valid_plugins' ) ) {
715
			return 'Running < WP 3.0';
716
		}
717
718 1
		$extensions = get_site_transient( self::related_plugins_key );
719
720 1
		if ( empty( $extensions ) ) {
721
722 1
			$active_plugins = wp_get_active_and_valid_plugins();
723 1
			$extensions = array();
724 1
			foreach ( $active_plugins as $active_plugin ) {
725
				// Match gravityview, gravity-forms, gravityforms, gravitate
726
				if ( ! preg_match( '/(gravityview|gravity-?forms|gravitate|perk|gravity|gf)/ism', $active_plugin ) ) {
727
					continue;
728
				}
729
730
				$plugin_data = get_plugin_data( $active_plugin );
731
732
				$extensions[] = sprintf( '%s %s', $plugin_data['Name'], $plugin_data['Version'] );
733
			}
734
735 1
			if ( ! empty( $extensions ) ) {
736
				set_site_transient( self::related_plugins_key, $extensions, HOUR_IN_SECONDS );
737
			} else {
738 1
				return 'There was an error fetching related plugins.';
739
			}
740
		}
741
742
		return $implode ? implode( $implode, $extensions ) : $extensions;
743
	}
744
745
	/**
746
	 * When a plugin is activated or deactivated, delete the cached extensions/plugins used by get_related_plugins_and_extensions()
747
	 *
748
	 * @see get_related_plugins_and_extensions()
749
	 * @since 1.15
750
	 */
751 1
	public function flush_related_plugins_transient() {
752 1
		if ( function_exists( 'delete_site_transient' ) ) {
753 1
			delete_site_transient( self::related_plugins_key );
754
		}
755 1
	}
756
}
757