wp_ajax_update_plugin

The timeline below displays how wordpress function wp_ajax_update_plugin has changed across different WordPress versions. If a version is not listed, refer to the next available version below.

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);
}

WordPress Version: 5.5

/**
 * Ajax handler for updating a plugin.
 *
 * @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);
}

WordPress Version: 5.4

/**
 * Ajax handler for updating a plugin.
 *
 * @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_update_data = current($result);
        /*
         * If the `update_plugins` site transient is empty (e.g. when you update
         * two plugins in quick succession before the transient repopulates),
         * this may be the return.
         *
         * Preferably something can be done to ensure `update_plugins` isn't empty.
         * For now, surface some sort of error here.
         */
        if (true === $plugin_update_data) {
            $status['errorMessage'] = __('Plugin update failed.');
            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);
}

WordPress Version: 5.3

/**
 * Ajax handler for updating a plugin.
 *
 * @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']);
    }
    include_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_update_data = current($result);
        /*
         * If the `update_plugins` site transient is empty (e.g. when you update
         * two plugins in quick succession before the transient repopulates),
         * this may be the return.
         *
         * Preferably something can be done to ensure `update_plugins` isn't empty.
         * For now, surface some sort of error here.
         */
        if (true === $plugin_update_data) {
            $status['errorMessage'] = __('Plugin update failed.');
            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);
}

WordPress Version: 5.1

/**
 * Ajax handler for updating a plugin.
 *
 * @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']);
    }
    include_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_update_data = current($result);
        /*
         * If the `update_plugins` site transient is empty (e.g. when you update
         * two plugins in quick succession before the transient repopulates),
         * this may be the return.
         *
         * Preferably something can be done to ensure `update_plugins` isn't empty.
         * For now, surface some sort of error here.
         */
        if (true === $plugin_update_data) {
            $status['errorMessage'] = __('Plugin update failed.');
            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);
}

WordPress Version: 4.9

/**
 * Ajax handler for updating a plugin.
 *
 * @since 4.2.0
 *
 * @see Plugin_Upgrader
 *
 * @global WP_Filesystem_Base $wp_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']);
    }
    include_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()->get_error_code()) {
        $status['errorMessage'] = $skin->get_error_messages();
        wp_send_json_error($status);
    } elseif (is_array($result) && !empty($result[$plugin])) {
        $plugin_update_data = current($result);
        /*
         * If the `update_plugins` site transient is empty (e.g. when you update
         * two plugins in quick succession before the transient repopulates),
         * this may be the return.
         *
         * Preferably something can be done to ensure `update_plugins` isn't empty.
         * For now, surface some sort of error here.
         */
        if (true === $plugin_update_data) {
            $status['errorMessage'] = __('Plugin update failed.');
            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->get_error_code()) {
            $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);
}

WordPress Version: 4.6

/**
 * Ajax handler for updating a plugin.
 *
 * @since 4.2.0
 *
 * @see Plugin_Upgrader
 */
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']);
    }
    include_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()->get_error_code()) {
        $status['errorMessage'] = $skin->get_error_messages();
        wp_send_json_error($status);
    } elseif (is_array($result) && !empty($result[$plugin])) {
        $plugin_update_data = current($result);
        /*
         * If the `update_plugins` site transient is empty (e.g. when you update
         * two plugins in quick succession before the transient repopulates),
         * this may be the return.
         *
         * Preferably something can be done to ensure `update_plugins` isn't empty.
         * For now, surface some sort of error here.
         */
        if (true === $plugin_update_data) {
            $status['errorMessage'] = __('Plugin update failed.');
            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->get_error_code()) {
            $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);
}

WordPress Version: 4.4

/**
 * AJAX handler for updating a plugin.
 *
 * @since 4.2.0
 *
 * @see Plugin_Upgrader
 */
