diff --git a/functions.php b/functions.php index 056daca..e187142 100755 --- a/functions.php +++ b/functions.php @@ -59,12 +59,12 @@ function wp_autoupdates_enqueues( $hook ) { <# if ( data.actions.autoupdate ) { #>

<# if ( data.autoupdate ) { #> - + {$text_disable} <# } else { #> - + {$text_enable} @@ -156,7 +156,7 @@ function wp_autoupdates_prepare_themes_for_js( $prepared_themes ) { return $prepared_themes; } -add_action( 'wp_prepare_themes_for_js', 'wp_autoupdates_prepare_themes_for_js' ); +add_filter( 'wp_prepare_themes_for_js', 'wp_autoupdates_prepare_themes_for_js' ); /** @@ -263,8 +263,7 @@ function wp_autoupdates_add_plugins_autoupdates_column_content( $column_name, $p return; } - $available_updates = get_site_transient( 'update_plugins' ); - $page = ! empty( $_GET['paged'] ) ? wp_unslash( esc_html( $_GET['paged'] ) ) : ''; + $page = ! empty( $_GET['paged'] ) ? absint( $_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() ); @@ -279,13 +278,13 @@ 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, 'updates' ), - esc_attr( $plugin_file ), + '%s', + wp_nonce_url( 'plugins.php?action=' . $action . '-auto-update&plugin=' . urlencode( $plugin_file ) . '&paged=' . $page . '&plugin_status=' . $plugin_status, 'updates' ), $action, $text ); + $available_updates = get_site_transient( 'update_plugins' ); if ( isset( $available_updates->response[ $plugin_file ] ) ) { printf( '

%s
', @@ -305,53 +304,66 @@ function wp_autoupdates_add_plugins_autoupdates_column_content( $column_name, $p * @return string[] */ function wp_autoupdates_plugins_bulk_actions( $actions ) { - $actions['enable-autoupdate-selected'] = __( 'Enable auto-updates', 'wp-autoupdates' ); - $actions['disable-autoupdate-selected'] = __( 'Disable auto-updates', 'wp-autoupdates' ); + $plugin_status = ! empty( $_GET['plugin_status'] ) ? $_GET['plugin_status'] : ''; + + if ( 'autoupdate_enabled' !== $plugin_status ) { + $actions['enable-autoupdate-selected'] = __( 'Enable Auto-updates' ); + } + if ( 'autoupdate_disabled' !== $plugin_status ) { + $actions['disable-autoupdate-selected'] = __( 'Disable Auto-updates' ); + } + return $actions; } -add_action( 'bulk_actions-plugins', 'wp_autoupdates_plugins_bulk_actions' ); -add_action( 'bulk_actions-plugins-network', 'wp_autoupdates_plugins_bulk_actions' ); +add_filter( 'bulk_actions-plugins', 'wp_autoupdates_plugins_bulk_actions' ); +add_filter( 'bulk_actions-plugins-network', 'wp_autoupdates_plugins_bulk_actions' ); /** * Handles auto-updates enabling for plugins. */ function wp_autoupdates_plugins_enabler() { - $action = isset( $_GET['action'] ) && ! empty( esc_html( $_GET['action'] ) ) ? wp_unslash( esc_html( $_GET['action'] ) ) : ''; - if ( 'autoupdate' === $action ) { - 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' ) ); - } - - if ( is_multisite() && ! is_network_admin() ) { - wp_die( __( 'Please connect to your network admin to manage plugins automatic updates.', 'wp-autoupdates' ) ); - } + if ( ! isset( $_GET['action'] ) ) { + return; + } + if ( ! ( 'enable-auto-update' === $_GET['action'] || 'disable-auto-update' === $_GET['action'] ) ) { + return; + } - $plugin = ! empty( esc_html( $_GET['plugin'] ) ) ? wp_unslash( esc_html( $_GET['plugin'] ) ) : ''; - $page = isset( $_GET['paged'] ) && ! empty( esc_html( $_GET['paged'] ) ) ? wp_unslash( esc_html( $_GET['paged'] ) ) : ''; - $status = isset( $_GET['plugin_status'] ) && ! empty( esc_html( $_GET['plugin_status'] ) ) ? wp_unslash( esc_html( $_GET['plugin_status'] ) ) : ''; - $s = isset( $_GET['s'] ) && ! empty( esc_html( $_GET['s'] ) ) ? wp_unslash( esc_html( $_GET['s'] ) ) : ''; + check_admin_referer( 'updates' ); - if ( empty( $plugin ) ) { - wp_redirect( self_admin_url( "plugins.php?plugin_status=$status&paged=$page&s=$s" ) ); - exit; - } + 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' ) ); + } - check_admin_referer( 'updates' ); + if ( is_multisite() && ! is_network_admin() ) { + wp_die( __( 'Please connect to your network admin to manage plugins automatic updates.', 'wp-autoupdates' ) ); + } - $wp_auto_update_plugins = get_site_option( 'wp_auto_update_plugins', array() ); + $plugin = ! empty( esc_html( $_GET['plugin'] ) ) ? wp_unslash( esc_html( $_GET['plugin'] ) ) : ''; + $page = ! empty( $_GET['paged'] ) ? absint( $_GET['paged'] ) : ''; + $status = isset( $_GET['plugin_status'] ) && ! empty( esc_html( $_GET['plugin_status'] ) ) ? wp_unslash( esc_html( $_GET['plugin_status'] ) ) : ''; + $s = isset( $_GET['s'] ) && ! empty( esc_html( $_GET['s'] ) ) ? wp_unslash( esc_html( $_GET['s'] ) ) : ''; - if ( in_array( $plugin, $wp_auto_update_plugins, true ) ) { - $wp_auto_update_plugins = array_diff( $wp_auto_update_plugins, array( $plugin ) ); - $action_type = 'disable-autoupdate=true'; - } else { - array_push( $wp_auto_update_plugins, $plugin ); - $action_type = 'enable-autoupdate=true'; - } - update_site_option( 'wp_auto_update_plugins', $wp_auto_update_plugins ); - wp_redirect( self_admin_url( "plugins.php?$action_type&plugin_status=$status&paged=$page&s=$s" ) ); + if ( empty( $plugin ) ) { + wp_redirect( self_admin_url( "plugins.php?plugin_status=$status&paged=$page&s=$s" ) ); exit; } + + $wp_auto_update_plugins = get_site_option( 'wp_auto_update_plugins', array() ); + + if ( 'disable-auto-update' === $_GET['action'] ) { + $wp_auto_update_plugins = array_diff( $wp_auto_update_plugins, array( $plugin ) ); + $action_type = 'disable-auto-update=true'; + } else { + $wp_auto_update_plugins[] = $plugin; + $wp_auto_update_plugins = array_unique( $wp_auto_update_plugins ); + $action_type = 'enable-auto-update=true'; + } + + update_site_option( 'wp_auto_update_plugins', $wp_auto_update_plugins ); + wp_redirect( self_admin_url( "plugins.php?$action_type&plugin_status=$status&paged=$page&s=$s" ) ); + exit; } @@ -359,46 +371,49 @@ function wp_autoupdates_plugins_enabler() { * Handles auto-updates enabling for themes. */ function wp_autoupdates_themes_enabler() { - $pagenow = $GLOBALS['pagenow']; + if ( ! isset( $_GET['action'] ) ) { + return; + } + if ( ! ( 'enable-auto-update' === $_GET['action'] || 'disable-auto-update' === $_GET['action'] ) ) { + return; + } - $action = isset( $_GET['action'] ) && ! empty( esc_html( $_GET['action'] ) ) ? wp_unslash( esc_html( $_GET['action'] ) ) : ''; - if ( 'autoupdate' === $action ) { - if ( ! current_user_can( 'update_themes' ) || ! wp_autoupdates_is_themes_auto_update_enabled() ) { - wp_die( __( 'Sorry, you are not allowed to enable themes automatic updates.', 'wp-autoupdates' ) ); - } + check_admin_referer( 'updates' ); - if ( is_multisite() && ! is_network_admin() ) { - wp_die( __( 'Please connect to your network admin to manage themes automatic updates.', 'wp-autoupdates' ) ); - } + if ( ! current_user_can( 'update_themes' ) || ! wp_autoupdates_is_themes_auto_update_enabled() ) { + wp_die( __( 'Sorry, you are not allowed to enable themes automatic updates.', 'wp-autoupdates' ) ); + } - $theme = ! empty( esc_html( $_GET['theme'] ) ) ? wp_unslash( esc_html( $_GET['theme'] ) ) : ''; - if ( empty( $theme ) ) { - wp_redirect( self_admin_url( 'themes.php' ) ); - exit; - } + if ( is_multisite() && ! is_network_admin() ) { + wp_die( __( 'Please connect to your network admin to manage themes automatic updates.', 'wp-autoupdates' ) ); + } - check_admin_referer( 'updates' ); - $wp_auto_update_themes = get_site_option( 'wp_auto_update_themes', array() ); + $theme = ! empty( esc_html( $_GET['theme'] ) ) ? wp_unslash( esc_html( $_GET['theme'] ) ) : ''; + if ( empty( $theme ) ) { + wp_redirect( self_admin_url( 'themes.php' ) ); + exit; + } - if ( in_array( $theme, $wp_auto_update_themes, true ) ) { - $wp_auto_update_themes = array_diff( $wp_auto_update_themes, array( $theme ) ); - $action_type = 'disable-autoupdate=true'; - } else { - array_push( $wp_auto_update_themes, $theme ); - $action_type = 'enable-autoupdate=true'; - } + $wp_auto_update_themes = get_site_option( 'wp_auto_update_themes', array() ); - update_site_option( 'wp_auto_update_themes', $wp_auto_update_themes ); + if ( 'disable-auto-update' === $_GET['action'] ) { + $wp_auto_update_themes = array_diff( $wp_auto_update_themes, array( $theme ) ); + $action_type = 'disable-auto-update=true'; + } else { + $wp_auto_update_themes[] = $theme; + $wp_auto_update_themes = array_unique( $wp_auto_update_themes ); + $action_type = 'enable-auto-update=true'; + } - $theme_status = ''; + update_site_option( 'wp_auto_update_themes', $wp_auto_update_themes ); - 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; + $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; } @@ -427,6 +442,8 @@ function wp_autoupdates_enabler() { */ function wp_autoupdates_plugins_bulk_actions_handle( $redirect_to, $doaction, $items ) { if ( 'enable-autoupdate-selected' === $doaction ) { + check_admin_referer( 'bulk-plugins' ); + 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' ) ); } @@ -435,10 +452,8 @@ function wp_autoupdates_plugins_bulk_actions_handle( $redirect_to, $doaction, $i wp_die( __( 'Please connect to your network admin to manage plugins automatic updates.', 'wp-autoupdates' ) ); } - check_admin_referer( 'bulk-plugins' ); - $plugins = ! empty( $items ) ? (array) wp_unslash( $items ) : array(); - $page = isset( $_GET['paged'] ) && ! empty( esc_html( $_GET['paged'] ) ) ? wp_unslash( esc_html( $_GET['paged'] ) ) : ''; + $page = ! empty( $_GET['paged'] ) ? absint( $_GET['paged'] ) : ''; $status = isset( $_GET['plugin_status'] ) && ! empty( esc_html( $_GET['plugin_status'] ) ) ? wp_unslash( esc_html( $_GET['plugin_status'] ) ) : ''; $s = isset( $_GET['s'] ) && ! empty( esc_html( $_GET['s'] ) ) ? wp_unslash( esc_html( $_GET['s'] ) ) : ''; @@ -447,16 +462,24 @@ function wp_autoupdates_plugins_bulk_actions_handle( $redirect_to, $doaction, $i return $redirect_to; } - $previous_autoupdated_plugins = get_site_option( 'wp_auto_update_plugins', array() ); - - $new_autoupdated_plugins = array_merge( $previous_autoupdated_plugins, $plugins ); + $auto_update_plugins = (array) get_site_option( 'wp_auto_update_plugins', array() ); + $new_autoupdated_plugins = array_merge( $auto_update_plugins, $plugins ); $new_autoupdated_plugins = array_unique( $new_autoupdated_plugins ); + // return early if all selected plugins already have auto-updates enabled. + // must use non-strict comparison, so that array order is not treated as significant. + if ( $new_autoupdated_plugins == $auto_update_plugins ) { + $redirect_to = self_admin_url( "plugins.php?plugin_status=$status&paged=$page&s=$s" ); + return $redirect_to; + } + update_site_option( 'wp_auto_update_plugins', $new_autoupdated_plugins ); - $redirect_to = self_admin_url( "plugins.php?enable-autoupdate=true&plugin_status=$status&paged=$page&s=$s" ); + $redirect_to = self_admin_url( "plugins.php?enable-auto-update=true&plugin_status=$status&paged=$page&s=$s" ); return $redirect_to; } elseif ( 'disable-autoupdate-selected' === $doaction ) { + check_admin_referer( 'bulk-plugins' ); + 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' ) ); } @@ -465,10 +488,8 @@ function wp_autoupdates_plugins_bulk_actions_handle( $redirect_to, $doaction, $i wp_die( __( 'Please connect to your network admin to manage plugins automatic updates.', 'wp-autoupdates' ) ); } - check_admin_referer( 'bulk-plugins' ); - $plugins = ! empty( $items ) ? (array) wp_unslash( $items ) : array(); - $page = isset( $_GET['paged'] ) && ! empty( esc_html( $_GET['paged'] ) ) ? wp_unslash( esc_html( $_GET['paged'] ) ) : ''; + $page = ! empty( $_GET['paged'] ) ? absint( $_GET['paged'] ) : ''; $status = isset( $_GET['plugin_status'] ) && ! empty( esc_html( $_GET['plugin_status'] ) ) ? wp_unslash( esc_html( $_GET['plugin_status'] ) ) : ''; $s = isset( $_GET['s'] ) && ! empty( esc_html( $_GET['s'] ) ) ? wp_unslash( esc_html( $_GET['s'] ) ) : ''; @@ -477,20 +498,26 @@ function wp_autoupdates_plugins_bulk_actions_handle( $redirect_to, $doaction, $i return $redirect_to; } - $previous_autoupdated_plugins = get_site_option( 'wp_auto_update_plugins', array() ); + $auto_update_plugins = (array) get_site_option( 'wp_auto_update_plugins', array() ); + $new_autoupdated_plugins = array_diff( $auto_update_plugins, $plugins ); - $new_autoupdated_plugins = array_diff( $previous_autoupdated_plugins, $plugins ); - $new_autoupdated_plugins = array_unique( $new_autoupdated_plugins ); + // return early if all selected plugins already have auto-updates disabled. + // must use non-strict comparison, so that array order is not treated as significant. + if ( $new_autoupdated_plugins == $auto_update_plugins ) { + $redirect_to = self_admin_url( "plugins.php?plugin_status=$status&paged=$page&s=$s" ); + return $redirect_to; + } update_site_option( 'wp_auto_update_plugins', $new_autoupdated_plugins ); - $redirect_to = self_admin_url( "plugins.php?disable-autoupdate=true&plugin_status=$status&paged=$page&s=$s" ); + $redirect_to = self_admin_url( "plugins.php?disable-auto-update=true&plugin_status=$status&paged=$page&s=$s" ); return $redirect_to; } + return $redirect_to; } -add_action( 'handle_bulk_actions-plugins', 'wp_autoupdates_plugins_bulk_actions_handle', 10, 3 ); -add_action( 'handle_bulk_actions-plugins-network', 'wp_autoupdates_plugins_bulk_actions_handle', 10, 3 ); +add_filter( 'handle_bulk_actions-plugins', 'wp_autoupdates_plugins_bulk_actions_handle', 10, 3 ); +add_filter( 'handle_bulk_actions-plugins-network', 'wp_autoupdates_plugins_bulk_actions_handle', 10, 3 ); /** @@ -519,13 +546,13 @@ function wp_autoupdates_plugin_deleted( $plugin_file, $deleted ) { * Auto-update notices for plugins. */ function wp_autoupdates_plugins_notices() { - if ( isset( $_GET['enable-autoupdate'] ) ) { + if ( isset( $_GET['enable-auto-update'] ) ) { echo '

