Completed
Push — develop ( 964e49...6d1660 )
by Zack
16:48
created

Plugin::is_compatible()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 7

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 12

Importance

Changes 0
Metric Value
cc 3
nc 3
nop 0
dl 0
loc 7
ccs 0
cts 2
cp 0
crap 12
rs 10
c 0
b 0
f 0
1
<?php
2
3
namespace GV;
4
5
/** If this file is called directly, abort. */
6
if ( ! defined( 'GRAVITYVIEW_DIR' ) ) {
7
	die();
8
}
9
10
/**
11
 * The GravityView WordPress plugin class.
12
 *
13
 * Contains functionality related to GravityView being
14
 * a WordPress plugin and doing WordPress pluginy things.
15
 *
16
 * Accessible via gravityview()->plugin
17
 */
18
final class Plugin {
19
20
	/**
21
	 * @since 2.0
22
	 * @api
23
	 * @var string The plugin version.
24
	 *
25
	 */
26
	public static $version = GV_PLUGIN_VERSION;
27
28
	/**
29
	 * @var string Minimum WordPress version.
30
	 *
31
	 * GravityView requires at least this version of WordPress to function properly.
32
	 */
33
	private static $min_wp_version = GV_MIN_WP_VERSION;
34
35
	/**
36
	 * @var string Minimum WordPress version.
37
	 *
38
	 * @since 2.9.3
39
	 *
40
	 * GravityView will require this version of WordPress soon.
41
	 */
42
	private static $future_min_wp_version = GV_FUTURE_MIN_WP_VERSION;
43
44
	/**
45
	 * @var string Minimum Gravity Forms version.
46
	 *
47
	 * GravityView requires at least this version of Gravity Forms to function properly.
48
	 */
49
	public static $min_gf_version = GV_MIN_GF_VERSION;
50
51
	/**
52
	 * @var string Minimum PHP version.
53
	 *
54
	 * GravityView requires at least this version of PHP to function properly.
55
	 */
56
	private static $min_php_version = GV_MIN_PHP_VERSION;
57
58
	/**
59
	 * @var string|bool Minimum future PHP version.
60
	 *
61
	 * GravityView will require this version of PHP soon. False if no future PHP version changes are planned.
62
	 */
63
	private static $future_min_php_version = GV_FUTURE_MIN_PHP_VERSION;
64
65
	/**
66
	 * @var string|bool Minimum future Gravity Forms version.
67
	 *
68
	 * GravityView will require this version of Gravity Forms soon. False if no future Gravity Forms version changes are planned.
69
	 */
70
	private static $future_min_gf_version = GV_FUTURE_MIN_GF_VERSION;
71
72
	/**
73
	 * @var \GV\Plugin The \GV\Plugin static instance.
74
	 */
75
	private static $__instance = null;
76
77
	/**
78
	 * @since 2.0
79
	 * @api
80
	 * @var \GV\Addon_Settings The plugin "addon" settings.
81
	 *
82
	 */
83
	public $settings;
84
85
	/**
86
	 * @var string The GFQuery functionality identifier.
87
	 */
88
	const FEATURE_GFQUERY = 'gfquery';
89
90
	/**
91
	 * @var string The joins functionality identifier.
92
	 */
93
	const FEATURE_JOINS = 'joins';
94
95
	/**
96
	 * @var string The unions functionality identifier.
97
	 */
98
	const FEATURE_UNIONS = 'unions';
99
100
	/**
101
	 * @var string The REST API functionality identifier.
102
	 */
103
	const FEATURE_REST = 'rest_api';
104
105
	/**
106
	 * Get the global instance of \GV\Plugin.
107
	 *
108
	 * @return \GV\Plugin The global instance of GravityView Plugin.
109
	 */
110
	public static function get() {
111
112
		if ( ! self::$__instance instanceof self ) {
113
			self::$__instance = new self;
114
		}
115
116
		return self::$__instance;
117
	}
118
119
	private function __construct() {
120
121
		/**
122
		 * Load translations.
123
		 */
124
		add_action( 'init', array( $this, 'load_textdomain' ) );
125
126
		/**
127
		 * Load some frontend-related legacy files.
128
		 */
129
		add_action( 'gravityview/loaded', array( $this, 'include_legacy_frontend' ) );
130
131
		/**
132
		 * GFAddOn-backed settings, licensing.
133
		 */
134
		add_action( 'plugins_loaded', array( $this, 'load_license_settings' ) );
135
	}
136
137
	public function load_license_settings() {
138
139
		require_once $this->dir( 'future/includes/class-gv-license-handler.php' );
140 1
		require_once $this->dir( 'future/includes/class-gv-settings-addon.php' );
141
		if ( class_exists( '\GV\Addon_Settings' ) ) {
142 1
			$this->settings = new Addon_Settings();
143
			include_once $this->dir( 'includes/class-gravityview-settings.php' );
144 1
		} else {
145
			gravityview()->log->notice( '\GV\Addon_Settings not loaded. Missing \GFAddOn.' );
146
		}
147
	}
148
149
	/**
150
	 * Check whether Gravity Forms is v2.5-beta or newer
151
	 *
152
	 * @return bool
153
	 * @todo add @since
154
	 *
155
	 */
156
	public function is_GF_25() {
157
158
		return version_compare( '2.5-beta', \GFForms::$version, '<=' );
159
	}
160
161
	/**
162
	 * Check whether GravityView `is network activated.
163
	 *
164
	 * @return bool Whether it's network activated or not.
165
	 */
166
	public static function is_network_activated() {
167
168
		$plugin_basename = plugin_basename( GRAVITYVIEW_FILE );
169
170
		return is_multisite() && ( function_exists( 'is_plugin_active_for_network' ) && is_plugin_active_for_network( $plugin_basename ) );
171
	}
172
173
	/**
174
	 * Include more legacy stuff.
175
	 *
176
	 * @param boolean $force Whether to force the includes.
177
	 *
178
	 * @return void
179
	 */
180
	public function include_legacy_frontend( $force = false ) {
181
182
		if ( gravityview()->request->is_admin() && ! $force ) {
183
			return;
184
		}
185
186
		include_once $this->dir( 'includes/class-gravityview-image.php' );
187
		include_once $this->dir( 'includes/class-template.php' );
188
		include_once $this->dir( 'includes/class-api.php' );
189
		include_once $this->dir( 'includes/class-frontend-views.php' );
190
		include_once $this->dir( 'includes/class-gravityview-change-entry-creator.php' );
191
192
		/**
193
		 * @action     `gravityview_include_frontend_actions` Triggered after all GravityView frontend files are loaded
194
		 *
195
		 * @deprecated Use `gravityview/loaded` along with \GV\Request::is_admin(), etc.
196
		 *
197
		 * Nice place to insert extensions' frontend stuff
198
		 */
199
		do_action( 'gravityview_include_frontend_actions' );
200
	}
201
202
	/**
203
	 * Load more legacy core files.
204
	 *
205
	 * @return void
206
	 */
207
	public function include_legacy_core() {
208
209
		if ( ! class_exists( '\GravityView_Extension' ) ) {
210
			include_once $this->dir( 'includes/class-gravityview-extension.php' );
211
		}
212
213
		if ( ! gravityview()->plugin->is_compatible() ) {
214
			return;
215
		}
216
217
		// Load fields
218
		include_once $this->dir( 'includes/fields/class-gravityview-fields.php' );
219
		include_once $this->dir( 'includes/fields/class-gravityview-field.php' );
220
221
		// Load all field files automatically
222
		foreach ( glob( $this->dir( 'includes/fields/class-gravityview-field*.php' ) ) as $gv_field_filename ) {
223
			include_once $gv_field_filename;
224
		}
225
226
		include_once $this->dir( 'includes/class-gravityview-entry-approval-status.php' );
227
		include_once $this->dir( 'includes/class-gravityview-entry-approval.php' );
228
229
		include_once $this->dir( 'includes/class-gravityview-entry-notes.php' );
230
		include_once $this->dir( 'includes/load-plugin-and-theme-hooks.php' );
231
232
		// Load Extensions
233
		// @todo: Convert to a scan of the directory or a method where this all lives
234
		include_once $this->dir( 'includes/extensions/edit-entry/class-edit-entry.php' );
235
		include_once $this->dir( 'includes/extensions/delete-entry/class-delete-entry.php' );
236
		include_once $this->dir( 'includes/extensions/duplicate-entry/class-duplicate-entry.php' );
237
		include_once $this->dir( 'includes/extensions/entry-notes/class-gravityview-field-notes.php' );
238
239
		// Load WordPress Widgets
240
		include_once $this->dir( 'includes/wordpress-widgets/register-wordpress-widgets.php' );
241
242
		// Load GravityView Widgets
243
		include_once $this->dir( 'includes/widgets/register-gravityview-widgets.php' );
244
245
		// Add oEmbed
246
		include_once $this->dir( 'includes/class-api.php' );
247
		include_once $this->dir( 'includes/class-oembed.php' );
248
249
		// Add logging
250
		include_once $this->dir( 'includes/class-gravityview-logging.php' );
251
252
		include_once $this->dir( 'includes/class-ajax.php' );
253
		include_once $this->dir( 'includes/class-gravityview-html-elements.php' );
254
		include_once $this->dir( 'includes/class-frontend-views.php' );
255
		include_once $this->dir( 'includes/class-gravityview-admin-bar.php' );
256
		include_once $this->dir( 'includes/class-gravityview-entry-list.php' );
257
		include_once $this->dir( 'includes/class-gravityview-merge-tags.php' );
258
		/** @since 1.8.4 */
259
		include_once $this->dir( 'includes/class-data.php' );
260
		include_once $this->dir( 'includes/class-gravityview-shortcode.php' );
261
		include_once $this->dir( 'includes/class-gravityview-entry-link-shortcode.php' );
262
		include_once $this->dir( 'includes/class-gvlogic-shortcode.php' );
263
		include_once $this->dir( 'includes/presets/register-default-templates.php' );
264
265
		if ( class_exists( '\GFFormsModel' ) ) {
266
			include_once $this->dir( 'includes/class-gravityview-gfformsmodel.php' );
267
		}
268
	}
269
270
	/**
271
	 * Load the translations.
272
	 *
273
	 * Order of look-ups:
274
	 *
275
	 * 1. /wp-content/languages/plugins/gravityview-{locale}.mo (loaded by WordPress Core)
276
	 * 2. /wp-content/mu-plugins/gravityview-{locale}.mo
277
	 * 3. /wp-content/mu-plugins/languages/gravityview-{locale}.mo
278
	 * 4. /wp-content/plugins/gravityview/languages/gravityview-{locale}.mo
279
	 *
280
	 * @return void
281
	 */
282
	public function load_textdomain() {
283
284
		$domain = 'gravityview';
285
286
		// 1. /wp-content/languages/plugins/gravityview-{locale}.mo (loaded by WordPress Core)
287
		if ( is_textdomain_loaded( $domain ) ) {
288
			return;
289
		}
290
291
		// 2. /wp-content/languages/plugins/gravityview-{locale}.mo
292
		// 3. /wp-content/mu-plugins/plugins/languages/gravityview-{locale}.mo
293
		$loaded = load_muplugin_textdomain( $domain, '/languages/' );
294
295
		if ( $loaded ) {
296
			return;
297
		}
298
299
		// 4. /wp-content/plugins/gravityview/languages/gravityview-{locale}.mo
300
		$loaded = load_plugin_textdomain( $domain, false, $this->relpath( '/languages/' ) );
301
302
		if ( $loaded ) {
303
			return;
304 1
		}
305 1
306
		gravityview()->log->error( sprintf( 'Unable to load textdomain for %s locale.', $locale ) );
0 ignored issues
show
Bug introduced by
The variable $locale does not exist. Did you forget to declare it?

This check marks access to variables or properties that have not been declared yet. While PHP has no explicit notion of declaring a variable, accessing it before a value is assigned to it is most likely a bug.

Loading history...
307 1
	}
308
309
	/**
310
	 * Register hooks that are fired when the plugin is activated and deactivated.
311
	 *
312 1
	 * @return void
313 1
	 */
314
	public function register_activation_hooks() {
315
316 1
		register_activation_hook( $this->dir( 'gravityview.php' ), array( $this, 'activate' ) );
317 1
		register_deactivation_hook( $this->dir( 'gravityview.php' ), array( $this, 'deactivate' ) );
318
	}
319
320 1
	/**
321
	 * Plugin activation function.
322 1
	 *
323
	 * @return void
324
	 * @internal
325 1
	 */
326
	public function activate() {
327
328 1
		gravityview();
329
330 1
		if ( ! $this->is_compatible() ) {
331 1
			return;
332
		}
333
334
		/** Register the gravityview post type upon WordPress core init. */
335
		require_once $this->dir( 'future/includes/class-gv-view.php' );
336
		View::register_post_type();
337
338
		/** Add the entry rewrite endpoint. */
339
		require_once $this->dir( 'future/includes/class-gv-entry.php' );
340
		Entry::add_rewrite_endpoint();
341
342
		/** Flush all URL rewrites. */
343
		flush_rewrite_rules();
344
345
		update_option( 'gv_version', self::$version );
346
347
		/** Add the transient to redirect to configuration page. */
348
		set_transient( '_gv_activation_redirect', true, 60 );
349
350
		/** Clear settings transient. */
351
		delete_transient( 'gravityview_edd-activate_valid' );
352 114
353 114
		\GravityView_Roles_Capabilities::get_instance()->add_caps();
354
	}
355
356
	/**
357
	 * Plugin deactivation function.
358
	 *
359
	 * @return void
360
	 * @internal
361
	 */
362
	public function deactivate() {
363
364
		flush_rewrite_rules();
365 1
	}
366
367 1
	/**
368
	 * Retrieve an absolute path within the GravityView plugin directory.
369 1
	 *
370
	 * @since 2.0
371
	 *
372
	 * @param string $path Optional. Append this extra path component.
373
	 * @return string The absolute path to the plugin directory.
374
	 * @api
375
	 */
376
	public function dir( $path = '' ) {
377
378
		return wp_normalize_path( GRAVITYVIEW_DIR . ltrim( $path, '/' ) );
379
	}
380
381 1
	/**
382 1
	 * Retrieve a relative path to the GravityView plugin directory from the WordPress plugin directory
383
	 *
384
	 * @since 2.2.3
385
	 *
386
	 * @param string $path Optional. Append this extra path component.
387
	 * @return string The relative path to the plugin directory from the plugin directory.
388
	 * @api
389
	 */
390
	public function relpath( $path = '' ) {
391
392
		$dirname = trailingslashit( dirname( plugin_basename( GRAVITYVIEW_FILE ) ) );
393 5
394
		return wp_normalize_path( $dirname . ltrim( $path, '/' ) );
395 5
	}
396 5
397 5
	/**
398
	 * Retrieve a URL within the GravityView plugin directory.
399
	 *
400
	 * @since 2.0
401
	 *
402
	 * @param string $path Optional. Extra path appended to the URL.
403
	 * @return string The URL to this plugin, with trailing slash.
404
	 * @api
405
	 */
406
	public function url( $path = '/' ) {
407
408 5
		return plugins_url( $path, $this->dir( 'gravityview.php' ) );
409 5
	}
410
411
	/**
412
	 * Is everything compatible with this version of GravityView?
413
	 *
414
	 * @since 2.0
415
	 *
416
	 * @return bool
417
	 * @api
418
	 */
419
	public function is_compatible() {
420
421
		return
422
			$this->is_compatible_php()
423
			&& $this->is_compatible_wordpress()
424
			&& $this->is_compatible_gravityforms();
425
	}
426
427
	/**
428
	 * Is this version of GravityView compatible with the current version of PHP?
429
	 *
430
	 * @since 2.0
431
	 *
432
	 * @return bool true if compatible, false otherwise.
433
	 * @api
434 5
	 */
435
	public function is_compatible_php() {
436 5
437 5
		return version_compare( $this->get_php_version(), self::$min_php_version, '>=' );
438
	}
439
440 5
	/**
441
	 * Is this version of GravityView compatible with the future required version of PHP?
442
	 *
443
	 * @since 2.0
444
	 *
445
	 * @return bool true if compatible, false otherwise.
446
	 * @api
447
	 */
448
	public function is_compatible_future_php() {
449
450
		return version_compare( $this->get_php_version(), self::$future_min_php_version, '>=' );
451 5
	}
452 5
453 5
	/**
454
	 * Is this version of GravityView compatible with the current version of WordPress?
455
	 *
456
	 * @since 2.0
457
	 *
458
	 * @param string $version Version to check against; otherwise uses GV_MIN_WP_VERSION
459
	 *
460
	 * @return bool true if compatible, false otherwise.
461
	 * @api
462
	 */
463
	public function is_compatible_wordpress( $version = null ) {
464
465
		if ( ! $version ) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $version of type string|null is loosely compared to false; this is ambiguous if the string can be empty. You might want to explicitly use === null 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...
466
			$version = self::$min_wp_version;
467
		}
468
469
		return version_compare( $this->get_wordpress_version(), $version, '>=' );
470
	}
