Request FTP and SSH credentials when needed during shiny updates
This is a restoration of [31749] which was reverted in [31755]. It includes a number of enhancements from the original version. Namely: * Not doing a credential check in src/wp-includes/script-loader.php * Add new function `wp_print_request_filesystem_credentials_modal` * update the version number in the list table when a plugin is updated UI still needs further work, but this basic version should enable more testing Props ericlewis, jorbin See #31528 git-svn-id: https://develop.svn.wordpress.org/trunk@31811 602fd350-edb4-49c9-b593-d223f7449a82
This commit is contained in:
parent
533aefdf13
commit
08ac58e160
|
@ -848,6 +848,27 @@ table.form-table td .updated p {
|
|||
margin-bottom: 5px;
|
||||
}
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
Credentials check dialog for Install and Updates
|
||||
------------------------------------------------------------------------------*/
|
||||
|
||||
.request-filesystem-credentials-dialog {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.request-filesystem-credentials-dialog .notification-dialog {
|
||||
top: 15%;
|
||||
}
|
||||
|
||||
.request-filesystem-credentials-dialog-content {
|
||||
margin: 25px;
|
||||
}
|
||||
|
||||
.request-filesystem-credentials-dialog-content input[type="text"],
|
||||
.request-filesystem-credentials-dialog-content input[type="password"] {
|
||||
width: 85%;
|
||||
}
|
||||
|
||||
/* =Media Queries
|
||||
-------------------------------------------------------------- */
|
||||
|
||||
|
|
|
@ -2913,6 +2913,10 @@ function wp_ajax_install_plugin() {
|
|||
if ( is_wp_error( $result ) ) {
|
||||
$status['error'] = $result->get_error_message();
|
||||
wp_send_json_error( $status );
|
||||
} else if ( is_null( $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 );
|
||||
}
|
||||
|
||||
$plugin_status = install_plugin_install_status( $api );
|
||||
|
@ -2933,10 +2937,16 @@ function wp_ajax_update_plugin() {
|
|||
$plugin = urldecode( $_POST['plugin'] );
|
||||
|
||||
$status = array(
|
||||
'update' => 'plugin',
|
||||
'plugin' => $plugin,
|
||||
'slug' => sanitize_key( $_POST['slug'] ),
|
||||
'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.' );
|
||||
|
@ -2956,15 +2966,31 @@ function wp_ajax_update_plugin() {
|
|||
$result = $upgrader->bulk_upgrade( array( $plugin ) );
|
||||
|
||||
if ( is_array( $result ) ) {
|
||||
$result = $result[ $plugin ];
|
||||
}
|
||||
|
||||
if ( is_wp_error( $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 );
|
||||
}
|
||||
|
||||
wp_send_json_success( $status );
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -1192,3 +1192,29 @@ submit_button( __( 'Proceed' ), 'button', 'upgrade' );
|
|||
<?php
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Print the credentials modal when needed
|
||||
*
|
||||
* @since 4.2.0
|
||||
*/
|
||||
function wp_print_request_filesystem_credentials_modal() {
|
||||
$filesystem_method = get_filesystem_method();
|
||||
ob_start();
|
||||
$filesystem_credentials_are_stored = request_filesystem_credentials( self_admin_url() );
|
||||
ob_end_clean();
|
||||
$request_filesystem_credentials = ( $filesystem_method != 'direct' && ! $filesystem_credentials_are_stored );
|
||||
if ( ! $request_filesystem_credentials ) {
|
||||
return;
|
||||
}
|
||||
?>
|
||||
<div id="request-filesystem-credentials-dialog" class="notification-dialog-wrap request-filesystem-credentials-dialog">
|
||||
<div class="notification-dialog-background"></div>
|
||||
<div class="notification-dialog">
|
||||
<div class="request-filesystem-credentials-dialog-content">
|
||||
<?php request_filesystem_credentials( site_url() ); ?>
|
||||
<div>
|
||||
</div>
|
||||
</div>
|
||||
<?php
|
||||
}
|
||||
|
|
|
@ -21,6 +21,35 @@ window.wp = window.wp || {};
|
|||
*/
|
||||
wp.updates.l10n = window._wpUpdatesSettings.l10n;
|
||||
|
||||
/**
|
||||
* Whether filesystem credentials need to be requested from the user.
|
||||
*
|
||||
* @since 4.2.0
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
wp.updates.shouldRequestFilesystemCredentials = null;
|
||||
|
||||
/**
|
||||
* Filesystem credentials to be packaged along with the request.
|
||||
*
|
||||
* @since 4.2.0
|
||||
*
|
||||
* @var object
|
||||
*/
|
||||
wp.updates.filesystemCredentials = {
|
||||
ftp: {
|
||||
host: null,
|
||||
username: null,
|
||||
password: null,
|
||||
connectionType: null
|
||||
},
|
||||
ssh: {
|
||||
publicKey: null,
|
||||
privateKey: null
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Flag if we're waiting for an install/update to complete.
|
||||
*
|
||||
|
@ -30,6 +59,15 @@ window.wp = window.wp || {};
|
|||
*/
|
||||
wp.updates.updateLock = false;
|
||||
|
||||
/**
|
||||
* * Flag if we've done an install or update successfully.
|
||||
*
|
||||
* @since 4.2.0
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
wp.updates.updateDoneSuccessfully = false;
|
||||
|
||||
/**
|
||||
* If the user tries to install/update a plugin while an install/update is
|
||||
* already happening, it can be placed in this queue to perform later.
|
||||
|
@ -123,15 +161,20 @@ window.wp = window.wp || {};
|
|||
wp.updates.updateLock = true;
|
||||
|
||||
var data = {
|
||||
'_ajax_nonce': wp.updates.ajaxNonce,
|
||||
'plugin': plugin,
|
||||
'slug': slug
|
||||
_ajax_nonce: wp.updates.ajaxNonce,
|
||||
plugin: plugin,
|
||||
slug: slug,
|
||||
username: wp.updates.filesystemCredentials.ftp.username,
|
||||
password: wp.updates.filesystemCredentials.ftp.password,
|
||||
hostname: wp.updates.filesystemCredentials.ftp.hostname,
|
||||
connection_type: wp.updates.filesystemCredentials.ftp.connectionType,
|
||||
public_key: wp.updates.filesystemCredentials.ssh.publicKey,
|
||||
private_key: wp.updates.filesystemCredentials.ssh.privateKey
|
||||
};
|
||||
|
||||
wp.ajax.post( 'update-plugin', data )
|
||||
.done( wp.updates.updateSuccess )
|
||||
.fail( wp.updates.updateError )
|
||||
.always( wp.updates.updateAlways );
|
||||
.fail( wp.updates.updateError );
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -147,6 +190,9 @@ window.wp = window.wp || {};
|
|||
$message = $( '#' + response.slug ).next().find( '.update-message' );
|
||||
$( '#' + response.slug ).addClass( 'updated' ).removeClass( 'update' );
|
||||
$( '#' + response.slug + '-update' ).addClass( 'updated' ).removeClass( 'update' );
|
||||
// Update the version number in the row.
|
||||
var newText = $( '#' + response.slug ).find('.plugin-version-author-uri').html().replace( response.oldVersion, response.newVersion );
|
||||
$( '#' + response.slug ).find('.plugin-version-author-uri').html( newText );
|
||||
} else if ( 'plugin-install' === pagenow ) {
|
||||
$message = $( '.plugin-card-' + response.slug ).find( '.update-now' );
|
||||
$message.addClass( 'button-disabled' );
|
||||
|
@ -157,6 +203,15 @@ window.wp = window.wp || {};
|
|||
wp.a11y.speak( wp.updates.l10n.updatedMsg );
|
||||
|
||||
wp.updates.decrementCount( 'plugin' );
|
||||
|
||||
wp.updates.updateDoneSuccessfully = true;
|
||||
|
||||
/*
|
||||
* The lock can be released since the update was successful,
|
||||
* and any other updates can commence.
|
||||
*/
|
||||
wp.updates.updateLock = false;
|
||||
wp.updates.queueChecker();
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -168,6 +223,11 @@ window.wp = window.wp || {};
|
|||
*/
|
||||
wp.updates.updateError = function( response ) {
|
||||
var $message;
|
||||
wp.updates.updateDoneSuccessfully = false;
|
||||
if ( response.errorCode && response.errorCode == 'unable_to_connect_to_filesystem' ) {
|
||||
wp.updates.credentialError( response, 'update-plugin' );
|
||||
return;
|
||||
}
|
||||
if ( 'plugins' === pagenow || 'plugins-network' === pagenow ) {
|
||||
$message = $( '#' + response.slug ).next().find( '.update-message' );
|
||||
} else if ( 'plugin-install' === pagenow ) {
|
||||
|
@ -176,18 +236,23 @@ window.wp = window.wp || {};
|
|||
$message.removeClass( 'updating-message' );
|
||||
$message.text( wp.updates.l10n.updateFailed );
|
||||
wp.a11y.speak( wp.updates.l10n.updateFailed );
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* After an update attempt has completed, check the queue.
|
||||
* Show an error message in the request for credentials form.
|
||||
*
|
||||
* @param {string} message
|
||||
* @since 4.2.0
|
||||
*/
|
||||
wp.updates.updateAlways = function() {
|
||||
wp.updates.updateLock = false;
|
||||
wp.updates.queueChecker();
|
||||
};
|
||||
wp.updates.showErrorInCredentialsForm = function( message ) {
|
||||
var $notificationDialog = $( '.notification-dialog' );
|
||||
|
||||
// Remove any existing error
|
||||
$notificationDialog.find( '.error' ).remove();
|
||||
|
||||
$notificationDialog.find( 'h3' ).after( '<div class="error">' + message + '</div>' );
|
||||
};
|
||||
|
||||
/**
|
||||
* Send an Ajax request to the server to install a plugin.
|
||||
|
@ -216,14 +281,19 @@ window.wp = window.wp || {};
|
|||
wp.updates.updateLock = true;
|
||||
|
||||
var data = {
|
||||
'_ajax_nonce': wp.updates.ajaxNonce,
|
||||
'slug': slug
|
||||
_ajax_nonce: wp.updates.ajaxNonce,
|
||||
slug: slug,
|
||||
username: wp.updates.filesystemCredentials.ftp.username,
|
||||
password: wp.updates.filesystemCredentials.ftp.password,
|
||||
hostname: wp.updates.filesystemCredentials.ftp.hostname,
|
||||
connection_type: wp.updates.filesystemCredentials.ftp.connectionType,
|
||||
public_key: wp.updates.filesystemCredentials.ssh.publicKey,
|
||||
private_key: wp.updates.filesystemCredentials.ssh.privateKey
|
||||
};
|
||||
|
||||
wp.ajax.post( 'install-plugin', data )
|
||||
.done( wp.updates.installSuccess )
|
||||
.fail( wp.updates.installError )
|
||||
.always( wp.updates.updateAlways );
|
||||
.fail( wp.updates.installError );
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -239,6 +309,14 @@ window.wp = window.wp || {};
|
|||
$message.removeClass( 'updating-message' ).addClass( 'updated-message button-disabled' );
|
||||
$message.text( wp.updates.l10n.installed );
|
||||
wp.a11y.speak( wp.updates.l10n.installedMsg );
|
||||
wp.updates.updateDoneSuccessfully = true;
|
||||
|
||||
/*
|
||||
* The lock can be released since the update was successful,
|
||||
* and any other updates can commence.
|
||||
*/
|
||||
wp.updates.updateLock = false;
|
||||
wp.updates.queueChecker();
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -250,11 +328,36 @@ window.wp = window.wp || {};
|
|||
*/
|
||||
wp.updates.installError = function( response ) {
|
||||
var $message = $( '.plugin-card-' + response.slug ).find( '.install-now' );
|
||||
wp.updates.updateDoneSuccessfully = false;
|
||||
if ( response.errorCode && response.errorCode == 'unable_to_connect_to_filesystem' ) {
|
||||
wp.updates.credentialError( response, 'install-plugin' );
|
||||
return;
|
||||
}
|
||||
|
||||
$message.removeClass( 'updating-message' );
|
||||
$message.text( wp.updates.l10n.installNow );
|
||||
|
||||
wp.updates.updateLock = false;
|
||||
};
|
||||
|
||||
/**
|
||||
* Events that need to happen when there is a credential error
|
||||
*
|
||||
* @since 4.2.0
|
||||
*/
|
||||
wp.updates.credentialError = function( response, type ) {
|
||||
wp.updates.updateQueue.push( {
|
||||
'type': type,
|
||||
'data': {
|
||||
// Not cool that we're depending on response for this data.
|
||||
// This would feel more whole in a view all tied together.
|
||||
plugin: response.plugin,
|
||||
slug: response.slug
|
||||
}
|
||||
} );
|
||||
wp.updates.showErrorInCredentialsForm( response.error );
|
||||
wp.updates.requestFilesystemCredentials();
|
||||
};
|
||||
|
||||
/**
|
||||
* If an install/update job has been placed in the queue, queueChecker pulls it out and runs it.
|
||||
|
@ -282,9 +385,55 @@ window.wp = window.wp || {};
|
|||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Request the users filesystem credentials if we don't have them already
|
||||
*
|
||||
* @since 4.2.0
|
||||
*/
|
||||
wp.updates.requestFilesystemCredentials = function() {
|
||||
if ( wp.updates.updateDoneSuccessfully === false ) {
|
||||
wp.updates.updateLock = true;
|
||||
$( 'body' ).addClass( 'modal-open' );
|
||||
$( '#request-filesystem-credentials-dialog' ).show();
|
||||
}
|
||||
};
|
||||
|
||||
$( document ).ready( function() {
|
||||
/*
|
||||
* Check whether a user needs to submit filesystem credentials based on whether
|
||||
* the form was output on the page server-side.
|
||||
*
|
||||
* @see {wp_print_request_filesystem_credentials_modal() in PHP}
|
||||
*/
|
||||
wp.updates.shouldRequestFilesystemCredentials = ( $( '#request-filesystem-credentials-dialog' ).length <= 0 ) ? false : true;
|
||||
|
||||
// File system credentials form submit noop-er / handler.
|
||||
$( '#request-filesystem-credentials-dialog form' ).on( 'submit', function() {
|
||||
// Persist the credentials input by the user for the duration of the page load.
|
||||
wp.updates.filesystemCredentials.ftp.hostname = $('#hostname').val();
|
||||
wp.updates.filesystemCredentials.ftp.username = $('#username').val();
|
||||
wp.updates.filesystemCredentials.ftp.password = $('#password').val();
|
||||
wp.updates.filesystemCredentials.ftp.connectionType = $('input[name="connection_type"]:checked').val();
|
||||
wp.updates.filesystemCredentials.ssh.publicKey = $('#public_key').val();
|
||||
wp.updates.filesystemCredentials.ssh.privateKey = $('#private_key').val();
|
||||
|
||||
$( '#request-filesystem-credentials-dialog' ).hide();
|
||||
$( 'body' ).removeClass( 'modal-open' );
|
||||
|
||||
// Unlock and invoke the queue.
|
||||
wp.updates.updateLock = false;
|
||||
wp.updates.queueChecker();
|
||||
|
||||
return false;
|
||||
});
|
||||
|
||||
// Click handler for plugin updates in List Table view.
|
||||
$( '.plugin-update-tr .update-link' ).on( 'click', function( e ) {
|
||||
e.preventDefault();
|
||||
if ( wp.updates.shouldRequestFilesystemCredentials && ! wp.updates.updateLock ) {
|
||||
wp.updates.requestFilesystemCredentials();
|
||||
}
|
||||
var $row = $( e.target ).parents( '.plugin-update-tr' );
|
||||
wp.updates.updatePlugin( $row.data( 'plugin' ), $row.data( 'slug' ) );
|
||||
} );
|
||||
|
@ -315,6 +464,9 @@ window.wp = window.wp || {};
|
|||
|
||||
$( '.plugin-card .install-now' ).on( 'click', function( e ) {
|
||||
e.preventDefault();
|
||||
if ( wp.updates.shouldRequestFilesystemCredentials && ! wp.updates.updateLock ) {
|
||||
wp.updates.requestFilesystemCredentials();
|
||||
}
|
||||
var $button = $( e.target );
|
||||
if ( $button.hasClass( 'button-disabled' ) ) {
|
||||
return;
|
||||
|
|
|
@ -128,7 +128,10 @@ if ( $tab !== 'upload' ) {
|
|||
*/
|
||||
do_action( "install_plugins_$tab", $paged ); ?>
|
||||
</div>
|
||||
<?php
|
||||
|
||||
<?php
|
||||
wp_print_request_filesystem_credentials_modal();
|
||||
|
||||
/**
|
||||
* WordPress Administration Template Footer.
|
||||
*/
|
||||
|
|
|
@ -476,4 +476,6 @@ do_action( 'pre_current_active_plugins', $plugins['all'] );
|
|||
</div>
|
||||
|
||||
<?php
|
||||
wp_print_request_filesystem_credentials_modal();
|
||||
|
||||
include(ABSPATH . 'wp-admin/admin-footer.php');
|
||||
|
|
Loading…
Reference in New Issue