wp_ajax_install_plugin()
云策文档标注
概述
wp_ajax_install_plugin() 是一个 WordPress AJAX 处理函数,用于通过 AJAX 请求安装插件。它验证用户权限、获取插件信息、执行安装过程,并返回 JSON 格式的成功或错误响应。
关键要点
- 函数通过 check_ajax_referer() 验证 AJAX 请求的安全性,确保非恶意操作。
- 检查用户是否具有 install_plugins 权限,若无权限则返回错误。
- 使用 plugins_api() 从 WordPress.org 插件 API 获取插件信息,包括下载链接。
- 利用 Plugin_Upgrader 和 WP_Ajax_Upgrader_Skin 类执行插件安装,处理安装过程中的各种错误情况。
- 安装成功后,根据用户权限和当前页面(如导入页面)生成激活插件的 URL。
- 返回 JSON 响应,使用 wp_send_json_success() 或 wp_send_json_error() 指示操作结果。
代码示例
// jQuery AJAX 请求示例
var data = {
action: 'wp_ajax_install_plugin',
_ajax_nonce: '', // 替换为实际的 nonce
slug: 'plugin_slug', // 插件 slug,例如 woocommerce
};
jQuery.post(ajax_url, data, function(response) {
console.log(response);
});
// 在 functions.php 中添加 AJAX 处理钩子
add_action('wp_ajax_wp_ajax_install_plugin', 'wp_ajax_install_plugin');注意事项
- 确保 AJAX 请求包含正确的 nonce 和插件 slug 参数,否则函数会返回错误。
- 在调试模式下(WP_DEBUG 为 true),安装过程中会包含调试信息在响应中。
- 对于多站点环境,函数会检查 manage_network_plugins 权限来生成网络激活链接。
- 安装失败时,函数会返回详细的错误代码和消息,便于问题排查。
原文内容
Handles installing a plugin via AJAX.
Description
See also
Source
function wp_ajax_install_plugin() {
check_ajax_referer( 'updates' );
if ( empty( $_POST['slug'] ) ) {
wp_send_json_error(
array(
'slug' => '',
'errorCode' => 'no_plugin_specified',
'errorMessage' => __( 'No plugin specified.' ),
)
);
}
$status = array(
'install' => 'plugin',
'slug' => sanitize_key( wp_unslash( $_POST['slug'] ) ),
);
if ( ! current_user_can( 'install_plugins' ) ) {
$status['errorMessage'] = __( 'Sorry, you are not allowed to install plugins on this site.' );
wp_send_json_error( $status );
}
require_once ABSPATH . 'wp-admin/includes/class-wp-upgrader.php';
require_once ABSPATH . 'wp-admin/includes/plugin-install.php';
$api = plugins_api(
'plugin_information',
array(
'slug' => sanitize_key( wp_unslash( $_POST['slug'] ) ),
'fields' => array(
'sections' => false,
),
)
);
if ( is_wp_error( $api ) ) {
$status['errorMessage'] = $api->get_error_message();
wp_send_json_error( $status );
}
$status['pluginName'] = $api->name;
$skin = new WP_Ajax_Upgrader_Skin();
$upgrader = new Plugin_Upgrader( $skin );
$result = $upgrader->install( $api->download_link );
if ( defined( 'WP_DEBUG' ) && WP_DEBUG ) {
$status['debug'] = $skin->get_upgrade_messages();
}
if ( is_wp_error( $result ) ) {
$status['errorCode'] = $result->get_error_code();
$status['errorMessage'] = $result->get_error_message();
wp_send_json_error( $status );
} elseif ( is_wp_error( $skin->result ) ) {
$status['errorCode'] = $skin->result->get_error_code();
$status['errorMessage'] = $skin->result->get_error_message();
wp_send_json_error( $status );
} elseif ( $skin->get_errors()->has_errors() ) {
$status['errorMessage'] = $skin->get_error_messages();
wp_send_json_error( $status );
} elseif ( is_null( $result ) ) {
global $wp_filesystem;
$status['errorCode'] = 'unable_to_connect_to_filesystem';
$status['errorMessage'] = __( 'Unable to connect to the filesystem. Please confirm your credentials.' );
// Pass through the error from WP_Filesystem if one was raised.
if ( $wp_filesystem instanceof WP_Filesystem_Base && is_wp_error( $wp_filesystem->errors ) && $wp_filesystem->errors->has_errors() ) {
$status['errorMessage'] = esc_html( $wp_filesystem->errors->get_error_message() );
}
wp_send_json_error( $status );
}
$install_status = install_plugin_install_status( $api );
$pagenow = isset( $_POST['pagenow'] ) ? sanitize_key( $_POST['pagenow'] ) : '';
// If installation request is coming from import page, do not return network activation link.
$plugins_url = ( 'import' === $pagenow ) ? admin_url( 'plugins.php' ) : network_admin_url( 'plugins.php' );
if ( current_user_can( 'activate_plugin', $install_status['file'] ) && is_plugin_inactive( $install_status['file'] ) ) {
$status['activateUrl'] = add_query_arg(
array(
'_wpnonce' => wp_create_nonce( 'activate-plugin_' . $install_status['file'] ),
'action' => 'activate',
'plugin' => $install_status['file'],
),
$plugins_url
);
}
if ( is_multisite() && current_user_can( 'manage_network_plugins' ) && 'import' !== $pagenow ) {
$status['activateUrl'] = add_query_arg( array( 'networkwide' => 1 ), $status['activateUrl'] );
}
wp_send_json_success( $status );
}
Changelog
| Version | Description |
|---|---|
| 4.6.0 | Introduced. |
Skip to note 2 content
Fida Al Hasan
Ajax js code needs to be added to the WordPress admin body. We can use
add_action('admin_footer', 'my_admin_add_js');hook or we can use separate js file & enqueue usingadd_action( 'admin_enqueue_scripts', 'my_admin_scripts' ); hook.// jQuery ajax POST request code var data = { action: 'wp_ajax_install_plugin', _ajax_nonce: '', // nonce slug: 'plugin_slug', // e.g. woocommerce }; jQuery.post( ajax_url, data, function(response) { console.log(response); });// code goes to functions.php add_action("wp_ajax_wp_ajax_install_plugin" , "wp_ajax_install_plugin");