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