: str_replace(): Passing null to parameter #2 ($replace) of type array|string is deprecated in
* Updates the UI appropriately after a failed plugin dependencies check.
* @param {Object} response Response from the server.
* @param {string} response.slug Slug of the plugin to be checked.
* @param {string=} response.pluginName Optional. Name of the plugin to be checked.
* @param {string} response.errorCode Error code for the error that occurred.
* @param {string} response.errorMessage The error that occurred.
wp.updates.checkPluginDependenciesError = function( response ) {
var $message = $( '.plugin-card-' + response.slug + ', #plugin-information-footer' ).find( '.install-now' ),
buttonText = _x( 'Activate', 'plugin' ),
/* translators: 1: Plugin name, 2. The reason the plugin cannot be activated. */
_x( 'Cannot activate %1$s. %2$s', 'plugin' ),
if ( ! wp.updates.isValidResponse( response, 'check-dependencies' ) ) {
/* translators: %s: Error string for a failed activation. */
__( 'Activation failed: %s' ),
wp.a11y.speak( errorMessage, 'assertive' );
$document.trigger( 'wp-check-plugin-dependencies-error', response );
.removeClass( 'install-now installed updated-message' )
.addClass( 'activate-now button-primary' )
.attr( 'aria-label', ariaLabel )
if ( 'plugin-information-footer' === $message.parent().attr('id' ) ) {
wp.updates.setCardButtonStatus(
status: 'dependencies-check-failed',
removeClasses: 'install-now installed updated-message',
addClasses: 'activate-now button-primary',
* Sends an Ajax request to the server to activate a plugin.
* @param {Object} args Arguments.
* @param {string} args.name The name of the plugin.
* @param {string} args.slug Plugin identifier in the WordPress.org Plugin repository.
* @param {string} args.plugin The plugin file, relative to the plugins directory.
* @param {activatePluginSuccess=} args.success Optional. Success callback. Default: wp.updates.activatePluginSuccess
* @param {activatePluginError=} args.error Optional. Error callback. Default: wp.updates.activatePluginError
* @return {$.promise} A jQuery promise that represents the request,
* decorated with an abort() method.
wp.updates.activatePlugin = function( args ) {
var $message = $( '.plugin-card-' + args.slug + ', #plugin-information-footer' ).find( '.activate-now, .activating-message' );
success: wp.updates.activatePluginSuccess,
error: wp.updates.activatePluginError
wp.a11y.speak( __( 'Activating... please wait.' ) );
$document.trigger( 'wp-activating-plugin', args );
if ( 'plugin-information-footer' === $message.parent().attr( 'id' ) ) {
wp.updates.setCardButtonStatus(
status: 'activating-plugin',
removeClasses: 'installed updated-message button-primary',
addClasses: 'activating-message',
text: __( 'Activating...' ),
/* translators: %s: Plugin name. */
_x( 'Activating %s', 'plugin' ),
return wp.updates.ajax( 'activate-plugin', args );
* Updates the UI appropriately after a successful plugin activation.
* @param {Object} response Response from the server.
* @param {string} response.slug Slug of the activated plugin.
* @param {string} response.pluginName Name of the activated plugin.
* @param {string} response.plugin The plugin file, relative to the plugins directory.
wp.updates.activatePluginSuccess = function( response ) {
var $message = $( '.plugin-card-' + response.slug + ', #plugin-information-footer' ).find( '.activating-message' ),
buttonText = _x( 'Activated!', 'plugin' ),
/* translators: %s: The plugin name. */
'%s activated successfully.',
wp.a11y.speak( __( 'Activation completed successfully.' ) );
$document.trigger( 'wp-plugin-activate-success', response );
.removeClass( 'activating-message' )
.addClass( 'activated-message button-disabled' )
.attr( 'aria-label', ariaLabel )
if ( 'plugin-information-footer' === $message.parent().attr( 'id' ) ) {
wp.updates.setCardButtonStatus(
status: 'activated-plugin',
removeClasses: 'activating-message',
addClasses: 'activated-message button-disabled',
$message.removeClass( 'activated-message' )
.text( _x( 'Active', 'plugin' ) );
if ( 'plugin-information-footer' === $message.parent().attr( 'id' ) ) {
wp.updates.setCardButtonStatus(
removeClasses: 'activated-message',
text: _x( 'Active', 'plugin' ),
/* translators: %s: The plugin name. */
* Updates the UI appropriately after a failed plugin activation.
* @param {Object} response Response from the server.
* @param {string} response.slug Slug of the plugin to be activated.
* @param {string=} response.pluginName Optional. Name of the plugin to be activated.
* @param {string} response.errorCode Error code for the error that occurred.
* @param {string} response.errorMessage The error that occurred.
wp.updates.activatePluginError = function( response ) {
var $message = $( '.plugin-card-' + response.slug + ', #plugin-information-footer' ).find( '.activating-message' ),
buttonText = __( 'Activation failed.' ),
/* translators: %s: Plugin name. */
_x( '%s activation failed', 'plugin' ),
if ( ! wp.updates.isValidResponse( response, 'activate' ) ) {
/* translators: %s: Error string for a failed activation. */
__( 'Activation failed: %s' ),
wp.a11y.speak( errorMessage, 'assertive' );
$document.trigger( 'wp-plugin-activate-error', response );
.removeClass( 'install-now installed activating-message' )
.addClass( 'button-disabled' )
.attr( 'aria-label', ariaLabel )
if ( 'plugin-information-footer' === $message.parent().attr( 'id' ) ) {
wp.updates.setCardButtonStatus(
status: 'plugin-activation-failed',
removeClasses: 'install-now installed activating-message',
addClasses: 'button-disabled',
* Updates the UI appropriately after a successful importer 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.installImporterSuccess = function( response ) {
wp.updates.addAdminNotice( {
className: 'notice-success is-dismissible',
/* translators: %s: Activation URL. */
__( 'Importer installed successfully. <a href="%s">Run importer</a>' ),
response.activateUrl + '&from=import'
$( '[data-slug="' + response.slug + '"]' )
.removeClass( 'install-now updating-message' )
.addClass( 'activate-now' )
'href': response.activateUrl + '&from=import',
/* translators: %s: Importer name. */
.text( __( 'Run Importer' ) );
wp.a11y.speak( __( 'Installation completed successfully.' ) );
$document.trigger( 'wp-importer-install-success', response );
* Updates the UI appropriately after a failed importer 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.installImporterError = function( response ) {
var errorMessage = sprintf(
/* translators: %s: Error string for a failed installation. */
__( 'Installation failed: %s' ),
$installLink = $( '[data-slug="' + response.slug + '"]' ),
pluginName = $installLink.data( 'name' );
if ( ! wp.updates.isValidResponse( response, 'install' ) ) {
if ( wp.updates.maybeHandleCredentialError( response, 'install-plugin' ) ) {
wp.updates.addAdminNotice( {
className: 'notice-error is-dismissible',
.removeClass( 'updating-message' )
/* translators: %s: Plugin name. */
_x( 'Install %s now', 'plugin' ),
.text( _x( 'Install Now', 'plugin' ) );
wp.a11y.speak( errorMessage, 'assertive' );
$document.trigger( 'wp-importer-install-error', response );
* Sends an Ajax request to the server to delete a plugin.
* @param {Object} args Arguments.
* @param {string} args.plugin Basename of the plugin to be deleted.
* @param {string} args.slug Slug of the plugin to be deleted.
* @param {deletePluginSuccess=} args.success Optional. Success callback. Default: wp.updates.deletePluginSuccess
* @param {deletePluginError=} args.error Optional. Error callback. Default: wp.updates.deletePluginError
* @return {$.promise} A jQuery promise that represents the request,
* decorated with an abort() method.
wp.updates.deletePlugin = function( args ) {
var $link = $( '[data-plugin="' + args.plugin + '"]' ).find( '.row-actions a.delete' );
success: wp.updates.deletePluginSuccess,
error: wp.updates.deletePluginError
if ( $link.html() !== __( 'Deleting...' ) ) {
.data( 'originaltext', $link.html() )
.text( __( 'Deleting...' ) );
wp.a11y.speak( __( 'Deleting...' ) );
$document.trigger( 'wp-plugin-deleting', args );
return wp.updates.ajax( 'delete-plugin', args );
* Updates the UI appropriately after a successful plugin deletion.
* @param {Object} response Response from the server.
* @param {string} response.slug Slug of the plugin that was deleted.
* @param {string} response.plugin Base name of the plugin that was deleted.
* @param {string} response.pluginName Name of the plugin that was deleted.
wp.updates.deletePluginSuccess = function( response ) {
// Removes the plugin and updates rows.
$( '[data-plugin="' + response.plugin + '"]' ).css( { backgroundColor: '#faafaa' } ).fadeOut( 350, function() {
var $form = $( '#bulk-action-form' ),
$views = $( '.subsubsub' ),
$currentView = $views.find( '[aria-current="page"]' ),
$itemsCount = $( '.displaying-num' ),
columnCount = $form.find( 'thead th:not(.hidden), thead td' ).length,
pluginDeletedRow = wp.template( 'item-deleted-row' ),
* Plugins Base names of plugins in their different states.
plugins = settings.plugins,
// Add a success message after deleting a plugin.
if ( ! $pluginRow.hasClass( 'plugin-update-tr' ) ) {
name: response.pluginName
// Remove plugin from update count.
if ( -1 !== _.indexOf( plugins.upgrade, response.plugin ) ) {
plugins.upgrade = _.without( plugins.upgrade, response.plugin );
wp.updates.decrementCount( 'plugin' );
if ( -1 !== _.indexOf( plugins.inactive, response.plugin ) ) {
plugins.inactive = _.without( plugins.inactive, response.plugin );
if ( plugins.inactive.length ) {
$views.find( '.inactive .count' ).text( '(' + plugins.inactive.length + ')' );
$views.find( '.inactive' ).remove();
if ( -1 !== _.indexOf( plugins.active, response.plugin ) ) {
plugins.active = _.without( plugins.active, response.plugin );
if ( plugins.active.length ) {
$views.find( '.active .count' ).text( '(' + plugins.active.length + ')' );
$views.find( '.active' ).remove();
if ( -1 !== _.indexOf( plugins.recently_activated, response.plugin ) ) {
plugins.recently_activated = _.without( plugins.recently_activated, response.plugin );
if ( plugins.recently_activated.length ) {
$views.find( '.recently_activated .count' ).text( '(' + plugins.recently_activated.length + ')' );
$views.find( '.recently_activated' ).remove();
if ( -1 !== _.indexOf( plugins['auto-update-enabled'], response.plugin ) ) {
plugins['auto-update-enabled'] = _.without( plugins['auto-update-enabled'], response.plugin );
if ( plugins['auto-update-enabled'].length ) {
$views.find( '.auto-update-enabled .count' ).text( '(' + plugins['auto-update-enabled'].length + ')' );
$views.find( '.auto-update-enabled' ).remove();
if ( -1 !== _.indexOf( plugins['auto-update-disabled'], response.plugin ) ) {
plugins['auto-update-disabled'] = _.without( plugins['auto-update-disabled'], response.plugin );
if ( plugins['auto-update-disabled'].length ) {
$views.find( '.auto-update-disabled .count' ).text( '(' + plugins['auto-update-disabled'].length + ')' );
$views.find( '.auto-update-disabled' ).remove();
plugins.all = _.without( plugins.all, response.plugin );
if ( plugins.all.length ) {
$views.find( '.all .count' ).text( '(' + plugins.all.length + ')' );
$form.find( '.tablenav' ).css( { visibility: 'hidden' } );
$views.find( '.all' ).remove();
if ( ! $form.find( 'tr.no-items' ).length ) {
$form.find( '#the-list' ).append( '<tr class="no-items"><td class="colspanchange" colspan="' + columnCount + '">' + __( 'No plugins are currently available.' ) + '</td></tr>' );
if ( $itemsCount.length && $currentView.length ) {
remainingCount = plugins[ $currentView.parent( 'li' ).attr('class') ].length;
/* translators: %s: The remaining number of plugins. */
_nx( '%s item', '%s items', remainingCount, 'plugin/plugins' ),
wp.a11y.speak( _x( 'Deleted!', 'plugin' ) );
$document.trigger( 'wp-plugin-delete-success', response );
* Updates the UI appropriately after a failed plugin deletion.
* @param {Object} response Response from the server.
* @param {string} response.slug Slug of the plugin to be deleted.
* @param {string} response.plugin Base name of the plugin to be deleted
* @param {string=} response.pluginName Optional. Name of the plugin to be deleted.
* @param {string} response.errorCode Error code for the error that occurred.
* @param {string} response.errorMessage The error that occurred.
wp.updates.deletePluginError = function( response ) {
var $plugin, $pluginUpdateRow,
pluginUpdateRow = wp.template( 'item-update-row' ),
noticeContent = wp.updates.adminNotice( {
className: 'update-message notice-error notice-alt',
message: response.errorMessage
$plugin = $( 'tr.inactive[data-plugin="' + response.plugin + '"]' );
$pluginUpdateRow = $plugin.siblings( '[data-plugin="' + response.plugin + '"]' );
$plugin = $( 'tr.inactive[data-slug="' + response.slug + '"]' );
$pluginUpdateRow = $plugin.siblings( '[data-slug="' + response.slug + '"]' );
if ( ! wp.updates.isValidResponse( response, 'delete' ) ) {