function wp_ajax_update_plugin()
{
    global $wp_filesystem;
    $plugin = urldecode($_POST['plugin']);
    $status = array('update' => 'plugin', 'plugin' => $plugin, 'slug' => sanitize_key($_POST['slug']), 'oldVersion' => '', 'newVersion' => '');
    $plugin_data = get_plugin_data(WP_PLUGIN_DIR . '/' . $plugin);
    if ($plugin_data['Version']) {
        $status['oldVersion'] = sprintf(__('Version %s'), $plugin_data['Version']);
    }
    if (!current_user_can('update_plugins')) {
        $status['error'] = __('You do not have sufficient permissions to update plugins for this site.');
        wp_send_json_error($status);
    }
    check_ajax_referer('updates');
    include_once ABSPATH . 'wp-admin/includes/class-wp-upgrader.php';
    wp_update_plugins();
    $skin = new Automatic_Upgrader_Skin();
    $upgrader = new Plugin_Upgrader($skin);
    $result = $upgrader->bulk_upgrade(array($plugin));
    if (is_array($result) && empty($result[$plugin]) && is_wp_error($skin->result)) {
        $result = $skin->result;
    }
    if (is_array($result) && !empty($result[$plugin])) {
        $plugin_update_data = current($result);
        /*
         * If the `update_plugins` site transient is empty (e.g. when you update
         * two plugins in quick succession before the transient repopulates),
         * this may be the return.
         *
         * Preferably something can be done to ensure `update_plugins` isn't empty.
         * For now, surface some sort of error here.
         */
        if ($plugin_update_data === true) {
            $status['error'] = __('Plugin update failed.');
            wp_send_json_error($status);
        }
        $plugin_data = get_plugins('/' . $result[$plugin]['destination_name']);
        $plugin_data = reset($plugin_data);
        if ($plugin_data['Version']) {
            $status['newVersion'] = sprintf(__('Version %s'), $plugin_data['Version']);
        }
        wp_send_json_success($status);
    } else if (is_wp_error($result)) {
        $status['error'] = $result->get_error_message();
        wp_send_json_error($status);
    } else if (is_bool($result) && !$result) {
        $status['errorCode'] = 'unable_to_connect_to_filesystem';
        $status['error'] = __('Unable to connect to the filesystem. Please confirm your credentials.');
        // Pass through the error from WP_Filesystem if one was raised
        if (is_wp_error($wp_filesystem->errors) && $wp_filesystem->errors->get_error_code()) {
            $status['error'] = $wp_filesystem->errors->get_error_message();
        }
        wp_send_json_error($status);
    } else {
        // An unhandled error occured
        $status['error'] = __('Plugin update failed.');
        wp_send_json_error($status);
    }
}

WordPress Version: 4.3

/**
 * AJAX handler for updating a plugin.
 *
 * @since 4.2.0
 *
 * @see Plugin_Upgrader
 */
function wp_ajax_update_plugin()
{
    global $wp_filesystem;
    $plugin = urldecode($_POST['plugin']);
    $status = array('update' => 'plugin', 'plugin' => $plugin, 'slug' => sanitize_key($_POST['slug']), 'oldVersion' => '', 'newVersion' => '');
    $plugin_data = get_plugin_data(WP_PLUGIN_DIR . '/' . $plugin);
    if ($plugin_data['Version']) {
        $status['oldVersion'] = sprintf(__('Version %s'), $plugin_data['Version']);
    }
    if (!current_user_can('update_plugins')) {
        $status['error'] = __('You do not have sufficient permissions to update plugins for this site.');
        wp_send_json_error($status);
    }
    check_ajax_referer('updates');
    include_once ABSPATH . 'wp-admin/includes/class-wp-upgrader.php';
    wp_update_plugins();
    $skin = new Automatic_Upgrader_Skin();
    $upgrader = new Plugin_Upgrader($skin);
    $result = $upgrader->bulk_upgrade(array($plugin));
    if (is_array($result) && empty($result[$plugin]) && is_wp_error($skin->result)) {
        $result = $skin->result;
    }
    if (is_array($result) && !empty($result[$plugin])) {
        $plugin_update_data = current($result);
        /*
         * If the `update_plugins` site transient is empty (e.g. when you update
         * two plugins in quick succession before the transient repopulates),
         * this may be the return.
         *
         * Preferably something can be done to ensure `update_plugins` isn't empty.
         * For now, surface some sort of error here.
         */
        if ($plugin_update_data === true) {
            wp_send_json_error($status);
        }
        $plugin_data = get_plugins('/' . $result[$plugin]['destination_name']);
        $plugin_data = reset($plugin_data);
        if ($plugin_data['Version']) {
            $status['newVersion'] = sprintf(__('Version %s'), $plugin_data['Version']);
        }
        wp_send_json_success($status);
    } else if (is_wp_error($result)) {
        $status['error'] = $result->get_error_message();
        wp_send_json_error($status);
    } else if (is_bool($result) && !$result) {
        $status['errorCode'] = 'unable_to_connect_to_filesystem';
        $status['error'] = __('Unable to connect to the filesystem. Please confirm your credentials.');
        // Pass through the error from WP_Filesystem if one was raised
        if (is_wp_error($wp_filesystem->errors) && $wp_filesystem->errors->get_error_code()) {
            $status['error'] = $wp_filesystem->errors->get_error_message();
        }
        wp_send_json_error($status);
    }
}

WordPress Version: .20

/**
 * AJAX handler for updating a plugin.
 *
 * @since 4.2.0
 *
 * @see Plugin_Upgrader
 */
