Passed
Push — master ( 8403c0...3ede7f )
by Chris
08:42
created

get_instance()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 6
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
cc 2
eloc 3
c 2
b 0
f 0
nc 2
nop 0
dl 0
loc 6
rs 10
1
<?php
2
3
if ( ! class_exists( 'MonsterInsights_Compatibility_Check' ) ) {
4
	/**
5
	 * Check PHP and WP compatibility
6
	 *
7
	 * @since 8.0.0
8
	 */
9
	class MonsterInsights_Compatibility_Check {
10
		/**
11
		 * Holds singleton instance
12
		 *
13
		 * @since 8.0.0
14
		 * @var MonsterInsights_Compatibility_Check
15
		 */
16
		private static $instance;
17
18
		/**
19
		 * Return Singleton instance
20
		 *
21
		 * @since 8.0.0
22
		 * @return MonsterInsights_Compatibility_Check
23
		 */
24
		public static function get_instance() {
25
			if ( empty( self::$instance ) ) {
26
				self::$instance = new self();
27
			}
28
29
			return self::$instance;
30
		}
31
32
		/**
33
		 * @since 8.0.0
34
		 * @var array {
35
		 *     PHP Version requirement and recommendation
36
		 *
37
		 *     @type string $required Halt and deactivate plugin if PHP is under this version
38
		 *     @type string $warning Display undismissable warning if PHP is under this version
39
		 *     @type string $recommended Display undismissable warning if PHP is under this version
40
		 * }
41
		 */
42
		private $compatible_php_version = array(
43
			'required'    => '5.5',
44
			'warning'     => '7.0',
45
			'recommended' => '7.2',
46
		);
47
48
		/**
49
		 * @since 8.0.0
50
		 * @var array {
51
		 *     WP Version requirement and recommendation
52
		 *
53
		 *     @type string $required Halt and deactivate plugin if WP is under this version
54
		 *     @type string $warning Display undismissable warning if WP is under this version
55
		 *     @type string $recommended Display undismissable warning if WP is under this version
56
		 * }
57
		 */
58
		private $compatible_wp_version = array(
59
			'required'    => '4.8',
60
			'warning'     => '4.9',
61
			'recommended' => false,
62
		);
63
64
		/**
65
		 * Private constructor
66
		 *
67
		 * @since 8.0.0
68
		 */
69
		private function __construct() {
70
			add_filter( 'monsterinsights_compatible_php_version', array( $this, 'filter_compatible_php_version' ), 10, 1 );
71
			add_filter( 'monsterinsights_compatible_wp_version', array( $this, 'filter_compatible_wp_version' ), 10, 1 );
72
		}
73
74
		/**
75
		 * Return the strictest php compatibility versions
76
		 *
77
		 * @param array $version {
78
		 *     PHP Version requirement and recommendation
79
		 *
80
		 *     @type string $required    Halt and deactivate plugin if PHP is under this version
81
		 *     @type string $warning     Display undismissable warning if PHP is under this version
82
		 *     @type string $recommended Display undismissable warning if PHP is under this version
83
		 * }
84
		 *
85
		 * @since 8.0.0
86
		 * @return array {
87
		 *     PHP Version requirement and recommendation
88
		 *
89
		 *     @type string $required    Halt and deactivate plugin if PHP is under this version
90
		 *     @type string $warning     Display undismissable warning if PHP is under this version
91
		 *     @type string $recommended Display undismissable warning if PHP is under this version
92
		 * }
93
		 */
94
		public function filter_compatible_php_version( $version ) {
95
			if ( ! $version || version_compare( $version['required'], $this->compatible_php_version['required'], '<' ) ) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $version of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
96
				return $this->compatible_php_version;
97
			}
98
99
			return $version;
100
		}
101
102
		/**
103
		 * Return the strictest WP compatibility versions
104
		 *
105
		 * @param array $version     {
106
		 *     WP Version requirement and recommendation
107
		 *
108
		 *     @type string $required Halt and deactivate plugin if WP is under this version
109
		 *     @type string $warning Display undismissable warning if WP is under this version
110
		 *     @type string $recommended Display undismissable warning if WP is under this version
111
		 * }
112
		 *
113
		 * @since 8.0.0
114
		 * @return array {
115
		 *     WP Version requirement and recommendation
116
		 *
117
		 *     @type string $required Halt and deactivate plugin if WP is under this version
118
		 *     @type string $warning Display undismissable warning if WP is under this version
119
		 *     @type string $recommended Display undismissable warning if WP is under this version
120
		 * }
121
		 */
122
		public function filter_compatible_wp_version( $version ) {
123
			if ( ! $version || version_compare( $version['required'], $this->compatible_wp_version['required'], '<' ) ) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $version of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
124
				return $this->compatible_wp_version;
125
			}
126
127
			return $version;
128
		}
