: str_replace(): Passing null to parameter #2 ($replace) of type array|string is deprecated in
/* translators: %s: Plugin name and version. */
_x( 'Updating %s...', 'plugin' ),
// Remove previous error messages, if any.
$card.removeClass( 'plugin-card-update-failed' ).find( '.notice.notice-error' ).remove();
$adminBarUpdates.addClass( 'spin' );
if ( $message.html() !== __( 'Updating...' ) ) {
$message.data( 'originaltext', $message.html() );
.attr( 'aria-label', message )
$document.trigger( 'wp-plugin-updating', args );
if ( isPluginInstall && 'plugin-information-footer' === $card.attr( 'id' ) ) {
wp.updates.setCardButtonStatus(
status: 'updating-plugin',
addClasses: 'updating-message',
return wp.updates.ajax( 'update-plugin', args );
* Updates the UI appropriately after a successful plugin update.
* @since 4.6.0 More accurately named `updatePluginSuccess`.
* @since 5.5.0 Auto-update "time to next update" text cleared.
* @param {Object} response Response from the server.
* @param {string} response.slug Slug of the plugin to be updated.
* @param {string} response.plugin Basename of the plugin to be updated.
* @param {string} response.pluginName Name of the plugin to be updated.
* @param {string} response.oldVersion Old version of the plugin.
* @param {string} response.newVersion New version of the plugin.
wp.updates.updatePluginSuccess = function( response ) {
var $pluginRow, $updateMessage, newText,
$adminBarUpdates = $( '#wp-admin-bar-updates' ),
buttonText = _x( 'Updated!', 'plugin' ),
/* translators: %s: Plugin name and version. */
_x( '%s updated!', 'plugin' ),
if ( 'plugins' === pagenow || 'plugins-network' === pagenow ) {
$pluginRow = $( 'tr[data-plugin="' + response.plugin + '"]' )
.removeClass( 'update is-enqueued' )
$updateMessage = $pluginRow.find( '.update-message' )
.removeClass( 'updating-message notice-warning' )
.addClass( 'updated-message notice-success' ).find( 'p' );
// Update the version number in the row.
newText = $pluginRow.find( '.plugin-version-author-uri' ).html().replace( response.oldVersion, response.newVersion );
$pluginRow.find( '.plugin-version-author-uri' ).html( newText );
// Clear the "time to next auto-update" text.
$pluginRow.find( '.auto-update-time' ).empty();
} else if ( 'plugin-install' === pagenow || 'plugin-install-network' === pagenow ) {
$updateMessage = $( '.plugin-card-' + response.slug + ', #plugin-information-footer' ).find( '.update-now' )
.removeClass( 'updating-message' )
.addClass( 'button-disabled updated-message' );
$adminBarUpdates.removeClass( 'spin' );
.attr( 'aria-label', ariaLabel )
wp.a11y.speak( __( 'Update completed successfully.' ) );
if ( 'plugin_install_from_iframe' !== $updateMessage.attr( 'id' ) ) {
wp.updates.decrementCount( 'plugin' );
wp.updates.setCardButtonStatus(
status: 'updated-plugin',
removeClasses: 'updating-message',
addClasses: 'button-disabled updated-message',
$document.trigger( 'wp-plugin-update-success', response );
* Updates the UI appropriately after a failed plugin update.
* @since 4.6.0 More accurately named `updatePluginError`.
* @param {Object} response Response from the server.
* @param {string} response.slug Slug of the plugin to be updated.
* @param {string} response.plugin Basename of the plugin to be updated.
* @param {string=} response.pluginName Optional. Name of the plugin to be updated.
* @param {string} response.errorCode Error code for the error that occurred.
* @param {string} response.errorMessage The error that occurred.
wp.updates.updatePluginError = function( response ) {
var $pluginRow, $card, $message, errorMessage, buttonText, ariaLabel,
$adminBarUpdates = $( '#wp-admin-bar-updates' );
if ( ! wp.updates.isValidResponse( response, 'update' ) ) {
if ( wp.updates.maybeHandleCredentialError( response, 'update-plugin' ) ) {
/* translators: %s: Error string for a failed update. */
__( 'Update failed: %s' ),
if ( 'plugins' === pagenow || 'plugins-network' === pagenow ) {
$pluginRow = $( 'tr[data-plugin="' + response.plugin + '"]' ).removeClass( 'is-enqueued' );
$message = $( 'tr[data-plugin="' + response.plugin + '"]' ).find( '.update-message' );
$message = $( 'tr[data-slug="' + response.slug + '"]' ).find( '.update-message' );
$message.removeClass( 'updating-message notice-warning' ).addClass( 'notice-error' ).find( 'p' ).html( errorMessage );
if ( response.pluginName ) {
/* translators: %s: Plugin name and version. */
_x( '%s update failed.', 'plugin' ),
$message.find( 'p' ).removeAttr( 'aria-label' );
} else if ( 'plugin-install' === pagenow || 'plugin-install-network' === pagenow ) {
buttonText = __( 'Update failed.' );
$card = $( '.plugin-card-' + response.slug + ', #plugin-information-footer' )
.append( wp.updates.adminNotice( {
className: 'update-message notice-error notice-alt is-dismissible',
if ( $card.hasClass( 'plugin-card-' + response.slug ) ) {
$card.addClass( 'plugin-card-update-failed' );
$card.find( '.update-now' )
.removeClass( 'updating-message' );
if ( response.pluginName ) {
/* translators: %s: Plugin name and version. */
_x( '%s update failed.', 'plugin' ),
$card.find( '.update-now' ).attr( 'aria-label', ariaLabel );
$card.find( '.update-now' ).removeAttr( 'aria-label' );
$card.on( 'click', '.notice.is-dismissible .notice-dismiss', function() {
// Use same delay as the total duration of the notice fadeTo + slideUp animation.
.removeClass( 'plugin-card-update-failed' )
.find( '.column-name a' ).trigger( 'focus' );
$card.find( '.update-now' )
.attr( 'aria-label', false )
.text( __( 'Update Now' ) );
$adminBarUpdates.removeClass( 'spin' );
wp.a11y.speak( errorMessage, 'assertive' );
if ( 'plugin-information-footer' === $card.attr('id' ) ) {
wp.updates.setCardButtonStatus(
status: 'plugin-update-failed',
removeClasses: 'updating-message',
$document.trigger( 'wp-plugin-update-error', response );
* Sends an Ajax request to the server to install a plugin.
* @param {Object} args Arguments.
* @param {string} args.slug Plugin identifier in the WordPress.org Plugin repository.
* @param {installPluginSuccess=} args.success Optional. Success callback. Default: wp.updates.installPluginSuccess
* @param {installPluginError=} args.error Optional. Error callback. Default: wp.updates.installPluginError
* @return {$.promise} A jQuery promise that represents the request,
* decorated with an abort() method.
wp.updates.installPlugin = function( args ) {
var $card = $( '.plugin-card-' + args.slug + ', #plugin-information-footer' ),
$message = $card.find( '.install-now' ),
buttonText = __( 'Installing...' ),
success: wp.updates.installPluginSuccess,
error: wp.updates.installPluginError
if ( 'import' === pagenow ) {
$message = $( '[data-slug="' + args.slug + '"]' );
if ( $message.html() !== __( 'Installing...' ) ) {
$message.data( 'originaltext', $message.html() );
/* translators: %s: Plugin name and version. */
_x( 'Installing %s...', 'plugin' ),
.addClass( 'updating-message' )
.attr( 'aria-label', ariaLabel )
wp.a11y.speak( __( 'Installing... please wait.' ) );
// Remove previous error messages, if any.
$card.removeClass( 'plugin-card-install-failed' ).find( '.notice.notice-error' ).remove();
$document.trigger( 'wp-plugin-installing', args );
if ( 'plugin-information-footer' === $message.parent().attr( 'id' ) ) {
wp.updates.setCardButtonStatus(
status: 'installing-plugin',
addClasses: 'updating-message',
return wp.updates.ajax( 'install-plugin', args );
* Updates the UI appropriately after a successful plugin install.
* @param {Object} response Response from the server.
* @param {string} response.slug Slug of the installed plugin.
* @param {string} response.pluginName Name of the installed plugin.
* @param {string} response.activateUrl URL to activate the just installed plugin.
wp.updates.installPluginSuccess = function( response ) {
var $message = $( '.plugin-card-' + response.slug + ', #plugin-information-footer' ).find( '.install-now' ),
buttonText = _x( 'Installed!', 'plugin' ),
/* translators: %s: Plugin name and version. */
_x( '%s installed!', 'plugin' ),
.removeClass( 'updating-message' )
.addClass( 'updated-message installed button-disabled' )
.attr( 'aria-label', ariaLabel )
wp.a11y.speak( __( 'Installation completed successfully.' ) );
$document.trigger( 'wp-plugin-install-success', response );
if ( response.activateUrl ) {
wp.updates.checkPluginDependencies( {
if ( 'plugin-information-footer' === $message.parent().attr( 'id' ) ) {
wp.updates.setCardButtonStatus(
status: 'installed-plugin',
removeClasses: 'updating-message',
addClasses: 'updated-message installed button-disabled',
* Updates the UI appropriately after a failed plugin install.
* @param {Object} response Response from the server.
* @param {string} response.slug Slug of the plugin to be installed.
* @param {string=} response.pluginName Optional. Name of the plugin to be installed.
* @param {string} response.errorCode Error code for the error that occurred.
* @param {string} response.errorMessage The error that occurred.
wp.updates.installPluginError = function( response ) {
var $card = $( '.plugin-card-' + response.slug + ', #plugin-information-footer' ),
$button = $card.find( '.install-now' ),
buttonText = __( 'Installation failed.' ),
/* translators: %s: Plugin name and version. */
_x( '%s installation failed', 'plugin' ),
if ( ! wp.updates.isValidResponse( response, 'install' ) ) {
if ( wp.updates.maybeHandleCredentialError( response, 'install-plugin' ) ) {
/* translators: %s: Error string for a failed installation. */
__( 'Installation failed: %s' ),
.addClass( 'plugin-card-update-failed' )
.append( '<div class="notice notice-error notice-alt is-dismissible" role="alert"><p>' + errorMessage + '</p></div>' );
$card.on( 'click', '.notice.is-dismissible .notice-dismiss', function() {
// Use same delay as the total duration of the notice fadeTo + slideUp animation.
.removeClass( 'plugin-card-update-failed' )
.find( '.column-name a' ).trigger( 'focus' );
.removeClass( 'updating-message' ).addClass( 'button-disabled' )
.attr( 'aria-label', ariaLabel )
wp.a11y.speak( errorMessage, 'assertive' );
wp.updates.setCardButtonStatus(
status: 'plugin-install-failed',
removeClasses: 'updating-message',
addClasses: 'button-disabled',
$document.trigger( 'wp-plugin-install-error', response );
* Sends an Ajax request to the server to check a plugin's dependencies.
* @param {Object} args Arguments.
* @param {string} args.slug Plugin identifier in the WordPress.org Plugin repository.
* @param {checkPluginDependenciesSuccess=} args.success Optional. Success callback. Default: wp.updates.checkPluginDependenciesSuccess
* @param {checkPluginDependenciesError=} args.error Optional. Error callback. Default: wp.updates.checkPluginDependenciesError
* @return {$.promise} A jQuery promise that represents the request,
* decorated with an abort() method.
wp.updates.checkPluginDependencies = function( args ) {
success: wp.updates.checkPluginDependenciesSuccess,
error: wp.updates.checkPluginDependenciesError
wp.a11y.speak( __( 'Checking plugin dependencies... please wait.' ) );
$document.trigger( 'wp-checking-plugin-dependencies', args );
return wp.updates.ajax( 'check_plugin_dependencies', args );
* Updates the UI appropriately after a successful plugin dependencies check.
* @param {Object} response Response from the server.
* @param {string} response.slug Slug of the checked plugin.
* @param {string} response.pluginName Name of the checked plugin.
* @param {string} response.plugin The plugin file, relative to the plugins directory.
* @param {string} response.activateUrl URL to activate the just checked plugin.
wp.updates.checkPluginDependenciesSuccess = function( response ) {
var $message = $( '.plugin-card-' + response.slug + ', #plugin-information-footer' ).find( '.install-now' ),
// Transform the 'Install' button into an 'Activate' button.
.removeClass( 'install-now installed button-disabled updated-message' )
.addClass( 'activate-now button-primary' )
.attr( 'href', response.activateUrl );
wp.a11y.speak( __( 'Plugin dependencies check completed successfully.' ) );
$document.trigger( 'wp-check-plugin-dependencies-success', response );
if ( 'plugins-network' === pagenow ) {
buttonText = _x( 'Network Activate', 'plugin' );
/* translators: %s: Plugin name. */
_x( 'Network Activate %s', 'plugin' ),
.attr( 'aria-label', ariaLabel )
buttonText = _x( 'Activate', 'plugin' );
/* translators: %s: Plugin name. */
_x( 'Activate %s', 'plugin' ),
.attr( 'aria-label', ariaLabel )
.attr( 'data-name', response.pluginName )
.attr( 'data-slug', response.slug )
.attr( 'data-plugin', response.plugin )
if ( 'plugin-information-footer' === $message.parent().attr( 'id' ) ) {
wp.updates.setCardButtonStatus(
status: 'dependencies-check-success',
removeClasses: 'install-now installed button-disabled updated-message',
addClasses: 'activate-now button-primary',
pluginName: response.pluginName,
href: response.activateUrl