wp_ajax_install_theme()
云策文档标注
概述
wp_ajax_install_theme() 是一个 WordPress AJAX 处理函数,用于通过 AJAX 请求安装主题。它验证用户权限、处理主题信息获取、执行安装过程,并返回 JSON 格式的成功或错误响应。
关键要点
- 函数通过 check_ajax_referer() 验证 AJAX 请求的安全性,确保 nonce 为 'updates'。
- 需要 POST 参数 'slug' 指定主题标识符,否则返回错误 'no_theme_specified'。
- 检查当前用户是否具有 'install_themes' 权限,若无权限则返回错误。
- 使用 themes_api() 获取主题信息,包括下载链接。
- 通过 Theme_Upgrader 和 WP_Ajax_Upgrader_Skin 执行主题安装,处理各种错误情况(如 WP_Error、文件系统连接问题)。
- 安装成功后,返回状态信息,包括主题名称、激活 URL(根据用户权限和是否为多站点)和自定义 URL。
- 使用 wp_send_json_success() 或 wp_send_json_error() 发送 JSON 响应。
代码示例
// 示例:前端 AJAX 调用 wp_ajax_install_theme()
jQuery(document).on('click', '.theme-install-button', function(e) {
e.preventDefault();
var data = {
action: "wp_ajax_install_theme",
_ajax_nonce: script_params.nonce,
slug: "blogfi"
};
jQuery.post(script_params.ajax_url, data, function(response) {
console.log(response);
});
});注意事项
- 确保在 AJAX 请求中传递正确的 nonce('updates')和主题 slug。
- 用户必须具有 'install_themes' 权限才能调用此函数。
- 在多站点环境中,激活 URL 会指向网络管理员页面。
- 函数内部处理了多种错误场景,开发者应在前端妥善处理 JSON 响应。
原文内容
Handles installing a theme via AJAX.
Description
See also
Source
function wp_ajax_install_theme() {
check_ajax_referer( 'updates' );
if ( empty( $_POST['slug'] ) ) {
wp_send_json_error(
array(
'slug' => '',
'errorCode' => 'no_theme_specified',
'errorMessage' => __( 'No theme specified.' ),
)
);
}
$slug = sanitize_key( wp_unslash( $_POST['slug'] ) );
$status = array(
'install' => 'theme',
'slug' => $slug,
);
if ( ! current_user_can( 'install_themes' ) ) {
$status['errorMessage'] = __( 'Sorry, you are not allowed to install themes on this site.' );
wp_send_json_error( $status );
}
require_once ABSPATH . 'wp-admin/includes/class-wp-upgrader.php';
require_once ABSPATH . 'wp-admin/includes/theme.php';
$api = themes_api(
'theme_information',
array(
'slug' => $slug,
'fields' => array( 'sections' => false ),
)
);
if ( is_wp_error( $api ) ) {
$status['errorMessage'] = $api->get_error_message();
wp_send_json_error( $status );
}
$skin = new WP_Ajax_Upgrader_Skin();
$upgrader = new Theme_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 );
}
$status['themeName'] = wp_get_theme( $slug )->get( 'Name' );
if ( current_user_can( 'switch_themes' ) ) {
if ( is_multisite() ) {
$status['activateUrl'] = add_query_arg(
array(
'action' => 'enable',
'_wpnonce' => wp_create_nonce( 'enable-theme_' . $slug ),
'theme' => $slug,
),
network_admin_url( 'themes.php' )
);
} else {
$status['activateUrl'] = add_query_arg(
array(
'action' => 'activate',
'_wpnonce' => wp_create_nonce( 'switch-theme_' . $slug ),
'stylesheet' => $slug,
),
admin_url( 'themes.php' )
);
}
}
$theme = wp_get_theme( $slug );
$status['blockTheme'] = $theme->is_block_theme();
if ( ! is_multisite() && current_user_can( 'edit_theme_options' ) && current_user_can( 'customize' ) ) {
$status['customizeUrl'] = add_query_arg(
array(
'return' => urlencode( network_admin_url( 'theme-install.php', 'relative' ) ),
),
wp_customize_url( $slug )
);
}
/*
* See WP_Theme_Install_List_Table::_get_theme_status() if we wanted to check
* on post-installation status.
*/
wp_send_json_success( $status );
}
Changelog
| Version | Description |
|---|---|
| 4.6.0 | Introduced. |
Skip to note 2 content
Jahid Hasan
/** * Register and enqueue a custom script in the WordPress admin. */ function wpdocs_enqueue_admin_script() { wp_enqueue_script( 'wpdocs_custom_script', plugin_dir_url( __FILE__ ) . 'myscript.js', array(), '1.0.0' ); wp_localize_script( 'wpdocs_custom_script', 'script_params', array( 'nonce' => wp_create_nonce( 'updates' ), //nonce updates are not gonna changeable 'ajax_url' => admin_url( 'admin-ajax.php' ) ) ); } add_action( 'admin_enqueue_scripts', 'wpdocs_enqueue_admin_script' ); // Callback wp_ajax_install_theme not gonna changeable. add_action( 'wp_ajax_wp_ajax_install_theme', 'wp_ajax_install_theme' );Add this code to your myscript.js file.
And Add the name of your selector, from where you want to install the theme by clicking. I’ve added .theme-install-button as an example.
jQuery( document ).on('click', '.theme-install-button', function ( e ) { e.preventDefault(); var data = { action: "wp_ajax_install_theme", // ajax action _ajax_nonce: script_params.nonce, // nonce slug: "blogfi", // theme slug }; jQuery.post( script_params.ajax_url, data, function ( response ) { console.log( response ); } ); } );