471
472
	/**
473
	 * Is this version of GravityView compatible with the future version of WordPress?
474
	 *
475
	 * @since 2.9.3
476 4
	 *
477 4
	 * @return bool true if compatible, false otherwise
478 4
	 * @api
479
	 */
480
	public function is_compatible_future_wordpress() {
481
482
		$version = $this->get_wordpress_version();
483
484
		return $version ? version_compare( $version, self::$future_min_wp_version, '>=' ) : false;
485
	}
486
487
	/**
488 4
	 * Is this version of GravityView compatible with the current version of Gravity Forms?
489 4
	 *
490 4
	 * @since 2.0
491
	 *
492
	 * @return bool true if compatible, false otherwise (or not active/installed).
493
	 * @api
494
	 */
495
	public function is_compatible_gravityforms() {
496
497
		$version = $this->get_gravityforms_version();
498
499
		return $version ? version_compare( $version, self::$min_gf_version, '>=' ) : false;
500 4
	}
501 4
502
	/**
503
	 * Is this version of GravityView compatible with the future version of Gravity Forms?
504
	 *
505
	 * @since 2.0
506 4
	 *
507 4
	 * @return bool true if compatible, false otherwise (or not active/installed).
508
	 * @api
509
	 */
510
	public function is_compatible_future_gravityforms() {
511
512
		$version = $this->get_gravityforms_version();
513
514
		return $version ? version_compare( $version, self::$future_min_gf_version, '>=' ) : false;
515
	}
