Completed
Push — master ( 39734d...9bfb60 )
by Zack
05:51 queued 02:37
created

includes/class-gravityview-compatibility.php (6 issues)

Upgrade to new PHP Analysis Engine

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

1
<?php
2
/**
3
 * Handle issues with plugin and version compatibility
4
 *
5
 * @package   GravityView
6
 * @license   GPL2+
7
 * @author    Katz Web Services, Inc.
8
 * @link      http://gravityview.co
9
 * @copyright Copyright 2015, Katz Web Services, Inc.
10
 *
11
 * @since 1.12
12
 */
13
14
/**
15
 * Handle GravityView compatibility notices and fallback shortcodes
16
 * @since 1.12
17
 */
18
class GravityView_Compatibility {
19
20
	/**
21
	 * @var GravityView_Compatibility
22
	 */
23
	static public $instance = null;
24
25
	/**
26
	 * @var bool Is Gravity Forms version valid and is Gravity Forms loaded?
27
	 */
28
	static public $valid_gravity_forms = false;
29
30
	/**
31
	 * @var bool Is the WordPress installation compatible?
32
	 */
33
	static public $valid_wordpress = false;
34
35
	/**
36
	 * @var bool Is the server's PHP version compatible?
37
	 */
38
	static public $valid_php = false;
39
40
	/**
41
	 * @var array Holder for notices to be displayed in frontend shortcodes if not valid GF
42
	 */
43
	static private $notices = array();
44
45
	function __construct() {
46
47
		self::$valid_gravity_forms = self::check_gravityforms();
48
49
		self::$valid_wordpress = self::check_wordpress();
50
51
		self::$valid_php = self::check_php();
52
53
		self::check_gf_directory();
54
55
		$this->add_hooks();
56
	}
57
58
	function add_hooks() {
59
60
		add_filter( 'gravityview/admin/notices', array( $this, 'insert_admin_notices' ) );
61
62
		$this->add_fallback_shortcode();
63
	}
64
65
	/**
66
	 * Add the compatibility notices to the other admin notices
67
	 * @param array $notices
68
	 *
69
	 * @return array
70
	 */
71
	function insert_admin_notices( $notices = array() ) {
72
		return array_merge( $notices, self::$notices );
73
	}
74
75
	/**
76
	 * @return GravityView_Compatibility
77
	 */
78
	public static function getInstance() {
79
		if( self::$instance ) {
80
			return self::$instance;
81
		}
82
		return new self;
83
	}
84
85
	/**
86
	 * Is everything compatible with this version of GravityView?
87
	 *
88
	 * @deprecated 1.19.4
89
	 * @see \GV\Plugin::is_compatible() accessible via gravityview()->plugin->is_compatible()
90
	 *
91
	 * @return bool
92
	 */
93
	public static function is_valid() {
94
		if ( function_exists( 'gravityview' ) ) {
95
			return gravityview()->plugin->is_compatible();
96
		}
97
98
		return ( self::is_valid_gravity_forms() && self::is_valid_wordpress() && self::is_valid_php() );
0 ignored issues
show
Deprecated Code introduced by
The method GravityView_Compatibilit...s_valid_gravity_forms() has been deprecated with message: 1.19.4

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...
Deprecated Code introduced by
The method GravityView_Compatibility::is_valid_wordpress() has been deprecated with message: 1.19.4

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...
Deprecated Code introduced by
The method GravityView_Compatibility::is_valid_php() has been deprecated with message: 1.19.4

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...
99
	}
100
101
	/**
102
	 * Is the version of WordPress compatible?
103
	 * @since 1.12
104
	 *
105
	 * @deprecated 1.19.4
106
	 * @see \GV\Plugin::is_compatible_wordpress() accessible via gravityview()->plugin->is_compatible_wordpress()
107
	 */
108
	private static function is_valid_wordpress() {
109
		if ( function_exists( 'gravityview' ) ) {
110
			return gravityview()->plugin->is_compatible_wordpress();
111
		}
112
113
		return self::$valid_wordpress;
114
	}
115
116
	/**
117
	 * @since 1.12
118
	 *
119
	 * @deprecated 1.19.4
120
	 * @see \GV\Plugin::is_compatible_gravityforms() accessible via gravityview()->plugin->is_compatible_gravityforms()
121
	 *
122
	 * @return bool
123
	 */
124
	private static function is_valid_gravity_forms() {
125
		if ( function_exists( 'gravityview' ) ) {
126
			return gravityview()->plugin->is_compatible_gravityforms();
127
		}
128
129
		return self::$valid_gravity_forms;
130
	}
131
132
	/**
133
	 * @since 1.12
134
	 *
135
	 * @deprecated 1.19.4
136
	 * @see \GV\Plugin::is_compatible_php() accessible via gravityview()->plugin->is_compatible_php()
137
	 *
138
	 * @return bool
139
	 */
140
	private static function is_valid_php() {
141
		if ( function_exists( 'gravityview' ) ) {
142
			return gravityview()->plugin->is_compatible_php();
143
		}
144
145
		return self::$valid_php;
146
	}
147
148
	/**
149
	 * @since 1.12
150
	 * @return bool
151
	 */
152
	private function add_fallback_shortcode() {
153
154
		// If Gravity Forms doesn't exist or is outdated, load the admin view class to
155
		// show the notice, but not load any post types or process shortcodes.
156
		// Without Gravity Forms, there is no GravityView. Beautiful, really.
157
		if( ! self::is_valid() ) {
0 ignored issues
show
Deprecated Code introduced by
The method GravityView_Compatibility::is_valid() has been deprecated with message: 1.19.4

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...
158
159
			// If the plugin's not loaded, might as well hide the shortcode for people.
160
			add_shortcode( 'gravityview', array( $this, '_shortcode_gf_notice') );
161
162
		}
163
	}
164
165
	/**
166
	 * Get admin notices
167
	 * @since 1.12
168
	 * @return array
169
	 */
170
	public static function get_notices() {
171
		return self::$notices;
172
	}
173
174
	/**
175
	 * @since 1.9.2 in gravityview.php
176
	 * @since 1.12
177
	 *
178
	 * @param array $atts
179
	 * @param null $content
180
	 * @param string $shortcode
181
	 *
182
	 * @return null|string NULL returned if user can't activate plugins. Notice shown with a warning that GF isn't supported.
183
	 */
184
	public function _shortcode_gf_notice( $atts = array(), $content = null, $shortcode = 'gravityview' ) {
185
186
		if( ! GVCommon::has_cap( 'activate_plugins' ) ) {
187
			return null;
188
		}
189
190
		$notices = self::get_notices();
191
192
		$message = '<div style="border:1px solid red; padding: 15px;"><p style="text-align:center;"><em>' . esc_html__( 'You are seeing this notice because you are an administrator. Other users of the site will see nothing.', 'gravityview') . '</em></p>';
193
		foreach( (array)$notices as $notice ) {
194
			$message .= wpautop( $notice['message'] );
195
		}
196
		$message .= '</div>';
197
198
		return $message;
199
200
	}
201
202
	/**
203
	 * Is the version of PHP compatible?
204
	 *
205
	 * @since 1.12
206
	 * @since 1.19.2 Shows a notice if it's compatible with future PHP version requirements
207
	 *
208
	 * @return boolean
209
	 */
210
	public static function check_php() {
211
212
		if (
213
			( function_exists( 'gravityview' ) && ! gravityview()->plugin->is_compatible_php() )
214
			|| ( false === version_compare( phpversion(), GV_MIN_PHP_VERSION , '>=' ) )
215
		) {
216
217
			self::$notices['php_version'] = array(
218
				'class' => 'error',
219
				'message' => sprintf( __( "%sGravityView requires PHP Version %s or newer.%s \n\nYou're using Version %s. Please ask your host to upgrade your server's PHP.", 'gravityview' ), '<h3>', GV_MIN_PHP_VERSION, "</h3>\n\n", '<span style="font-family: Consolas, Courier, monospace;">'.phpversion().'</span>' ),
220
				'cap' => 'manage_options',
221
				'dismiss' => 'php_version',
222
			);
223
224
			return false;
225
		}
226
227
		if( false === version_compare( phpversion(), GV_FUTURE_MIN_PHP_VERSION , '>=' ) ) {
228
229
			// Show the notice on every update. Yes, annoying, but not as annoying as a plugin breaking.
230
			$key = sprintf('php_%s_%s', GV_FUTURE_MIN_PHP_VERSION, GravityView_Plugin::version );
231
232
			self::$notices[ $key ] = array(
233
				'class' => 'error',
234
				'message' => sprintf( __( "%sGravityView will soon require PHP Version %s.%s \n\nYou're using Version %s. Please ask your host to upgrade your server's PHP.", 'gravityview' ), '<h3>', GV_FUTURE_MIN_PHP_VERSION, "</h3>\n\n", '<span style="font-family: Consolas, Courier, monospace;">'.phpversion().'</span>' ),
235
				'cap' => 'manage_options',
236
				'dismiss' => $key,
237
			);
238
239
		}
240
241
		return true;
242
	}
243
244
	/**
245
	 * Is WordPress compatible?
246
	 *
247
	 * @since 1.12
248
	 * @return boolean
249
	 */
250
	public static function check_wordpress() {
251
		global $wp_version;
252
253
		if (
254
			( function_exists( 'gravityview' ) && ! gravityview()->plugin->is_compatible_wordpress() )
255
			|| ( version_compare( $wp_version, GV_MIN_WP_VERSION ) <= 0 )
256
		) {
257
258
			self::$notices['wp_version'] = array(
259
				'class' => 'error',
260
				'message' => sprintf( __( "%sGravityView requires WordPress %s or newer.%s \n\nYou're using Version %s. Please upgrade your WordPress installation.", 'gravityview' ), '<h3>', GV_MIN_WP_VERSION, "</h3>\n\n", '<span style="font-family: Consolas, Courier, monospace;">'.$wp_version.'</span>' ),
261
			    'cap' => 'update_core',
262
				'dismiss' => 'wp_version',
263
			);
264
265
			return false;
266
		}
267
268
		return true;
269
	}
270
271
272
	/**
273
	 * Check if Gravity Forms plugin is active and show notice if not.
274
	 *
275
	 * @since 1.12
276
	 *
277
	 * @access public
278
	 * @return boolean True: checks have been passed; GV is fine to run; False: checks have failed, don't continue loading
279
	 */
280
	public static function check_gravityforms() {
281
282
		// Bypass other checks: if the class exists
283
		if( class_exists( 'GFCommon' ) ) {
284
285
			// Does the version meet future requirements?
286
			if( true === version_compare( GFCommon::$version, GV_FUTURE_MIN_GF_VERSION, ">=" ) ) {
287
				return true;
288
			}
289
290
			// Does it meet minimum requirements?
291
			if ( function_exists( 'gravityview' ) ) {
292
				$meets_minimum = gravityview()->plugin->is_compatible_gravityforms();
293
			} else {
294
				$meets_minimum = ( true === version_compare( GFCommon::$version, GV_MIN_GF_VERSION, ">=" ) );
0 ignored issues
show
Coding Style Comprehensibility introduced by
The string literal >= does not require double quotes, as per coding-style, please use single quotes.

PHP provides two ways to mark string literals. Either with single quotes 'literal' or with double quotes "literal". The difference between these is that string literals in double quotes may contain variables with are evaluated at run-time as well as escape sequences.

String literals in single quotes on the other hand are evaluated very literally and the only two characters that needs escaping in the literal are the single quote itself (\') and the backslash (\\). Every other character is displayed as is.

Double quoted string literals may contain other variables or more complex escape sequences.

<?php

$singleQuoted = 'Value';
$doubleQuoted = "\tSingle is $singleQuoted";

print $doubleQuoted;

will print an indented: Single is Value

If your string literal does not contain variables or escape sequences, it should be defined using single quotes to make that fact clear.

For more information on PHP string literals and available escape sequences see the PHP core documentation.

Loading history...
295
			}
296
297
			$class = $meets_minimum ? 'notice-warning' : 'error';
298
299
			// Show the notice even if the future version requirements aren't met
300
			self::$notices['gf_version'] = array(
301
				'class' => $class,
302
				'message' => sprintf( __( "%sGravityView requires Gravity Forms Version %s or newer.%s \n\nYou're using Version %s. Please update your Gravity Forms or purchase a license. %sGet Gravity Forms%s - starting at $39%s%s", 'gravityview' ), '<h3>', GV_FUTURE_MIN_GF_VERSION, "</h3>\n\n", '<span style="font-family: Consolas, Courier, monospace;">'.GFCommon::$version.'</span>', "\n\n".'<a href="https://katz.si/gravityforms" class="button button-secondary button-large button-hero">' , '<em>', '</em>', '</a>'),
303
				'cap' => 'update_plugins',
304
				'dismiss' => 'gf_version_' . GV_FUTURE_MIN_GF_VERSION,
0 ignored issues
show
Expected a sanitizing function (see Codex for 'Data Validation'), but instead saw 'GV_FUTURE_MIN_GF_VERSION'
Loading history...
305
			);
306
307
			// Return false if the plugin is not compatible, true if meets minimum
308
			return $meets_minimum;
309
		}
310
311
		$gf_status = self::get_plugin_status( 'gravityforms/gravityforms.php' );
312
313
		/**
314
		 * The plugin is activated and yet somehow GFCommon didn't get picked up...
315
		 * OR
316
		 * It's the Network Admin and we just don't know whether the sites have GF activated themselves.
317
		 */
318
		if( true === $gf_status || is_network_admin() ) {
319
			return true;
320
		}
321
322
		// If GFCommon doesn't exist, assume GF not active
323
		$return = false;
324
325
		switch( $gf_status ) {
326
			case 'inactive':
327
328
				// Required for multisite
329
				if( ! function_exists('wp_create_nonce') ) {
330
					require_once ABSPATH . WPINC . '/pluggable.php';
331
				}
332
333
				// Otherwise, throws an error on activation & deactivation "Use of undefined constant LOGGED_IN_COOKIE"
334
				if( is_multisite() ) {
335
					wp_cookie_constants();
336
				}
337
338
				$return = false;
339
340
				$button = function_exists('is_network_admin') && is_network_admin() ? '<strong><a href="#gravity-forms">' : '<strong><a href="'. wp_nonce_url( admin_url( 'plugins.php?action=activate&plugin=gravityforms/gravityforms.php' ), 'activate-plugin_gravityforms/gravityforms.php') . '" class="button button-large">';
341
342
				self::$notices['gf_inactive'] = array(
343
					'class' => 'error',
344
					'message' => sprintf( __( '%sGravityView requires Gravity Forms to be active. %sActivate Gravity Forms%s to use the GravityView plugin.', 'gravityview' ), '<h3>', "</h3>\n\n". $button, '</a></strong>' ),
345
					'cap' => 'activate_plugins',
346
					'dismiss' => 'gf_inactive',
347
				);
348
349
				break;
350
			default:
351
				self::$notices['gf_installed'] = array(
352
					'class' => 'error',
353
					'message' => sprintf( __( '%sGravityView requires Gravity Forms to be installed in order to run properly. %sGet Gravity Forms%s - starting at $39%s%s', 'gravityview' ), '<h3>', "</h3>\n\n".'<a href="http://katz.si/gravityforms" class="button button-secondary button-large button-hero">' , '<em>', '</em>', '</a>'),
354
					'cap' => 'install_plugins',
355
					'dismiss' => 'gf_installed',
356
				);
357
				break;
358
		}
359
360
		return $return;
361
	}
362
363
	/**
364
	 * Check for potential conflicts and let users know about common issues.
365
	 *
366
	 * @return void
367
	 */
368
	private static function check_gf_directory() {
369
370
		if( class_exists( 'GFDirectory' ) ) {
371
			self::$notices['gf_directory'] = array(
372
				'class' => 'error is-dismissible',
373
				'title' => __('Potential Conflict', 'gravityview' ),
374
				'message' => __( 'GravityView and Gravity Forms Directory are both active. This may cause problems. If you experience issues, disable the Gravity Forms Directory plugin.', 'gravityview' ),
375
				'dismiss' => 'gf_directory',
376
				'cap' => 'activate_plugins',
377
			);
378
		}
379
380
	}
381
382
	/**
383
	 * Check if specified plugin is active, inactive or not installed
384
	 *
385
	 * @access public
386
	 * @static
387
	 * @param string $location (default: '')
388
	 * @return boolean|string True: plugin is active; False: plugin file doesn't exist at path; 'inactive' it's inactive
389
	 */
390
	public static function get_plugin_status( $location = '' ) {
391
392
		if( ! function_exists('is_plugin_active') ) {
393
			include_once( ABSPATH . '/wp-admin/includes/plugin.php' );
394
		}
395
396
		if( is_network_admin() && is_plugin_active_for_network( $location ) ) {
397
			return true;
398
		}
399
400
		if( !is_network_admin() && is_plugin_active( $location ) ) {
401
			return true;
402
		}
403
404
		if(
405
			!file_exists( trailingslashit( WP_PLUGIN_DIR ) . $location ) &&
406
			!file_exists( trailingslashit( WPMU_PLUGIN_DIR ) . $location )
407
		) {
408
			return false;
409
		}
410
411
		return 'inactive';
412
	}
413
414
}
415
416
GravityView_Compatibility::getInstance();
417