Completed
Push — master ( 454d28...08f45f )
by Der Mundschenk
02:11
created

Mundschenk_WP_Requirements::check_php_support()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 2
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 1
c 1
b 0
f 0
nc 1
nop 0
dl 0
loc 2
ccs 2
cts 2
cp 1
crap 1
rs 10
1
<?php
2
/**
3
 *  This file is part of mundschenk-at/check-wp-requirements.
4
 *
5
 *  Copyright 2014-2018 Peter Putzer.
6
 *  Copyright 2009-2011 KINGdesk, LLC.
7
 *
8
 *  This program is free software; you can redistribute it and/or
9
 *  modify it under the terms of the GNU General Public License
10
 *  as published by the Free Software Foundation; either version 2
11
 *  of the License, or (at your option) any later version.
12
 *
13
 *  This program is distributed in the hope that it will be useful,
14
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
15
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
 *  GNU General Public License for more details.
17
 *
18
 *  You should have received a copy of the GNU General Public License
19
 *  along with this program; if not, write to the Free Software
20
 *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
21
 *
22
 *  ***
23
 *
24
 *  @package mundschenk-at/check-wp-requirements
25
 *  @license http://www.gnu.org/licenses/gpl-2.0.html
26
 */
27
28
// Prevent multiple class definitions because there is no autoloader to protect us.
29
if ( ! class_exists( 'Mundschenk_WP_Requirements' ) ) {
30
31
	/**
32
	 * This class checks if the required runtime environment is available.
33
	 *
34
	 * Included checks:
35
	 *    - PHP version
36
	 *    - mb_string extension
37
	 *    - UTF-8 encoding
38
	 *
39
	 * Note: All code must be executable on PHP 5.2.
40
	 */
41
	class Mundschenk_WP_Requirements {
42
43
		/**
44
		 * The minimum requirements for running the plugins. Must contain:
45
		 *  - 'php'
46
		 *  - 'multibyte'
47
		 *  - 'utf-8'
48
		 *
49
		 * @var array A hash containing the version requirements for the plugin.
50
		 */
51
		private $install_requirements;
52
53
		/**
54
		 * The user-visible name of the plugin.
55
		 *
56
		 * @todo Should the plugin name be translated?
57
		 * @var string
58
		 */
59
		private $plugin_name;
60
61
		/**
62
		 * The full path to the main plugin file.
63
		 *
64
		 * @var string
65
		 */
66
		private $plugin_file;
67
68
		/**
69
		 * The textdomain used for loading plugin translations.
70
		 *
71
		 * @var string
72
		 */
73
		private $textdomain;
74
75
		/**
76
		 * The base directory of the Check_WP_Requirements component (i.e. the equivalent of __DIR__).
77
		 *
78
		 * @var string
79
		 */
80
		private $base_dir;
81
82
		/**
83
		 * Sets up a new Mundschenk_WP_Requirements object.
84
		 *
85
		 * @param string $name         The plugin name.
86
		 * @param string $plugin_path  The full path to the main plugin file.
87
		 * @param string $textdomain   The text domain used for i18n.
88
		 * @param array  $requirements The requirements to check against.
89
		 */
90 1
		public function __construct( $name, $plugin_path, $textdomain, $requirements ) {
91 1
			$this->plugin_name = $name;
92 1
			$this->plugin_file = $plugin_path;
93 1
			$this->textdomain  = $textdomain;
94 1
			$this->base_dir    = dirname( __FILE__ );
95
96 1
			$this->install_requirements = \wp_parse_args( $requirements, array(
97 1
				'php'       => '5.2.0',
98
				'multibyte' => false,
99
				'utf-8'     => false,
100
			) );
101 1
		}
102
103
		/**
104
		 * Checks if all runtime requirements for the plugin are met.
105
		 *
106
		 * @return bool
107
		 */
108 11
		public function check() {
109 11
			$requirements_met = true;
110
111 11
			foreach ( $this->get_requirements() as $requirement ) {
112 11
				if ( ! empty( $this->install_requirements[ $requirement['enable_key'] ] ) && ! call_user_func( $requirement['check'] ) ) {
113 9
					$notice           = $requirement['notice'];
114 9
					$requirements_met = false;
115 11
					break;
116
				}
117
			}
118
119 11
			if ( ! $requirements_met && ! empty( $notice ) && is_admin() ) {
120
				// Load text domain to ensure translated admin notices.
121 5
				load_plugin_textdomain( $this->textdomain );
122
123
				// Add admin notice.
124 5
				add_action( 'admin_notices', $notice );
125
			}
126
127 11
			return $requirements_met;
128
		}
129
130
131
		/**
132
		 * Retrieves an array of requirement specifications.
133
		 *
134
		 * @return array {
135
		 *         An array of requirements checks.
136
		 *
137
		 *   @type string   $enable_key An index in the $install_requirements array to switch the check on and off.
138
		 *   @type callable $check      A function returning true if the check was successful, false otherwise.
139
		 *   @type callable $notice     A function displaying an appropriate error notice.
140
		 * }
141
		 */
142 11
		protected function get_requirements() {
143
			return array(
144
				array(
145 11
					'enable_key' => 'php',
146 11
					'check'      => array( $this, 'check_php_support' ),
147 11
					'notice'     => array( $this, 'admin_notices_php_version_incompatible' ),
148
				),
149
				array(
150 11
					'enable_key' => 'multibyte',
151 11
					'check'      => array( $this, 'check_multibyte_support' ),
152 11
					'notice'     => array( $this, 'admin_notices_mbstring_incompatible' ),
153
				),
154
				array(
155 11
					'enable_key' => 'utf-8',
156 11
					'check'      => array( $this, 'check_utf8_support' ),
157 11
					'notice'     => array( $this, 'admin_notices_charset_incompatible' ),
158
				),
159
			);
160
		}
161
162
		/**
163
		 * Deactivates the plugin.
164
		 */
165 1
		public function deactivate_plugin() {
166 1
			deactivate_plugins( plugin_basename( $this->plugin_file ) );
167 1
		}
168
169
		/**
170
		 * Checks if the PHP version in use is at least equal to the required version.
171
		 *
172
		 * @return bool
173
		 */
174 1
		protected function check_php_support() {
175 1
			return version_compare( PHP_VERSION, $this->install_requirements['php'], '>=' );
176
		}
177
178
		/**
179
		 * Checks if multibyte functions are supported.
180
		 *
181
		 * @return bool
182
		 */
183 1
		protected function check_multibyte_support() {
184 1
			return function_exists( 'mb_strlen' )
185 1
				&& function_exists( 'mb_strtolower' )
186 1
				&& function_exists( 'mb_substr' )
187 1
				&& function_exists( 'mb_detect_encoding' );
188
		}
189
190
		/**
191
		 * Checks if the blog charset is set to UTF-8.
192
		 *
193
		 * @return bool
194
		 */
195 4
		protected function check_utf8_support() {
196 4
			return 'utf-8' === strtolower( get_bloginfo( 'charset' ) );
197
		}
198
199
		/**
200
		 * Print 'PHP version incompatible' admin notice
201
		 */
202 1
		public function admin_notices_php_version_incompatible() {
203 1
			$this->display_error_notice(
204
				/* translators: 1: plugin name 2: target PHP version number 3: actual PHP version number */
205 1
				__( 'The activated plugin %1$s requires PHP %2$s or later. Your server is running PHP %3$s. Please deactivate this plugin, or upgrade your server\'s installation of PHP.', $this->textdomain ),
206 1
				"<strong>{$this->plugin_name}</strong>",
207 1
				$this->install_requirements['php'],
208 1
				phpversion()
209
			);
210 1
		}
211
212
		/**
213
		 * Prints 'mbstring extension missing' admin notice
214
		 */
215 1
		public function admin_notices_mbstring_incompatible() {
216 1
			$this->display_error_notice(
217
				/* translators: 1: plugin name 2: mbstring documentation URL */
218 1
				__( 'The activated plugin %1$s requires the mbstring PHP extension to be enabled on your server. Please deactivate this plugin, or <a href="%2$s">enable the extension</a>.', $this->textdomain ),
219 1
				"<strong>{$this->plugin_name}</strong>",
220
				/* translators: URL with mbstring PHP extension installation instructions */
221 1
				__( 'http://www.php.net/manual/en/mbstring.installation.php', $this->textdomain )
222
			);
223 1
		}
224
225
		/**
226
		 * Prints 'Charset incompatible' admin notice
227
		 */
228 1
		public function admin_notices_charset_incompatible() {
229 1
			$this->display_error_notice(
230
				/* translators: 1: plugin name 2: current character encoding 3: options URL */
231 1
				__( 'The activated plugin %1$s requires your blog use the UTF-8 character encoding. You have set your blogs encoding to %2$s. Please deactivate this plugin, or <a href="%3$s">change your character encoding to UTF-8</a>.', $this->textdomain ),
232 1
				"<strong>{$this->plugin_name}</strong>",
233 1
				get_bloginfo( 'charset' ),
234 1
				'/wp-admin/options-reading.php'
235
			);
236 1
		}
237
238
		/**
239
		 * Shows an error message in the admin area.
240
		 *
241
		 * @param string $format ... An `sprintf` format string, followd by an unspecified number of optional parameters.
242
		 */
243 2
		protected function display_error_notice( $format ) {
244 2
			if ( func_num_args() < 1 || empty( $format ) ) {
245 1
				return; // abort.
246
			}
247
248 1
			$args    = func_get_args();
249 1
			$format  = array_shift( $args );
250 1
			$message = vsprintf( $format, $args );
251
252 1
			require "{$this->base_dir}/partials/requirements-error-notice.php";
253 1
		}
254
	}
255
}
256