diff --git a/css/wp-autoupdates.css b/css/wp-autoupdates.css
index 1edc286..bc7a94a 100644
--- a/css/wp-autoupdates.css
+++ b/css/wp-autoupdates.css
@@ -1,7 +1,3 @@
-.theme-overlay .theme-autoupdate a {
- text-decoration: none;
-}
-
#autoupdates_column {
min-width: 200px;
}
@@ -17,4 +13,18 @@
.plugin-autoupdate-enabled,
.theme-autoupdate-enabled {
color: #006505;
+}
+
+.plugins .plugin-title .plugin-autoupdate-enabled .dashicons {
+ float: none;
+ padding: 0;
+ width: auto;
+ height: auto;
+}
+.plugins .plugin-title .plugin-autoupdate-enabled .dashicons:before {
+ padding: 0;
+ background: transparent;
+ box-shadow: none;
+ font-size: 20px;
+ color: #006505;
}
\ No newline at end of file
diff --git a/readme.md b/readme.md
new file mode 100755
index 0000000..abca8f5
--- /dev/null
+++ b/readme.md
@@ -0,0 +1,68 @@
+# WordPress Autoupdates π€
+
+A feature plugin to integrate Plugins & Themes automatic updates in WordPress Core.
+
+## About π
+
+The purpose of this repository is to prepare a future Plugins & Themes automatic updates feature.
+
+To test/contribute, just install this plugin and activate it on your WordPress installation.
+
+## Context β³
+
+In 2018, Matt Mullenweg posted 9 projects for Core to focus on in 2019. We didnβt ship as many as hoped, but we made a lot of progress. Plugins and Themes Automatic Updates were one of those 9 projects. This project is now milestoned to WordPress 5.5 and this feature plugin is here to help move towards this achievement.
+
+- [See also: Update on the 9 projects for 2019](https://make.wordpress.org/core/2019/12/06/update-9-projects-for-2019/):
+- [Related Trac ticket for plugins autoupdates](https://core.trac.wordpress.org/ticket/48850)
+- [Related Trac ticket for themes autoupdates](https://core.trac.wordpress.org/ticket/48850)
+
+## Features / to-do list π
+
+- β
Open a Trac ticket to handle Core merge for plugins
+- β
Open a Trac ticket to handle Core merge for themes
+- β
Handle plugin autoupdates
+- π² Handle themes autoupdates
+- β
Handle plugin autoupdates in a multisite context
+- π² Handle themes autoupdates in a multisite context
+- π² Validate design for plugins screen
+- π² Validate design for themes screen
+- π² Validate design for update-core screen
+- π² Email notifications for plugins
+- π² Email notifications for themes
+- π² Documentation
+- π² Submit Feature Plugin on WordPress.org repository
+- π² Publish the feature plugin proposal
+- π² Get the plugin featured as beta plugin on WordPress.org
+- π² Open a dedicated Slack channel on Make WordPress
+- π² Copy review
+- π² Accessibility audit
+- π² Security audit
+- π² Coding standards audit
+- π² Inline Docs audit
+
+## Contributors π₯
+
+- audrasjb
+- whodunitagency
+
+## Documentation π
+
+TODO.
+
+## Screenshots πΌ
+
+### Plugins Admin screen - screenshot
+
+
+
+### Plugins Admin screen - Toggle update single plugin - screenshot
+
+
+
+### Plugins Admin screen - Buk Edit - animated screenshot
+
+
+
+### Update Core Admin Screen
+
+
\ No newline at end of file
diff --git a/wp-autoupdates-themes-draft.php b/wp-autoupdates-themes-draft.php
new file mode 100755
index 0000000..a26723c
--- /dev/null
+++ b/wp-autoupdates-themes-draft.php
@@ -0,0 +1,147 @@
+';
+ $autoupdate_text .= sprintf(
+ /* translators: Time until the next update. */
+ __( 'Automatic update scheduled in %s', 'wp-autoupdates' ),
+ $time_to_next_update
+ );
+ $autoupdate_text .= ' ';
+ $script .= 'jQuery(".check-column input[value=\'' . $theme . '\']").closest("tr").find(".plugin-title > p").append(\'' . $autoupdate_text . '\');';
+ }
+ }
+ $script .= '});';
+ wp_add_inline_script( 'jquery', $script );
+ }
+ if ( 'themes.php' === $hook ) {
+ if ( 'autoupdate' === esc_url( $_GET['action'] ) ) {
+ check_admin_referer( 'autoupdate-theme_' . $_GET['stylesheet'] );
+ $theme = wp_get_theme( $_GET['stylesheet'] );
+ $slug = $theme->get_stylesheet();
+ if ( ! current_user_can( 'update_themes' ) ) {
+ wp_die(
+ '
' . __( 'You need a higher level of permission.' ) . '
' .
+ '' . __( 'Sorry, you are not allowed to enable automatic update for themes.' ) . '
',
+ 403
+ );
+ }
+ $autoupdated_themes = get_option( 'wp_autoupdated_themes', array() );
+ if ( ! in_array( $slug, $autoupdated_themes, true ) ) {
+ $autoupdate_action = 'enable';
+ $autoupdated_themes[] = $slug;
+ } else {
+ $autoupdate_action = 'disable';
+ $autoupdated_themes = array_diff( $autoupdated_themes, array( $slug ) );
+ }
+ update_option( 'wp_autoupdated_themes', $autoupdated_themes );
+ wp_redirect( admin_url( 'themes.php?autoupdated=' . $autoupdate_action ) );
+ exit;
+ }
+ if ( wp_is_themes_auto_update_enabled() ) {
+ $script = 'jQuery( document ).ready(function() {';
+ $wp_auto_update_themes = get_site_option( 'wp_auto_update_themes', array() );
+ foreach ( $wp_auto_update_themes as $theme ) {
+ $aria_label_enabled = esc_attr__( 'Disable automatic updates', 'plugin', 'wp-autoupdates' );
+ $autoupdate_enabled_text = '';
+ $autoupdate_enabled_text .= ' ' . __( 'Automatic updates enabled', 'wp-autoupdates' );
+ $autoupdate_enabled_text = '
';
+ if ( current_user_can( 'update_themes', $theme ) ) {
+ $autoupdate_enabled_text .= sprintf(
+ '%s',
+ wp_nonce_url( 'plugins.php?action=autoupdate&plugin=' . urlencode( $theme ) . '&paged=' . $page, 'autoupdate-plugin_' . $theme ),
+ $aria_label,
+ __( 'Disable', 'wp-autoupdates' )
+ );
+ }
+ $autoupdate_enabled_text .= '
';
+ $script .= 'jQuery(".check-column input[value=\'' . $theme . '\']").closest("tr").find(".plugin-title > p").append(\'' . $autoupdate_enabled_text . '\');';
+ }
+ $script .= '});';
+ wp_add_inline_script( 'jquery', $script );
+ }
+ }
+}
+add_action( 'admin_enqueue_scripts', 'wp_auto_updates_styles_scripts' );
+
+
+/**
+ * Checks whether themes manual autoupdate is enabled.
+ */
+function wp_is_themes_auto_update_enabled() {
+ $enabled = ! defined( 'WP_DISABLE_THEMES_AUTO_UPDATE' ) || ! WP_DISABLE_THEMES_AUTO_UPDATE;
+
+ /**
+ * Filters whether themes manual autoupdate is enabled.
+ *
+ * @param bool $enabled True if themes auto udpate is enabled, false otherwise.
+ */
+ return apply_filters( 'wp_themes_auto_update_enabled', $enabled );
+}
+
+/**
+ * Autoupdate selected themes.
+ */
+function wp_auto_update_theme( $update, $item ) {
+ $wp_auto_update_themes = get_site_option( 'wp_auto_update_themes', array() );
+ if ( in_array( $item->theme, $wp_auto_update_themes, true ) && wp_is_themes_auto_update_enabled() ) {
+ return true;
+ } else {
+ return $update;
+ }
+}
+add_filter( 'auto_update_theme', 'wp_auto_update_theme', 10, 2 );
+
+/**
+ * Filter the themes prepared for JavaScript, for themes.php.
+ */
+function wp_filter_themes_for_js( $prepared_themes ) {
+ $autoupdated_themes = get_option( 'wp_autoupdated_themes', array() );
+ foreach( $autoupdated_themes as $theme ) {
+ $slug = $theme['id'];
+ $encoded_slug = urlencode( $slug );
+ if ( in_array( $slug, $autoupdated_themes, true ) ) {
+ $theme['autoupdated'] = true;
+ $theme['actions']['autoupdate'] = current_user_can( 'update_themes' ) ? wp_nonce_url( admin_url( 'themes.php?action=autoupdate&stylesheet=' . $encoded_slug ), 'autoupdate-theme_' . $slug ) : null;
+ }
+ }
+ return $prepared_themes;
+}
+add_filter( 'wp_prepare_themes_for_js', 'wp_filter_themes_for_js' );
+
+/**
+ * Auto-update notices
+ */
+function wp_autoupdates_themes_notices() {
+ // Themes screen
+ if ( isset( $_GET['autoupdated'] ) ) {
+ $autoupdated_themes = get_option( 'wp_autoupdated_themes', array() );
+ $autoupdate_notice = __( 'The selected theme wonβt update automatically anymore.' );
+ if ( 'enable' === $_GET['autoupdated'] ) {
+ echo '';
+ _e( 'The selected theme will now update automatically.', 'wp-autoupdates' );
+ echo '
';
+ } else {
+ echo '';
+ _e( 'The selected theme wonβt automatically update anymore.', 'wp-autoupdates' );
+ echo '
';
+ }
+ }
+}
+add_action( 'admin_notices', 'wp_autoupdates_themes_notices' );
\ No newline at end of file
diff --git a/wp-autoupdates.php b/wp-autoupdates.php
index 71ec040..58d3e1a 100755
--- a/wp-autoupdates.php
+++ b/wp-autoupdates.php
@@ -19,20 +19,22 @@
/**
* Enqueue styles and scripts
*/
-function wp_auto_updates_styles_scripts( $hook ) {
- if ( ! in_array( $hook, array( 'plugins.php', 'themes.php', 'update-core.php' ) ) ) {
+function wp_autoupdates_enqueues( $hook ) {
+ if ( ! in_array( $hook, array( 'plugins.php', 'update-core.php' ) ) ) {
return;
}
wp_register_style( 'wp-autoupdates', plugin_dir_url( __FILE__ ) . 'css/wp-autoupdates.css', array() );
wp_enqueue_style( 'wp-autoupdates' );
+
+ // Update core screen JS hack (due to lack of filters)
if ( 'update-core.php' === $hook ) {
$script = 'jQuery( document ).ready(function() {';
- if ( wp_is_plugins_auto_update_enabled() ) {
+ if ( wp_autoupdates_is_plugins_auto_update_enabled() ) {
$wp_auto_update_plugins = get_site_option( 'wp_auto_update_plugins', array() );
foreach ( $wp_auto_update_plugins as $plugin ) {
$next_update_time = wp_next_scheduled( 'wp_version_check' );
$time_to_next_update = human_time_diff( intval( $next_update_time ) );
- $autoupdate_text = ' | ';
+ $autoupdate_text = ' ';
$autoupdate_text .= sprintf(
/* translators: Time until the next update. */
__( 'Automatic update scheduled in %s', 'wp-autoupdates' ),
@@ -42,32 +44,17 @@ function wp_auto_updates_styles_scripts( $hook ) {
$script .= 'jQuery(".check-column input[value=\'' . $plugin . '\']").closest("tr").find(".plugin-title > p").append(\'' . $autoupdate_text . '\');';
}
}
- if ( wp_is_themes_auto_update_enabled() ) {
- $wp_auto_update_themes = get_site_option( 'wp_auto_update_themes', array() );
- foreach ( $wp_auto_update_themes as $theme ) {
- $next_update_time = wp_next_scheduled( 'wp_version_check' );
- $time_to_next_update = human_time_diff( intval( $next_update_time ) );
- $autoupdate_text = ' | ';
- $autoupdate_text .= sprintf(
- /* translators: Time until the next update. */
- __( 'Automatic update scheduled in %s', 'wp-autoupdates' ),
- $time_to_next_update
- );
- $autoupdate_text .= ' ';
- $script .= 'jQuery(".check-column input[value=\'' . $theme . '\']").closest("tr").find(".plugin-title > p").append(\'' . $autoupdate_text . '\');';
- }
- }
$script .= '});';
wp_add_inline_script( 'jquery', $script );
}
}
-add_action( 'admin_enqueue_scripts', 'wp_auto_updates_styles_scripts' );
+add_action( 'admin_enqueue_scripts', 'wp_autoupdates_enqueues' );
/**
* Checks whether plugins manual autoupdate is enabled.
*/
-function wp_is_plugins_auto_update_enabled() {
+function wp_autoupdates_is_plugins_auto_update_enabled() {
$enabled = ! defined( 'WP_DISABLE_PLUGINS_AUTO_UPDATE' ) || ! WP_DISABLE_PLUGINS_AUTO_UPDATE;
/**
@@ -78,66 +65,39 @@ function wp_is_plugins_auto_update_enabled() {
return apply_filters( 'wp_plugins_auto_update_enabled', $enabled );
}
-/**
- * Checks whether themes manual autoupdate is enabled.
- */
-function wp_is_themes_auto_update_enabled() {
- $enabled = ! defined( 'WP_DISABLE_THEMES_AUTO_UPDATE' ) || ! WP_DISABLE_THEMES_AUTO_UPDATE;
-
- /**
- * Filters whether themes manual autoupdate is enabled.
- *
- * @param bool $enabled True if themes auto udpate is enabled, false otherwise.
- */
- return apply_filters( 'wp_themes_auto_update_enabled', $enabled );
-}
-
/**
* Autoupdate selected plugins.
*/
-function wp_auto_update_plugin( $update, $item ) {
+function wp_autoupdates_selected_plugins( $update, $item ) {
$wp_auto_update_plugins = get_site_option( 'wp_auto_update_plugins', array() );
- if ( in_array( $item->plugin, $wp_auto_update_plugins, true ) && wp_is_plugins_auto_update_enabled() ) {
+ if ( in_array( $item->plugin, $wp_auto_update_plugins, true ) && wp_autoupdates_is_plugins_auto_update_enabled() ) {
return true;
} else {
return $update;
}
}
-add_filter( 'auto_update_plugin', 'wp_auto_update_plugin', 10, 2 );
-
-/**
- * Autoupdate selected themes.
- */
-function wp_auto_update_theme( $update, $item ) {
- $wp_auto_update_themes = get_site_option( 'wp_auto_update_themes', array() );
- if ( in_array( $item->theme, $wp_auto_update_themes, true ) && wp_is_themes_auto_update_enabled() ) {
- return true;
- } else {
- return $update;
- }
-}
-add_filter( 'auto_update_theme', 'wp_auto_update_theme', 10, 2 );
+add_filter( 'auto_update_plugin', 'wp_autoupdates_selected_plugins', 10, 2 );
/**
* Add autoupdate column to plugins screen.
*/
-function wp_add_plugins_autoupdates_column( $columns ) {
+function wp_autoupdates_add_plugins_autoupdates_column( $columns ) {
$columns['autoupdates_column'] = 'Automatic updates';
return $columns;
}
-add_filter( 'manage_plugins_columns', 'wp_add_plugins_autoupdates_column' );
+add_filter( 'manage_plugins_columns', 'wp_autoupdates_add_plugins_autoupdates_column' );
/**
* Render autoupdate columnβs content.
*/
-function wp_add_plugins_autoupdates_column_content( $column_name, $plugin_file, $plugin_data ) {
- if ( ! current_user_can( 'update_plugins' ) || ! wp_is_plugins_auto_update_enabled() ) {
+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() ) {
return;
}
if ( is_multisite() && ! is_network_admin() ) {
return;
}
- if ( wp_is_plugins_auto_update_enabled() ) {
+ if ( wp_autoupdates_is_plugins_auto_update_enabled() ) {
$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(
@@ -180,17 +140,17 @@ function wp_add_plugins_autoupdates_column_content( $column_name, $plugin_file,
}
}
}
-add_action( 'manage_plugins_custom_column' , 'wp_add_plugins_autoupdates_column_content', 10, 3 );
+add_action( 'manage_plugins_custom_column' , 'wp_autoupdates_add_plugins_autoupdates_column_content', 10, 3 );
/**
* Add plugins autoupdates bulk actions
*/
-function wp_plugins_bulk_actions( $actions ) {
+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' );
return $actions;
}
-add_action( 'bulk_actions-plugins', 'wp_plugins_bulk_actions' );
+add_action( 'bulk_actions-plugins', 'wp_autoupdates_plugins_bulk_actions' );
/**
@@ -202,7 +162,7 @@ function wp_autoupdates_enabler() {
return;
}
if ( 'autoupdate' === esc_html( $_GET['action'] ) ) {
- if ( ! current_user_can( 'update_plugins' ) || ! wp_is_plugins_auto_update_enabled() ) {
+ 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' ) );
}
@@ -218,7 +178,6 @@ function wp_autoupdates_enabler() {
}
check_admin_referer( 'autoupdate-plugin_' . $plugin );
-
$wp_auto_update_plugins = get_site_option( 'wp_auto_update_plugins', array() );
if ( in_array( $plugin, $wp_auto_update_plugins, true ) ) {
@@ -228,12 +187,9 @@ function wp_autoupdates_enabler() {
$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" ) );
exit;
-
}
}
add_action( 'admin_init', 'wp_autoupdates_enabler' );
@@ -241,9 +197,9 @@ function wp_autoupdates_enabler() {
/**
* Handle plugins autoupdates bulk actions
*/
-function wp_plugins_bulk_actions_handle( $redirect_to, $doaction, $items ) {
+function wp_autoupdates_plugins_bulk_actions_handle( $redirect_to, $doaction, $items ) {
if ( 'enable-autoupdate-selected' === $doaction ) {
- if ( ! current_user_can( 'update_plugins' ) || ! wp_is_plugins_auto_update_enabled() ) {
+ 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' ) );
}
@@ -272,7 +228,7 @@ function wp_plugins_bulk_actions_handle( $redirect_to, $doaction, $items ) {
}
if ( 'disable-autoupdate-selected' === $doaction ) {
- if ( ! current_user_can( 'update_plugins' ) || ! wp_is_plugins_auto_update_enabled() ) {
+ 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' ) );
}
@@ -301,22 +257,22 @@ function wp_plugins_bulk_actions_handle( $redirect_to, $doaction, $items ) {
}
}
-add_action( 'handle_bulk_actions-plugins', 'wp_plugins_bulk_actions_handle', 10, 3 );
+add_action( 'handle_bulk_actions-plugins', 'wp_autoupdates_plugins_bulk_actions_handle', 10, 3 );
/**
* Auto-update notices
*/
-function wp_autoupdate_notices() {
- if ( isset( esc_html( $_GET['enable-autoupdate'] ) ) ) {
+function wp_autoupdates_notices() {
+ // Plugins screen
+ if ( isset( $_GET['enable-autoupdate'] ) ) {
echo '';
_e( 'The selected plugins will now update automatically.', 'wp-autoupdates' );
echo '
';
}
-
- if ( isset( esc_html( $_GET['disable-autoupdate'] ) ) ) {
+ if ( isset( $_GET['disable-autoupdate'] ) ) {
echo '';
_e( 'The selected plugins wonβt automatically update anymore.', 'wp-autoupdates' );
echo '
';
}
}
-add_action( 'admin_notices', 'wp_autoupdate_notices' );
\ No newline at end of file
+add_action( 'admin_notices', 'wp_autoupdates_notices' );
\ No newline at end of file