Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
0.00% |
0 / 312 |
|
0.00% |
0 / 18 |
CRAP | |
0.00% |
0 / 1 |
PluginInstaller | |
0.00% |
0 / 312 |
|
0.00% |
0 / 18 |
9312 | |
0.00% |
0 / 1 |
install | |
0.00% |
0 / 60 |
|
0.00% |
0 / 1 |
420 | |||
install_from_wordpress | |
0.00% |
0 / 23 |
|
0.00% |
0 / 1 |
20 | |||
install_premium_plugin | |
0.00% |
0 / 76 |
|
0.00% |
0 / 1 |
342 | |||
install_from_zip | |
0.00% |
0 / 65 |
|
0.00% |
0 / 1 |
210 | |||
is_nfd_slug | |
0.00% |
0 / 4 |
|
0.00% |
0 / 1 |
6 | |||
is_plugin_installed | |
0.00% |
0 / 6 |
|
0.00% |
0 / 1 |
12 | |||
get_plugin_type | |
0.00% |
0 / 5 |
|
0.00% |
0 / 1 |
12 | |||
get_plugin_path | |
0.00% |
0 / 2 |
|
0.00% |
0 / 1 |
6 | |||
exists | |
0.00% |
0 / 7 |
|
0.00% |
0 / 1 |
30 | |||
is_active | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
activate | |
0.00% |
0 / 7 |
|
0.00% |
0 / 1 |
20 | |||
deactivate | |
0.00% |
0 / 8 |
|
0.00% |
0 / 1 |
20 | |||
install_endurance_page_cache | |
0.00% |
0 / 25 |
|
0.00% |
0 / 1 |
30 | |||
connect_to_filesystem | |
0.00% |
0 / 8 |
|
0.00% |
0 / 1 |
12 | |||
check_install_permissions | |
0.00% |
0 / 3 |
|
0.00% |
0 / 1 |
6 | |||
rest_get_plugin_install_hash | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
rest_verify_plugin_install_hash | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
get_plugin_status | |
0.00% |
0 / 10 |
|
0.00% |
0 / 1 |
20 |
1 | <?php |
2 | namespace NewfoldLabs\WP\Module\Installer\Services; |
3 | |
4 | use NewfoldLabs\WP\Module\Installer\Data\Plugins; |
5 | use NewfoldLabs\WP\Module\Installer\Permissions; |
6 | use NewfoldLabs\WP\Module\PLS\Utilities\PLSUtility; |
7 | |
8 | /** |
9 | * Class PluginInstaller |
10 | */ |
11 | class PluginInstaller { |
12 | |
13 | /** |
14 | * Install a whitelisted plugin. |
15 | * |
16 | * @param string $plugin The plugin slug from Plugins.php. |
17 | * @param boolean $should_activate Whether to activate the plugin after install. |
18 | * |
19 | * @return \WP_Error|\WP_REST_Response |
20 | */ |
21 | public static function install( $plugin, $should_activate = true ) { |
22 | $plugins_list = Plugins::get(); |
23 | |
24 | // Check if the plugin param contains a zip url. |
25 | if ( \wp_http_validate_url( $plugin ) ) { |
26 | $domain = \wp_parse_url( $plugin, PHP_URL_HOST ); |
27 | // If the zip URL/domain is not approved. |
28 | if ( ! isset( $plugins_list['urls'][ $plugin ] ) |
29 | && ! isset( $plugins_list['domains'][ $domain ] ) ) { |
30 | return new \WP_Error( |
31 | 'plugin-error', |
32 | /* Translators: %s plugin slug */ |
33 | sprintf( __( 'You do not have permission to install from %s.', 'wp-module-installer' ), $plugin ), |
34 | array( 'status' => 400 ) |
35 | ); |
36 | } |
37 | |
38 | $status = self::install_from_zip( $plugin, $should_activate ); |
39 | if ( \is_wp_error( $status ) ) { |
40 | return $status; |
41 | } |
42 | |
43 | return new \WP_REST_Response( |
44 | array(), |
45 | 201 |
46 | ); |
47 | } |
48 | |
49 | // If it is not a zip URL then check if it is an approved slug. |
50 | $plugin = \sanitize_text_field( $plugin ); |
51 | if ( self::is_nfd_slug( $plugin ) ) { |
52 | // [TODO] Better handle mu-plugins and direct file downloads. |
53 | if ( 'nfd_slug_endurance_page_cache' === $plugin ) { |
54 | return self::install_endurance_page_cache(); |
55 | } |
56 | $plugin_path = $plugins_list['nfd_slugs'][ $plugin ]['path']; |
57 | if ( ! self::is_plugin_installed( $plugin_path ) ) { |
58 | $status = self::install_from_zip( $plugins_list['nfd_slugs'][ $plugin ]['url'], $should_activate ); |
59 | if ( \is_wp_error( $status ) ) { |
60 | return $status; |
61 | } |
62 | } |
63 | if ( $should_activate && ! \is_plugin_active( $plugin_path ) ) { |
64 | $status = \activate_plugin( $plugin_path ); |
65 | if ( \is_wp_error( $status ) ) { |
66 | $status->add_data( array( 'status' => 500 ) ); |
67 | |
68 | return $status; |
69 | } |
70 | } |
71 | return new \WP_REST_Response( |
72 | array(), |
73 | 201 |
74 | ); |
75 | } |
76 | |
77 | if ( ! isset( $plugins_list['wp_slugs'][ $plugin ] ) ) { |
78 | return new \WP_Error( |
79 | 'plugin-error', |
80 | /* Translators: %s plugin slug */ |
81 | sprintf( __( 'You do not have permission to install %s.', 'wp-module-installer' ), $plugin ), |
82 | array( 'status' => 400 ) |
83 | ); |
84 | } |
85 | |
86 | $plugin_path = $plugins_list['wp_slugs'][ $plugin ]['path']; |
87 | $plugin_post_install_callback = isset( $plugins_list['wp_slugs'][ $plugin ]['post_install_callback'] ) |
88 | ? $plugins_list['wp_slugs'][ $plugin ]['post_install_callback'] |
89 | : false; |
90 | if ( ! self::is_plugin_installed( $plugin_path ) ) { |
91 | $status = self::install_from_wordpress( $plugin, $should_activate ); |
92 | if ( \is_wp_error( $status ) ) { |
93 | return $status; |
94 | } |
95 | if ( is_callable( $plugin_post_install_callback ) ) { |
96 | $plugin_post_install_callback(); |
97 | } |
98 | } |
99 | |
100 | if ( $should_activate && ! \is_plugin_active( $plugin_path ) ) { |
101 | $status = \activate_plugin( $plugin_path ); |
102 | if ( \is_wp_error( $status ) ) { |
103 | $status->add_data( array( 'status' => 500 ) ); |
104 | |
105 | return $status; |
106 | } |
107 | } |
108 | |
109 | return new \WP_REST_Response( |
110 | array(), |
111 | 201 |
112 | ); |
113 | } |
114 | |
115 | /** |
116 | * Install a plugin from wordpress.org. |
117 | * |
118 | * @param string $plugin The wp_slug to install. |
119 | * @param boolean $should_activate Whether to activate the plugin after install. |
120 | * @return \WP_REST_Response|\WP_Error |
121 | */ |
122 | public static function install_from_wordpress( $plugin, $should_activate = true ) { |
123 | require_once ABSPATH . 'wp-admin/includes/plugin-install.php'; |
124 | |
125 | $api = \plugins_api( |
126 | 'plugin_information', |
127 | array( |
128 | 'slug' => $plugin, |
129 | 'fields' => array( |
130 | 'sections' => false, |
131 | 'language_packs' => true, |
132 | ), |
133 | ) |
134 | ); |
135 | |
136 | if ( is_wp_error( $api ) ) { |
137 | if ( false !== strpos( $api->get_error_message(), 'Plugin not found.' ) ) { |
138 | $api->add_data( array( 'status' => 404 ) ); |
139 | } else { |
140 | $api->add_data( array( 'status' => 500 ) ); |
141 | } |
142 | |
143 | return $api; |
144 | } |
145 | |
146 | $status = self::install_from_zip( $api->download_link, $should_activate, $api->language_packs ); |
147 | if ( \is_wp_error( $status ) ) { |
148 | return $status; |
149 | } |
150 | |
151 | return new \WP_REST_Response( |
152 | array(), |
153 | 200 |
154 | ); |
155 | } |
156 | |
157 | /** |
158 | * Provisions a license and installs or activates a premium plugin. |
159 | * |
160 | * @param string $plugin The slug of the premium plugin. |
161 | * @param string $provider The provider name for the premium plugin. |
162 | * @param boolean $should_activate Whether to activate the plugin after installation. (default: true) |
163 | * @param mixed $plugin_basename The plugin basename, if known. (default: false) |
164 | * |
165 | * @return \WP_Error|\WP_REST_Response |
166 | */ |
167 | public static function install_premium_plugin( $plugin, $provider, $should_activate = true, $plugin_basename = false ) { |
168 | $is_installed = false; |
169 | $is_active = false; |
170 | |
171 | // Ensure plugin and provider are not empty |
172 | if ( empty( $plugin ) || empty( $provider ) ) { |
173 | return new \WP_Error( |
174 | 'nfd_installer_error', |
175 | __( 'Plugin slug and provider name cannot be empty.', 'wp-module-installer' ) |
176 | ); |
177 | } |
178 | |
179 | $pls_utility = new PLSUtility(); |
180 | |
181 | // Provision a license for the premium plugin, this returns basename and download URL |
182 | $license_response = $pls_utility->provision_license( $plugin, $provider ); |
183 | if ( is_wp_error( $license_response ) ) { |
184 | $license_response->add( |
185 | 'nfd_installer_error', |
186 | __( 'Failed to provision license for premium plugin: ', 'wp-module-installer' ) . $plugin, |
187 | array( |
188 | 'plugin' => $plugin, |
189 | 'provider' => $provider, |
190 | ) |
191 | ); |
192 | return $license_response; |
193 | } |
194 | |
195 | // Maybe get the plugin basename from the license response |
196 | // This is only returned if the plugin is already installed and licensed |
197 | $plugin_basename = ! empty( $license_response['basename'] ) ? $license_response['basename'] : false; |
198 | |
199 | // Check if the plugin is already installed |
200 | if ( $plugin_basename && self::is_plugin_installed( $plugin_basename ) ) { |
201 | $is_installed = true; |
202 | } |
203 | // If NOT installed, install plugin |
204 | if ( ! $is_installed ) { |
205 | // Check if the download URL is present in the license response |
206 | if ( empty( $license_response['downloadUrl'] ) ) { |
207 | return new \WP_Error( |
208 | 'nfd_installer_error', |
209 | __( 'Download URL is missing for premium plugin: ', 'wp-module-installer' ) . $plugin, |
210 | array( |
211 | 'plugin' => $plugin, |
212 | 'provider' => $provider, |
213 | ) |
214 | ); |
215 | } |
216 | $install_status = self::install_from_zip( $license_response['downloadUrl'], $should_activate ); |
217 | if ( is_wp_error( $install_status ) ) { |
218 | $install_status->add( |
219 | 'nfd_installer_error', |
220 | __( 'Failed to install or activate the premium plugin: ', 'wp-module-installer' ) . $plugin, |
221 | array( |
222 | 'plugin' => $plugin, |
223 | 'provider' => $provider, |
224 | 'download_url' => $license_response['downloadUrl'], |
225 | ) |
226 | ); |
227 | return $install_status; |
228 | } |
229 | } |
230 | |
231 | // Check if the plugin is already active |
232 | // Can only be true if the plugin was already installed |
233 | // Only need to check if it should be activated |
234 | if ( $is_installed && $should_activate && is_plugin_active( $plugin_basename ) ) { |
235 | $is_active = true; |
236 | } |
237 | // If should activate, and not already active, activate the plugin |
238 | if ( $is_installed && $should_activate && ! $is_active ) { |
239 | $activate_plugin_response = activate_plugin( $plugin_basename ); |
240 | if ( is_wp_error( $activate_plugin_response ) ) { |
241 | $activate_plugin_response->add( |
242 | 'nfd_installer_error', |
243 | __( 'Failed to activate the plugin: ', 'wp-module-installer' ) . $plugin, |
244 | array( |
245 | 'plugin' => $plugin, |
246 | 'provider' => $provider, |
247 | 'basename' => $plugin_basename, |
248 | ) |
249 | ); |
250 | return $activate_plugin_response; |
251 | } |
252 | } |
253 | |
254 | // Activate the license |
255 | // Should we do this here or let the activation hook handle it - see WPAdmin/Listeners/InstallerListener.php |
256 | $license_activation_response = $pls_utility->activate_license( $plugin ); |
257 | if ( is_wp_error( $license_activation_response ) ) { |
258 | $license_activation_response->add( |
259 | 'nfd_installer_error', |
260 | __( 'Failed to activate the license for the premium plugin: ', 'wp-module-installer' ) . $plugin, |
261 | array( |
262 | 'plugin' => $plugin, |
263 | 'provider' => $provider, |
264 | ) |
265 | ); |
266 | return $license_activation_response; |
267 | } |
268 | |
269 | // Return success response |
270 | return new \WP_REST_Response( |
271 | array( |
272 | 'message' => __( 'Successfully provisioned and installed: ', 'wp-module-installer' ) . $plugin, |
273 | ), |
274 | 200 |
275 | ); |
276 | } |
277 | |
278 | /** |
279 | * Install the plugin from a custom ZIP. |
280 | * |
281 | * @param string $url The ZIP URL to install from. |
282 | * @param boolean $should_activate Whether to activate the plugin after install. |
283 | * @param array $language_packs The set of language packs to install for the plugin. |
284 | * @return \WP_REST_Response|\WP_Error |
285 | */ |
286 | public static function install_from_zip( $url, $should_activate, $language_packs = array() ) { |
287 | require_once ABSPATH . 'wp-admin/includes/file.php'; |
288 | require_once ABSPATH . 'wp-admin/includes/misc.php'; |
289 | require_once ABSPATH . 'wp-admin/includes/class-wp-upgrader.php'; |
290 | |
291 | \wp_cache_flush(); |
292 | $skin = new \WP_Ajax_Upgrader_Skin(); |
293 | $upgrader = new \Plugin_Upgrader( $skin ); |
294 | |
295 | $result = $upgrader->install( $url ); |
296 | if ( \is_wp_error( $result ) ) { |
297 | $result->add_data( array( 'status' => 500 ) ); |
298 | |
299 | return $result; |
300 | } |
301 | if ( \is_wp_error( $skin->result ) ) { |
302 | $skin->result->add_data( array( 'status' => 500 ) ); |
303 | |
304 | return $skin->result; |
305 | } |
306 | if ( $skin->get_errors()->has_errors() ) { |
307 | $error = $skin->get_errors(); |
308 | $error->add_data( array( 'status' => 500 ) ); |
309 | |
310 | return $error; |
311 | } |
312 | if ( is_null( $result ) ) { |
313 | // Pass through the error from WP_Filesystem if one was raised. |
314 | if ( $wp_filesystem instanceof \WP_Filesystem_Base |
315 | && \is_wp_error( $wp_filesystem->errors ) && $wp_filesystem->errors->has_errors() |
316 | ) { |
317 | return new \WP_Error( |
318 | 'unable_to_connect_to_filesystem', |
319 | $wp_filesystem->errors->get_error_message(), |
320 | array( 'status' => 500 ) |
321 | ); |
322 | } |
323 | |
324 | return new \WP_Error( |
325 | 'unable_to_connect_to_filesystem', |
326 | __( 'Unable to connect to the filesystem.', 'wp-module-installer' ), |
327 | array( 'status' => 500 ) |
328 | ); |
329 | } |
330 | |
331 | $plugin_file = $upgrader->plugin_info(); |
332 | if ( ! $plugin_file ) { |
333 | return new \WP_Error( |
334 | 'unable_to_determine_installed_plugin', |
335 | __( 'Unable to determine what plugin was installed.', 'wp-module-installer' ), |
336 | array( 'status' => 500 ) |
337 | ); |
338 | } |
339 | |
340 | if ( $should_activate && ! \is_plugin_active( $plugin_file ) ) { |
341 | $status = \activate_plugin( $plugin_file ); |
342 | if ( \is_wp_error( $status ) ) { |
343 | $status->add_data( array( 'status' => 500 ) ); |
344 | |
345 | return $status; |
346 | } |
347 | } |
348 | |
349 | // Install translations. |
350 | $installed_locales = array_values( get_available_languages() ); |
351 | /** This filter is documented in wp-includes/update.php */ |
352 | $installed_locales = apply_filters( 'plugins_update_check_locales', $installed_locales ); |
353 | |
354 | if ( ! empty( $language_packs ) ) { |
355 | $language_packs = array_map( |
356 | static function ( $item ) { |
357 | return (object) $item; |
358 | }, |
359 | $language_packs |
360 | ); |
361 | |
362 | $language_packs = array_filter( |
363 | $language_packs, |
364 | static function ( $pack ) use ( $installed_locales ) { |
365 | return in_array( $pack->language, $installed_locales, true ); |
366 | } |
367 | ); |
368 | |
369 | if ( $language_packs ) { |
370 | $lp_upgrader = new \Language_Pack_Upgrader( $skin ); |
371 | |
372 | // Install all applicable language packs for the plugin. |
373 | $lp_upgrader->bulk_upgrade( $language_packs ); |
374 | } |
375 | } |
376 | |
377 | return new \WP_REST_Response( |
378 | array(), |
379 | 200 |
380 | ); |
381 | } |
382 | |
383 | /** |
384 | * Checks if a given slug is a valid nfd_slug. Ref: includes/Data/Plugins.php for nfd_slug. |
385 | * |
386 | * @param string $plugin Slug of the plugin. |
387 | * @return boolean |
388 | */ |
389 | public static function is_nfd_slug( $plugin ) { |
390 | $plugins_list = Plugins::get(); |
391 | if ( isset( $plugins_list['nfd_slugs'][ $plugin ]['approved'] ) ) { |
392 | return true; |
393 | } |
394 | return false; |
395 | } |
396 | |
397 | /** |
398 | * Determines if a plugin has already been installed. |
399 | * |
400 | * @param string $plugin_path Path to the plugin's header file. |
401 | * @return boolean |
402 | */ |
403 | public static function is_plugin_installed( $plugin_path ) { |
404 | if ( ! function_exists( 'get_plugins' ) ) { |
405 | require_once ABSPATH . 'wp-admin/includes/plugin.php'; |
406 | } |
407 | $all_plugins = \get_plugins(); |
408 | if ( ! empty( $all_plugins[ $plugin_path ] ) ) { |
409 | return true; |
410 | } else { |
411 | return false; |
412 | } |
413 | } |
414 | |
415 | /** |
416 | * Get the type of plugin slug. Ref: includes/Data/Plugins.php for the different types. |
417 | * |
418 | * @param string $plugin The plugin slug to retrieve the type. |
419 | * @return string |
420 | */ |
421 | public static function get_plugin_type( $plugin ) { |
422 | if ( \wp_http_validate_url( $plugin ) ) { |
423 | return 'urls'; |
424 | } |
425 | if ( self::is_nfd_slug( $plugin ) ) { |
426 | return 'nfd_slugs'; |
427 | } |
428 | return 'wp_slugs'; |
429 | } |
430 | |
431 | /** |
432 | * Get the path to the Plugin's header file. |
433 | * |
434 | * @param string $plugin The slug of the plugin. |
435 | * @param string $plugin_type The type of plugin. |
436 | * @return string|false |
437 | */ |
438 | public static function get_plugin_path( $plugin, $plugin_type ) { |
439 | $plugin_list = Plugins::get(); |
440 | return isset( $plugin_list[ $plugin_type ][ $plugin ] ) ? $plugin_list[ $plugin_type ][ $plugin ]['path'] : false; |
441 | } |
442 | |
443 | /** |
444 | * Checks if a plugin with the given slug and activation criteria already exists. |
445 | * |
446 | * @param string $plugin The slug of the plugin to check for |
447 | * @param boolean $is_active The activation criteria. |
448 | * @return boolean |
449 | */ |
450 | public static function exists( $plugin, $is_active ) { |
451 | $plugin_type = self::get_plugin_type( $plugin ); |
452 | $plugin_path = self::get_plugin_path( $plugin, $plugin_type ); |
453 | if ( ! ( $plugin_path && self::is_plugin_installed( $plugin_path ) ) ) { |
454 | return false; |
455 | } |
456 | |
457 | if ( $is_active && ! \is_plugin_active( $plugin_path ) ) { |
458 | return false; |
459 | } |
460 | return true; |
461 | } |
462 | |
463 | /** |
464 | * Checks if a give plugin is active, given the plugin path. |
465 | * |
466 | * @param string $plugin_path The plugin path. |
467 | * @return boolean |
468 | */ |
469 | public static function is_active( $plugin_path ) { |
470 | return \is_plugin_active( $plugin_path ); |
471 | } |
472 | |
473 | /** |
474 | * Activates a plugin slug after performing the necessary checks. |
475 | * |
476 | * @param string $plugin The plugin slug. Ref: includes/Data/Plugins.php for the slugs. |
477 | * @return boolean |
478 | */ |
479 | public static function activate( $plugin ) { |
480 | $plugin_type = self::get_plugin_type( $plugin ); |
481 | $plugin_path = self::get_plugin_path( $plugin, $plugin_type ); |
482 | if ( ! ( $plugin_path && self::is_plugin_installed( $plugin_path ) ) ) { |
483 | return false; |
484 | } |
485 | |
486 | if ( \is_plugin_active( $plugin_path ) ) { |
487 | return true; |
488 | } |
489 | |
490 | return \activate_plugin( $plugin_path ); |
491 | // handle post install callback here. |
492 | } |
493 | |
494 | /** |
495 | * Deactivates a given plugin slug after performing the necessary checks. |
496 | * |
497 | * @param string $plugin The plugin slug. Ref: includes/Data/Plugins.php for the slugs. |
498 | * @return boolean |
499 | */ |
500 | public static function deactivate( $plugin ) { |
501 | $plugin_type = self::get_plugin_type( $plugin ); |
502 | $plugin_path = self::get_plugin_path( $plugin, $plugin_type ); |
503 | if ( ! ( $plugin_path && self::is_plugin_installed( $plugin_path ) ) ) { |
504 | return false; |
505 | } |
506 | |
507 | if ( ! \is_plugin_active( $plugin_path ) ) { |
508 | return true; |
509 | } |
510 | |
511 | \deactivate_plugins( $plugin_path ); |
512 | return true; |
513 | // handle post install callback here. |
514 | } |
515 | |
516 | /** |
517 | * Install the Endurance Page Cache Plugin |
518 | * |
519 | * [TODO] Make this generic for mu-plugins and direct file downloads. |
520 | * |
521 | * @return \WP_REST_Response|\WP_Error |
522 | */ |
523 | public static function install_endurance_page_cache() { |
524 | if ( ! self::connect_to_filesystem() ) { |
525 | return new \WP_Error( |
526 | 'nfd_installer_error', |
527 | __( 'Could not connect to the filesystem.', 'wp-module-installer' ), |
528 | array( 'status' => 500 ) |
529 | ); |
530 | } |
531 | |
532 | global $wp_filesystem; |
533 | |
534 | $plugin_list = Plugins::get(); |
535 | $plugin_url = $plugin_list['nfd_slugs']['nfd_slug_endurance_page_cache']['url']; |
536 | $plugin_path = $plugin_list['nfd_slugs']['nfd_slug_endurance_page_cache']['path']; |
537 | |
538 | if ( $wp_filesystem->exists( $plugin_path ) ) { |
539 | return new \WP_REST_Response( |
540 | array(), |
541 | 200 |
542 | ); |
543 | } |
544 | |
545 | if ( ! $wp_filesystem->is_dir( WP_CONTENT_DIR . '/mu-plugins' ) ) { |
546 | $wp_filesystem->mkdir( WP_CONTENT_DIR . '/mu-plugins' ); |
547 | } |
548 | |
549 | $request = \wp_remote_get( $plugin_url ); |
550 | if ( \is_wp_error( $request ) ) { |
551 | return $request; |
552 | } |
553 | |
554 | $wp_filesystem->put_contents( $plugin_path, $request['body'], FS_CHMOD_FILE ); |
555 | |
556 | return new \WP_REST_Response( |
557 | array(), |
558 | 200 |
559 | ); |
560 | } |
561 | |
562 | /** |
563 | * Establishes a connection to the wp_filesystem. |
564 | * |
565 | * @return boolean |
566 | */ |
567 | protected static function connect_to_filesystem() { |
568 | require_once ABSPATH . 'wp-admin/includes/file.php'; |
569 | |
570 | // We want to ensure that the user has direct access to the filesystem. |
571 | $access_type = \get_filesystem_method(); |
572 | if ( 'direct' !== $access_type ) { |
573 | return false; |
574 | } |
575 | |
576 | $creds = \request_filesystem_credentials( site_url() . '/wp-admin', '', false, false, array() ); |
577 | |
578 | if ( ! \WP_Filesystem( $creds ) ) { |
579 | return false; |
580 | } |
581 | |
582 | return true; |
583 | } |
584 | |
585 | /** |
586 | * Verify caller has permissions to install plugins. |
587 | * |
588 | * @param \WP_REST_Request $request the incoming request object. |
589 | * |
590 | * @return boolean |
591 | */ |
592 | public static function check_install_permissions( \WP_REST_Request $request ) { |
593 | $install_hash = $request->get_header( 'X-NFD-INSTALLER' ); |
594 | return self::rest_verify_plugin_install_hash( $install_hash ) |
595 | && Permissions::rest_is_authorized_admin(); |
596 | } |
597 | |
598 | /** |
599 | * Retrieve Plugin Install Hash Value. |
600 | * |
601 | * @return string |
602 | */ |
603 | public static function rest_get_plugin_install_hash() { |
604 | return 'NFD_INSTALLER_' . hash( 'sha256', NFD_INSTALLER_VERSION . wp_salt( 'nonce' ) . site_url() ); |
605 | } |
606 | |
607 | /** |
608 | * Verify Plugin Install Hash Value. |
609 | * |
610 | * @param string $hash Hash Value. |
611 | * @return boolean |
612 | */ |
613 | public static function rest_verify_plugin_install_hash( $hash ) { |
614 | return self::rest_get_plugin_install_hash() === $hash; |
615 | } |
616 | |
617 | /** |
618 | * Retrieves the current status of a plugin. |
619 | * |
620 | * @param string $plugin The slug or identifier of the plugin. |
621 | * |
622 | * @return string |
623 | */ |
624 | public static function get_plugin_status( $plugin ) { |
625 | $plugin_type = self::get_plugin_type( $plugin ); |
626 | $plugin_path = self::get_plugin_path( $plugin, $plugin_type ); |
627 | $plugin_status_codes = Plugins::get_status_codes(); |
628 | |
629 | if ( ! $plugin_path ) { |
630 | return $plugin_status_codes['unknown']; |
631 | } |
632 | |
633 | if ( is_plugin_active( $plugin_path ) ) { |
634 | return $plugin_status_codes['active']; |
635 | } |
636 | |
637 | if ( self::is_plugin_installed( $plugin_path ) ) { |
638 | return $plugin_status_codes['installed']; |
639 | } |
640 | |
641 | return $plugin_status_codes['not_installed']; |
642 | } |
643 | } |