Make WordPress Core


Ignore:
Timestamp:
06/15/2016 04:36:07 PM (10 years ago)
Author:
obenland
Message:

Update/Install: Shiny Updates v2.

Gone are the days of isolation and feelings of "meh", brought on by The Bleak Screen of Sadness. For a shiny knight has arrived to usher our plugins and themes along their arduous journey of installation, updates, and the inevitable fate of ultimate deletion.

Props swissspidy, adamsilverstein, mapk, afragen, ocean90, ryelle, j-falk, michael-arestad, melchoyce, DrewAPicture, AdamSoucie, ethitter, pento, dd32, kraftbj, Ipstenu, jorbin, afercia, stephdau, paulwilde, jipmoors, khag7, svovaf, jipmoors, obenland.
Fixes #22029, #25828, #31002, #31529, #31530, #31773, #33637, #35032.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/wp-admin/includes/ajax-actions.php

    r37674 r37714  
    28622862                ), $update_php );
    28632863
     2864                if ( current_user_can( 'switch_themes' ) ) {
     2865                        if ( is_multisite() ) {
     2866                                $theme->activate_url = add_query_arg( array(
     2867                                        'action'   => 'enable',
     2868                                        '_wpnonce' => wp_create_nonce( 'enable-theme_' . $theme->slug ),
     2869                                        'theme'    => $theme->slug,
     2870                                ), network_admin_url( 'themes.php' ) );
     2871                        } else {
     2872                                $theme->activate_url = add_query_arg( array(
     2873                                        'action'     => 'activate',
     2874                                        '_wpnonce'   => wp_create_nonce( 'switch-theme_' . $theme->slug ),
     2875                                        'stylesheet' => $theme->slug,
     2876                                ), admin_url( 'themes.php' ) );
     2877                        }
     2878                }
     2879
     2880                if ( ! is_multisite() && current_user_can( 'edit_theme_options' ) && current_user_can( 'customize' ) ) {
     2881                        $theme->customize_url = add_query_arg( array(
     2882                                'return' => urlencode( network_admin_url( 'theme-install.php', 'relative' ) ),
     2883                        ), wp_customize_url( $theme->slug ) );
     2884                }
     2885
    28642886                $theme->name        = wp_kses( $theme->name, $themes_allowedtags );
    28652887                $theme->author      = wp_kses( $theme->author, $themes_allowedtags );
     
    30683090
    30693091        wp_send_json_success( array( 'message' => $message ) );
    3070 }
    3071 
    3072 
    3073 /**
    3074  * AJAX handler for updating a plugin.
    3075  *
    3076  * @since 4.2.0
    3077  *
    3078  * @see Plugin_Upgrader
    3079  */
    3080 function wp_ajax_update_plugin() {
    3081         global $wp_filesystem;
    3082 
    3083         $plugin = urldecode( $_POST['plugin'] );
    3084 
    3085         $status = array(
    3086                 'update'     => 'plugin',
    3087                 'plugin'     => $plugin,
    3088                 'slug'       => sanitize_key( $_POST['slug'] ),
    3089                 'oldVersion' => '',
    3090                 'newVersion' => '',
    3091         );
    3092 
    3093         $plugin_data = get_plugin_data( WP_PLUGIN_DIR . '/' . $plugin );
    3094         if ( $plugin_data['Version'] ) {
    3095                 $status['oldVersion'] = sprintf( __( 'Version %s' ), $plugin_data['Version'] );
    3096         }
    3097 
    3098         if ( ! current_user_can( 'update_plugins' ) ) {
    3099                 $status['error'] = __( 'You do not have sufficient permissions to update plugins for this site.' );
    3100                 wp_send_json_error( $status );
    3101         }
    3102 
    3103         check_ajax_referer( 'updates' );
    3104 
    3105         include_once( ABSPATH . 'wp-admin/includes/class-wp-upgrader.php' );
    3106 
    3107         wp_update_plugins();
    3108 
    3109         $skin = new Automatic_Upgrader_Skin();
    3110         $upgrader = new Plugin_Upgrader( $skin );
    3111         $result = $upgrader->bulk_upgrade( array( $plugin ) );
    3112 
    3113         if ( is_array( $result ) && empty( $result[$plugin] ) && is_wp_error( $skin->result ) ) {
    3114                 $result = $skin->result;
    3115         }
    3116 
    3117         if ( is_array( $result ) && !empty( $result[ $plugin ] ) ) {
    3118                 $plugin_update_data = current( $result );
    3119 
    3120                 /*
    3121                  * If the `update_plugins` site transient is empty (e.g. when you update
    3122                  * two plugins in quick succession before the transient repopulates),
    3123                  * this may be the return.
    3124                  *
    3125                  * Preferably something can be done to ensure `update_plugins` isn't empty.
    3126                  * For now, surface some sort of error here.
    3127                  */
    3128                 if ( $plugin_update_data === true ) {
    3129                         $status['error'] = __( 'Plugin update failed.' );
    3130                         wp_send_json_error( $status );
    3131                 }
    3132 
    3133                 $plugin_data = get_plugins( '/' . $result[ $plugin ]['destination_name'] );
    3134                 $plugin_data = reset( $plugin_data );
    3135 
    3136                 if ( $plugin_data['Version'] ) {
    3137                         $status['newVersion'] = sprintf( __( 'Version %s' ), $plugin_data['Version'] );
    3138                 }
    3139 
    3140                 wp_send_json_success( $status );
    3141         } else if ( is_wp_error( $result ) ) {
    3142                 $status['error'] = $result->get_error_message();
    3143                 wp_send_json_error( $status );
    3144 
    3145         } else if ( is_bool( $result ) && ! $result ) {
    3146                 $status['errorCode'] = 'unable_to_connect_to_filesystem';
    3147                 $status['error'] = __( 'Unable to connect to the filesystem. Please confirm your credentials.' );
    3148 
    3149                 // Pass through the error from WP_Filesystem if one was raised
    3150                 if ( is_wp_error( $wp_filesystem->errors ) && $wp_filesystem->errors->get_error_code() ) {
    3151                         $status['error'] = $wp_filesystem->errors->get_error_message();
    3152                 }
    3153 
    3154                 wp_send_json_error( $status );
    3155 
    3156         } else {
    3157                 // An unhandled error occured
    3158                 $status['error'] = __( 'Plugin update failed.' );
    3159                 wp_send_json_error( $status );
    3160         }
    31613092}
    31623093
     
    33343265        wp_send_json_success( update_user_meta( get_current_user_id(), 'wporg_favorites', $username ) );
    33353266}
     3267
     3268/**
     3269 * AJAX handler for installing a theme.
     3270 *
     3271 * @since 4.6.0
     3272 */
     3273function wp_ajax_install_theme() {
     3274        check_ajax_referer( 'updates' );
     3275
     3276        if ( empty( $_POST['slug'] ) ) {
     3277                wp_send_json_error( array(
     3278                        'slug'         => '',
     3279                        'errorCode'    => 'no_theme_specified',
     3280                        'errorMessage' => __( 'No theme specified.' ),
     3281                ) );
     3282        }
     3283
     3284        $slug = sanitize_key( wp_unslash( $_POST['slug'] ) );
     3285
     3286        $status = array(
     3287                'install' => 'theme',
     3288                'slug'    => $slug,
     3289        );
     3290
     3291        if ( ! current_user_can( 'install_themes' ) ) {
     3292                $status['errorMessage'] = __( 'You do not have sufficient permissions to install themes on this site.' );
     3293                wp_send_json_error( $status );
     3294        }
     3295
     3296        include_once( ABSPATH . 'wp-admin/includes/class-wp-upgrader.php' );
     3297        include_once( ABSPATH . 'wp-admin/includes/theme.php' );
     3298
     3299        $api = themes_api( 'theme_information', array(
     3300                'slug'   => $slug,
     3301                'fields' => array( 'sections' => false ),
     3302        ) );
     3303
     3304        if ( is_wp_error( $api ) ) {
     3305                $status['errorMessage'] = $api->get_error_message();
     3306                wp_send_json_error( $status );
     3307        }
     3308
     3309        $upgrader = new Theme_Upgrader( new Automatic_Upgrader_Skin() );
     3310        $result   = $upgrader->install( $api->download_link );
     3311
     3312        if ( defined( 'WP_DEBUG' ) && WP_DEBUG ) {
     3313                $status['debug'] = $upgrader->skin->get_upgrade_messages();
     3314        }
     3315
     3316        if ( is_wp_error( $result ) ) {
     3317                $status['errorMessage'] = $result->get_error_message();
     3318                wp_send_json_error( $status );
     3319        } elseif ( is_null( $result ) ) {
     3320                global $wp_filesystem;
     3321
     3322                $status['errorCode']    = 'unable_to_connect_to_filesystem';
     3323                $status['errorMessage'] = __( 'Unable to connect to the filesystem. Please confirm your credentials.' );
     3324
     3325                // Pass through the error from WP_Filesystem if one was raised.
     3326                if ( $wp_filesystem instanceof WP_Filesystem_Base && is_wp_error( $wp_filesystem->errors ) && $wp_filesystem->errors->get_error_code() ) {
     3327                        $status['errorMessage'] = esc_html( $wp_filesystem->errors->get_error_message() );
     3328                }
     3329
     3330                wp_send_json_error( $status );
     3331        }
     3332
     3333        if ( current_user_can( 'switch_themes' ) ) {
     3334                if ( is_multisite() ) {
     3335                        $status['activateUrl'] = add_query_arg( array(
     3336                                'action'   => 'enable',
     3337                                '_wpnonce' => wp_create_nonce( 'enable-theme_' . $slug ),
     3338                                'theme'    => $slug,
     3339                        ), network_admin_url( 'themes.php' ) );
     3340                } else {
     3341                        $status['activateUrl'] = add_query_arg( array(
     3342                                'action'     => 'activate',
     3343                                '_wpnonce'   => wp_create_nonce( 'switch-theme_' . $slug ),
     3344                                'stylesheet' => $slug,
     3345                        ), admin_url( 'themes.php' ) );
     3346                }
     3347        }
     3348
     3349        if ( ! is_multisite() && current_user_can( 'edit_theme_options' ) && current_user_can( 'customize' ) ) {
     3350                $status['customizeUrl'] = add_query_arg( array(
     3351                        'return' => urlencode( network_admin_url( 'theme-install.php', 'relative' ) ),
     3352                ), wp_customize_url( $slug ) );
     3353        }
     3354
     3355        /*
     3356         * See WP_Theme_Install_List_Table::_get_theme_status() if we wanted to check
     3357         * on post-install status.
     3358         */
     3359        wp_send_json_success( $status );
     3360}
     3361
     3362/**
     3363 * AJAX handler for updating a theme.
     3364 *
     3365 * @since 4.6.0
     3366 *
     3367 * @see Theme_Upgrader
     3368 */
     3369function wp_ajax_update_theme() {
     3370        check_ajax_referer( 'updates' );
     3371
     3372        if ( empty( $_POST['slug'] ) ) {
     3373                wp_send_json_error( array(
     3374                        'slug'         => '',
     3375                        'errorCode'    => 'no_theme_specified',
     3376                        'errorMessage' => __( 'No theme specified.' ),
     3377                ) );
     3378        }
     3379
     3380        $stylesheet = sanitize_key( wp_unslash( $_POST['slug'] ) );
     3381        $status     = array(
     3382                'update'     => 'theme',
     3383                'slug'       => $stylesheet,
     3384                'newVersion' => '',
     3385        );
     3386
     3387        if ( ! current_user_can( 'update_themes' ) ) {
     3388                $status['errorMessage'] = __( 'You do not have sufficient permissions to update themes on this site.' );
     3389                wp_send_json_error( $status );
     3390        }
     3391
     3392        include_once( ABSPATH . 'wp-admin/includes/class-wp-upgrader.php' );
     3393
     3394        $current = get_site_transient( 'update_themes' );
     3395        if ( empty( $current ) ) {
     3396                wp_update_themes();
     3397        }
     3398
     3399        $upgrader = new Theme_Upgrader( new Automatic_Upgrader_Skin() );
     3400        $result   = $upgrader->bulk_upgrade( array( $stylesheet ) );
     3401
     3402        if ( defined( 'WP_DEBUG' ) && WP_DEBUG ) {
     3403                $status['debug'] = $upgrader->skin->get_upgrade_messages();
     3404        }
     3405
     3406        if ( is_array( $result ) && ! empty( $result[ $stylesheet ] ) ) {
     3407
     3408                // Theme is already at the latest version.
     3409                if ( true === $result[ $stylesheet ] ) {
     3410                        $status['errorMessage'] = $upgrader->strings['up_to_date'];
     3411                        wp_send_json_error( $status );
     3412                }
     3413
     3414                $theme = wp_get_theme( $stylesheet );
     3415                if ( $theme->get( 'Version' ) ) {
     3416                        $status['newVersion'] = $theme->get( 'Version' );
     3417                }
     3418
     3419                wp_send_json_success( $status );
     3420        } elseif ( is_wp_error( $upgrader->skin->result ) ) {
     3421                $status['errorCode']    = $upgrader->skin->result->get_error_code();
     3422                $status['errorMessage'] = $upgrader->skin->result->get_error_message();
     3423                wp_send_json_error( $status );
     3424        } elseif ( false === $result ) {
     3425                global $wp_filesystem;
     3426
     3427                $status['errorCode']    = 'unable_to_connect_to_filesystem';
     3428                $status['errorMessage'] = __( 'Unable to connect to the filesystem. Please confirm your credentials.' );
     3429
     3430                // Pass through the error from WP_Filesystem if one was raised.
     3431                if ( $wp_filesystem instanceof WP_Filesystem_Base && is_wp_error( $wp_filesystem->errors ) && $wp_filesystem->errors->get_error_code() ) {
     3432                        $status['errorMessage'] = esc_html( $wp_filesystem->errors->get_error_message() );
     3433                }
     3434
     3435                wp_send_json_error( $status );
     3436        }
     3437
     3438        // An unhandled error occurred.
     3439        $status['errorMessage'] = __( 'Update failed.' );
     3440        wp_send_json_error( $status );
     3441}
     3442
     3443/**
     3444 * AJAX handler for deleting a theme.
     3445 *
     3446 * @since 4.6.0
     3447 */
     3448function wp_ajax_delete_theme() {
     3449        check_ajax_referer( 'updates' );
     3450
     3451        if ( empty( $_POST['slug'] ) ) {
     3452                wp_send_json_error( array(
     3453                        'slug'         => '',
     3454                        'errorCode'    => 'no_theme_specified',
     3455                        'errorMessage' => __( 'No theme specified.' ),
     3456                ) );
     3457        }
     3458
     3459        $stylesheet = sanitize_key( wp_unslash( $_POST['slug'] ) );
     3460        $status     = array(
     3461                'delete' => 'theme',
     3462                'slug'   => $stylesheet,
     3463        );
     3464
     3465        if ( ! current_user_can( 'delete_themes' ) ) {
     3466                $status['errorMessage'] = __( 'You do not have sufficient permissions to delete themes on this site.' );
     3467                wp_send_json_error( $status );
     3468        }
     3469
     3470        if ( ! wp_get_theme( $stylesheet )->exists() ) {
     3471                $status['errorMessage'] = __( 'The requested theme does not exist.' );
     3472                wp_send_json_error( $status );
     3473        }
     3474
     3475        // Check filesystem credentials. `delete_plugins()` will bail otherwise.
     3476        ob_start();
     3477        $url = wp_nonce_url( 'themes.php?action=delete&stylesheet=' . urlencode( $stylesheet ), 'delete-theme_' . $stylesheet );
     3478        if ( false === ( $credentials = request_filesystem_credentials( $url ) ) || ! WP_Filesystem( $credentials ) ) {
     3479                global $wp_filesystem;
     3480                ob_end_clean();
     3481
     3482                $status['errorCode']    = 'unable_to_connect_to_filesystem';
     3483                $status['errorMessage'] = __( 'Unable to connect to the filesystem. Please confirm your credentials.' );
     3484
     3485                // Pass through the error from WP_Filesystem if one was raised.
     3486                if ( $wp_filesystem instanceof WP_Filesystem_Base && is_wp_error( $wp_filesystem->errors ) && $wp_filesystem->errors->get_error_code() ) {
     3487                        $status['errorMessage'] = esc_html( $wp_filesystem->errors->get_error_message() );
     3488                }
     3489
     3490                wp_send_json_error( $status );
     3491        }
     3492
     3493        include_once( ABSPATH . 'wp-admin/includes/theme.php' );
     3494
     3495        $result = delete_theme( $stylesheet );
     3496
     3497        if ( is_wp_error( $result ) ) {
     3498                $status['errorMessage'] = $result->get_error_message();
     3499                wp_send_json_error( $status );
     3500        } elseif ( false === $result ) {
     3501                $status['errorMessage'] = __( 'Theme could not be deleted.' );
     3502                wp_send_json_error( $status );
     3503        }
     3504
     3505        wp_send_json_success( $status );
     3506}
     3507
     3508/**
     3509 * AJAX handler for installing a plugin.
     3510 *
     3511 * @since 4.6.0
     3512 */
     3513function wp_ajax_install_plugin() {
     3514        check_ajax_referer( 'updates' );
     3515
     3516        if ( empty( $_POST['slug'] ) ) {
     3517                wp_send_json_error( array(
     3518                        'slug'         => '',
     3519                        'errorCode'    => 'no_plugin_specified',
     3520                        'errorMessage' => __( 'No plugin specified.' ),
     3521                ) );
     3522        }
     3523
     3524        $status = array(
     3525                'install' => 'plugin',
     3526                'slug'    => sanitize_key( wp_unslash( $_POST['slug'] ) ),
     3527        );
     3528
     3529        if ( ! current_user_can( 'install_plugins' ) ) {
     3530                $status['errorMessage'] = __( 'You do not have sufficient permissions to install plugins on this site.' );
     3531                wp_send_json_error( $status );
     3532        }
     3533
     3534        include_once( ABSPATH . 'wp-admin/includes/class-wp-upgrader.php' );
     3535        include_once( ABSPATH . 'wp-admin/includes/plugin-install.php' );
     3536
     3537        $api = plugins_api( 'plugin_information', array(
     3538                'slug'   => sanitize_key( wp_unslash( $_POST['slug'] ) ),
     3539                'fields' => array(
     3540                        'sections' => false,
     3541                ),
     3542        ) );
     3543
     3544        if ( is_wp_error( $api ) ) {
     3545                $status['errorMessage'] = $api->get_error_message();
     3546                wp_send_json_error( $status );
     3547        }
     3548
     3549        $status['pluginName'] = $api->name;
     3550
     3551        $upgrader = new Plugin_Upgrader( new Automatic_Upgrader_Skin() );
     3552        $result   = $upgrader->install( $api->download_link );
     3553
     3554        if ( defined( 'WP_DEBUG' ) && WP_DEBUG ) {
     3555                $status['debug'] = $upgrader->skin->get_upgrade_messages();
     3556        }
     3557
     3558        if ( is_wp_error( $result ) ) {
     3559                $status['errorMessage'] = $result->get_error_message();
     3560                wp_send_json_error( $status );
     3561        } elseif ( is_null( $result ) ) {
     3562                global $wp_filesystem;
     3563
     3564                $status['errorCode']    = 'unable_to_connect_to_filesystem';
     3565                $status['errorMessage'] = __( 'Unable to connect to the filesystem. Please confirm your credentials.' );
     3566
     3567                // Pass through the error from WP_Filesystem if one was raised.
     3568                if ( $wp_filesystem instanceof WP_Filesystem_Base && is_wp_error( $wp_filesystem->errors ) && $wp_filesystem->errors->get_error_code() ) {
     3569                        $status['errorMessage'] = esc_html( $wp_filesystem->errors->get_error_message() );
     3570                }
     3571
     3572                wp_send_json_error( $status );
     3573        }
     3574
     3575        $install_status = install_plugin_install_status( $api );
     3576
     3577        if ( current_user_can( 'activate_plugins' ) && is_plugin_inactive( $install_status['file'] ) ) {
     3578                $status['activateUrl'] = add_query_arg( array(
     3579                        '_wpnonce' => wp_create_nonce( 'activate-plugin_' . $install_status['file'] ),
     3580                        'action'   => 'activate',
     3581                        'plugin'   => $install_status['file'],
     3582                ), network_admin_url( 'plugins.php' ) );
     3583        }
     3584
     3585        if ( is_multisite() && current_user_can( 'manage_network_plugins' ) ) {
     3586                $status['activateUrl'] = add_query_arg( array( 'networkwide' => 1 ), $status['activateUrl'] );
     3587        }
     3588
     3589        wp_send_json_success( $status );
     3590}
     3591
     3592/**
     3593 * AJAX handler for updating a plugin.
     3594 *
     3595 * @since 4.2.0
     3596 *
     3597 * @see Plugin_Upgrader
     3598 */
     3599function wp_ajax_update_plugin() {
     3600        check_ajax_referer( 'updates' );
     3601
     3602        if ( empty( $_POST['plugin'] ) || empty( $_POST['slug'] ) ) {
     3603                wp_send_json_error( array(
     3604                        'slug'         => '',
     3605                        'errorCode'    => 'no_plugin_specified',
     3606                        'errorMessage' => __( 'No plugin specified.' ),
     3607                ) );
     3608        }
     3609
     3610        $plugin      = plugin_basename( sanitize_text_field( wp_unslash( $_POST['plugin'] ) ) );
     3611        $plugin_data = get_plugin_data( WP_PLUGIN_DIR . '/' . $plugin );
     3612
     3613        $status = array(
     3614                'update'     => 'plugin',
     3615                'plugin'     => $plugin,
     3616                'slug'       => sanitize_key( wp_unslash( $_POST['slug'] ) ),
     3617                'pluginName' => $plugin_data['Name'],
     3618                'oldVersion' => '',
     3619                'newVersion' => '',
     3620        );
     3621
     3622        if ( $plugin_data['Version'] ) {
     3623                /* translators: %s: Plugin version */
     3624                $status['oldVersion'] = sprintf( __( 'Version %s' ), $plugin_data['Version'] );
     3625        }
     3626
     3627        if ( ! current_user_can( 'update_plugins' ) ) {
     3628                $status['errorMessage'] = __( 'You do not have sufficient permissions to update plugins for this site.' );
     3629                wp_send_json_error( $status );
     3630        }
     3631
     3632        include_once ABSPATH . 'wp-admin/includes/class-wp-upgrader.php';
     3633
     3634        wp_update_plugins();
     3635
     3636        $skin     = new Automatic_Upgrader_Skin();
     3637        $upgrader = new Plugin_Upgrader( $skin );
     3638        $result   = $upgrader->bulk_upgrade( array( $plugin ) );
     3639
     3640        if ( defined( 'WP_DEBUG' ) && WP_DEBUG ) {
     3641                $status['debug'] = $upgrader->skin->get_upgrade_messages();
     3642        }
     3643
     3644        if ( is_array( $result ) && empty( $result[ $plugin ] ) && is_wp_error( $skin->result ) ) {
     3645                $result = $skin->result;
     3646        }
     3647
     3648        if ( is_array( $result ) && ! empty( $result[ $plugin ] ) ) {
     3649                $plugin_update_data = current( $result );
     3650
     3651                /*
     3652                 * If the `update_plugins` site transient is empty (e.g. when you update
     3653                 * two plugins in quick succession before the transient repopulates),
     3654                 * this may be the return.
     3655                 *
     3656                 * Preferably something can be done to ensure `update_plugins` isn't empty.
     3657                 * For now, surface some sort of error here.
     3658                 */
     3659                if ( true === $plugin_update_data ) {
     3660                        $status['errorMessage'] = __( 'Plugin update failed.' );
     3661                        wp_send_json_error( $status );
     3662                }
     3663
     3664                $plugin_data = get_plugins( '/' . $result[ $plugin ]['destination_name'] );
     3665                $plugin_data = reset( $plugin_data );
     3666
     3667                if ( $plugin_data['Version'] ) {
     3668                        /* translators: %s: Plugin version */
     3669                        $status['newVersion'] = sprintf( __( 'Version %s' ), $plugin_data['Version'] );
     3670                }
     3671                wp_send_json_success( $status );
     3672        } elseif ( is_wp_error( $result ) ) {
     3673                $status['errorMessage'] = $result->get_error_message();
     3674                wp_send_json_error( $status );
     3675        } elseif ( false === $result ) {
     3676                global $wp_filesystem;
     3677
     3678                $status['errorCode']    = 'unable_to_connect_to_filesystem';
     3679                $status['errorMessage'] = __( 'Unable to connect to the filesystem. Please confirm your credentials.' );
     3680
     3681                // Pass through the error from WP_Filesystem if one was raised.
     3682                if ( $wp_filesystem instanceof WP_Filesystem_Base && is_wp_error( $wp_filesystem->errors ) && $wp_filesystem->errors->get_error_code() ) {
     3683                        $status['errorMessage'] = esc_html( $wp_filesystem->errors->get_error_message() );
     3684                }
     3685
     3686                wp_send_json_error( $status );
     3687        }
     3688
     3689        // An unhandled error occurred.
     3690        $status['errorMessage'] = __( 'Plugin update failed.' );
     3691        wp_send_json_error( $status );
     3692}
     3693
     3694/**
     3695 * AJAX handler for deleting a plugin.
     3696 *
     3697 * @since 4.6.0
     3698 */
     3699function wp_ajax_delete_plugin() {
     3700        check_ajax_referer( 'updates' );
     3701
     3702        if ( empty( $_POST['slug'] ) || empty( $_POST['plugin'] ) ) {
     3703                wp_send_json_error( array( 'errorCode' => 'no_plugin_specified' ) );
     3704        }
     3705
     3706        $plugin      = plugin_basename( sanitize_text_field( wp_unslash( $_POST['plugin'] ) ) );
     3707        $plugin_data = get_plugin_data( WP_PLUGIN_DIR . '/' . $plugin );
     3708
     3709        $status = array(
     3710                'delete'     => 'plugin',
     3711                'slug'       => sanitize_key( wp_unslash( $_POST['slug'] ) ),
     3712                'plugin'     => $plugin,
     3713                'pluginName' => $plugin_data['Name'],
     3714        );
     3715
     3716        if ( ! current_user_can( 'delete_plugins' ) ) {
     3717                $status['errorMessage'] = __( 'You do not have sufficient permissions to delete plugins for this site.' );
     3718                wp_send_json_error( $status );
     3719        }
     3720
     3721        if ( is_plugin_active( $plugin ) ) {
     3722                $status['errorMessage'] = __( 'You cannot delete a plugin while it is active on the main site.' );
     3723                wp_send_json_error( $status );
     3724        }
     3725
     3726        // Check filesystem credentials. `delete_plugins()` will bail otherwise.
     3727        ob_start();
     3728        $url = wp_nonce_url( 'plugins.php?action=delete-selected&verify-delete=1&checked[]=' . $plugin, 'bulk-plugins' );
     3729        if ( false === ( $credentials = request_filesystem_credentials( $url ) ) || ! WP_Filesystem( $credentials ) ) {
     3730                global $wp_filesystem;
     3731                ob_end_clean();
     3732
     3733                $status['errorCode']    = 'unable_to_connect_to_filesystem';
     3734                $status['errorMessage'] = __( 'Unable to connect to the filesystem. Please confirm your credentials.' );
     3735
     3736                // Pass through the error from WP_Filesystem if one was raised.
     3737                if ( $wp_filesystem instanceof WP_Filesystem_Base && is_wp_error( $wp_filesystem->errors ) && $wp_filesystem->errors->get_error_code() ) {
     3738                        $status['errorMessage'] = esc_html( $wp_filesystem->errors->get_error_message() );
     3739                }
     3740
     3741                wp_send_json_error( $status );
     3742        }
     3743
     3744        $result = delete_plugins( array( $plugin ) );
     3745
     3746        if ( is_wp_error( $result ) ) {
     3747                $status['errorMessage'] = $result->get_error_message();
     3748                wp_send_json_error( $status );
     3749        } elseif ( false === $result ) {
     3750                $status['errorMessage'] = __( 'Plugin could not be deleted.' );
     3751                wp_send_json_error( $status );
     3752        }
     3753
     3754        wp_send_json_success( $status );
     3755}
     3756
     3757/**
     3758 * AJAX handler for searching plugins.
     3759 *
     3760 * @since 4.6.0
     3761 *
     3762 * @global WP_List_Table $wp_list_table Current list table instance.
     3763 * @global string        $hook_suffix   Current admin page.
     3764 * @global string        $s             Search term.
     3765 */
     3766function wp_ajax_search_plugins() {
     3767        check_ajax_referer( 'updates' );
     3768
     3769        global $wp_list_table, $hook_suffix, $s;
     3770        $hook_suffix = 'plugins.php';
     3771
     3772        /** @var WP_Plugins_List_Table $wp_list_table */
     3773        $wp_list_table = _get_list_table( 'WP_Plugins_List_Table' );
     3774        $status        = array();
     3775
     3776        if ( ! $wp_list_table->ajax_user_can() ) {
     3777                $status['errorMessage'] = __( 'You do not have sufficient permissions to manage plugins on this site.' );
     3778                wp_send_json_error( $status );
     3779        }
     3780
     3781        // Set the correct requester, so pagination works.
     3782        $_SERVER['REQUEST_URI'] = add_query_arg( array_diff_key( $_POST, array(
     3783                '_ajax_nonce' => null,
     3784                'action'      => null,
     3785        ) ), network_admin_url( 'plugins.php', 'relative' ) );
     3786
     3787        $s = sanitize_text_field( $_POST['s'] );
     3788
     3789        $wp_list_table->prepare_items();
     3790
     3791        ob_start();
     3792        $wp_list_table->display();
     3793        $status['items'] = ob_get_clean();
     3794
     3795        wp_send_json_success( $status );
     3796}
     3797
     3798/**
     3799 * AJAX handler for searching plugins to install.
     3800 *
     3801 * @since 4.6.0
     3802 *
     3803 * @global WP_List_Table $wp_list_table Current list table instance.
     3804 * @global string        $hook_suffix   Current admin page.
     3805 */
     3806function wp_ajax_search_install_plugins() {
     3807        check_ajax_referer( 'updates' );
     3808
     3809        global $wp_list_table, $hook_suffix;
     3810        $hook_suffix = 'plugin-install.php';
     3811
     3812        /** @var WP_Plugin_Install_List_Table $wp_list_table */
     3813        $wp_list_table = _get_list_table( 'WP_Plugin_Install_List_Table' );
     3814        $status        = array();
     3815
     3816        if ( ! $wp_list_table->ajax_user_can() ) {
     3817                $status['errorMessage'] = __( 'You do not have sufficient permissions to manage plugins on this site.' );
     3818                wp_send_json_error( $status );
     3819        }
     3820
     3821        // Set the correct requester, so pagination works.
     3822        $_SERVER['REQUEST_URI'] = add_query_arg( array_diff_key( $_POST, array(
     3823                '_ajax_nonce' => null,
     3824                'action'      => null,
     3825        ) ), network_admin_url( 'plugin-install.php', 'relative' ) );
     3826
     3827        $wp_list_table->prepare_items();
     3828
     3829        ob_start();
     3830        $wp_list_table->display();
     3831        $status['items'] = ob_get_clean();
     3832
     3833        wp_send_json_success( $status );
     3834}
Note: See TracChangeset for help on using the changeset viewer.