function wp_ajax_update_plugin()
{
    global $wp_filesystem;
    $plugin = urldecode($_POST['plugin']);
    $status = array('update' => 'plugin', 'plugin' => $plugin, 'slug' => sanitize_key($_POST['slug']), 'oldVersion' => '', 'newVersion' => '');
    $plugin_data = get_plugin_data(WP_PLUGIN_DIR . '/' . $plugin);
    if ($plugin_data['Version']) {
        $status['oldVersion'] = sprintf(__('Version %s'), $plugin_data['Version']);
    }
    if (!current_user_can('update_plugins')) {
        $status['error'] = __('You do not have sufficient permissions to update plugins on this site.');
        wp_send_json_error($status);
    }
    check_ajax_referer('updates');
    include_once ABSPATH . 'wp-admin/includes/class-wp-upgrader.php';
    wp_update_plugins();
    $skin = new Automatic_Upgrader_Skin();
    $upgrader = new Plugin_Upgrader($skin);
    $result = $upgrader->bulk_upgrade(array($plugin));
    if (is_array($result) && empty($result[$plugin]) && is_wp_error($skin->result)) {
        $result = $skin->result;
    }
    if (is_array($result) && !empty($result[$plugin])) {
        $plugin_update_data = current($result);
        /*
         * If the `update_plugins` site transient is empty (e.g. when you update
         * two plugins in quick succession before the transient repopulates),
         * this may be the return.
         *
         * Preferably something can be done to ensure `update_plugins` isn't empty.
         * For now, surface some sort of error here.
         */
        if ($plugin_update_data === true) {
            wp_send_json_error($status);
        }
        $plugin_data = get_plugins('/' . $result[$plugin]['destination_name']);
        $plugin_data = reset($plugin_data);
        if ($plugin_data['Version']) {
            $status['newVersion'] = sprintf(__('Version %s'), $plugin_data['Version']);
        }
        wp_send_json_success($status);
    } else if (is_wp_error($result)) {
        $status['error'] = $result->get_error_message();
        wp_send_json_error($status);
    } else if (is_bool($result) && !$result) {
        $status['errorCode'] = 'unable_to_connect_to_filesystem';
        $status['error'] = __('Unable to connect to the filesystem. Please confirm your credentials.');
        // Pass through the error from WP_Filesystem if one was raised
        if (is_wp_error($wp_filesystem->errors) && $wp_filesystem->errors->get_error_code()) {
            $status['error'] = $wp_filesystem->errors->get_error_message();
        }
        wp_send_json_error($status);
    }
}

WordPress Version: 2.2

/**
 * AJAX handler for updating a plugin.
 *
 * @since 4.2.0
 *
 * @see Plugin_Upgrader
 */
function wp_ajax_update_plugin()
{
    $plugin = urldecode($_POST['plugin']);
    $status = array('update' => 'plugin', 'plugin' => $plugin, 'slug' => sanitize_key($_POST['slug']), 'oldVersion' => '', 'newVersion' => '');
    $plugin_data = get_plugin_data(WP_PLUGIN_DIR . '/' . $plugin);
    if ($plugin_data['Version']) {
        $status['oldVersion'] = sprintf(__('Version %s'), $plugin_data['Version']);
    }
    if (!current_user_can('update_plugins')) {
        $status['error'] = __('You do not have sufficient permissions to update plugins on this site.');
        wp_send_json_error($status);
    }
    check_ajax_referer('updates');
    include_once ABSPATH . 'wp-admin/includes/class-wp-upgrader.php';
    $current = get_site_transient('update_plugins');
    if (empty($current)) {
        wp_update_plugins();
    }
    $upgrader = new Plugin_Upgrader(new Automatic_Upgrader_Skin());
    $result = $upgrader->bulk_upgrade(array($plugin));
    if (is_array($result)) {
        $plugin_update_data = current($result);
        /*
         * If the `update_plugins` site transient is empty (e.g. when you update
         * two plugins in quick succession before the transient repopulates),
         * this may be the return.
         *
         * Preferably something can be done to ensure `update_plugins` isn't empty.
         * For now, surface some sort of error here.
         */
        if ($plugin_update_data === true) {
            wp_send_json_error($status);
        }
        $plugin_data = get_plugin_data(WP_PLUGIN_DIR . '/' . $plugin);
        if ($plugin_data['Version']) {
            $status['newVersion'] = sprintf(__('Version %s'), $plugin_data['Version']);
        }
        wp_send_json_success($status);
    } else if (is_wp_error($result)) {
        $status['error'] = $result->get_error_message();
        wp_send_json_error($status);
    } else if (is_bool($result) && !$result) {
        $status['errorCode'] = 'unable_to_connect_to_filesystem';
        $status['error'] = __('Unable to connect to the filesystem. Please confirm your credentials.');
        wp_send_json_error($status);
    }
}

WordPress Version: .10

/**
 * AJAX handler for updating a plugin.
 *
 * @since 4.2.0
 *
 * @see Plugin_Upgrader
 */
