Completed
Push — develop ( 4659b8...3ce645 )
by Zack
16:21
created

includes/class-gravityview-compatibility.php (2 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
	 * @return bool
88
	 */
89
	public static function is_valid() {
90
		return ( self::is_valid_gravity_forms() && self::is_valid_wordpress() && self::is_valid_php() );
91
	}
92
93
	/**
94
	 * Is the version of WordPress compatible?
95
	 * @since 1.12
96
	 */
97
	private static function is_valid_wordpress() {
98
		return self::$valid_wordpress;
99
	}
100
101
	/**
102
	 * @since 1.12
103
	 * @return bool
104
	 */
105
	private static function is_valid_gravity_forms() {
106
		return self::$valid_gravity_forms;
107
	}
108
109
	/**
110
	 * @since 1.12
111
	 * @return bool
112
	 */
113
	private static function is_valid_php() {
114
		return self::$valid_php;
115
	}
116
117
	/**
118
	 * @since 1.12
119
	 * @return bool
120
	 */
121
	private function add_fallback_shortcode() {
122
123
		// If Gravity Forms doesn't exist or is outdated, load the admin view class to
124
		// show the notice, but not load any post types or process shortcodes.
125
		// Without Gravity Forms, there is no GravityView. Beautiful, really.
126
		if( ! self::is_valid() ) {
127
128
			// If the plugin's not loaded, might as well hide the shortcode for people.
129
			add_shortcode( 'gravityview', array( $this, '_shortcode_gf_notice') );
130
131
		}
132
	}
133
134
	/**
135
	 * Get admin notices
136
	 * @since 1.12
137
	 * @return array
138
	 */
139
	public static function get_notices() {
140
		return self::$notices;
141
	}
142
143
	/**
144
	 * @since 1.9.2 in gravityview.php
145
	 * @since 1.12
146
	 *
147
	 * @param array $atts
148
	 * @param null $content
149
	 * @param string $shortcode
150
	 *
151
	 * @return null|string NULL returned if user can't activate plugins. Notice shown with a warning that GF isn't supported.
152
	 */
153
	public function _shortcode_gf_notice( $atts = array(), $content = null, $shortcode = 'gravityview' ) {
154
155
		if( ! GVCommon::has_cap( 'activate_plugins' ) ) {
156
			return null;
157
		}
158
159
		$notices = self::get_notices();
160
161
		$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>';
162
		foreach( (array)$notices as $notice ) {
163
			$message .= wpautop( $notice['message'] );
164
		}
165
		$message .= '</div>';
166
167
		return $message;
168
169
	}
170
171
	/**
172
	 * Is the version of PHP compatible?
173
	 *
174
	 * @since 1.12
175
	 * @since 1.19.2 Shows a notice if it's compatible with future PHP version requirements
176
	 *
177
	 * @return boolean
178
	 */
179
	public static function check_php() {
180
181
		if( false === version_compare( phpversion(), GV_MIN_PHP_VERSION , '>=' ) ) {
182
183
			self::$notices['php_version'] = array(
184
				'class' => 'error',
185
				'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>' ),
186
				'cap' => 'manage_options',
187
				'dismiss' => 'php_version',
188
			);
189
190
			return false;
191
		}
192
193
		if( false === version_compare( phpversion(), GV_FUTURE_MIN_PHP_VERSION , '>=' ) ) {
194
195
			// Show the notice on every update. Yes, annoying, but not as annoying as a plugin breaking.
196
			$key = sprintf('php_%s_%s', GV_FUTURE_MIN_PHP_VERSION, GravityView_Plugin::version );
197
198
			self::$notices[ $key ] = array(
199
				'class' => 'error',
200
				'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>' ),
201
				'cap' => 'manage_options',
202
				'dismiss' => $key,
203
			);
204
205
		}
206
207
		return true;
208
	}
209
210
	/**
211
	 * Is WordPress compatible?
212
	 *
213
	 * @since 1.12
214
	 * @return boolean
215
	 */
216
	public static function check_wordpress() {
217
		global $wp_version;
218
219
		if( version_compare( $wp_version, GV_MIN_WP_VERSION ) <= 0 ) {
220
221
			self::$notices['wp_version'] = array(
222
				'class' => 'error',
223
				'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>' ),
224
			    'cap' => 'update_core',
225
				'dismiss' => 'wp_version',
226
			);
227
228
			return false;
229
		}
230
231
		return true;
232
	}