516
517 194
	/**
518 194
	 * Retrieve the current PHP version.
519
	 *
520
	 * Overridable with GRAVITYVIEW_TESTS_PHP_VERSION_OVERRIDE during testing.
521
	 *
522
	 * @return string The version of PHP.
523 194
	 */
524 74
	private function get_php_version() {
525 194
526 194
		return ! empty( $GLOBALS['GRAVITYVIEW_TESTS_PHP_VERSION_OVERRIDE'] ) ?
527 181
			$GLOBALS['GRAVITYVIEW_TESTS_PHP_VERSION_OVERRIDE'] : phpversion();
528 194
	}
529 194
530
	/**
531
	 * Retrieve the current WordPress version.
532
	 *
533
	 * Overridable with GRAVITYVIEW_TESTS_WP_VERSION_OVERRIDE during testing.
534
	 *
535
	 * @return string The version of WordPress.
536
	 */
537
	private function get_wordpress_version() {
538
539
		return ! empty( $GLOBALS['GRAVITYVIEW_TESTS_WP_VERSION_OVERRIDE'] ) ?
540
			$GLOBALS['GRAVITYVIEW_TESTS_WP_VERSION_OVERRIDE'] : $GLOBALS['wp_version'];
541
	}
542
543
	/**
544
	 * Retrieve the current Gravity Forms version.
545
	 *
546
	 * Overridable with GRAVITYVIEW_TESTS_GF_VERSION_OVERRIDE during testing.
547
	 *
548
	 * @return string|null The version of Gravity Forms or null if inactive.
549
	 */
