Make WordPress Core

Ticket #31528: 31528.12.diff

File 31528.12.diff, 14.1 KB (added by ericlewis, 10 years ago)
  • src/wp-admin/css/forms.css

     
    850850        margin-bottom: 5px;
    851851}
    852852
     853/*------------------------------------------------------------------------------
     854   Credentials check dialog for Install and Updates
     855------------------------------------------------------------------------------*/
     856
     857.request-filesystem-credentials-dialog {
     858        display: none;
     859}
     860
     861.request-filesystem-credentials-dialog .notification-dialog {
     862        top: 15%;
     863}
     864
     865.request-filesystem-credentials-dialog-content {
     866        margin: 25px;
     867}
     868
     869.request-filesystem-credentials-dialog-content input[type="text"],
     870.request-filesystem-credentials-dialog-content input[type="password"] {
     871        width: 85%;
     872}
     873
    853874/* =Media Queries
    854875-------------------------------------------------------------- */
    855876
  • src/wp-admin/includes/ajax-actions.php

     
    29132913        if ( is_wp_error( $result ) ) {
    29142914                $status['error'] = $result->get_error_message();
    29152915                wp_send_json_error( $status );
     2916        } else if ( is_null( $result ) ) {
     2917                $status['errorCode'] = 'unable_to_connect_to_filesystem';
     2918                $status['error'] = __( 'Unable to connect to the filesystem. Please confirm your credentials.' );
     2919                wp_send_json_error( $status );
    29162920        }
    29172921
    29182922        $plugin_status = install_plugin_install_status( $api );
     
    29332937        $plugin = urldecode( $_POST['plugin'] );
    29342938
    29352939        $status = array(
    2936                 'update' => 'plugin',
    2937                 'plugin' => $plugin,
    2938                 'slug'   => sanitize_key( $_POST['slug'] ),
     2940                'update'     => 'plugin',
     2941                'plugin'     => $plugin,
     2942                'slug'       => sanitize_key( $_POST['slug'] ),
     2943                'oldVersion' => '',
     2944                'newVersion' => '',
    29392945        );
     2946        $plugin_data = get_plugin_data( WP_PLUGIN_DIR . '/' . $plugin );
     2947        if ( $plugin_data['Version'] ) {
     2948                $status['oldVersion'] = sprintf( __( 'Version %s' ), $plugin_data['Version'] );
     2949        }
    29402950
    29412951        if ( ! current_user_can( 'update_plugins' ) ) {
    29422952                $status['error'] = __( 'You do not have sufficient permissions to update plugins on this site.' );
     
    29562966        $result = $upgrader->bulk_upgrade( array( $plugin ) );
    29572967
    29582968        if ( is_array( $result ) ) {
    2959                 $result = $result[ $plugin ];
    2960         }
    2961 
    2962         if ( is_wp_error( $result ) ) {
     2969                $plugin_update_data = current( $result );
     2970                /*
     2971                 * If the `update_plugins` site transient is empty (e.g. when you update
     2972                 * two plugins in quick succession before the transient repopulates),
     2973                 * this may be the return.
     2974                 *
     2975                 * Preferably something can be done to ensure `update_plugins` isn't empty.
     2976                 * For now, surface some sort of error here.
     2977                 */
     2978                if ( $plugin_update_data === true ) {
     2979                        wp_send_json_error( $status );
     2980                }
     2981                $plugin_data = get_plugin_data( WP_PLUGIN_DIR . '/' . $plugin );
     2982                if ( $plugin_data['Version'] ) {
     2983                        $status['newVersion'] = sprintf( __( 'Version %s' ), $plugin_data['Version'] );
     2984                }
     2985                wp_send_json_success( $status );
     2986        } else if ( is_wp_error( $result ) ) {
    29632987                $status['error'] = $result->get_error_message();
    29642988                wp_send_json_error( $status );
     2989        } else if ( is_bool( $result ) && ! $result ) {
     2990                $status['errorCode'] = 'unable_to_connect_to_filesystem';
     2991                $status['error'] = __( 'Unable to connect to the filesystem. Please confirm your credentials.' );
     2992                wp_send_json_error( $status );
    29652993        }
    2966 
    2967         wp_send_json_success( $status );
    29682994}
    29692995
    29702996/**
  • src/wp-admin/includes/file.php

     
    11921192<?php
    11931193        return false;
    11941194}
     1195
     1196/**
     1197 * Print the credentials modal when needed 
     1198 *
     1199 * @since 4.2.0
     1200 */
     1201function wp_print_request_filesystem_credentials_modal() {
     1202        $filesystem_method = get_filesystem_method();
     1203        ob_start();
     1204        $filesystem_credentials_are_stored = request_filesystem_credentials( self_admin_url() );
     1205        ob_end_clean();
     1206        $request_filesystem_credentials = ( $filesystem_method != 'direct' && ! $filesystem_credentials_are_stored );
     1207        if ( ! $request_filesystem_credentials ) {
     1208                return;
     1209        }
     1210        ?>
     1211        <div id="request-filesystem-credentials-dialog" class="notification-dialog-wrap request-filesystem-credentials-dialog">
     1212                <div class="notification-dialog-background"></div>
     1213                <div class="notification-dialog">
     1214                        <div class="request-filesystem-credentials-dialog-content">
     1215                                <?php request_filesystem_credentials( site_url() ); ?>
     1216                        <div>
     1217                </div>
     1218        </div>
     1219        <?php
     1220}
  • src/wp-admin/js/updates.js

     
    2222        wp.updates.l10n = window._wpUpdatesSettings.l10n;
    2323
    2424        /**
     25         * Whether filesystem credentials need to be requested from the user.
     26         *
     27         * @since 4.2.0
     28         *
     29         * @var bool
     30         */
     31        wp.updates.shouldRequestFilesystemCredentials = null;
     32
     33        /**
     34         * Filesystem credentials to be packaged along with the request.
     35         *
     36         * @since  4.2.0
     37         *
     38         * @var object
     39         */
     40        wp.updates.filesystemCredentials = {
     41                ftp: {
     42                        host: null,
     43                        username: null,
     44                        password: null,
     45                        connectionType: null
     46                },
     47                ssh: {
     48                        publicKey: null,
     49                        privateKey: null
     50                }
     51        };
     52
     53        /**
    2554         * Flag if we're waiting for an install/update to complete.
    2655         *
    2756         * @since 4.2.0
     
    3160        wp.updates.updateLock = false;
    3261
    3362        /**
     63         * * Flag if we've done an install or update successfully.
     64         *
     65         * @since 4.2.0
     66         *
     67         * @var bool
     68         */
     69        wp.updates.updateDoneSuccessfully = false;
     70
     71        /**
    3472         * If the user tries to install/update a plugin while an install/update is
    3573         * already happening, it can be placed in this queue to perform later.
    3674         *
     
    123161                wp.updates.updateLock = true;
    124162
    125163                var data = {
    126                         '_ajax_nonce': wp.updates.ajaxNonce,
    127                         'plugin':      plugin,
    128                         'slug':        slug
     164                        _ajax_nonce:     wp.updates.ajaxNonce,
     165                        plugin:          plugin,
     166                        slug:            slug,
     167                        username:        wp.updates.filesystemCredentials.ftp.username,
     168                        password:        wp.updates.filesystemCredentials.ftp.password,
     169                        hostname:        wp.updates.filesystemCredentials.ftp.hostname,
     170                        connection_type: wp.updates.filesystemCredentials.ftp.connectionType,
     171                        public_key:      wp.updates.filesystemCredentials.ssh.publicKey,
     172                        private_key:     wp.updates.filesystemCredentials.ssh.privateKey
    129173                };
    130174
    131175                wp.ajax.post( 'update-plugin', data )
    132176                        .done( wp.updates.updateSuccess )
    133                         .fail( wp.updates.updateError )
    134                         .always( wp.updates.updateAlways );
     177                        .fail( wp.updates.updateError );
    135178        };
    136179
    137180        /**
     
    147190                        $message = $( '#' + response.slug ).next().find( '.update-message' );
    148191                        $( '#' + response.slug ).addClass( 'updated' ).removeClass( 'update' );
    149192                        $( '#' + response.slug + '-update' ).addClass( 'updated' ).removeClass( 'update' );
     193                        // Update the version number in the row.
     194                        var newText = $( '#' + response.slug ).find('.plugin-version-author-uri').html().replace( response.oldVersion, response.newVersion );
     195                        $( '#' + response.slug ).find('.plugin-version-author-uri').html( newText );
    150196                } else if ( 'plugin-install' === pagenow ) {
    151197                        $message = $( '.plugin-card-' + response.slug ).find( '.update-now' );
    152198                        $message.addClass( 'button-disabled' );
     
    157203                wp.a11y.speak( wp.updates.l10n.updatedMsg );
    158204
    159205                wp.updates.decrementCount( 'plugin' );
     206
     207                wp.updates.updateDoneSuccessfully = true;
     208
     209                /*
     210                 * The lock can be released since the update was successful,
     211                 * and any other updates can commence.
     212                 */
     213                wp.updates.updateLock = false;
     214                wp.updates.queueChecker();
    160215        };
    161216
    162217        /**
     
    168223         */
    169224        wp.updates.updateError = function( response ) {
    170225                var $message;
     226                wp.updates.updateDoneSuccessfully = false;
     227                if ( response.errorCode && response.errorCode == 'unable_to_connect_to_filesystem' ) {
     228                        wp.updates.credentialError( response, 'update-plugin' );
     229                        return;
     230                }
    171231                if ( 'plugins' === pagenow || 'plugins-network' === pagenow ) {
    172232                        $message = $( '#' + response.slug ).next().find( '.update-message' );
    173233                } else if ( 'plugin-install' === pagenow ) {
     
    179239        };
    180240
    181241        /**
    182          * After an update attempt has completed, check the queue.
     242         * Show an error message in the request for credentials form.
    183243         *
     244         * @param {string} message
    184245         * @since 4.2.0
    185246         */
    186         wp.updates.updateAlways = function() {
    187                 wp.updates.updateLock = false;
    188                 wp.updates.queueChecker();
     247        wp.updates.showErrorInCredentialsForm = function( message ) {
     248                var $notificationDialog = $( '.notification-dialog' );
     249
     250                // Remove any existing error
     251                $notificationDialog.find( '.error' ).remove();
     252
     253                $notificationDialog.find( 'h3' ).after( '<div class="error">' + message + '</div>' );
    189254        };
    190255
    191 
    192256        /**
    193257         * Send an Ajax request to the server to install a plugin.
    194258         *
     
    216280                wp.updates.updateLock = true;
    217281
    218282                var data = {
    219                         '_ajax_nonce': wp.updates.ajaxNonce,
    220                         'slug':        slug
     283                        _ajax_nonce:     wp.updates.ajaxNonce,
     284                        slug:            slug,
     285                        username:        wp.updates.filesystemCredentials.ftp.username,
     286                        password:        wp.updates.filesystemCredentials.ftp.password,
     287                        hostname:        wp.updates.filesystemCredentials.ftp.hostname,
     288                        connection_type: wp.updates.filesystemCredentials.ftp.connectionType,
     289                        public_key:      wp.updates.filesystemCredentials.ssh.publicKey,
     290                        private_key:     wp.updates.filesystemCredentials.ssh.privateKey
    221291                };
    222292
    223293                wp.ajax.post( 'install-plugin', data )
     
    239309                $message.removeClass( 'updating-message' ).addClass( 'updated-message button-disabled' );
    240310                $message.text( wp.updates.l10n.installed );
    241311                wp.a11y.speak( wp.updates.l10n.installedMsg );
     312                wp.updates.updateDoneSuccessfully = true;
    242313        };
    243314
    244315        /**
     
    250321         */
    251322        wp.updates.installError = function( response ) {
    252323                var $message = $( '.plugin-card-' + response.slug ).find( '.install-now' );
     324                wp.updates.updateDoneSuccessfully = false;
     325                if ( response.errorCode && response.errorCode == 'unable_to_connect_to_filesystem' ) {
     326                        wp.updates.credentialError( response, 'update-plugin' );
     327                        return;
     328                }
    253329
    254330                $message.removeClass( 'updating-message' );
    255331                $message.text( wp.updates.l10n.installNow );
    256332        };
    257333
     334        /**
     335         * Events that need to happen when there is a credential error
     336         *
     337         * @since 4.2.0
     338         */
     339        wp.updates.credentialError = function( response, type ) {
     340                wp.updates.updateQueue.push( {
     341                        'type': type,
     342                        'data': {
     343                                // Not cool that we're depending on response for this data.
     344                                // This would feel more whole in a view all tied together.
     345                                plugin: response.plugin,
     346                                slug: response.slug
     347                        }
     348                } );
     349                wp.updates.showErrorInCredentialsForm( response.error );
     350                wp.updates.requestFilesystemCredentials();
     351        };
    258352
    259353        /**
    260354         * If an install/update job has been placed in the queue, queueChecker pulls it out and runs it.
     
    282376                }
    283377        };
    284378
     379
     380        /**
     381         * Request the users filesystem credentials if we don't have them already
     382         *
     383         * @since 4.2.0
     384         */
     385        wp.updates.requestFilesystemCredentials = function() {
     386                if ( wp.updates.updateDoneSuccessfully === false ) {
     387                        wp.updates.updateLock = true;
     388                        $( 'body' ).addClass( 'modal-open' );
     389                        $( '#request-filesystem-credentials-dialog' ).show();
     390                }
     391        };
     392
    285393        $( document ).ready( function() {
     394                /*
     395                 * Check whether a user needs to submit filesystem credentials based on whether
     396                 * the form was output on the page server-side.
     397                 *
     398                 * @see {wp_print_request_filesystem_credentials_modal() in PHP}
     399                 */
     400                wp.updates.shouldRequestFilesystemCredentials = ( $( '#request-filesystem-credentials-dialog' ).length <= 0 ) ? false : true;
     401
     402                // File system credentials form submit noop-er / handler.
     403                $( '#request-filesystem-credentials-dialog form' ).on( 'submit', function() {
     404                        // Persist the credentials input by the user for the duration of the page load.
     405                        wp.updates.filesystemCredentials.ftp.hostname = $('#hostname').val();
     406                        wp.updates.filesystemCredentials.ftp.username = $('#username').val();
     407                        wp.updates.filesystemCredentials.ftp.password = $('#password').val();
     408                        wp.updates.filesystemCredentials.ftp.connectionType = $('input[name="connection_type"]:checked').val();
     409                        wp.updates.filesystemCredentials.ssh.publicKey = $('#public_key').val();
     410                        wp.updates.filesystemCredentials.ssh.privateKey = $('#private_key').val();
     411
     412                        $( '#request-filesystem-credentials-dialog' ).hide();
     413                        $( 'body' ).removeClass( 'modal-open' );
     414
     415                        // Unlock and invoke the queue.
     416                        wp.updates.updateLock = false;
     417                        wp.updates.queueChecker();
     418
     419                        return false;
     420                });
     421
     422                // Click handler for plugin updates in List Table view.
    286423                $( '.plugin-update-tr .update-link' ).on( 'click', function( e ) {
    287424                        e.preventDefault();
     425                        if ( wp.updates.shouldRequestFilesystemCredentials && ! wp.updates.updateLock ) {
     426                                wp.updates.requestFilesystemCredentials();
     427                        }
    288428                        var $row = $( e.target ).parents( '.plugin-update-tr' );
    289429                        wp.updates.updatePlugin( $row.data( 'plugin' ), $row.data( 'slug' ) );
    290430                } );
     
    315455
    316456                $( '.plugin-card .install-now' ).on( 'click', function( e ) {
    317457                        e.preventDefault();
     458                        if ( wp.updates.shouldRequestFilesystemCredentials && ! wp.updates.updateLock ) {
     459                                wp.updates.requestFilesystemCredentials();
     460                        }
    318461                        var $button = $( e.target );
    319462                        if ( $button.hasClass( 'button-disabled' ) ) {
    320463                                return;
  • src/wp-admin/plugin-install.php

     
    128128 */
    129129do_action( "install_plugins_$tab", $paged ); ?>
    130130</div>
    131 <?php
     131
     132<?php
     133wp_print_request_filesystem_credentials_modal();
     134
    132135/**
    133136 * WordPress Administration Template Footer.
    134137 */
  • src/wp-admin/plugins.php

     
    476476</div>
    477477
    478478<?php
     479wp_print_request_filesystem_credentials_modal();
     480
    479481include(ABSPATH . 'wp-admin/admin-footer.php');