WordPress Version: 6.3
/**
* Handles updating a plugin via AJAX.
*
* @since 4.2.0
*
* @see Plugin_Upgrader
*
* @global WP_Filesystem_Base $wp_filesystem WordPress filesystem subclass.
*/
function wp_ajax_update_plugin()
{
check_ajax_referer('updates');
if (empty($_POST['plugin']) || empty($_POST['slug'])) {
wp_send_json_error(array('slug' => '', 'errorCode' => 'no_plugin_specified', 'errorMessage' => __('No plugin specified.')));
}
$plugin = plugin_basename(sanitize_text_field(wp_unslash($_POST['plugin'])));
$status = array('update' => 'plugin', 'slug' => sanitize_key(wp_unslash($_POST['slug'])), 'oldVersion' => '', 'newVersion' => '');
if (!current_user_can('update_plugins') || 0 !== validate_file($plugin)) {
$status['errorMessage'] = __('Sorry, you are not allowed to update plugins for this site.');
wp_send_json_error($status);
}
$plugin_data = get_plugin_data(WP_PLUGIN_DIR . '/' . $plugin);
$status['plugin'] = $plugin;
$status['pluginName'] = $plugin_data['Name'];
if ($plugin_data['Version']) {
/* translators: %s: Plugin version. */
$status['oldVersion'] = sprintf(__('Version %s'), $plugin_data['Version']);
}
require_once ABSPATH . 'wp-admin/includes/class-wp-upgrader.php';
wp_update_plugins();
$skin = new WP_Ajax_Upgrader_Skin();
$upgrader = new Plugin_Upgrader($skin);
$result = $upgrader->bulk_upgrade(array($plugin));
if (defined('WP_DEBUG') && WP_DEBUG) {
$status['debug'] = $skin->get_upgrade_messages();
}
if (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_array($result) && !empty($result[$plugin])) {
/*
* Plugin is already at the latest version.
*
* This may also be the return value if the `update_plugins` site transient is empty,
* e.g. when you update two plugins in quick succession before the transient repopulates.
*
* Preferably something can be done to ensure `update_plugins` isn't empty.
* For now, surface some sort of error here.
*/
if (true === $result[$plugin]) {
$status['errorMessage'] = $upgrader->strings['up_to_date'];
wp_send_json_error($status);
}
$plugin_data = get_plugins('/' . $result[$plugin]['destination_name']);
$plugin_data = reset($plugin_data);
if ($plugin_data['Version']) {
/* translators: %s: Plugin version. */
$status['newVersion'] = sprintf(__('Version %s'), $plugin_data['Version']);
}
wp_send_json_success($status);
} elseif (false === $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);
}
// An unhandled error occurred.
$status['errorMessage'] = __('Plugin update failed.');
wp_send_json_error($status);
}