550
	private function get_gravityforms_version() {
551
552
		if ( ! class_exists( '\GFCommon' ) || ! empty( $GLOBALS['GRAVITYVIEW_TESTS_GF_INACTIVE_OVERRIDE'] ) ) {
553
			gravityview()->log->error( 'Gravity Forms is inactive or not installed.' );
554
555
			return null;
556
		}
557
558
		return ! empty( $GLOBALS['GRAVITYVIEW_TESTS_GF_VERSION_OVERRIDE'] ) ?
559
			$GLOBALS['GRAVITYVIEW_TESTS_GF_VERSION_OVERRIDE'] : \GFCommon::$version;
560
	}
561
562
	/**
563
	 * Feature support detection.
564
	 *
565
	 * @param string $feature Feature name. Check FEATURE_* class constants.
566
	 *
567
	 * @return boolean
568
	 */
569
	public function supports( $feature ) {
570
571
		if ( ! is_null( $supports = apply_filters( "gravityview/plugin/feature/$feature", null ) ) ) {
572
			return $supports;
573
		}
574
575
		switch ( $feature ):
576
			case self::FEATURE_GFQUERY:
577
				return class_exists( '\GF_Query' );
578
			case self::FEATURE_JOINS:
579
			case self::FEATURE_UNIONS:
580
				return apply_filters( 'gravityview/query/class', false ) === '\GF_Patched_Query';
581
			case self::FEATURE_REST:
582
				return class_exists( '\WP_REST_Controller' );
583
			default:
584
				return false;
585
		endswitch;
586
	}