function wp_ajax_update_plugin()
{
    global $wp_filesystem;
    $plugin = urldecode($_POST['plugin']);
    $status = array('update' => 'plugin', 'plugin' => $plugin, 'slug' => sanitize_key($_POST['slug']), 'oldVersion' => '', 'newVersion' => '');
    $plugin_data = get_plugin_data(WP_PLUGIN_DIR . '/' . $plugin);
    if ($plugin_data['Version']) {
        $status['oldVersion'] = sprintf(__('Version %s'), $plugin_data['Version']);
    }
    if (!current_user_can('update_plugins')) {
        $status['error'] = __('You do not have sufficient permissions to update plugins on this site.');
        wp_send_json_error($status);
    }
    check_ajax_referer('updates');
    include_once ABSPATH . 'wp-admin/includes/class-wp-upgrader.php';
    wp_update_plugins();
    $skin = new Automatic_Upgrader_Skin();
    $upgrader = new Plugin_Upgrader($skin);
    $result = $upgrader->bulk_upgrade(array($plugin));
    if (is_array($result) && empty($result[$plugin]) && is_wp_error($skin->result)) {
        $result = $skin->result;
    }
    if (is_array($result) && !empty($result[$plugin])) {
        $plugin_update_data = current($result);
        /*
         * If the `update_plugins` site transient is empty (e.g. when you update
         * two plugins in quick succession before the transient repopulates),
         * this may be the return.
         *
         * Preferably something can be done to ensure `update_plugins` isn't empty.
         * For now, surface some sort of error here.
         */
        if ($plugin_update_data === true) {
            wp_send_json_error($status);
        }
        $plugin_data = get_plugins('/' . $result[$plugin]['destination_name']);
        $plugin_data = reset($plugin_data);
        if ($plugin_data['Version']) {
            $status['newVersion'] = sprintf(__('Version %s'), $plugin_data['Version']);
        }
        wp_send_json_success($status);
    } else if (is_wp_error($result)) {
        $status['error'] = $result->get_error_message();
        wp_send_json_error($status);
    } else if (is_bool($result) && !$result) {
        $status['errorCode'] = 'unable_to_connect_to_filesystem';
        $status['error'] = __('Unable to connect to the filesystem. Please confirm your credentials.');
        // Pass through the error from WP_Filesystem if one was raised
        if (is_wp_error($wp_filesystem->errors) && $wp_filesystem->errors->get_error_code()) {
            $status['error'] = $wp_filesystem->errors->get_error_message();
        }
        wp_send_json_error($status);
    }
}

WordPress Version: 4.2

/**
 * AJAX handler for updating a plugin.
 *
 * @since 4.2.0
 *
 * @see Plugin_Upgrader
 */
function wp_ajax_update_plugin()
{
    $plugin = urldecode($_POST['plugin']);
    $status = array('update' => 'plugin', 'plugin' => $plugin, 'slug' => sanitize_key($_POST['slug']), 'oldVersion' => '', 'newVersion' => '');
    $plugin_data = get_plugin_data(WP_PLUGIN_DIR . '/' . $plugin);
    if ($plugin_data['Version']) {
        $status['oldVersion'] = sprintf(__('Version %s'), $plugin_data['Version']);
    }
    if (!current_user_can('update_plugins')) {
        $status['error'] = __('You do not have sufficient permissions to update plugins on this site.');
        wp_send_json_error($status);
    }
    check_ajax_referer('updates');
    include_once ABSPATH . 'wp-admin/includes/class-wp-upgrader.php';
    $current = get_site_transient('update_plugins');
    if (empty($current)) {
        wp_update_plugins();
    }
    $upgrader = new Plugin_Upgrader(new Automatic_Upgrader_Skin());
    $result = $upgrader->bulk_upgrade(array($plugin));
    if (is_array($result)) {
        $plugin_update_data = current($result);
        /*
         * If the `update_plugins` site transient is empty (e.g. when you update
         * two plugins in quick succession before the transient repopulates),
         * this may be the return.
         *
         * Preferably something can be done to ensure `update_plugins` isn't empty.
         * For now, surface some sort of error here.
         */
        if ($plugin_update_data === true) {
            wp_send_json_error($status);
        }
        $plugin_data = get_plugin_data(WP_PLUGIN_DIR . '/' . $plugin);
        if ($plugin_data['Version']) {
            $status['newVersion'] = sprintf(__('Version %s'), $plugin_data['Version']);
        }
        wp_send_json_success($status);
    } else if (is_wp_error($result)) {
        $status['error'] = $result->get_error_message();
        wp_send_json_error($status);
    } else if (is_bool($result) && !$result) {
        $status['errorCode'] = 'unable_to_connect_to_filesystem';
        $status['error'] = __('Unable to connect to the filesystem. Please confirm your credentials.');
        wp_send_json_error($status);
    }
}