233
234
235
	/**
236
	 * Check if Gravity Forms plugin is active and show notice if not.
237
	 *
238
	 * @since 1.12
239
	 *
240
	 * @access public
241
	 * @return boolean True: checks have been passed; GV is fine to run; False: checks have failed, don't continue loading
242
	 */
243
	public static function check_gravityforms() {
244
245
		// Bypass other checks: if the class exists
246
		if( class_exists( 'GFCommon' ) ) {
247
248
			// Does the version meet future requirements?
249
			if( true === version_compare( GFCommon::$version, GV_FUTURE_MIN_GF_VERSION, ">=" ) ) {
250
				return true;
251
			}
252
253
			// Does it meet minimum requirements?
254
			$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...
255
256
			$class = $meets_minimum ? 'notice-warning' : 'error';
257
258
			// Show the notice even if the future version requirements aren't met
259
			self::$notices['gf_version'] = array(
260
				'class' => $class,
261
				'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>'),
262
				'cap' => 'update_plugins',
263
				'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...
264
			);
265
266
			// Return false if the plugin is not compatible, true if meets minimum
267
			return $meets_minimum;
268
		}
269
270
		$gf_status = self::get_plugin_status( 'gravityforms/gravityforms.php' );
271
272
		/**
273
		 * The plugin is activated and yet somehow GFCommon didn't get picked up...
274
		 * OR
275
		 * It's the Network Admin and we just don't know whether the sites have GF activated themselves.
276
		 */
277
		if( true === $gf_status || is_network_admin() ) {
278
			return true;
279
		}
280
281
		// If GFCommon doesn't exist, assume GF not active
282
		$return = false;
283
284
		switch( $gf_status ) {
285
			case 'inactive':
286
287
				// Required for multisite
288
				if( ! function_exists('wp_create_nonce') ) {
289
					require_once ABSPATH . WPINC . '/pluggable.php';
290
				}
291
292
				// Otherwise, throws an error on activation & deactivation "Use of undefined constant LOGGED_IN_COOKIE"
293
				if( is_multisite() ) {
294
					wp_cookie_constants();
295
				}
296
297
				$return = false;
298
299
				$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">';
300
301
				self::$notices['gf_inactive'] = array(
302
					'class' => 'error',
303
					'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>' ),
304
					'cap' => 'activate_plugins',
305
					'dismiss' => 'gf_inactive',
306
				);
307
308
				break;
309
			default:
310
				self::$notices['gf_installed'] = array(
311
					'class' => 'error',
312
					'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>'),
313
					'cap' => 'install_plugins',
314
					'dismiss' => 'gf_installed',
315
				);
316
				break;
317
		}
318
319
		return $return;
320
	}
321
322
	/**
323
	 * Check for potential conflicts and let users know about common issues.
324
	 *
325
	 * @return void
326
	 */
327
	private static function check_gf_directory() {
328
329
		if( class_exists( 'GFDirectory' ) ) {
330
			self::$notices['gf_directory'] = array(
331
				'class' => 'error is-dismissible',
332
				'title' => __('Potential Conflict', 'gravityview' ),
333
				'message' => __( 'GravityView and Gravity Forms Directory are both active. This may cause problems. If you experience issues, disable the Gravity Forms Directory plugin.', 'gravityview' ),
334
				'dismiss' => 'gf_directory',
335
				'cap' => 'activate_plugins',
336
			);
337
		}
338
339
	}
340
341
	/**
342
	 * Check if specified plugin is active, inactive or not installed
343
	 *
344
	 * @access public
345
	 * @static
346
	 * @param string $location (default: '')
347
	 * @return boolean|string True: plugin is active; False: plugin file doesn't exist at path; 'inactive' it's inactive
348
	 */
349
	public static function get_plugin_status( $location = '' ) {
350
351
		if( ! function_exists('is_plugin_active') ) {
352
			include_once( ABSPATH . '/wp-admin/includes/plugin.php' );
353
		}
354
355
		if( is_network_admin() && is_plugin_active_for_network( $location ) ) {
356
			return true;
357
		}
358
359
		if( !is_network_admin() && is_plugin_active( $location ) ) {
360
			return true;
361
		}
362
363
		if(
364
			!file_exists( trailingslashit( WP_PLUGIN_DIR ) . $location ) &&
365
			!file_exists( trailingslashit( WPMU_PLUGIN_DIR ) . $location )
366
		) {
367
			return false;
368
		}
369
370
		return 'inactive';
371
	}
372
373
}
374
375
GravityView_Compatibility::getInstance();
376