129
130
		/**
131
		 * Return required, warning and recommended PHP versions
132
		 *
133
		 * @since 8.0.0
134
		 * @return array {
135
		 *     PHP Version requirement and recommendation
136
		 *
137
		 *     @type string $required    Halt and deactivate plugin if PHP is under this version
138
		 *     @type string $warning     Display undismissable warning if PHP is under this version
139
		 *     @type string $recommended Display undismissable warning if PHP is under this version
140
		 * }
141
		 */
142
		public function get_compatible_php_version() {
143
			return apply_filters( 'monsterinsights_compatible_php_version', $this->compatible_php_version );
144
		}
145
146
		/**
147
		 * Check to see if PHP version meets the minimum required version
148
		 *
149
		 * @since 8.0.0
150
		 * @return bool
151
		 */
152
		public function is_php_compatible() {
153
			$compatible_php_version = $this->get_compatible_php_version();
154
155
			return empty( $compatible_php_version['required'] ) || version_compare( phpversion(), $compatible_php_version['required'], '>=' );
156
		}
157
158
		/**
159
		 * Return required, warning and recommended WP versions
160
		 *
161
		 * @since 8.0.0
162
		 * @return array {
163
		 *     WP Version requirement and recommendation
164
		 *
165
		 *     @type string $required Halt and deactivate plugin if WP is under this version
166
		 *     @type string $warning Display undismissable warning if WP is under this version
167
		 *     @type string $recommended Display undismissable warning if WP is under this version
168
		 * }
169
		 */
170
		public function get_compatible_wp_version() {
171
			return apply_filters( 'monsterinsights_compatible_wp_version', $this->compatible_wp_version );
172
		}
173
174
		/**
175
		 * Check to see if WP version meets the minimum required version
176
		 *
177
		 * @since 8.0.0
178
		 * @return bool
179
		 */
180
		public function is_wp_compatible() {
181
			global $wp_version;
182
			$compatible_wp_version = $this->get_compatible_wp_version();
183
184
			return empty( $compatible_wp_version['required'] ) || version_compare( $wp_version, $compatible_wp_version['required'], '>=' );
185
		}
186
187
		/**
188
		 * Check to see if the main plugin or any other add-ons have displayed the required version notice
189
		 *
190
		 * @since 8.0.0
191
		 * @return bool
192
		 */
193
		private function is_notice_already_active() {
194
			return defined( 'MONSTERINSIGHTS_VERSION_NOTICE_ACTIVE' ) && MONSTERINSIGHTS_VERSION_NOTICE_ACTIVE;
195
		}
196
197
		/**
198
		 * Set global constant so that main plugin or other add-ons are aware that the version notice
199
		 * has been set for display already
200
		 *
201
		 * @since 8.0.0
202
		 * @return void
203
		 */
204
		private function set_notice_active() {
205
			if ( ! defined( 'MONSTERINSIGHTS_VERSION_NOTICE_ACTIVE' ) ) {
206
				define( 'MONSTERINSIGHTS_VERSION_NOTICE_ACTIVE', true );
207
			}
208
		}
209
210
		/**
211
		 * Display version notice in admin area if:
212
		 * 1. Minimum PHP and WP versions are not met
213
		 * 2. The notice has been displayed elsewhere (in case there are multiple add-ons)
214
		 *
215
		 * @since 8.0.0
216
		 * @return void
217
		 */
218
		public function maybe_display_notice() {
219
			if ( defined( 'MONSTERINSIGHTS_FORCE_ACTIVATION' ) && MONSTERINSIGHTS_FORCE_ACTIVATION ) {
0 ignored issues
show
Bug introduced by
The constant MONSTERINSIGHTS_FORCE_ACTIVATION was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
220
				return;
221
			}
222
223
			if ( $this->is_notice_already_active() ) {
224
				return;
225
			}
226
227
			if ( ! $this->is_php_compatible() ) {
228
				add_action( 'admin_notices', array( $this, 'display_php_notice' ) );
229
			}
230
231
			if ( ! $this->is_wp_compatible() ) {
232
				add_action( 'admin_notices', array( $this, 'display_wp_notice' ) );
233
			}
234
		}
235
236
		/**
237
		 * Deactivate plugin if minimum PHP and WP requirements are not met.
238
		 *
239
		 * @since 8.0.0
240
		 * @param $plugin
241
		 * @return void
242
		 */
