wp_ajax_install_theme

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

WordPress Version: 6.3

/**
 * Handles installing a theme via AJAX.
 *
 * @since 4.6.0
 *
 * @see Theme_Upgrader
 *
 * @global WP_Filesystem_Base $wp_filesystem WordPress filesystem subclass.
 */
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);
}

WordPress Version: 9.3

/**
 * Ajax handler for installing a theme.
 *
 * @since 4.6.0
 *
 * @see Theme_Upgrader
 *
 * @global WP_Filesystem_Base $wp_filesystem WordPress filesystem subclass.
 */
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';
    include_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);
}

WordPress Version: 5.4

/**
 * Ajax handler for installing a theme.
 *
 * @since 4.6.0
 *
 * @see Theme_Upgrader
 *
 * @global WP_Filesystem_Base $wp_filesystem WordPress filesystem subclass.
 */
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';
    include_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'));
        }
    }
    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);
}

WordPress Version: 5.1

/**
 * Ajax handler for installing a theme.
 *
 * @since 4.6.0
 *
 * @see Theme_Upgrader
 *
 * @global WP_Filesystem_Base $wp_filesystem WordPress filesystem subclass.
 */
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);
    }
    include_once ABSPATH . 'wp-admin/includes/class-wp-upgrader.php';
    include_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'));
        }
    }
    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);
}

WordPress Version: 4.9

/**
 * Ajax handler for installing a theme.
 *
 * @since 4.6.0
 *
 * @see Theme_Upgrader
 *
 * @global WP_Filesystem_Base $wp_filesystem Subclass
 */
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);
    }
    include_once ABSPATH . 'wp-admin/includes/class-wp-upgrader.php';
    include_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()->get_error_code()) {
        $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->get_error_code()) {
            $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'));
        }
    }
    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);
}

WordPress Version: 4.6

/**
 * Ajax handler for installing a theme.
 *
 * @since 4.6.0
 *
 * @see Theme_Upgrader
 */
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);
    }
    include_once ABSPATH . 'wp-admin/includes/class-wp-upgrader.php';
    include_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()->get_error_code()) {
        $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->get_error_code()) {
            $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'));
        }
    }
    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-install status.
     */
    wp_send_json_success($status);
}