Completed
Push — master ( 6337a4...1e5684 )
by Zack
11s
created

includes/class-gravityview-compatibility.php (9 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>' ),
0 ignored issues
show
Expected a sanitizing function (see Codex for 'Data Validation'), but instead saw 'phpversion'
Loading history...
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 );
0 ignored issues
show
Expected 1 spaces after opening bracket; 0 found
Loading history...
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>' ),
0 ignored issues
show
Expected a sanitizing function (see Codex for 'Data Validation'), but instead saw 'phpversion'
Loading history...
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>' ),
0 ignored issues
show
Expected next thing to be a escaping function, not '$wp_version'
Loading history...
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
			// and the version's right, we're good.
249
			if( true === version_compare( GFCommon::$version, GV_MIN_GF_VERSION, ">=" ) ) {
250
				return true;
251
			}
252
253
			// Or the version's wrong
254
			self::$notices['gf_version'] = array(
255
				'class' => 'error',
256
				'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_MIN_GF_VERSION, "</h3>\n\n", '<span style="font-family: Consolas, Courier, monospace;">'.GFCommon::$version.'</span>', "\n\n".'<a href="http://katz.si/gravityforms" class="button button-secondary button-large button-hero">' , '<em>', '</em>', '</a>'),
0 ignored issues
show
Expected 1 spaces before closing bracket; 0 found
Loading history...
Expected a sanitizing function (see Codex for 'Data Validation'), but instead saw 'GFCommon'
Loading history...
257
				'cap' => 'update_plugins',
258
				'dismiss' => 'gf_version',
259
			);
260
261
			return false;
262
		}
263
264
		$gf_status = self::get_plugin_status( 'gravityforms/gravityforms.php' );
265
266
		/**
267
		 * The plugin is activated and yet somehow GFCommon didn't get picked up...
268
		 * OR
269
		 * It's the Network Admin and we just don't know whether the sites have GF activated themselves.
270
		 */
271
		if( true === $gf_status || is_network_admin() ) {
272
			return true;
273
		}
274
275
		// If GFCommon doesn't exist, assume GF not active
276
		$return = false;
277
278
		switch( $gf_status ) {
279
			case 'inactive':
280
281
				// Required for multisite
282
				if( ! function_exists('wp_create_nonce') ) {
283
					require_once ABSPATH . WPINC . '/pluggable.php';
284
				}
285
286
				// Otherwise, throws an error on activation & deactivation "Use of undefined constant LOGGED_IN_COOKIE"
287
				if( is_multisite() ) {
288
					wp_cookie_constants();
289
				}
290
291
				$return = false;
292
293
				$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">';
0 ignored issues
show
Expected 1 spaces after opening bracket; 0 found
Loading history...
Expected 1 spaces before closing bracket; 0 found
Loading history...
294
295
				self::$notices['gf_inactive'] = array(
296
					'class' => 'error',
297
					'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>' ),
298
					'cap' => 'activate_plugins',
299
					'dismiss' => 'gf_inactive',
300
				);
301
302
				break;
303
			default:
304
				self::$notices['gf_installed'] = array(
305
					'class' => 'error',
306
					'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>'),
0 ignored issues
show
Expected 1 spaces before closing bracket; 0 found
Loading history...
307
					'cap' => 'install_plugins',
308
					'dismiss' => 'gf_installed',
309
				);
310
				break;
311
		}
312
313
		return $return;
314
	}
315
316
	/**
317
	 * Check for potential conflicts and let users know about common issues.
318
	 *
319
	 * @return void
320
	 */
321
	private static function check_gf_directory() {
322
323
		if( class_exists( 'GFDirectory' ) ) {
324
			self::$notices['gf_directory'] = array(
325
				'class' => 'error is-dismissible',
326
				'title' => __('Potential Conflict', 'gravityview' ),
327
				'message' => __( 'GravityView and Gravity Forms Directory are both active. This may cause problems. If you experience issues, disable the Gravity Forms Directory plugin.', 'gravityview' ),
328
				'dismiss' => 'gf_directory',
329
				'cap' => 'activate_plugins',
330
			);
331
		}
332
333
	}
334
335
	/**
336
	 * Check if specified plugin is active, inactive or not installed
337
	 *
338
	 * @access public
339
	 * @static
340
	 * @param string $location (default: '')
341
	 * @return boolean|string True: plugin is active; False: plugin file doesn't exist at path; 'inactive' it's inactive
342
	 */
343
	public static function get_plugin_status( $location = '' ) {
344
345
		if( ! function_exists('is_plugin_active') ) {
346
			include_once( ABSPATH . '/wp-admin/includes/plugin.php' );
347
		}
348
349
		if( is_network_admin() && is_plugin_active_for_network( $location ) ) {
350
			return true;
351
		}
352
353
		if( !is_network_admin() && is_plugin_active( $location ) ) {
354
			return true;
355
		}
356
357
		if(
358
			!file_exists( trailingslashit( WP_PLUGIN_DIR ) . $location ) &&
359
			!file_exists( trailingslashit( WPMU_PLUGIN_DIR ) . $location )
360
		) {
361
			return false;
362
		}
363
364
		return 'inactive';
365
	}
366
367
}
368
369
GravityView_Compatibility::getInstance();
370