'; _e( 'Selected plugins will be auto-updated.', 'wp-autoupdates' ); echo '

'; } - if ( isset( $_GET['disable-autoupdate'] ) ) { + if ( isset( $_GET['disable-auto-update'] ) ) { echo '

'; _e( 'Selected plugins will no longer be auto-updated.', 'wp-autoupdates' ); echo '

'; @@ -537,13 +564,13 @@ function wp_autoupdates_plugins_notices() { * Auto-update notices for themes. */ function wp_autoupdates_themes_notices() { - if ( isset( $_GET['enable-autoupdate'] ) ) { + if ( isset( $_GET['enable-auto-update'] ) ) { echo '

'; _e( 'Selected themes will be auto-updated.', 'wp-autoupdates' ); echo '

'; } - if ( isset( $_GET['disable-autoupdate'] ) ) { + if ( isset( $_GET['disable-auto-update'] ) ) { echo '

'; _e( 'Selected themes will no longer be auto-updated.', 'wp-autoupdates' ); echo '

'; @@ -1165,9 +1192,8 @@ function wp_autoupdates_add_themes_autoupdates_column_content( $column_name, $st return; } - $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'] ) ) : ''; + $page = ! empty( $_GET['paged'] ) ? absint( $_GET['paged'] ) : ''; + $theme_status = ! empty( $_GET['theme_status'] ) ? wp_unslash( esc_html( $_GET['theme_status'] ) ) : ''; $wp_auto_update_themes = (array) get_site_option( 'wp_auto_update_themes', array() ); $auto_update_time_class = ' hidden'; @@ -1181,13 +1207,13 @@ 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, 'updates' ), - esc_attr( $stylesheet ), + '%s', + wp_nonce_url( 'themes.php?action=' . $action . '-auto-update&theme=' . urlencode( $stylesheet ) . '&paged=' . $page . '&theme_status=' . $theme_status, 'updates' ), $action, $text ); + $available_updates = get_site_transient( 'update_themes' ); if ( isset( $available_updates->response[ $stylesheet ] ) ) { printf( '
%s
', @@ -1211,7 +1237,7 @@ function wp_autoupdates_themes_bulk_actions( $actions ) { $actions['disable-autoupdate-selected'] = __( 'Disable auto-updates', 'wp-autoupdates' ); return $actions; } -add_action( 'bulk_actions-themes-network', 'wp_autoupdates_themes_bulk_actions' ); +add_filter( 'bulk_actions-themes-network', 'wp_autoupdates_themes_bulk_actions' ); /** @@ -1223,9 +1249,9 @@ function wp_autoupdates_themes_bulk_actions( $actions ) { * @return string */ function wp_autoupdates_themes_bulk_actions_handle( $redirect_to, $doaction, $items ) { - $pagenow = $GLOBALS['pagenow']; - if ( 'enable-autoupdate-selected' === $doaction ) { + check_admin_referer( 'bulk-themes' ); + if ( ! current_user_can( 'update_themes' ) || ! wp_autoupdates_is_themes_auto_update_enabled() ) { wp_die( __( 'Sorry, you are not allowed to enable themes automatic updates.', 'wp-autoupdates' ) ); } @@ -1234,10 +1260,8 @@ function wp_autoupdates_themes_bulk_actions_handle( $redirect_to, $doaction, $it wp_die( __( 'Please connect to your network admin to manage themes automatic updates.', 'wp-autoupdates' ) ); } - check_admin_referer( 'bulk-themes' ); - $themes = ! empty( $items ) ? (array) wp_unslash( $items ) : array(); - $page = isset( $_GET['paged'] ) && ! empty( esc_html( $_GET['paged'] ) ) ? wp_unslash( esc_html( $_GET['paged'] ) ) : ''; + $page = ! empty( $_GET['paged'] ) ? absint( $_GET['paged'] ) : ''; $status = isset( $_GET['theme_status'] ) && ! empty( esc_html( $_GET['theme_status'] ) ) ? wp_unslash( esc_html( $_GET['theme_status'] ) ) : ''; $s = isset( $_GET['s'] ) && ! empty( esc_html( $_GET['s'] ) ) ? wp_unslash( esc_html( $_GET['s'] ) ) : ''; @@ -1246,18 +1270,26 @@ function wp_autoupdates_themes_bulk_actions_handle( $redirect_to, $doaction, $it return $redirect_to; } - $previous_autoupdated_themes = get_site_option( 'wp_auto_update_themes', array() ); + $themes = isset( $_POST['checked'] ) ? (array) wp_unslash( $_POST['checked'] ) : array(); - $new_autoupdated_themes = array_merge( $previous_autoupdated_themes, $themes ); - $new_autoupdated_themes = array_unique( $new_autoupdated_themes ); + $auto_update_themes = (array) get_site_option( 'wp_auto_update_themes', array() ); + $new_auto_update_themes = array_merge( $auto_update_themes, $themes ); + $new_auto_update_themes = array_unique( $new_auto_update_themes ); - update_site_option( 'wp_auto_update_themes', $new_autoupdated_themes ); + // return early if all selected themes already have auto-updates enabled. + // must use non-strict comparison, so that array order is not treated as significant. + if ( $new_auto_update_themes == $auto_update_themes ) { + wp_redirect( self_admin_url( "themes.php?theme_status=$status&paged=$page&s=$s" ) ); + exit; + } + + update_site_option( 'wp_auto_update_themes', $new_auto_update_themes ); - $redirect_to = self_admin_url( "themes.php?enable-autoupdate=true&theme_status=$status&paged=$page&s=$s" ); + $redirect_to = self_admin_url( "themes.php?enable-auto-update=true&theme_status=$status&paged=$page&s=$s" ); return $redirect_to; - } + } elseif ( 'disable-autoupdate-selected' === $doaction ) { + check_admin_referer( 'bulk-themes' ); - if ( 'disable-autoupdate-selected' === $doaction ) { if ( ! current_user_can( 'update_themes' ) || ! wp_autoupdates_is_themes_auto_update_enabled() ) { wp_die( __( 'Sorry, you are not allowed to enable themes automatic updates.', 'wp-autoupdates' ) ); } @@ -1266,10 +1298,8 @@ function wp_autoupdates_themes_bulk_actions_handle( $redirect_to, $doaction, $it wp_die( __( 'Please connect to your network admin to manage themes automatic updates.', 'wp-autoupdates' ) ); } - check_admin_referer( 'bulk-themes' ); - $themes = ! empty( $items ) ? (array) wp_unslash( $items ) : array(); - $page = isset( $_GET['paged'] ) && ! empty( esc_html( $_GET['paged'] ) ) ? wp_unslash( esc_html( $_GET['paged'] ) ) : ''; + $page = ! empty( $_GET['paged'] ) ? absint( $_GET['paged'] ) : ''; $status = isset( $_GET['theme_status'] ) && ! empty( esc_html( $_GET['theme_status'] ) ) ? wp_unslash( esc_html( $_GET['theme_status'] ) ) : ''; $s = isset( $_GET['s'] ) && ! empty( esc_html( $_GET['s'] ) ) ? wp_unslash( esc_html( $_GET['s'] ) ) : ''; @@ -1278,46 +1308,65 @@ function wp_autoupdates_themes_bulk_actions_handle( $redirect_to, $doaction, $it return $redirect_to; } - $previous_autoupdated_themes = get_site_option( 'wp_auto_update_themes', array() ); + $auto_update_themes = (array) get_site_option( 'wp_auto_update_themes', array() ); + $new_auto_update_themes = array_diff( $auto_update_themes, $themes ); - $new_autoupdated_themes = array_diff( $previous_autoupdated_themes, $themes ); - $new_autoupdated_themes = array_unique( $new_autoupdated_themes ); + // return early if all selected themes already have auto-updates disabled. + // must use non-strict comparison, so that array order is not treated as significant. + if ( $new_auto_update_themes == $auto_update_themes ) { + wp_redirect( self_admin_url( "themes.php?plugin_status=$status&paged=$page&s=$s" ) ); + exit; + } - update_site_option( 'wp_auto_update_themes', $new_autoupdated_themes ); + update_site_option( 'wp_auto_update_themes', $new_auto_update_themes ); - $redirect_to = self_admin_url( "themes.php?disable-autoupdate=true&theme_status=$status&paged=$page&s=$s" ); + $redirect_to = self_admin_url( "themes.php?disable-auto-update=true&theme_status=$status&paged=$page&s=$s" ); return $redirect_to; } + + return $redirect_to; } -add_action( 'handle_network_bulk_actions-themes-network', 'wp_autoupdates_themes_bulk_actions_handle', 10, 3 ); +add_filter( 'handle_network_bulk_actions-themes-network', 'wp_autoupdates_themes_bulk_actions_handle', 10, 3 ); /** * Toggle auto updates via Ajax. */ function wp_autoupdates_toggle_auto_updates() { + check_ajax_referer( 'updates' ); + if ( empty( $_POST['type'] ) || empty( $_POST['asset'] ) || empty( $_POST['state'] ) ) { wp_send_json_error( array( 'error' => __( 'Invalid data. No selected item.', 'wp-autoupdates' ) ) ); } - $type = sanitize_text_field( $_POST['type'] ); - $state = sanitize_text_field( $_POST['state'] ); $asset = sanitize_text_field( urldecode( $_POST['asset'] ) ); - if ( ! in_array( $state, array( 'enable', 'disable', true ) ) ) { + if ( 'enable' !== $_POST['state'] && 'disable' !== $_POST['state'] ) { wp_send_json_error( array( 'error' => __( 'Invalid data. Unknown state.', 'wp-autoupdates' ) ) ); } + $state = $_POST['state']; - check_ajax_referer( 'updates' ); + if ( 'plugin' !== $_POST['type'] && 'theme' !== $_POST['type'] ) { + wp_send_json_error( array( 'error' => __( 'Invalid data. Unknown type.', 'wp-autoupdates' ) ) ); + } + $type = $_POST['type']; switch ( $type ) { case 'plugin': - $cap = 'update_plugins'; + if ( ! current_user_can( 'update_plugins' ) ) { + $error_message = __( 'You do not have permission to modify plugins.', 'wp-autoupdates' ); + wp_send_json_error( array( 'error' => $error_message ) ); + } + $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'; + if ( ! current_user_can( 'update_themes' ) ) { + $error_message = __( 'You do not have permission to modify themes.', 'wp-autoupdates' ); + wp_send_json_error( array( 'error' => $error_message ) ); + } + $option = 'wp_auto_update_themes'; $all_items = wp_get_themes(); break; @@ -1325,31 +1374,22 @@ function wp_autoupdates_toggle_auto_updates() { wp_send_json_error( array( 'error' => __( 'Invalid data. Unknown type.', 'wp-autoupdates' ) ) ); } - if ( ! $all_items[ $asset ] ) { - wp_send_json_error( - array( - 'error' => 'plugin' === $type ? __( 'Invalid data. Plugin does not exist.', 'wp-autoupdates' ) : __( 'Invalid data. Theme does not exist.', 'wp-autoupdates' ), - ) - ); - } - - if ( ! current_user_can( $cap ) ) { - wp_send_json_error( - array( - 'error' => 'plugin' === $type ? __( 'You do not have permission to modify plugins.', 'wp-autoupdates' ) : __( 'You do not have permission to modify themes.', 'wp-autoupdates' ), - ) - ); + if ( ! array_key_exists( $asset, $all_items ) ) { + $error_message = __( 'Invalid data. The item does not exist.', 'wp-autoupdates' ); + wp_send_json_error( array( 'error' => $error_message ) ); } $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_success(); } -add_action( 'wp_ajax_toggle_auto_updates', 'wp_autoupdates_toggle_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 218fed4..e55feae 100644 --- a/js/wp-autoupdates.js +++ b/js/wp-autoupdates.js @@ -1,38 +1,56 @@ -/* global wp_autoupdates */ -( function( $, settings, pagenow ) { +// For merging with wp-admin/js/updates.js +// in this plugin, translatable strings are in l10n. settings is used only for the +// ajax_nonce. Once merged into core, all the strings will be in settings.l10n +// and the l10n param will not be passed. +( function( $, l10n, settings, pagenow ) { 'use strict'; $( document ).ready( function() { $( '.autoupdates_column, .theme-overlay' ).on( 'click', - 'a.auto-update', + '.toggle-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' ); + var data, asset, type, + $anchor = $( this ), + action = $anchor.attr( 'data-wp-action' ), + $label = $anchor.find( '.label' ), + $parent = $anchor.parents( 'themes' !== pagenow ? '.autoupdates_column' : '.theme-autoupdate' ); event.preventDefault(); + switch ( pagenow ) { + case 'plugins': + case 'plugins-network': + type = 'plugin'; + asset = $anchor.closest( 'tr' ).attr( 'data-plugin' ); + break; + case 'themes-network': + type = 'theme'; + asset = $anchor.closest( 'tr' ).attr( 'data-slug' ); + break; + case 'themes': + type = 'theme'; + asset = $anchor.attr( 'data-slug' ); + break; + } + // 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 ); + $label.text( 'enable' === action ? l10n.enabling : l10n.disabling ); $anchor.find( '.dashicons-update' ).removeClass( 'hidden' ); data = { - action: 'toggle_auto_updates', + action: 'toggle-auto-updates', _ajax_nonce: settings.ajax_nonce, state: action, type: type, - asset: $anchor.attr( 'data-wp-asset' ), + asset: asset, }; - $.post( ajaxurl, data ) + $.post( window.ajaxurl, data ) .done( function( response ) { var $enabled, $disabled, enabledNumber, disabledNumber; @@ -69,15 +87,15 @@ if ( 'enable' === action ) { $anchor.attr( 'data-wp-action', 'disable' ); - $label.text( wp_autoupdates.disable ); + $label.text( l10n.disable ); $parent.find( '.auto-update-time' ).removeClass( 'hidden' ); } else { $anchor.attr( 'data-wp-action', 'enable' ); - $label.text( wp_autoupdates.enable ); + $label.text( l10n.enable ); $parent.find( '.auto-update-time' ).addClass( 'hidden' ); } - wp.a11y.speak( 'enable' === action ? wp_autoupdates.enabled : wp_autoupdates.disabled, 'polite' ); + wp.a11y.speak( 'enable' === action ? l10n.enabled : l10n.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' ); @@ -86,8 +104,8 @@ ) .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' ); + $parent.find( '.auto-updates-error' ).removeClass( 'hidden' ).addClass( 'notice error' ).find( 'p' ).text( l10n.auto_update_error ); + wp.a11y.speak( l10n.auto_update_error, 'polite' ); } ) .always( @@ -99,17 +117,28 @@ ); /** - * 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 succeeds. + * Clear the "time until next update" when a plugin is successfully updated manually. + */ + $( document ).on( 'wp-plugin-update-success', + function( event, response ) { + $( 'tr[data-plugin="' + response.plugin + '"]' ).find( '.auto-update-time' ).empty(); + } + ); + + /** + * Clear the "time until next update" when a theme is successfully updated manually. */ - $( '.update-link' ).click( - function() { - var plugin = $( this ).closest( 'tr' ).attr( 'data-plugin' ); + $( document ).on( 'wp-theme-update-success', + function( event, response ) { + var isModalOpen = $( 'body.modal-open' ).length; - $( 'tr.update[data-plugin="' + plugin + '"]' ).find( '.auto-update-time' ).empty(); + if ( 'themes-network' === pagenow ) { + $( 'tr[data-slug="' + response.slug + '"]' ).find( '.auto-update-time' ).empty(); + } else if ( isModalOpen ) { + $( '.theme-autoupdate' ).find ( '.auto-update-time' ).empty(); + } } ); } ); -} )( jQuery, window._wpUpdatesSettings, window.pagenow ); +} )( window.jQuery, window.wp_autoupdates, window._wpUpdatesSettings, window.pagenow );