587
588
	/**
589
	 * Delete GravityView Views, settings, roles, caps, etc.
590
	 *
591
	 * @return void
592
	 */
593
	public function uninstall() {
594
595
		global $wpdb;
596
597
		$suppress = $wpdb->suppress_errors();
598
599
		/**
600
		 * Posts.
601
		 */
602
		$items = get_posts( array(
603
			'post_type'   => 'gravityview',
604
			'post_status' => 'any',
605
			'numberposts' => - 1,
606
			'fields'      => 'ids',
607
		) );
608
609
		foreach ( $items as $item ) {
610
			wp_delete_post( $item, true );
611
		}
612
613
		/**
614
		 * Meta.
615
		 */
616
		$tables = array();
617
618
		if ( version_compare( \GravityView_GFFormsModel::get_database_version(), '2.3-dev-1', '>=' ) ) {
619
			$tables [] = \GFFormsModel::get_entry_meta_table_name();
620
		} elseif ( ! $this->is_GF_25() ) {
621
			$tables [] = \GFFormsModel::get_lead_meta_table_name();
622
		}
623
624
		foreach ( $tables as $meta_table ) {
625
			$sql = "
626
				DELETE FROM $meta_table
627
				WHERE (
628
					`meta_key` = 'is_approved'
629
				);
630
			";
631
			$wpdb->query( $sql );
632
		}
633
634
		/**
635
		 * Notes.
636
		 */
637
		$tables = array();
638
639
		if ( version_compare( \GravityView_GFFormsModel::get_database_version(), '2.3-dev-1', '>=' ) && method_exists( 'GFFormsModel', 'get_entry_notes_table_name' ) ) {
640
			$tables[] = \GFFormsModel::get_entry_notes_table_name();
641
		} elseif ( ! $this->is_GF_25() ) {
642
			$tables[] = \GFFormsModel::get_lead_notes_table_name();
643
		}
644
645
		$disapproved = __( 'Disapproved the Entry for GravityView', 'gravityview' );
646
		$approved    = __( 'Approved the Entry for GravityView', 'gravityview' );
647
648
		$suppress = $wpdb->suppress_errors();
649
		foreach ( $tables as $notes_table ) {
650
			$sql = $wpdb->prepare( "
651
				DELETE FROM $notes_table
652
				WHERE (
653
					`note_type` = 'gravityview' OR
654
					`value` = %s OR
655
					`value` = %s
656
				);
657
			", $approved, $disapproved );
658
			$wpdb->query( $sql );
659
		}
660
661
		$wpdb->suppress_errors( $suppress );
662
663
		/**
664
		 * Capabilities.
665
		 */
666
		\GravityView_Roles_Capabilities::get_instance()->remove_caps();
667
668
		/**
669
		 * Options.
670
		 */
671
		delete_option( 'gravityview_cache_blacklist' );
672
		delete_option( 'gv_version_upgraded_from' );
673
		delete_transient( 'gravityview_edd-activate_valid' );
674
		delete_transient( 'gravityview_edd-deactivate_valid' );
675
		delete_transient( 'gravityview_dismissed_notices' );
676
		delete_site_transient( 'gravityview_related_plugins' );
677
	}
678
679
	private function __clone() {
680
	}
681
682
	private function __wakeup() {
683
	}
684
}
685