From 3ad8c409658ac14a6aacf52c911ff7dc6c09edaa Mon Sep 17 00:00:00 2001
From: Paul Biron
Date: Mon, 4 May 2020 16:45:25 -0600
Subject: [PATCH 1/4] Simplifies Ajax on both the JS and PHP sides.
Also fixes several other WPCS-related issues.
---
css/wp-autoupdates.css | 4 +
functions.php | 656 +++++++++++++++--------------------------
js/wp-autoupdates.js | 364 ++++++-----------------
3 files changed, 326 insertions(+), 698 deletions(-)
diff --git a/css/wp-autoupdates.css b/css/wp-autoupdates.css
index af9edaf..189cf40 100755
--- a/css/wp-autoupdates.css
+++ b/css/wp-autoupdates.css
@@ -2,6 +2,10 @@
animation: rotation 2s infinite linear;
}
+.auto-updates-error {
+ display: inline-block;
+}
+
#autoupdates_column {
min-width: 200px;
}
diff --git a/functions.php b/functions.php
index 80b9f8d..2623c27 100755
--- a/functions.php
+++ b/functions.php
@@ -65,56 +65,62 @@ function wp_autoupdates_enqueues( $hook ) {
if ( 'themes.php' === $hook ) {
if ( wp_autoupdates_is_themes_auto_update_enabled() ) {
- $script = 'jQuery( document ).ready( function() {';
-
/* translators: %s: Theme name. */
- $aria_label_enable = sprintf( _x( 'Enable automatic update for %s', 'theme' ), '{{ data.name }}' );
- $aria_label_disable = sprintf( _x( 'Disable automatic update for %s', 'theme' ), '{{ data.name }}' );
-
- // Put the enable/disable link below the author and before the update box.
- $autoupdate_text = ' <# if ( data.autoupdate ) { #>';
- $autoupdate_text .= '';
- $autoupdate_text .= '' . __( 'Disable automatic updates' ) . '';
- $autoupdate_text .= '';
- $autoupdate_text .= '<# } else { #>';
- $autoupdate_text .= '';
- $autoupdate_text .= '' . __( 'Enable automatic updates' ) . '';
- $autoupdate_text .= '';
- $autoupdate_text .= '<# } #>
';
-
- $script .= ' const theme_template_single = jQuery( "#tmpl-theme-single" );
-
- // Pull template into new html element, manipulate, then put back.
- // Props https://stackoverflow.com/a/42248980.
- function insert_into_template(positioning_text, added_text, insert_before) {
- var template_text = theme_template_single.text();
- var position = template_text.search(positioning_text);
- if ( -1 !== position ) {
- if ( true !== insert_before ) {
- position += positioning_text.length;
- }
-
- const new_template_text = template_text.substr(0, position) + added_text + template_text.substr(position);
- theme_template_single.text( new_template_text );
- }
- }
-
- const position_beginning_of_update_box = "<# if \\\\( data.hasUpdate \\\\) { #>";
- insert_into_template(position_beginning_of_update_box, "' . str_replace('"', '\"', $autoupdate_text) . '", true);
- ';
-
- // Put the time until next update within the data.hasUpdate block.
- $update_message = wp_autoupdates_get_update_message();
- $autoupdate_time_text = '<# if ( data.autoupdate ) { #>';
- $autoupdate_time_text .= '' . $update_message . '
';
- $autoupdate_time_text .= '<# } #>';
-
- $script .= '
- const position_data_update = "{{{ data.update }}}";
- insert_into_template(position_data_update, "' . str_replace('"', '\"', $autoupdate_time_text) . '", false);
- ';
+ $aria_label_enable = sprintf( _x( 'Enable automatic update for %s', 'theme name' ), '{{ data.name }}' );
+ /* translators: %s: Theme name. */
+ $aria_label_disable = sprintf( _x( 'Disable automatic update for %s', 'theme name' ), '{{ data.name }}' );
+ $text_enable = __( 'Enable automatic updates', 'wp-autoupdates' );
+ $text_disable = __( 'Disable automatic updates', 'wp-autoupdates' );
+
+ $update_message = wp_autoupdates_get_update_message();
+ $autoupdate_text = <<
+
+<# if ( data.autoupdate ) { #>
+
+
+ {$text_disable}
+
+<# } else { #>
+
+
+ {$text_enable}
+
+<# } #>
+<# if ( data.hasUpdate ) { #>
+ <# if ( data.autoupdate) { #>
+
{$update_message}
+ <# } else { #>
+
{$update_message}
+ <# } #>
+<# } #>
+
+
+<# } #>
+
+EOF;
+ $autoupdate_text = str_replace( PHP_EOL, '\\' . PHP_EOL, $autoupdate_text );
+ $script = <<' );
+
+ if ( -1 !== position ) {
+ template_text =
+ template_text.substr( 0, position ) +
+ '{$autoupdate_text}' +
+ template_text.substr( position );
+
+ template.text( template_text );
+ }
+ } );
+} )( jQuery );
+EOF;
- $script .= '});';
wp_add_inline_script( 'jquery', $script );
}
}
@@ -132,12 +138,12 @@ function insert_into_template(positioning_text, added_text, insert_before) {
'wp_autoupdates',
array(
'enable' => __( 'Enable auto-updates', 'wp-autoupdates' ),
- 'enabling' => __( 'Enabling auto-updates...', 'wp-autoupdates' ),
+ 'enabling' => __( 'Enabling...', 'wp-autoupdates' ),
+ 'enabled' => __( 'Auto-updates enabled', 'wp-autoupdates' ),
'disable' => __( 'Disable auto-updates', 'wp-autoupdates' ),
- 'disabling' => __( 'Disabling auto-updates...', 'wp-autoupdates' ),
- 'auto_enabled' => __( 'Auto-updates enabled', 'wp-autoupdates' ),
- 'auto_disabled' => __( 'Auto-updates disabled', 'wp-autoupdates' ),
- 'auto_update_error' => __( 'The request could not be completed', 'wp-autoupdates' ),
+ 'disabling' => __( 'Disabling...', 'wp-autoupdates' ),
+ 'disabled' => __( 'Auto-updates disabled', 'wp-autoupdates' ),
+ 'auto_update_error' => __( 'The request could not be completed.', 'wp-autoupdates' ),
)
);
}
@@ -152,13 +158,17 @@ function insert_into_template(positioning_text, added_text, insert_before) {
* @return array
*/
function wp_autoupdates_prepare_themes_for_js( $prepared_themes ) {
+ if ( ! wp_autoupdates_is_themes_auto_update_enabled() ) {
+ return $prepared_themes;
+ }
+
$wp_auto_update_themes = get_option( 'wp_auto_update_themes', array() );
foreach( $prepared_themes as $theme ) {
// Set extra data for use in the template.
- $slug = $theme['id'];
+ $slug = $theme['id'];
$encoded_slug = urlencode( $slug );
- $theme['autoupdate'] = in_array( $slug, $wp_auto_update_themes, true );
+ $theme['autoupdate'] = in_array( $slug, $wp_auto_update_themes, true );
$theme['actions']['autoupdate'] = current_user_can( 'update_themes' ) ? wp_nonce_url( admin_url( 'themes.php?action=autoupdate&theme=' . $encoded_slug ), 'autoupdate-theme_' . $slug ) : null;
$prepared_themes[ $slug ] = $theme;
@@ -246,7 +256,7 @@ function wp_autoupdates_selected_themes( $update, $item ) {
* @return string[]
*/
function wp_autoupdates_add_plugins_autoupdates_column( $columns ) {
- if ( ! current_user_can( 'update_plugins' ) || ! wp_autoupdates_is_plugins_auto_update_enabled() ) {
+ if ( ! ( current_user_can( 'update_plugins' ) && wp_autoupdates_is_plugins_auto_update_enabled() ) ) {
return $columns;
}
if ( ! isset( $_GET['plugin_status'] ) || ( 'mustuse' !== $_GET['plugin_status'] && 'dropins' !== $_GET['plugin_status'] ) ) {
@@ -264,69 +274,64 @@ function wp_autoupdates_add_plugins_autoupdates_column( $columns ) {
* @param array $plugin_data An array of plugin data.
*/
function wp_autoupdates_add_plugins_autoupdates_column_content( $column_name, $plugin_file, $plugin_data ) {
- if ( ! current_user_can( 'update_plugins' ) || ! wp_autoupdates_is_plugins_auto_update_enabled() ) {
+ if ( ! ( current_user_can( 'update_plugins' ) && wp_autoupdates_is_plugins_auto_update_enabled() ) ) {
return;
}
if ( 'autoupdates_column' !== $column_name ) {
return;
}
- $plugins = get_plugins();
- $plugins_updates = get_site_transient( 'update_plugins' );
- $page = isset( $_GET['paged'] ) && ! empty( $_GET['paged'] ) ? wp_unslash( esc_html( $_GET['paged'] ) ) : '';
- $plugin_status = isset( $_GET['plugin_status'] ) && ! empty( $_GET['plugin_status'] ) ? wp_unslash( esc_html( $_GET['plugin_status'] ) ) : '';
- if ( wp_autoupdates_is_plugins_auto_update_enabled() ) {
- if ( ! isset( $plugins[ $plugin_file ] ) ) {
- return;
- }
- $wp_auto_update_plugins = get_site_option( 'wp_auto_update_plugins', array() );
- if ( in_array( $plugin_file, $wp_auto_update_plugins, true ) ) {
- $aria_label = esc_attr(
- sprintf(
- /* translators: Plugin name. */
- _x( 'Disable automatic updates for %s', 'plugin', 'wp-autoupdates' ),
- esc_html( $plugins[ $plugin_file ]['Name'] )
- )
- );
- echo '';
- echo '' . __( 'Auto-updates enabled', 'wp-autoupdates' ) . '';
- echo '
';
- $update_message = wp_autoupdates_get_update_message();
- if ( isset( $plugins_updates->response[$plugin_file] ) ) {
- echo '';
- echo $update_message;
- echo '
';
- echo '';
- }
- if ( current_user_can( 'update_plugins', $plugin_file ) ) {
- echo sprintf(
- '%s',
- wp_nonce_url( 'plugins.php?action=autoupdate&plugin=' . urlencode( $plugin_file ) . '&paged=' . $page . '&plugin_status=' . $plugin_status, 'autoupdate-plugin_' . $plugin_file ),
- $aria_label,
- __( 'Disable auto-updates', 'wp-autoupdates' )
- );
- }
- echo '
';
- } else {
- if ( current_user_can( 'update_plugins', $plugin_file ) ) {
- $aria_label = esc_attr(
- sprintf(
- /* translators: Plugin name. */
- _x( 'Enable automatic updates for %s', 'plugin', 'wp-autoupdates' ),
- esc_html( $plugins[ $plugin_file ]['Name'] )
- )
- );
- echo '';
- echo sprintf(
- '%s',
- wp_nonce_url( 'plugins.php?action=autoupdate&plugin=' . urlencode( $plugin_file ) . '&paged=' . $page . '&plugin_status=' . $plugin_status, 'autoupdate-plugin_' . $plugin_file ),
- $aria_label,
- __( 'Enable auto-updates', 'wp-autoupdates' )
- );
- echo '
';
- }
- }
+ /** This filter is documented in wp-admin/includes/class-wp-plugins-list-table.php */
+ $plugins = apply_filters( 'all_plugins', get_plugins() );
+ if ( ! isset( $plugins[ $plugin_file ] ) ) {
+ return;
+ }
+
+ $available_updates = get_site_transient( 'update_plugins' );
+ $page = ! empty( $_GET['paged'] ) ? wp_unslash( esc_html( $_GET['paged'] ) ) : '';
+ $plugin_status = ! empty( $_GET['plugin_status'] ) ? wp_unslash( esc_html( $_GET['plugin_status'] ) ) : '';
+
+ $wp_auto_update_plugins = get_site_option( 'wp_auto_update_plugins', array() );
+ $auto_update_time_class = ' hidden';
+ if ( in_array( $plugin_file, $wp_auto_update_plugins, true ) ) {
+ $aria_label = esc_attr(
+ sprintf(
+ /* translators: Plugin name. */
+ _x( 'Disable automatic updates for %s', 'plugin name', 'wp-autoupdates' ),
+ $plugins[ $plugin_file ]['Name']
+ )
+ );
+ $text = __( 'Disable auto-updates', 'wp-autoupdates' );
+ $auto_update_time_class = '';
+ $action = 'disable';
+ } else {
+ $aria_label = esc_attr(
+ sprintf(
+ /* translators: Plugin name. */
+ _x( 'Enable automatic updates for %s', 'plugin name', 'wp-autoupdates' ),
+ $plugins[ $plugin_file ]['Name']
+ )
+ );
+ $text = __( 'Enable auto-updates', 'wp-autoupdates' );
+ $action = 'enable';
}
+
+ printf(
+ '%s',
+ wp_nonce_url( 'plugins.php?action=autoupdate&plugin=' . urlencode( $plugin_file ) . '&paged=' . $page . '&plugin_status=' . $plugin_status, 'autoupdate-plugin_' . $plugin_file ),
+ $action,
+ $aria_label,
+ $text
+ );
+
+ if ( isset( $available_updates->response[ $plugin_file ] ) ) {
+ printf(
+ '%s
',
+ $auto_update_time_class,
+ wp_autoupdates_get_update_message()
+ );
+ }
+ echo '';
}
add_action( 'manage_plugins_custom_column' , 'wp_autoupdates_add_plugins_autoupdates_column_content', 10, 3 );
@@ -421,10 +426,13 @@ function wp_autoupdates_themes_enabler() {
}
update_site_option( 'wp_auto_update_themes', $wp_auto_update_themes );
+
$theme_status = '';
+
if ( is_multisite() && is_network_admin() ) {
$theme_status = ! empty( $_GET['theme_status'] ) ? "theme_status=" . $_GET['theme_status'] : '';
}
+
wp_redirect( self_admin_url( "themes.php?$action_type&$theme_status" ) );
exit;
}
@@ -436,10 +444,10 @@ function wp_autoupdates_themes_enabler() {
*/
function wp_autoupdates_enabler() {
$pagenow = $GLOBALS['pagenow'];
+
if ( 'plugins.php' === $pagenow ) {
wp_autoupdates_plugins_enabler();
- }
- else if ( 'themes.php' === $pagenow ) {
+ } elseif ( 'themes.php' === $pagenow ) {
wp_autoupdates_themes_enabler();
}
}
@@ -485,9 +493,7 @@ function wp_autoupdates_plugins_bulk_actions_handle( $redirect_to, $doaction, $i
$redirect_to = self_admin_url( "plugins.php?enable-autoupdate=true&plugin_status=$status&paged=$page&s=$s" );
return $redirect_to;
- }
-
- if ( 'disable-autoupdate-selected' === $doaction ) {
+ } elseif ( 'disable-autoupdate-selected' === $doaction ) {
if ( ! current_user_can( 'update_plugins' ) || ! wp_autoupdates_is_plugins_auto_update_enabled() ) {
wp_die( __( 'Sorry, you are not allowed to enable plugins automatic updates.', 'wp-autoupdates' ) );
}
@@ -555,6 +561,7 @@ function wp_autoupdates_plugins_notices() {
_e( 'Selected plugins will be auto-updated.', 'wp-autoupdates' );
echo '
';
}
+
if ( isset( $_GET['disable-autoupdate'] ) ) {
echo '';
_e( 'Selected themes will no longer be auto-updated.', 'wp-autoupdates' );
@@ -586,10 +594,10 @@ function wp_autoupdates_themes_notices() {
function wp_autoupdates_notices() {
// Plugins screen.
$pagenow = $GLOBALS['pagenow'];
+
if ( 'plugins.php' === $pagenow ) {
wp_autoupdates_plugins_notices();
- }
- else if ( 'themes.php' === $pagenow ) {
+ } elseif ( 'themes.php' === $pagenow ) {
wp_autoupdates_themes_notices();
}
}
@@ -635,6 +643,7 @@ function wp_autoupdates_plugins_status_links( $status_links ) {
if ( 0 === $count ) {
continue;
}
+
switch( $type ) {
case 'autoupdate_enabled':
/* translators: %s: Number of plugins. */
@@ -703,7 +712,8 @@ function wp_autoupdates_plugins_filter_plugins_by_status( $plugins ) {
}
$wp_auto_update_plugins = get_site_option( 'wp_auto_update_plugins', array() );
- $_plugins = array();
+ $_plugins = array();
+
foreach ( $plugins as $plugin_file => $plugin_data ) {
switch ( $_REQUEST['plugin_status'] ) {
case 'autoupdate_enabled':
@@ -807,6 +817,7 @@ function wp_autoupdates_debug_information( $info ) {
/* translators: %s: Plugin author name. */
$plugin_version_string_debug = sprintf( __( 'author: %s, version: (undefined)', 'wp-autoupdates' ), $plugin_author );
}
+
if ( ! empty( $plugin_version ) ) {
/* translators: %s: Plugin version number. */
$plugin_version_string = sprintf( __( 'Version %s', 'wp-autoupdates' ), $plugin_version );
@@ -844,11 +855,13 @@ function wp_autoupdates_debug_information( $info ) {
$themes = wp_get_themes();
$active_theme = wp_get_theme();
+
foreach ( $themes as $theme_path => $theme ) {
$theme_version = sanitize_text_field( $theme['Version'] );
$theme_author = sanitize_text_field( $theme['Author'] );
$is_active_theme = $theme->name === $active_theme->name;
+
if ($is_active_theme) {
$theme_part = 'wp-active-theme';
@@ -881,6 +894,7 @@ function wp_autoupdates_debug_information( $info ) {
/* translators: %s: Theme author name. */
$theme_version_string_debug = sprintf( __( 'author: %s, version: (undefined)', 'wp-autoupdates' ), $theme_author );
}
+
if ( ! empty( $theme_version ) ) {
/* translators: %s: Theme version number. */
$theme_version_string = sprintf( __( 'Version %s', 'wp-autoupdates' ), $theme_version );
@@ -899,6 +913,7 @@ function wp_autoupdates_debug_information( $info ) {
$theme_name = sanitize_text_field( $theme['Name'] );
$label_name = sprintf( __( '%1$s (%2$s)', 'wp-autoupdates' ), $theme_name, $theme_path);
+
$info[ $theme_part ]['fields'][ $theme_name ] = array(
'label' => $label_name,
'value' => $theme_version_string,
@@ -969,7 +984,8 @@ function wp_autoupdates_is_themes_auto_update_email_enabled() {
*/
function wp_autoupdates_automatic_updates_complete_notification( $results ) {
$successful_updates = array();
- $failed_updates = array();
+ $failed_updates = array();
+
if ( isset( $results['plugin'] ) && wp_autoupdates_is_plugins_auto_update_email_enabled() ) {
foreach ( $results['plugin'] as $update_result ) {
if ( true === $update_result->result ) {
@@ -979,6 +995,7 @@ function wp_autoupdates_automatic_updates_complete_notification( $results ) {
}
}
}
+
if ( isset( $results['theme'] ) && wp_autoupdates_is_themes_auto_update_enabled() ) {
foreach ( $results['theme'] as $update_result ) {
if ( true === $update_result->result ) {
@@ -988,9 +1005,11 @@ function wp_autoupdates_automatic_updates_complete_notification( $results ) {
}
}
}
+
if ( empty( $successful_updates ) && empty( $failed_updates ) ) {
return;
}
+
if ( empty( $failed_updates ) ) {
wp_autoupdates_send_email_notification( 'success', $successful_updates, $failed_updates );
} elseif ( empty( $successful_updates ) ) {
@@ -1014,6 +1033,7 @@ function wp_autoupdates_send_email_notification( $type, $successful_updates, $fa
if ( empty( $successful_updates ) && empty( $failed_updates ) ) {
return;
}
+
$body = array();
switch ( $type ) {
@@ -1171,9 +1191,11 @@ function wp_autoupdates_add_themes_autoupdates_column( $columns ) {
if ( ! current_user_can( 'update_themes' ) || ! wp_autoupdates_is_themes_auto_update_enabled() ) {
return $columns;
}
+
if ( ! isset( $_GET['theme_status'] ) || 'broken' !== $_GET['theme_status'] ) {
$columns['autoupdates_column'] = __( 'Automatic updates', 'wp-autoupdates' );
}
+
return $columns;
}
add_filter( 'manage_themes-network_columns', 'wp_autoupdates_add_themes_autoupdates_column' );
@@ -1187,73 +1209,64 @@ function wp_autoupdates_add_themes_autoupdates_column( $columns ) {
* @param WP_Theme $theme Current WP_Theme object.
*/
function wp_autoupdates_add_themes_autoupdates_column_content( $column_name, $stylesheet, $theme ) {
- $pagenow = $GLOBALS['pagenow'];
-
- if ( ! current_user_can( 'update_themes' ) || ! wp_autoupdates_is_themes_auto_update_enabled() ) {
+ if ( ! ( current_user_can( 'update_plugins' ) && wp_autoupdates_is_themes_auto_update_enabled() ) ) {
return;
}
if ( 'autoupdates_column' !== $column_name ) {
return;
}
- $themes = wp_get_themes();
- $themes_updates = get_site_transient( 'update_themes' );
- $page = isset( $_GET['paged'] ) && ! empty( $_GET['paged'] ) ? wp_unslash( esc_html( $_GET['paged'] ) ) : '';
- $theme_status = isset( $_GET['theme_status'] ) && ! empty( $_GET['theme_status'] ) ? wp_unslash( esc_html( $_GET['theme_status'] ) ) : '';
- $base_url = 'themes.php?action=autoupdate&theme=' . urlencode( $stylesheet ) . '&paged=' . $page . '&theme_status=' . $theme_status;
- if ( wp_autoupdates_is_themes_auto_update_enabled() ) {
- if ( ! isset( $themes[ $stylesheet ] ) ) {
- return;
- }
- $wp_auto_update_themes = get_site_option( 'wp_auto_update_themes', array() );
- if ( in_array( $stylesheet, $wp_auto_update_themes, true ) ) {
- $aria_label = esc_attr(
- sprintf(
- /* translators: Theme name. */
- _x( 'Disable automatic updates for %s', 'theme', 'wp-autoupdates' ),
- esc_html( $themes[ $stylesheet ]->get( 'Name' ) )
- )
- );
- echo '
';
- echo '' . __( 'Auto-updates enabled', 'wp-autoupdates' ) . '';
- echo '
';
+ $themes = wp_get_themes();
+ if ( ! isset( $themes[ $stylesheet ] ) ) {
+ return;
+ }
- $update_message = wp_autoupdates_get_update_message();
- if ( isset( $themes_updates->response[ $stylesheet ] ) ) {
- echo '';
- echo $update_message;
- echo '
';
- echo '';
- }
- if ( current_user_can( 'update_themes', $stylesheet ) ) {
- echo sprintf(
- '%s',
- wp_nonce_url( $base_url, 'autoupdate-theme_' . $stylesheet ),
- $aria_label,
- __( 'Disable auto-updates', 'wp-autoupdates' )
- );
- }
- echo '
';
- } else {
- if ( current_user_can( 'update_themes', $stylesheet ) ) {
- $aria_label = esc_attr(
- sprintf(
- /* translators: Theme name. */
- _x( 'Enable automatic updates for %s', 'theme', 'wp-autoupdates' ),
- esc_html( $themes[ $stylesheet ]->get( 'Name' ) )
- )
- );
- echo '
';
- echo sprintf(
- '%s',
- wp_nonce_url( $base_url, 'autoupdate-theme_' . $stylesheet ),
- $aria_label,
- __( 'Enable auto-updates', 'wp-autoupdates' )
- );
- echo '
';
- }
- }
+ $available_updates = get_site_transient( 'update_themes' );
+ $page = ! empty( $_GET['paged'] ) ? wp_unslash( esc_html( $_GET['paged'] ) ) : '';
+ $thene_status = ! empty( $_GET['thene_status'] ) ? wp_unslash( esc_html( $_GET['thene_status'] ) ) : '';
+
+
+ $wp_auto_update_themes = (array) get_site_option( 'wp_auto_update_themes', array() );
+ $auto_update_time_class = ' hidden';
+ if ( in_array( $stylesheet, $wp_auto_update_themes, true ) ) {
+ $aria_label = esc_attr(
+ sprintf(
+ /* translators: Theme name. */
+ _x( 'Disable automatic updates for %s', 'theme name', 'wp-autoupdates' ),
+ $themes[ $stylesheet ]['Name']
+ )
+ );
+ $text = __( 'Disable auto-updates', 'wp-autoupdates' );
+ $auto_update_time_class = '';
+ $action = 'disable';
+ } else {
+ $aria_label = esc_attr(
+ sprintf(
+ /* translators: Theme name. */
+ _x( 'Enable automatic updates for %s', 'theme name', 'wp-autoupdates' ),
+ $themes[ $stylesheet ]['Name']
+ )
+ );
+ $text = __( 'Enable auto-updates', 'wp-autoupdates' );
+ $action = 'enable';
}
+
+ printf(
+ '
%s',
+ wp_nonce_url( 'themes.php?action=autoupdate&theme=' . urlencode( $stylesheet ) . '&paged=' . $page . '&plugin_status=' . $thene_status , 'autoupdate-theme_' . $stylesheet ),
+ $action,
+ $aria_label,
+ $text
+ );
+
+ if ( isset( $available_updates->response[ $stylesheet ] ) ) {
+ printf(
+ '
%s
',
+ $auto_update_time_class,
+ wp_autoupdates_get_update_message()
+ );
+ }
+ echo '
';
}
add_action( 'manage_themes_custom_column' , 'wp_autoupdates_add_themes_autoupdates_column_content', 10, 3 );
@@ -1350,261 +1363,70 @@ function wp_autoupdates_themes_bulk_actions_handle( $redirect_to, $doaction, $it
add_action( 'handle_network_bulk_actions-themes-network', 'wp_autoupdates_themes_bulk_actions_handle', 10, 3 );
/**
- * Disable auto updates via Ajax.
+ * Toggle auto updates via Ajax.
*/
-function wp_autoupdates_disable_auto_updates() {
- $type = sanitize_text_field( $_POST['type'] );
- $asset = sanitize_text_field( urldecode( $_POST['asset'] ) );
- check_ajax_referer(
- sprintf(
- 'autoupdate-%s_%s',
- $type,
- $asset
- )
- );
-
- // Capability check.
- if ( 'plugin' === $type ) {
- if ( ! current_user_can( 'update_plugins' ) ) {
- wp_send_json_error(
- array(
- 'error' => __( 'You do not have permission to modify plugins.', 'wp-autoupdate' ),
- )
- );
- }
- }
- if ( 'theme' === $type ) {
- if ( ! current_user_can( 'update_themes' ) ) {
- wp_send_json_error(
- array(
- 'error' => __( 'You do not have permission to modify themes.', 'wp-autoupdate' ),
- )
- );
- }
+function wp_autoupdates_toggle_auto_updates() {
+ if ( empty( $_POST['type'] ) || empty( $_POST['asset'] ) || empty( $_POST['state'] ) ) {
+ wp_send_json_error( array( 'error' => __( 'Invalid data. No selected item.', 'wp-autoupdates' ) ) );
}
- // Check Asset Type.
- if ( 'plugin' === $type ) {
- $wp_autoupdate_plugins = (array) get_site_option( 'wp_auto_update_plugins', array() );
- $wp_autoupdate_plugins = array_diff( $wp_autoupdate_plugins, array( $asset ) );
- update_site_option( 'wp_auto_update_plugins', $wp_autoupdate_plugins );
-
- /** This filter is documented in wp-admin/includes/class-wp-plugins-list-table.php */
- $all_plugins = apply_filters( 'all_plugins', get_plugins() );
- $wp_autoupdate_plugins = array_intersect( $wp_autoupdate_plugins, array_keys( $all_plugins ) );
- $enabled_count = count( $wp_autoupdate_plugins );
-
- $plugin_url = add_query_arg(
- array(
- 'action' => 'autoupdate',
- 'plugin' => $asset,
- '_wpnonce' => wp_create_nonce( 'autoupdate-plugin_' . $asset ),
- ),
- 'plugins.php'
- );
-
- $aria_label = esc_attr(
- sprintf(
- /* translators: Plugin name. */
- _x( 'Enable automatic updates for %s', 'plugin', 'wp-autoupdates' ),
- $all_plugins[ $asset ]['Name']
- )
- );
-
- $return_html = sprintf(
- '
%s
',
- esc_url_raw( $plugin_url ),
- $aria_label,
- esc_html__( 'Enable auto-updates', 'wp-autoupdates' )
- );
-
- wp_send_json_success(
- array(
- 'enabled_count' => '(' . $enabled_count . ')',
- 'disabled_count' => '(' . absint( count( $all_plugins ) - $enabled_count ) . ')',
- 'return_html' => wp_kses_post( $return_html ),
- 'type' => 'plugin',
- )
- );
- } elseif ( 'theme' === $type ) {
- $wp_autoupdate_themes = (array) get_site_option( 'wp_auto_update_themes', array() );
- $wp_autoupdate_themes = array_diff( $wp_autoupdate_themes, array( $asset ) );
- update_site_option( 'wp_auto_update_themes', $wp_autoupdate_themes );
-
- /** This filter is documented in wp-admin/includes/class-wp-plugins-list-table.php */
- $all_themes = wp_get_themes();
- $wp_autoupdate_themes = array_intersect( $wp_autoupdate_themes, array_keys( $all_themes ) );
- $enabled_count = count( $wp_autoupdate_themes );
-
- $theme_url = add_query_arg(
- array(
- 'action' => 'autoupdate',
- 'theme' => $asset,
- '_wpnonce' => wp_create_nonce( 'autoupdate-theme_' . $asset ),
- ),
- 'themes.php'
- );
-
- $aria_label = esc_attr(
- sprintf(
- /* translators: Theme name. */
- _x( 'Enable automatic updates for %s', 'plugin', 'wp-autoupdates' ),
- $all_themes[ $asset ]->get( 'Name' )
- )
- );
-
- $return_html = sprintf(
- '
%s
',
- esc_url_raw( $theme_url ),
- $aria_label,
- esc_html__( 'Enable auto-updates', 'wp-autoupdates' )
- );
-
- wp_send_json_success(
- array(
- 'enabled_count' => '(' . $enabled_count . ')',
- 'disabled_count' => '(' . absint( count( $all_themes ) - $enabled_count ) . ')',
- 'return_html' => wp_kses_post( $return_html ),
- 'type' => 'theme',
- )
- );
- }
-
- wp_send_json_error(
- array(
- 'error' => __( 'Could not disable auto-updates for the selected item.', 'wp-autoupdates' ),
- )
- );
-}
-add_action( 'wp_ajax_disable_auto_updates', 'wp_autoupdates_disable_auto_updates' );
-/**
- * Enable auto updates via Ajax.
- */
-function wp_autoupdates_enable_auto_updates() {
$type = sanitize_text_field( $_POST['type'] );
+ $state = sanitize_text_field( $_POST['state'] );
$asset = sanitize_text_field( urldecode( $_POST['asset'] ) );
- check_ajax_referer(
- sprintf(
- 'autoupdate-%s_%s',
- $type,
- $asset
- )
- );
- // Capability check.
- if ( 'plugin' === $type ) {
- if ( ! current_user_can( 'update_plugins' ) ) {
- wp_send_json_error(
- array(
- 'error' => __( 'You do not have permission to modify plugins.', 'wp-autoupdate' ),
- )
- );
- }
- }
- if ( 'theme' === $type ) {
- if ( ! current_user_can( 'update_themes' ) ) {
- wp_send_json_error(
- array(
- 'error' => __( 'You do not have permission to modify themes.', 'wp-autoupdate' ),
- )
- );
- }
+ if ( ! in_array( $state, array( 'enable', 'disable', true ) ) ) {
+ wp_send_json_error( array( 'error' => __( 'Invalid data. Unknown state.', 'wp-autoupdates' ) ) );
}
- // Check Asset Type.
- if ( 'plugin' === $type ) {
- $wp_autoupdate_plugins = (array) get_site_option( 'wp_auto_update_plugins', array() );
- $wp_autoupdate_plugins[] = $asset;
- array_unique( $wp_autoupdate_plugins );
- update_site_option( 'wp_auto_update_plugins', $wp_autoupdate_plugins );
+ check_ajax_referer( "autoupdate-{$type}_{$asset}" );
- /** This filter is documented in wp-admin/includes/class-wp-plugins-list-table.php */
- $all_plugins = apply_filters( 'all_plugins', get_plugins() );
- $wp_autoupdate_plugins = array_intersect( $wp_autoupdate_plugins, array_keys( $all_plugins ) );
- $enabled_count = count( $wp_autoupdate_plugins );
-
- $plugin_url = add_query_arg(
- array(
- 'action' => 'autoupdate',
- 'plugin' => $asset,
- '_wpnonce' => wp_create_nonce( 'autoupdate-plugin_' . $asset ),
- ),
- 'plugins.php'
- );
-
- $aria_label = esc_attr(
- sprintf(
- /* translators: Plugin name. */
- _x( 'Disable automatic updates for %s', 'plugin', 'wp-autoupdates' ),
- esc_html( $all_plugins[ $asset ]['Name'] )
- )
- );
-
- $return_html = sprintf(
- '
%s
%s
',
- esc_html__( 'Auto-updates enabled', 'wp-autoupdates' ),
- esc_url_raw( $plugin_url ),
- $aria_label,
- esc_html__( 'Disable auto-updates', 'wp-autoupdates' )
- );
+ switch ( $type ) {
+ case 'plugin':
+ $cap = 'update_plugins';
+ $option = 'wp_auto_update_plugins';
+ /** This filter is documented in wp-admin/includes/class-wp-plugins-list-table.php */
+ $all_items = apply_filters( 'all_plugins', get_plugins() );
+ break;
+ case 'theme':
+ $cap = 'update_themes';
+ $option = 'wp_auto_update_themes';
+ $all_items = wp_get_themes();
+ break;
+ default:
+ wp_send_json_error( array( 'error' => __( 'Invalid data. Unknown type.', 'wp-autoupdates' ) ) );
+ }
- wp_send_json_success(
+ if ( ! $all_items[ $asset ] ) {
+ wp_send_json_error(
array(
- 'enabled_count' => '(' . absint( $enabled_count ) . ')',
- 'disabled_count' => '(' . absint( count( $all_plugins ) - $enabled_count ) . ')',
- 'return_html' => wp_kses_post( $return_html ),
- 'type' => 'plugin',
+ 'error' => sprintf(
+ __( 'Invalid data. %s does not exist.', 'wp-autoupdates' ),
+ 'plugin' === $type ? __( 'Plugin', 'wp-autoupdates' ) : __( 'Theme', 'wp-autoupdates' )
+ )
)
);
- } elseif ( 'theme' === $type ) {
- $wp_autoupdate_themes = (array) get_site_option( 'wp_auto_update_themes', array() );
- $wp_autoupdate_themes[] = $asset;
- array_unique( $wp_autoupdate_themes );
- update_site_option( 'wp_auto_update_themes', $wp_autoupdate_themes );
-
- $all_themes = wp_get_themes();
- $wp_autoupdate_themes = array_intersect( $wp_autoupdate_themes, array_keys( $all_themes ) );
- $enabled_count = count( $wp_autoupdate_themes );
+ }
- $theme_url = add_query_arg(
+ if ( ! current_user_can( $cap ) ) {
+ wp_send_json_error(
array(
- 'action' => 'autoupdate',
- 'theme' => $asset,
- '_wpnonce' => wp_create_nonce( 'autoupdate-theme_' . $asset ),
- ),
- 'themes.php'
- );
-
- $aria_label = esc_attr(
- sprintf(
- /* translators: Theme name. */
- _x( 'Disable automatic updates for %s', 'theme', 'wp-autoupdates' ),
- esc_html( $all_themes[ $asset ]->get( 'Name' ) )
+ 'error' => sprintf(
+ __( 'You do not have permission to modify %s.', 'wp-autoupdates' ),
+ 'plugin' === $type ? __( 'plugins', 'wp-autoupdates' ) : __( 'themes', 'wp-autoupdates' )
+ )
)
);
+ }
- $return_html = sprintf(
- '
%s
%s
',
- esc_html__( 'Auto-updates enabled', 'wp-autoupdates' ),
- esc_url_raw( $theme_url ),
- $aria_label,
- esc_html__( 'Disable auto-updates', 'wp-autoupdates' )
- );
-
- wp_send_json_success(
- array(
- 'enabled_count' => '(' . absint( $enabled_count ) . ')',
- 'disabled_count' => '(' . absint( count( $all_themes ) - $enabled_count ) . ')',
- 'return_html' => wp_kses_post( $return_html ),
- 'type' => 'theme',
- )
- );
+ $wp_autoupdates = (array) get_site_option( $option, array() );
+ if ( 'disable' === $state ) {
+ $wp_autoupdates = array_diff( $wp_autoupdates, array( $asset ) );
+ } else {
+ $wp_autoupdates[] = $asset;
+ $wp_autoupdates = array_unique( $wp_autoupdates );
}
+ update_site_option( $option, $wp_autoupdates );
- wp_send_json_error(
- array(
- 'error' => __( 'Could not enable auto-updates for the selected item.', 'wp-autoupdates' ),
- )
- );
+ wp_send_json_success();
}
-add_action( 'wp_ajax_enable_auto_updates', 'wp_autoupdates_enable_auto_updates' );
+add_action( 'wp_ajax_toggle_auto_updates', 'wp_autoupdates_toggle_auto_updates' );
diff --git a/js/wp-autoupdates.js b/js/wp-autoupdates.js
index 3607767..b76159a 100644
--- a/js/wp-autoupdates.js
+++ b/js/wp-autoupdates.js
@@ -1,286 +1,88 @@
-jQuery(function ($) {
+/* global wp_autoupdates, pagenow */
+( function( $ ) {
+ 'use strict';
- function add_error_notice( html, error ) {
- html += '
';
- return html;
- }
- // Disable auto-updates for a plugin.
- $('.autoupdates_column').on('click', 'a.plugin-autoupdate-disable', function (e) {
- e.preventDefault();
- var $anchor = $( this );
- $anchor.blur();
- var href = wpAjax.unserialize($anchor.attr( 'href' ) );
- var $parent = $anchor.parents( '.autoupdates_column' );
- // Clear errors
- $parent.find( '.notice' ).remove();
- var html = $parent.html();
+ $( '.autoupdates_column, .theme-overlay' ).on( 'click', 'a.auto-update', function( event ) {
+ // TODO: Drop use of unserialize, perhaps switch to data-* attr.
+ var data,
+ anchor = $( this ),
+ type = anchor.hasClass( 'plugin' ) ? 'plugin' : 'theme',
+ action = anchor.hasClass( 'enable' ) ? 'enable' : 'disable',
+ href = wpAjax.unserialize( anchor.attr( 'href' ) ),
+ label = anchor.find( '.label' ),
+ parent = anchor.parents( 'themes' !== pagenow ? '.autoupdates_column' : '.theme-autoupdate' );
- // Show loading status.
- $anchor.html( '
' + wp_autoupdates.disabling );
-
- $.post(
- ajaxurl,
- {
- action: 'disable_auto_updates',
- _ajax_nonce: href._wpnonce,
- type: 'plugin',
- asset: href.plugin
- },
- function (response) {
-
- }
- )
- .done(function (response) {
- if ( response.success ) {
- $( '.autoupdate_enabled span' ).html( response.data.enabled_count );
- $( '.autoupdate_disabled span' ).html( response.data.disabled_count );
- $parent.html( response.data.return_html );
- $parent.find('.plugin-autoupdate-enable').focus();
- wp.a11y.speak( wp_autoupdates.auto_disabled, 'polite' );
- } else {
- var errorHTML = add_error_notice( html, response.data.error );
- wp.a11y.speak( response.data.error, 'polite' );
- $parent.html( errorHTML );
- }
- })
- .fail(function (response) {
- var errorHTML = add_error_notice( html, wp_autoupdates.auto_update_error );
- wp.a11y.speak( wp_autoupdates.auto_update_error, 'polite' );
- $parent.html( errorHTML );
- })
- .always(function (response) {
- });
- });
- // Enable auto-updates for a plugin.
- $('.autoupdates_column').on('click', 'a.plugin-autoupdate-enable', function (e) {
- e.preventDefault();
- var $anchor = $( this );
- $anchor.blur();
- var href = wpAjax.unserialize( $anchor.attr( 'href' ) );
- var $parent = $anchor.parents( '.autoupdates_column' );
- // Clear errors
- $parent.find( '.notice' ).remove();
- var html = $parent.html();
-
- // Show loading status.
- $anchor.addClass( 'spin' ).find( '.plugin-autoupdate-label' ).html( '
' + wp_autoupdates.enabling );
-
- $.post(
- ajaxurl,
- {
- action: 'enable_auto_updates',
- _ajax_nonce: href._wpnonce,
- type: 'plugin',
- asset: href.plugin
- },
- function (response) {
-
- }
- )
- .done(function (response) {
- if ( response.success ) {
- $( '.autoupdate_enabled span' ).html( response.data.enabled_count );
- $( '.autoupdate_disabled span' ).html( response.data.disabled_count );
- $parent.html( response.data.return_html );
- $parent.find('.plugin-autoupdate-disable').focus();
- wp.a11y.speak( wp_autoupdates.auto_enabled, 'polite' );
- } else {
- var errorHTML = add_error_notice( html, response.data.error );
- wp.a11y.speak( response.data.error, 'polite' );
- $parent.html( errorHTML );
- }
- })
- .fail(function (response) {
- var errorHTML = add_error_notice( html, wp_autoupdates.auto_update_error );
- wp.a11y.speak( wp_autoupdates.auto_update_error, 'polite' );
- $parent.html( errorHTML );
- })
- .always(function (response) {
- });
- });
- // Disable auto-updates for a theme.
- $('.autoupdates_column').on('click', 'a.theme-autoupdate-disable', function (e) {
- e.preventDefault();
- var $anchor = $( this );
- $anchor.blur();
- var href = wpAjax.unserialize($anchor.attr( 'href' ) );
- var $parent = $anchor.parents( '.autoupdates_column' );
- // Clear errors
- $parent.find( '.notice' ).remove();
- var html = $parent.html();
-
- // Show loading status.
- $anchor.html( '
' + wp_autoupdates.disabling );
-
- $.post(
- ajaxurl,
- {
- action: 'disable_auto_updates',
- _ajax_nonce: href._wpnonce,
- type: 'theme',
- asset: href.theme
- },
- function (response) {
+ event.preventDefault();
- }
- )
- .done(function (response) {
- if ( response.success ) {
- $( '.autoupdate_enabled span' ).html( response.data.enabled_count );
- $( '.autoupdate_disabled span' ).html( response.data.disabled_count );
- $parent.html( response.data.return_html );
- $parent.find('.theme-autoupdate-enable').focus();
- wp.a11y.speak( wp_autoupdates.auto_disabled, 'polite' );
- } else {
- var errorHTML = add_error_notice( html, response.data.error );
- wp.a11y.speak( response.data.error, 'polite' );
- $parent.html( errorHTML );
- }
- })
- .fail(function (response) {
- var errorHTML = add_error_notice( html, wp_autoupdates.auto_update_error );
- wp.a11y.speak( wp_autoupdates.auto_update_error, 'polite' );
- $parent.html( errorHTML );
- })
- .always(function (response) {
- });
- });
- // Enable auto-updates for a theme.
- $('.autoupdates_column').on('click', 'a.theme-autoupdate-enable', function (e) {
- e.preventDefault();
- var $anchor = $( this );
- $anchor.blur();
- var href = wpAjax.unserialize( $anchor.attr( 'href' ) );
- var $parent = $anchor.parents( '.autoupdates_column' );
- // Clear errors
- $parent.find( '.notice' ).remove();
- var html = $parent.html();
+ // Clear any previous errors.
+ parent.find( '.auto-updates-error' ).removeClass( 'notice error' ).addClass( 'hidden' );
// Show loading status.
- $anchor.addClass( 'spin' ).find( '.theme-autoupdate-label' ).html( '
' + wp_autoupdates.enabling );
-
- $.post(
- ajaxurl,
- {
- action: 'enable_auto_updates',
- _ajax_nonce: href._wpnonce,
- type: 'theme',
- asset: href.theme
- },
- function (response) {
-
- }
- )
- .done(function (response) {
- if ( response.success ) {
- $( '.autoupdate_enabled span' ).html( response.data.enabled_count );
- $( '.autoupdate_disabled span' ).html( response.data.disabled_count );
- $parent.html( response.data.return_html );
- $parent.find('.theme-autoupdate-disable').focus();
- wp.a11y.speak( wp_autoupdates.auto_enabled, 'polite' );
- } else {
- var errorHTML = add_error_notice( html, response.data.error );
- wp.a11y.speak( response.data.error, 'polite' );
- $parent.html( errorHTML );
- }
- })
- .fail(function (response) {
- var errorHTML = add_error_notice( html, wp_autoupdates.auto_update_error );
- wp.a11y.speak( wp_autoupdates.auto_update_error, 'polite' );
- $parent.html( errorHTML );
- })
- .always(function (response) {
- });
- });
- // Disable auto-updates for a theme.
- $('.theme-overlay').on('click', 'a.theme-autoupdate-disable', function (e) {
- e.preventDefault();
- var $anchor = $( this );
- $anchor.blur();
- var href = wpAjax.unserialize($anchor.attr( 'href' ) );
- var $parent = $anchor.parents( '.theme-autoupdate' );
- // Clear errors
- $parent.find( '.notice' ).remove();
- var html = $parent.html();
-
- // Show loading status.
- $anchor.html( '
' + wp_autoupdates.disabling );
-
- $.post(
- ajaxurl,
- {
- action: 'disable_auto_updates',
- _ajax_nonce: href._wpnonce,
- type: 'theme',
- asset: href.theme
- },
- function (response) {
-
- }
- )
- .done(function (response) {
- if ( response.success ) {
- $parent.html( response.data.return_html );
- $parent.find('.theme-autoupdate-enable').focus();
- wp.a11y.speak( wp_autoupdates.auto_disabled, 'polite' );
- } else {
- var errorHTML = add_error_notice( html, response.data.error );
- wp.a11y.speak( response.data.error, 'polite' );
- $parent.html( errorHTML );
- }
- })
- .fail(function (response) {
- var errorHTML = add_error_notice( html, wp_autoupdates.auto_update_error );
- wp.a11y.speak( wp_autoupdates.auto_update_error, 'polite' );
- $parent.html( errorHTML );
- })
- .always(function (response) {
- });
- });
- // Enable auto-updates for a theme.
- $('.theme-overlay').on('click', 'a.theme-autoupdate-enable', function (e) {
- e.preventDefault();
- var $anchor = $( this );
- $anchor.blur();
- var href = wpAjax.unserialize( $anchor.attr( 'href' ) );
- var $parent = $anchor.parents( '.theme-autoupdate' );
- // Clear errors
- $parent.find( '.notice' ).remove();
- var html = $parent.html();
-
- // Show loading status.
- $parent.find( '.theme-autoupdate-label' ).html( '
' + wp_autoupdates.enabling );
-
- $.post(
- ajaxurl,
- {
- action: 'enable_auto_updates',
- _ajax_nonce: href._wpnonce,
- type: 'theme',
- asset: href.theme
- },
- function (response) {
-
- }
- )
- .done(function (response) {
- if ( response.success ) {
- $parent.html( response.data.return_html );
- $parent.find('.theme-autoupdate-disable').focus();
- wp.a11y.speak( wp_autoupdates.auto_enabled, 'polite' );
- } else {
- var errorHTML = add_error_notice( html, response.data.error );
- wp.a11y.speak( response.data.error, 'polite' );
- $parent.html( errorHTML );
- }
-
- })
- .fail(function (response) {
- var errorHTML = add_error_notice( html, wp_autoupdates.auto_update_error );
- wp.a11y.speak( wp_autoupdates.auto_update_error, 'polite' );
- $parent.html( errorHTML );
- })
- .always(function (response) {
- });
- });
-});
\ No newline at end of file
+ label.text( 'enable' === action ? wp_autoupdates.enabling : wp_autoupdates.disabling );
+ anchor.find( '.dashicons-update' ).removeClass( 'hidden' );
+
+ data = {
+ action: 'toggle_auto_updates',
+ _ajax_nonce: href._wpnonce,
+ state: action,
+ type: type,
+ asset: 'plugin' === type ? href.plugin : href.theme,
+ };
+
+ $.post( ajaxurl, data )
+ .done( function( response ) {
+ if ( response.success ) {
+ // Update the counts in the enabled/disabled views if on on
+ // screen with a list table.
+ // TODO: If either count started out 0 the appropriate span won't
+ // be there and hence won't be updated.
+ if ( 'themes' !== pagenow ) {
+ var enabled = $( '.autoupdate_enabled span' ),
+ disabled = $( '.autoupdate_disabled span' ),
+ enabledNumber = parseInt( enabled.text().replace( /[^\d]+/g, '' ) ) || 0,
+ disabledNumber = parseInt( disabled.text().replace( /[^\d]+/g, '' ) ) || 0;
+
+ switch ( action ) {
+ case 'enable':
+ ++enabledNumber;
+ --disabledNumber;
+
+ break;
+ case 'disable':
+ --enabledNumber;
+ ++disabledNumber;
+ break;
+ }
+
+ enabledNumber = Math.max( 0, enabledNumber );
+ disabledNumber = Math.max( 0, disabledNumber );
+
+ enabled.text( '(' + enabledNumber + ')' );
+ disabled.text( '(' + disabledNumber + ')' );
+ }
+
+ if ( 'enable' === action ) {
+ anchor.removeClass( 'enable' ).addClass( 'disable' );
+ label.text( wp_autoupdates.disable );
+ parent.find( '.auto-update-time').removeClass( 'hidden' );
+ } else {
+ anchor.removeClass( 'disable' ).addClass( 'enable' );
+ label.text( wp_autoupdates.enable );
+ parent.find( '.auto-update-time').addClass( 'hidden' );
+ }
+
+ wp.a11y.speak( 'enable' === action ? wp_autoupdates.enabled : wp_autoupdates.disabled, 'polite' );
+ } else {
+ parent.find( '.auto-updates-error' ).removeClass( 'hidden' ).addClass( 'notice error' ).find( 'p' ).text( response.data.error );
+ wp.a11y.speak( response.data.error, 'polite' );
+ }
+ } )
+ .fail( function( response ) {
+ parent.find( '.auto-updates-error' ).removeClass( 'hidden' ).addClass( 'notice error' ).find( 'p' ).text( wp_autoupdates.auto_update_error );
+ wp.a11y.speak( wp_autoupdates.auto_update_error, 'polite' );
+ } )
+ .always( function() {
+ anchor.find( '.dashicons-update' ).addClass( 'hidden' );
+ } );
+ } );
+} )( jQuery );
From 6ed296dcafee91a754dfc515547a43e6e625a790 Mon Sep 17 00:00:00 2001
From: Paul Biron
Date: Tue, 5 May 2020 17:11:26 -0600
Subject: [PATCH 2/4] Replace use of wpAjax.unserialize() and some CSS classes
used in the JS with @data attributes.
Also corrects a few more coding standards issues.
---
functions.php | 27 +++++++++----------
js/wp-autoupdates.js | 62 ++++++++++++++++++++++----------------------
2 files changed, 45 insertions(+), 44 deletions(-)
diff --git a/functions.php b/functions.php
index 2623c27..f794d2f 100755
--- a/functions.php
+++ b/functions.php
@@ -77,12 +77,12 @@ function wp_autoupdates_enqueues( $hook ) {
<# if ( data.actions.autoupdate ) { #>
<# if ( data.autoupdate ) { #>
-
+
{$text_disable}
<# } else { #>
-
+
{$text_enable}
@@ -163,15 +163,13 @@ function wp_autoupdates_prepare_themes_for_js( $prepared_themes ) {
}
$wp_auto_update_themes = get_option( 'wp_auto_update_themes', array() );
- foreach( $prepared_themes as $theme ) {
+ foreach( $prepared_themes as &$theme ) {
// Set extra data for use in the template.
$slug = $theme['id'];
$encoded_slug = urlencode( $slug );
$theme['autoupdate'] = in_array( $slug, $wp_auto_update_themes, true );
- $theme['actions']['autoupdate'] = current_user_can( 'update_themes' ) ? wp_nonce_url( admin_url( 'themes.php?action=autoupdate&theme=' . $encoded_slug ), 'autoupdate-theme_' . $slug ) : null;
-
- $prepared_themes[ $slug ] = $theme;
+ $theme['actions']['autoupdate'] = current_user_can( 'update_themes' ) ? wp_nonce_url( admin_url( 'themes.php?action=autoupdate&theme=' . $encoded_slug ), 'updates' ) : null;
}
return $prepared_themes;
@@ -317,8 +315,9 @@ function wp_autoupdates_add_plugins_autoupdates_column_content( $column_name, $p
}
printf(
- '%s',
- wp_nonce_url( 'plugins.php?action=autoupdate&plugin=' . urlencode( $plugin_file ) . '&paged=' . $page . '&plugin_status=' . $plugin_status, 'autoupdate-plugin_' . $plugin_file ),
+ '%s',
+ wp_nonce_url( 'plugins.php?action=autoupdate&plugin=' . urlencode( $plugin_file ) . '&paged=' . $page . '&plugin_status=' . $plugin_status, 'updates' ),
+ esc_attr( $plugin_file ),
$action,
$aria_label,
$text
@@ -375,7 +374,8 @@ function wp_autoupdates_plugins_enabler() {
exit;
}
- check_admin_referer( 'autoupdate-plugin_' . $plugin );
+ check_admin_referer( 'updates' );
+
$wp_auto_update_plugins = get_site_option( 'wp_auto_update_plugins', array() );
if ( in_array( $plugin, $wp_auto_update_plugins, true ) ) {
@@ -414,7 +414,7 @@ function wp_autoupdates_themes_enabler() {
exit;
}
- check_admin_referer( 'autoupdate-theme_' . $theme );
+ check_admin_referer( 'updates' );
$wp_auto_update_themes = get_site_option( 'wp_auto_update_themes', array() );
if ( in_array( $theme, $wp_auto_update_themes, true ) ) {
@@ -1252,8 +1252,9 @@ function wp_autoupdates_add_themes_autoupdates_column_content( $column_name, $st
}
printf(
- '%s',
- wp_nonce_url( 'themes.php?action=autoupdate&theme=' . urlencode( $stylesheet ) . '&paged=' . $page . '&plugin_status=' . $thene_status , 'autoupdate-theme_' . $stylesheet ),
+ '%s',
+ wp_nonce_url( 'themes.php?action=autoupdate&theme=' . urlencode( $stylesheet ) . '&paged=' . $page . '&plugin_status=' . $thene_status , 'updates' ),
+ esc_attr( $stylesheet ),
$action,
$aria_label,
$text
@@ -1378,7 +1379,7 @@ function wp_autoupdates_toggle_auto_updates() {
wp_send_json_error( array( 'error' => __( 'Invalid data. Unknown state.', 'wp-autoupdates' ) ) );
}
- check_ajax_referer( "autoupdate-{$type}_{$asset}" );
+ check_ajax_referer( 'updates' );
switch ( $type ) {
case 'plugin':
diff --git a/js/wp-autoupdates.js b/js/wp-autoupdates.js
index b76159a..e814c91 100644
--- a/js/wp-autoupdates.js
+++ b/js/wp-autoupdates.js
@@ -1,46 +1,46 @@
-/* global wp_autoupdates, pagenow */
-( function( $ ) {
+/* global wp_autoupdates */
+( function( $, settings, pagenow ) {
'use strict';
$( '.autoupdates_column, .theme-overlay' ).on( 'click', 'a.auto-update', function( event ) {
- // TODO: Drop use of unserialize, perhaps switch to data-* attr.
var data,
- anchor = $( this ),
- type = anchor.hasClass( 'plugin' ) ? 'plugin' : 'theme',
- action = anchor.hasClass( 'enable' ) ? 'enable' : 'disable',
- href = wpAjax.unserialize( anchor.attr( 'href' ) ),
- label = anchor.find( '.label' ),
- parent = anchor.parents( 'themes' !== pagenow ? '.autoupdates_column' : '.theme-autoupdate' );
+ $anchor = $( this ),
+ type = $anchor.data( 'type' ),
+ action = $anchor.data( 'action' ),
+ $label = $anchor.find( '.label' ),
+ $parent = $anchor.parents( 'themes' !== pagenow ? '.autoupdates_column' : '.theme-autoupdate' );
event.preventDefault();
// Clear any previous errors.
- parent.find( '.auto-updates-error' ).removeClass( 'notice error' ).addClass( 'hidden' );
+ $parent.find( '.auto-updates-error' ).removeClass( 'notice error' ).addClass( 'hidden' );
// Show loading status.
- label.text( 'enable' === action ? wp_autoupdates.enabling : wp_autoupdates.disabling );
- anchor.find( '.dashicons-update' ).removeClass( 'hidden' );
+ $label.text( 'enable' === action ? wp_autoupdates.enabling : wp_autoupdates.disabling );
+ $anchor.find( '.dashicons-update' ).removeClass( 'hidden' );
data = {
action: 'toggle_auto_updates',
- _ajax_nonce: href._wpnonce,
- state: action,
+ _ajax_nonce: settings.ajax_nonce,
+ state: action,
type: type,
- asset: 'plugin' === type ? href.plugin : href.theme,
+ asset: $anchor.data( 'asset' ),
};
$.post( ajaxurl, data )
.done( function( response ) {
+ var $enabled, $disabled, enabledNumber, disabledNumber;
+
if ( response.success ) {
// Update the counts in the enabled/disabled views if on on
// screen with a list table.
// TODO: If either count started out 0 the appropriate span won't
// be there and hence won't be updated.
if ( 'themes' !== pagenow ) {
- var enabled = $( '.autoupdate_enabled span' ),
- disabled = $( '.autoupdate_disabled span' ),
- enabledNumber = parseInt( enabled.text().replace( /[^\d]+/g, '' ) ) || 0,
- disabledNumber = parseInt( disabled.text().replace( /[^\d]+/g, '' ) ) || 0;
+ $enabled = $( '.autoupdate_enabled span' );
+ $disabled = $( '.autoupdate_disabled span' );
+ enabledNumber = parseInt( $enabled.text().replace( /[^\d]+/g, '' ) ) || 0;
+ disabledNumber = parseInt( $disabled.text().replace( /[^\d]+/g, '' ) ) || 0;
switch ( action ) {
case 'enable':
@@ -57,32 +57,32 @@
enabledNumber = Math.max( 0, enabledNumber );
disabledNumber = Math.max( 0, disabledNumber );
- enabled.text( '(' + enabledNumber + ')' );
- disabled.text( '(' + disabledNumber + ')' );
+ $enabled.text( '(' + enabledNumber + ')' );
+ $disabled.text( '(' + disabledNumber + ')' );
}
if ( 'enable' === action ) {
- anchor.removeClass( 'enable' ).addClass( 'disable' );
- label.text( wp_autoupdates.disable );
- parent.find( '.auto-update-time').removeClass( 'hidden' );
+ $anchor.data( 'action', 'disable' );
+ $label.text( wp_autoupdates.disable );
+ $parent.find( '.auto-update-time').removeClass( 'hidden' );
} else {
- anchor.removeClass( 'disable' ).addClass( 'enable' );
- label.text( wp_autoupdates.enable );
- parent.find( '.auto-update-time').addClass( 'hidden' );
+ $anchor.data( 'action', 'enabled' );
+ $label.text( wp_autoupdates.enable );
+ $parent.find( '.auto-update-time').addClass( 'hidden' );
}
wp.a11y.speak( 'enable' === action ? wp_autoupdates.enabled : wp_autoupdates.disabled, 'polite' );
} else {
- parent.find( '.auto-updates-error' ).removeClass( 'hidden' ).addClass( 'notice error' ).find( 'p' ).text( response.data.error );
+ $parent.find( '.auto-updates-error' ).removeClass( 'hidden' ).addClass( 'notice error' ).find( 'p' ).text( response.data.error );
wp.a11y.speak( response.data.error, 'polite' );
}
} )
.fail( function( response ) {
- parent.find( '.auto-updates-error' ).removeClass( 'hidden' ).addClass( 'notice error' ).find( 'p' ).text( wp_autoupdates.auto_update_error );
+ $parent.find( '.auto-updates-error' ).removeClass( 'hidden' ).addClass( 'notice error' ).find( 'p' ).text( wp_autoupdates.auto_update_error );
wp.a11y.speak( wp_autoupdates.auto_update_error, 'polite' );
} )
.always( function() {
- anchor.find( '.dashicons-update' ).addClass( 'hidden' );
+ $anchor.find( '.dashicons-update' ).addClass( 'hidden' );
} );
} );
-} )( jQuery );
+} )( jQuery, window._wpUpdatesSettings, window.pagenow );
From 8b75528200f5e9c96e32ad4b700049890cbf5924 Mon Sep 17 00:00:00 2001
From: Paul Biron
Date: Tue, 5 May 2020 19:24:06 -0600
Subject: [PATCH 3/4] Use jQuery attr( 'data-xyz' ) to access the data
attributes instead of data(). Also moves the .update-link click handler to
the JS file instead loading that script inline.
---
functions.php | 26 ++------
js/wp-autoupdates.js | 150 +++++++++++++++++++++++--------------------
2 files changed, 88 insertions(+), 88 deletions(-)
diff --git a/functions.php b/functions.php
index f794d2f..389d1d9 100755
--- a/functions.php
+++ b/functions.php
@@ -49,40 +49,26 @@ function wp_autoupdates_enqueues( $hook ) {
wp_add_inline_script( 'jquery', $script );
}
- // When manually updating a plugin the 'time until next update' text needs to be hidden.
- // Doesn't need to be done on the update-core.php page since that page refreshes after an update.
- if ( 'plugins.php' === $hook ) {
- $script = 'jQuery( document ).ready(function() {
- jQuery( ".update-link" ).click( function() {
- var plugin = jQuery( this ).closest("tr").data("plugin");
- var plugin_row = jQuery( "tr.update[data-plugin=\'" + plugin + "\']" );
- var plugin_auto_update_time_text = plugin_row.find("span.plugin-autoupdate-time");
- plugin_auto_update_time_text.remove();
- });
- });';
- wp_add_inline_script( 'jquery', $script );
- }
-
if ( 'themes.php' === $hook ) {
if ( wp_autoupdates_is_themes_auto_update_enabled() ) {
/* translators: %s: Theme name. */
$aria_label_enable = sprintf( _x( 'Enable automatic update for %s', 'theme name' ), '{{ data.name }}' );
/* translators: %s: Theme name. */
$aria_label_disable = sprintf( _x( 'Disable automatic update for %s', 'theme name' ), '{{ data.name }}' );
- $text_enable = __( 'Enable automatic updates', 'wp-autoupdates' );
- $text_disable = __( 'Disable automatic updates', 'wp-autoupdates' );
+ $text_enable = __( 'Enable auto-updates', 'wp-autoupdates' );
+ $text_disable = __( 'Disable auto-updates', 'wp-autoupdates' );
$update_message = wp_autoupdates_get_update_message();
$autoupdate_text = <<
<# if ( data.autoupdate ) { #>
-
+
{$text_disable}
<# } else { #>
-
+
{$text_enable}
@@ -315,7 +301,7 @@ function wp_autoupdates_add_plugins_autoupdates_column_content( $column_name, $p
}
printf(
- '%s',
+ '%s',
wp_nonce_url( 'plugins.php?action=autoupdate&plugin=' . urlencode( $plugin_file ) . '&paged=' . $page . '&plugin_status=' . $plugin_status, 'updates' ),
esc_attr( $plugin_file ),
$action,
@@ -1252,7 +1238,7 @@ function wp_autoupdates_add_themes_autoupdates_column_content( $column_name, $st
}
printf(
- '%s',
+ '%s',
wp_nonce_url( 'themes.php?action=autoupdate&theme=' . urlencode( $stylesheet ) . '&paged=' . $page . '&plugin_status=' . $thene_status , 'updates' ),
esc_attr( $stylesheet ),
$action,
diff --git a/js/wp-autoupdates.js b/js/wp-autoupdates.js
index e814c91..65f5aa2 100644
--- a/js/wp-autoupdates.js
+++ b/js/wp-autoupdates.js
@@ -2,87 +2,101 @@
( function( $, settings, pagenow ) {
'use strict';
- $( '.autoupdates_column, .theme-overlay' ).on( 'click', 'a.auto-update', function( event ) {
- var data,
- $anchor = $( this ),
- type = $anchor.data( 'type' ),
- action = $anchor.data( 'action' ),
- $label = $anchor.find( '.label' ),
- $parent = $anchor.parents( 'themes' !== pagenow ? '.autoupdates_column' : '.theme-autoupdate' );
+ $( document ).ready( function() {
+ $( '.autoupdates_column, .theme-overlay' ).on( 'click', 'a.auto-update', function( event ) {
+ var data,
+ $anchor = $( this ),
+ type = $anchor.attr( 'data-wp-type' ),
+ action = $anchor.attr( 'data-wp-action' ),
+ $label = $anchor.find( '.label' ),
+ $parent = $anchor.parents( 'themes' !== pagenow ? '.autoupdates_column' : '.theme-autoupdate' );
- event.preventDefault();
+ event.preventDefault();
- // Clear any previous errors.
- $parent.find( '.auto-updates-error' ).removeClass( 'notice error' ).addClass( 'hidden' );
+ // Clear any previous errors.
+ $parent.find( '.auto-updates-error' ).removeClass( 'notice error' ).addClass( 'hidden' );
- // Show loading status.
- $label.text( 'enable' === action ? wp_autoupdates.enabling : wp_autoupdates.disabling );
- $anchor.find( '.dashicons-update' ).removeClass( 'hidden' );
+ // Show loading status.
+ $label.text( 'enable' === action ? wp_autoupdates.enabling : wp_autoupdates.disabling );
+ $anchor.find( '.dashicons-update' ).removeClass( 'hidden' );
- data = {
- action: 'toggle_auto_updates',
- _ajax_nonce: settings.ajax_nonce,
- state: action,
- type: type,
- asset: $anchor.data( 'asset' ),
- };
+ data = {
+ action: 'toggle_auto_updates',
+ _ajax_nonce: settings.ajax_nonce,
+ state: action,
+ type: type,
+ asset: $anchor.attr( 'data-wp-asset' ),
+ };
- $.post( ajaxurl, data )
- .done( function( response ) {
- var $enabled, $disabled, enabledNumber, disabledNumber;
+ $.post( ajaxurl, data )
+ .done( function( response ) {
+ var $enabled, $disabled, enabledNumber, disabledNumber;
- if ( response.success ) {
- // Update the counts in the enabled/disabled views if on on
- // screen with a list table.
- // TODO: If either count started out 0 the appropriate span won't
- // be there and hence won't be updated.
- if ( 'themes' !== pagenow ) {
- $enabled = $( '.autoupdate_enabled span' );
- $disabled = $( '.autoupdate_disabled span' );
- enabledNumber = parseInt( $enabled.text().replace( /[^\d]+/g, '' ) ) || 0;
- disabledNumber = parseInt( $disabled.text().replace( /[^\d]+/g, '' ) ) || 0;
+ if ( response.success ) {
+ // Update the counts in the enabled/disabled views if on on
+ // screen with a list table.
+ // TODO: If either count started out 0 the appropriate span won't
+ // be there and hence won't be updated.
+ if ( 'themes' !== pagenow ) {
+ $enabled = $( '.autoupdate_enabled span' );
+ $disabled = $( '.autoupdate_disabled span' );
+ enabledNumber = parseInt( $enabled.text().replace( /[^\d]+/g, '' ) ) || 0;
+ disabledNumber = parseInt( $disabled.text().replace( /[^\d]+/g, '' ) ) || 0;
- switch ( action ) {
- case 'enable':
- ++enabledNumber;
- --disabledNumber;
+ switch ( action ) {
+ case 'enable':
+ ++enabledNumber;
+ --disabledNumber;
- break;
- case 'disable':
- --enabledNumber;
- ++disabledNumber;
- break;
- }
+ break;
+ case 'disable':
+ --enabledNumber;
+ ++disabledNumber;
+ break;
+ }
- enabledNumber = Math.max( 0, enabledNumber );
- disabledNumber = Math.max( 0, disabledNumber );
+ enabledNumber = Math.max( 0, enabledNumber );
+ disabledNumber = Math.max( 0, disabledNumber );
- $enabled.text( '(' + enabledNumber + ')' );
- $disabled.text( '(' + disabledNumber + ')' );
- }
+ $enabled.text( '(' + enabledNumber + ')' );
+ $disabled.text( '(' + disabledNumber + ')' );
+ }
- if ( 'enable' === action ) {
- $anchor.data( 'action', 'disable' );
- $label.text( wp_autoupdates.disable );
- $parent.find( '.auto-update-time').removeClass( 'hidden' );
+ if ( 'enable' === action ) {
+ $anchor.attr( 'data-wp-action', 'disable' );
+ $label.text( wp_autoupdates.disable );
+ $parent.find( '.auto-update-time').removeClass( 'hidden' );
+ } else {
+ $anchor.attr( 'data-wp-action', 'enable' );
+ $label.text( wp_autoupdates.enable );
+ $parent.find( '.auto-update-time').addClass( 'hidden' );
+ }
+
+ wp.a11y.speak( 'enable' === action ? wp_autoupdates.enabled : wp_autoupdates.disabled, 'polite' );
} else {
- $anchor.data( 'action', 'enabled' );
- $label.text( wp_autoupdates.enable );
- $parent.find( '.auto-update-time').addClass( 'hidden' );
+ $parent.find( '.auto-updates-error' ).removeClass( 'hidden' ).addClass( 'notice error' ).find( 'p' ).text( response.data.error );
+ wp.a11y.speak( response.data.error, 'polite' );
}
+ } )
+ .fail( function( response ) {
+ $parent.find( '.auto-updates-error' ).removeClass( 'hidden' ).addClass( 'notice error' ).find( 'p' ).text( wp_autoupdates.auto_update_error );
+ wp.a11y.speak( wp_autoupdates.auto_update_error, 'polite' );
+ } )
+ .always( function() {
+ $anchor.find( '.dashicons-update' ).addClass( 'hidden' );
+ } );
+ } );
+
+ /**
+ * When manually updating a plugin the 'time until next update' text needs to be hidden.
+ *
+ * TODO: fire this off an event that wp-admin/js/updates.js triggers when the update is complete.
+ */
+ $( '.update-link' ).click( function() {
+ var plugin = $( this ).closest( 'tr' ).attr( 'data-plugin' ),
+ $plugin_row = $( 'tr.update[data-plugin="' + plugin + '"]' );
- wp.a11y.speak( 'enable' === action ? wp_autoupdates.enabled : wp_autoupdates.disabled, 'polite' );
- } else {
- $parent.find( '.auto-updates-error' ).removeClass( 'hidden' ).addClass( 'notice error' ).find( 'p' ).text( response.data.error );
- wp.a11y.speak( response.data.error, 'polite' );
- }
- } )
- .fail( function( response ) {
- $parent.find( '.auto-updates-error' ).removeClass( 'hidden' ).addClass( 'notice error' ).find( 'p' ).text( wp_autoupdates.auto_update_error );
- wp.a11y.speak( wp_autoupdates.auto_update_error, 'polite' );
- } )
- .always( function() {
- $anchor.find( '.dashicons-update' ).addClass( 'hidden' );
- } );
+ $plugin_row.find( '.auto-update-time' ).empty();
+ } );
} );
} )( jQuery, window._wpUpdatesSettings, window.pagenow );
From 82e180037d19394b048464ddbde09eba6c576b95 Mon Sep 17 00:00:00 2001
From: Paul Biron
Date: Tue, 5 May 2020 19:33:02 -0600
Subject: [PATCH 4/4] Shorten the .update-link click handler and improve it's
inline comments.
---
js/wp-autoupdates.js | 9 ++++-----
1 file changed, 4 insertions(+), 5 deletions(-)
diff --git a/js/wp-autoupdates.js b/js/wp-autoupdates.js
index 65f5aa2..f57ace1 100644
--- a/js/wp-autoupdates.js
+++ b/js/wp-autoupdates.js
@@ -88,15 +88,14 @@
} );
/**
- * When manually updating a plugin the 'time until next update' text needs to be hidden.
+ * When manually updating a plugin/theme the 'time until next update' text needs to be cleared.
*
- * TODO: fire this off an event that wp-admin/js/updates.js triggers when the update is complete.
+ * TODO: fire this off an event that wp-admin/js/updates.js triggers when the update succeeds.
*/
$( '.update-link' ).click( function() {
- var plugin = $( this ).closest( 'tr' ).attr( 'data-plugin' ),
- $plugin_row = $( 'tr.update[data-plugin="' + plugin + '"]' );
+ var plugin = $( this ).closest( 'tr' ).attr( 'data-plugin' );
- $plugin_row.find( '.auto-update-time' ).empty();
+ $( 'tr.update[data-plugin="' + plugin + '"]' ).find( '.auto-update-time' ).empty();
} );
} );
} )( jQuery, window._wpUpdatesSettings, window.pagenow );