243
		public function maybe_deactivate_plugin( $plugin ) {
244
			if ( defined( 'MONSTERINSIGHTS_FORCE_ACTIVATION' ) && MONSTERINSIGHTS_FORCE_ACTIVATION ) {
0 ignored issues
show
Bug introduced by
The constant MONSTERINSIGHTS_FORCE_ACTIVATION was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
245
				return;
246
			}
247
248
			$url = admin_url( 'plugins.php' );
249
			$compatible_php_version = $this->get_compatible_php_version();
250
			$compatible_wp_version  = $this->get_compatible_wp_version();
251
252
			if ( ! empty( $compatible_php_version['required'] ) && ! $this->is_php_compatible() ) {
253
				deactivate_plugins( $plugin );
254
				wp_die(
255
					sprintf( esc_html__( 'Sorry, but your version of PHP does not meet MonsterInsights\' required version of %1$s%2$s%3$s to run properly. The plugin has not been activated. %4$sClick here to return to the Dashboard%5$s.', 'google-analytics-for-wordpress' ),
256
						'<strong>',
257
						$compatible_php_version['required'],
258
						'</strong>',
259
						'<a href="' . $url . '">',
260
						'</a>'
261
					)
262
				);
263
			}
264
265
			if ( ! empty( $compatible_wp_version['required'] ) && ! $this->is_wp_compatible() ) {
266
				deactivate_plugins( plugin_basename( __FILE__ ) );
267
				wp_die(
268
					sprintf(
269
						esc_html__( 'Sorry, but your version of WordPress does not meet MonsterInsights\' required version of %1$s%2$s%3$s to run properly. The plugin has not been activated. %4$sClick here to return to the Dashboard%5$s.', 'google-analytics-for-wordpress' ),
270
						'<strong>',
271
						$compatible_wp_version['required'],
272
						'</strong>',
273
						'<a href="' . $url . '">',
274
						'</a>'
275
					)
276
				);
277
			}
278
		}
279
280
		/**
281
		 * Output a nag notice if the user has an out of date PHP version installed
282
		 *
283
		 * @since 8.0.0
284
		 * @return void
285
		 */
286
		public function display_php_notice() {
287
			$url = admin_url( 'plugins.php' );
288
			// Check for MS dashboard
289
			if ( is_network_admin() ) {
290
				$url = network_admin_url( 'plugins.php' );
291
			}
292
293
			$compatible_php_version = $this->get_compatible_php_version();
294
			if ( empty( $compatible_php_version['required'] ) ) {
295
				return;
296
			}
297
298
			$this->set_notice_active();
299
			?>
300
			<div class="error">
301
				<p>
302
					<?php echo sprintf(
303
						esc_html__( 'Sorry, but your version of PHP does not meet MonsterInsights\' required version of %1$s%2$s%3$s to run properly. The plugin has not been activated. %4$sClick here to return to the Dashboard%5$s.', 'google-analytics-for-wordpress' ),
304
						'<strong>',
305
						$compatible_php_version['required'],
306
						'</strong>',
307
						'<a href="' . $url . '">',
308
						'</a>' );
309
					?>
310
				</p>
311
			</div>
312
			<?php
313
		}
314
315
		/**
316
		 * Output a nag notice if the user has an out of date WP version installed
317
		 *
318
		 * @since 8.0.0
319
		 * @return void
320
		 */
321
		public function display_wp_notice() {
322
			$url = admin_url( 'plugins.php' );
323
324
			// Check for MS dashboard
325
			if( is_network_admin() ) {
326
				$url = network_admin_url( 'plugins.php' );
327
			}
328
329
			$compatible_wp_version = $this->get_compatible_wp_version();
330
			if ( empty( $compatible_wp_version['required'] ) ) {
331
				return;
332
			}
333
334
			$this->set_notice_active();
335
			?>
336
			<div class="error">
337
				<p>
338
					<?php
339
					// Translators: Make version number bold and add a link to return to the plugins page.
340
					echo sprintf(
341
						esc_html__( 'Sorry, but your version of WordPress does not meet MonsterInsights\' required version of %1$s%2$s%3$s to run properly. The plugin has not been activated. %4$sClick here to return to the Dashboard%5$s.', 'google-analytics-for-wordpress' ),
342
						'<strong>',
343
						$compatible_wp_version['required'],
344
						'</strong>',
345
						'<a href="' . $url . '">',
346
						'</a>'
347
					);
348
					?>
349
				</p>
350
			</div>
351
			<?php
352
		}
353
	}
354
}
355