WordPress.org

Make WordPress Core

Changeset 31749


Ignore:
Timestamp:
03/12/2015 08:52:42 AM (7 years ago)
Author:
jorbin
Message:

Request FTP and SSH credentials when needed during shiny updates

This is a first pass at requesting FTP and SSH credentials when needed during shiny updates. Styling and some UX improvements are still needed, but we do show the prompt and use the passed data when doing plugin installs and updates for shiny updates. There are also a couple of areas that we could improve code wise such how we create the requestFilesystemCredentials part of the localized _wpUpdatesSettings. Over the past half century, we've split the atom, we've spliced the gene and we've roamed Tranquility Base. We've reached for the stars and never have we been closer to having them in our grasp. That has nothing to do with shiny updates.

Props ericlewis, jorbin, and drewapicture for testing
Fixes #31528

Location:
trunk/src
Files:
6 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/wp-admin/css/forms.css

    r31611 r31749  
    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.request-filesystem-credentials-dialog-content input[type="text"],
     869.request-filesystem-credentials-dialog-content input[type="password"]{
     870    width:85%;
     871}
     872
    853873/* =Media Queries
    854874-------------------------------------------------------------- */
  • trunk/src/wp-admin/includes/ajax-actions.php

    r31645 r31749  
    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
     
    29552959    $upgrader = new Plugin_Upgrader( new Automatic_Upgrader_Skin() );
    29562960    $result = $upgrader->bulk_upgrade( array( $plugin ) );
    2957 
    29582961    if ( is_array( $result ) ) {
    2959         $result = $result[ $plugin ];
    2960     }
    2961 
    2962     if ( is_wp_error( $result ) ) {
     2962        wp_send_json_success( $status );
     2963    } else if ( is_wp_error( $result ) ) {
    29632964        $status['error'] = $result->get_error_message();
    29642965        wp_send_json_error( $status );
    2965     }
    2966 
    2967     wp_send_json_success( $status );
     2966    } else if ( is_bool( $result ) && ! $result ) {
     2967        $status['errorCode'] = __( 'unable_to_connect_to_filesystem' );
     2968        $status['error'] = __( 'Unable to connect to the filesystem. Please confirm your credentials.' );
     2969        wp_send_json_error( $status );
     2970    }
    29682971}
    29692972
  • trunk/src/wp-admin/js/updates.js

    r31594 r31749  
    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 = window._wpUpdatesSettings.requestFilesystemCredentials;
     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     *
     
    3059     */
    3160    wp.updates.updateLock = false;
     61
     62    /**
     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;
    3270
    3371    /**
     
    125163        var data = {
    126164            '_ajax_nonce': wp.updates.ajaxNonce,
    127             'plugin':      plugin,
    128             'slug':        slug
     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
     
    158202
    159203        wp.updates.decrementCount( 'plugin' );
     204
     205        wp.updates.updateDoneSuccessfully = true;
    160206    };
    161207
     
    169215    wp.updates.updateError = function( response ) {
    170216        var $message;
     217        wp.updates.updateDoneSuccessfully = false;
     218        if ( response.errorCode && response.errorCode == 'unable_to_connect_to_filesystem' ) {
     219            wp.updates.credentialError( response, 'update-plugin' );
     220            return;
     221        }
    171222        if ( 'plugins' === pagenow || 'plugins-network' === pagenow ) {
    172223            $message = $( '#' + response.slug ).next().find( '.update-message' );
     
    178229        wp.a11y.speak( wp.updates.l10n.updateFailed );
    179230    };
     231
     232    /**
     233     * Show an
     234     *
     235     * @param {string} message
     236     * @since 4.2.0
     237     */
     238    wp.updates.showErrorInCredentialsForm = function( message ) {
     239        var $notificationDialog = $( '.notification-dialog' );
     240
     241        // Remove any existing error
     242        $notificationDialog.find( '.error' ).remove();
     243
     244        $notificationDialog.find( 'h3' ).after( '<div class="error">' + message + '</div>' );
     245    };
    180246
    181247    /**
     
    217283
    218284        var data = {
    219             '_ajax_nonce': wp.updates.ajaxNonce,
    220             'slug':        slug
     285            '_ajax_nonce':     wp.updates.ajaxNonce,
     286            'slug':            slug,
     287            'username':        wp.updates.filesystemCredentials.ftp.username,
     288            'password':        wp.updates.filesystemCredentials.ftp.password,
     289            'hostname':        wp.updates.filesystemCredentials.ftp.hostname,
     290            'connection_type': wp.updates.filesystemCredentials.ftp.connectionType,
     291            'public_key':      wp.updates.filesystemCredentials.ssh.publicKey,
     292            'private_key':     wp.updates.filesystemCredentials.ssh.privateKey
    221293        };
    222294
     
    240312        $message.text( wp.updates.l10n.installed );
    241313        wp.a11y.speak( wp.updates.l10n.installedMsg );
     314        wp.updates.updateDoneSuccessfully = true;
    242315    };
    243316
     
    251324    wp.updates.installError = function( response ) {
    252325        var $message = $( '.plugin-card-' + response.slug ).find( '.install-now' );
     326        wp.updates.updateDoneSuccessfully = false;
     327        if ( response.errorCode && response.errorCode == 'unable_to_connect_to_filesystem' ) {
     328            wp.updates.credentialError( response, 'update-plugin' );
     329            return;
     330        }
    253331
    254332        $message.removeClass( 'updating-message' );
    255333        $message.text( wp.updates.l10n.installNow );
     334    };
     335
     336    /**
     337     * Events that need to happen when there is a credential error
     338     *
     339     * @since 4.2.0
     340     */
     341    wp.updates.credentialError = function( response, type ) {
     342        wp.updates.updateQueue.push( {
     343            'type': type,
     344            'data': {
     345                // Not cool that we're depending on response for this data.
     346                // This would feel more whole in a view all tied together.
     347                plugin: response.plugin,
     348                slug: response.slug
     349            }
     350        } );
     351        wp.updates.showErrorInCredentialsForm( response.error );
     352        wp.updates.requestFilesystemCredentials();
    256353    };
    257354
     
    282379        }
    283380    };
    284 
     381    /**
     382     * Request the users filesystem credentials if we don't have them already
     383     *
     384     * @since 4.2.0
     385     */
     386    wp.updates.requestFilesystemCredentials = function() {
     387        if ( wp.updates.updateDoneSuccessfully === false ) {
     388            wp.updates.updateLock = true;
     389            $('#request-filesystem-credentials-dialog').show();
     390        }
     391    };
     392
     393    // Bind various click handlers.
    285394    $( document ).ready( function() {
     395        // File system credentials form submit noop-er / handler.
     396        $('#request-filesystem-credentials-dialog form').on( 'submit', function() {
     397            // Persist the credentials input by the user for the duration of the page load.
     398            wp.updates.filesystemCredentials.ftp.hostname = $('#hostname').val();
     399            wp.updates.filesystemCredentials.ftp.username = $('#username').val();
     400            wp.updates.filesystemCredentials.ftp.password = $('#password').val();
     401            wp.updates.filesystemCredentials.ftp.connectionType = $('input[name="connection_type"]:checked').val();
     402            wp.updates.filesystemCredentials.ssh.publicKey = $('#public_key').val();
     403            wp.updates.filesystemCredentials.ssh.privateKey = $('#private_key').val();
     404
     405            $('#request-filesystem-credentials-dialog').hide();
     406
     407            // Unlock and invoke the queue.
     408            wp.updates.updateLock = false;
     409            wp.updates.queueChecker();
     410
     411            return false;
     412        });
     413
     414        // Click handler for plugin updates in List Table view.
    286415        $( '.plugin-update-tr .update-link' ).on( 'click', function( e ) {
    287416            e.preventDefault();
     417            if ( wp.updates.shouldRequestFilesystemCredentials === '1' && ! wp.updates.updateLock ) {
     418                wp.updates.requestFilesystemCredentials();
     419            }
    288420            var $row = $( e.target ).parents( '.plugin-update-tr' );
    289421            wp.updates.updatePlugin( $row.data( 'plugin' ), $row.data( 'slug' ) );
     
    316448        $( '.plugin-card .install-now' ).on( 'click', function( e ) {
    317449            e.preventDefault();
     450            if ( wp.updates.shouldRequestFilesystemCredentials === '1' && ! wp.updates.updateLock ) {
     451                wp.updates.requestFilesystemCredentials();
     452            }
     453
    318454            var $button = $( e.target );
    319455            if ( $button.hasClass( 'button-disabled' ) ) {
  • trunk/src/wp-admin/plugin-install.php

    r31333 r31749  
    129129do_action( "install_plugins_$tab", $paged ); ?>
    130130</div>
     131
     132<div id="request-filesystem-credentials-dialog" class="notification-dialog-wrap request-filesystem-credentials-dialog">
     133    <div class="notification-dialog-background"></div>
     134    <div class="notification-dialog">
     135        <div class="request-filesystem-credentials-dialog-content">
     136            <?php request_filesystem_credentials( site_url() ); ?>
     137        <div>
     138    </div>
     139</div>
     140
    131141<?php
    132142/**
  • trunk/src/wp-admin/plugins.php

    r31696 r31749  
    476476</div>
    477477
     478<div id="request-filesystem-credentials-dialog" class="notification-dialog-wrap request-filesystem-credentials-dialog">
     479    <div class="notification-dialog-background"></div>
     480    <div class="notification-dialog">
     481        <div class="request-filesystem-credentials-dialog-content">
     482            <?php request_filesystem_credentials( site_url() ); ?>
     483        <div>
     484    </div>
     485</div>
    478486<?php
    479487include(ABSPATH . 'wp-admin/admin-footer.php');
  • trunk/src/wp-includes/script-loader.php

    r31746 r31749  
    543543
    544544        $scripts->add( 'updates', "/wp-admin/js/updates$suffix.js", array( 'jquery', 'wp-util', 'wp-a11y' ) );
     545
     546        /*
     547         * Determine whether the user will need to enter filesystem credentials
     548         * on the front-end.
     549         */
     550        require_once(ABSPATH . 'wp-admin/includes/file.php');
     551        $filesystem_method = get_filesystem_method();
     552        ob_start();
     553        $filesystem_credentials_are_stored = request_filesystem_credentials( self_admin_url() );
     554        ob_end_clean();
     555        $request_filesystem_credentials = ( $filesystem_method != 'direct' && ! $filesystem_credentials_are_stored ) ? 1 : 0;
     556
    545557        did_action( 'init' ) && $scripts->localize( 'updates', '_wpUpdatesSettings', array(
    546558            'ajax_nonce' => wp_create_nonce( 'updates' ),
     559            'requestFilesystemCredentials' => $request_filesystem_credentials,
    547560            'l10n'       => array(
    548561                'updating'      => __( 'Updating...' ),
Note: See TracChangeset for help on using the changeset viewer.