summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/jetpack/sync')
-rw-r--r--plugins/jetpack/sync/class.jetpack-sync-actions.php2
-rw-r--r--plugins/jetpack/sync/class.jetpack-sync-listener.php8
-rw-r--r--plugins/jetpack/sync/class.jetpack-sync-module-full-sync.php26
-rw-r--r--plugins/jetpack/sync/class.jetpack-sync-module-menus.php78
-rw-r--r--plugins/jetpack/sync/class.jetpack-sync-module-options.php13
-rw-r--r--plugins/jetpack/sync/class.jetpack-sync-module-plugins.php3
-rw-r--r--plugins/jetpack/sync/class.jetpack-sync-module-posts.php77
-rw-r--r--plugins/jetpack/sync/class.jetpack-sync-module-terms.php18
-rw-r--r--plugins/jetpack/sync/class.jetpack-sync-module-themes.php183
-rw-r--r--plugins/jetpack/sync/class.jetpack-sync-module-updates.php74
-rw-r--r--plugins/jetpack/sync/class.jetpack-sync-module-woocommerce.php23
-rw-r--r--plugins/jetpack/sync/class.jetpack-sync-modules.php2
-rw-r--r--plugins/jetpack/sync/class.jetpack-sync-options.php62
-rw-r--r--plugins/jetpack/sync/class.jetpack-sync-sender.php20
14 files changed, 475 insertions, 114 deletions
diff --git a/plugins/jetpack/sync/class.jetpack-sync-actions.php b/plugins/jetpack/sync/class.jetpack-sync-actions.php
index 43f45cdc..05a50778 100644
--- a/plugins/jetpack/sync/class.jetpack-sync-actions.php
+++ b/plugins/jetpack/sync/class.jetpack-sync-actions.php
@@ -265,7 +265,7 @@ class Jetpack_Sync_Actions {
}
$result = 'full_sync' === $type ? self::$sender->do_full_sync() : self::$sender->do_sync();
- } while ( $result && ( $start_time + $time_limit ) > time() );
+ } while ( $result && ! is_wp_error( $result ) && ( $start_time + $time_limit ) > time() );
}
static function initialize_listener() {
diff --git a/plugins/jetpack/sync/class.jetpack-sync-listener.php b/plugins/jetpack/sync/class.jetpack-sync-listener.php
index 4ff5b291..baafde54 100644
--- a/plugins/jetpack/sync/class.jetpack-sync-listener.php
+++ b/plugins/jetpack/sync/class.jetpack-sync-listener.php
@@ -234,12 +234,16 @@ class Jetpack_Sync_Listener {
}
}
}
+
function get_actor() {
$current_user = wp_get_current_user();
+
$actor = array();
if ( $current_user ) {
- $actor[ 'display_name' ] = $current_user->display_name;
- $actor[ 'user_email' ] = $current_user->user_email;
+ $actor['display_name'] = $current_user->display_name;
+ $actor['user_email'] = $current_user->user_email;
+ $actor['user_roles'] = $current_user->roles; /* Since 5.0.0 */
+ $actor['translated_role'] = Jetpack::translate_current_user_to_role(); /* Since 5.0.0 */
}
if ( isset( $_SERVER['REMOTE_ADDR'] ) ) {
diff --git a/plugins/jetpack/sync/class.jetpack-sync-module-full-sync.php b/plugins/jetpack/sync/class.jetpack-sync-module-full-sync.php
index d16b22f4..35ac6383 100644
--- a/plugins/jetpack/sync/class.jetpack-sync-module-full-sync.php
+++ b/plugins/jetpack/sync/class.jetpack-sync-module-full-sync.php
@@ -1,7 +1,5 @@
<?php
-require_once dirname( __FILE__ ) . '/class.jetpack-sync-options.php';
-
/**
* This class does a full resync of the database by
* enqueuing an outbound action for every single object
@@ -267,14 +265,14 @@ class Jetpack_Sync_Module_Full_Sync extends Jetpack_Sync_Module {
public function clear_status() {
$prefix = self::STATUS_OPTION_PREFIX;
- Jetpack_Sync_Options::delete_option( "{$prefix}_started" );
- Jetpack_Sync_Options::delete_option( "{$prefix}_params" );
- Jetpack_Sync_Options::delete_option( "{$prefix}_queue_finished" );
- Jetpack_Sync_Options::delete_option( "{$prefix}_send_started" );
- Jetpack_Sync_Options::delete_option( "{$prefix}_finished" );
+ Jetpack_Options::delete_raw_option( "{$prefix}_started" );
+ Jetpack_Options::delete_raw_option( "{$prefix}_params" );
+ Jetpack_Options::delete_raw_option( "{$prefix}_queue_finished" );
+ Jetpack_Options::delete_raw_option( "{$prefix}_send_started" );
+ Jetpack_Options::delete_raw_option( "{$prefix}_finished" );
foreach ( Jetpack_Sync_Modules::get_modules() as $module ) {
- Jetpack_Sync_Options::delete_option( "{$prefix}_{$module->name()}_sent" );
+ Jetpack_Options::delete_raw_option( "{$prefix}_{$module->name()}_sent" );
}
}
@@ -286,29 +284,29 @@ class Jetpack_Sync_Module_Full_Sync extends Jetpack_Sync_Module {
}
private function get_status_option( $name, $default = null ) {
- $value = Jetpack_Sync_Options::get_option( self::STATUS_OPTION_PREFIX . "_$name", $default );
+ $value = Jetpack_Options::get_raw_option( self::STATUS_OPTION_PREFIX . "_$name", $default );
return is_numeric( $value ) ? intval( $value ) : $value;
}
private function update_status_option( $name, $value, $autoload = false ) {
- Jetpack_Sync_Options::update_option( self::STATUS_OPTION_PREFIX . "_$name", $value, $autoload );
+ Jetpack_Options::update_raw_option( self::STATUS_OPTION_PREFIX . "_$name", $value, $autoload );
}
private function set_enqueue_status( $new_status ) {
- Jetpack_Sync_Options::update_option( 'jetpack_sync_full_enqueue_status', $new_status );
+ Jetpack_Options::update_raw_option( 'jetpack_sync_full_enqueue_status', $new_status );
}
private function get_enqueue_status() {
- return Jetpack_Sync_Options::get_option( 'jetpack_sync_full_enqueue_status' );
+ return Jetpack_Options::get_raw_option( 'jetpack_sync_full_enqueue_status' );
}
private function set_config( $config ) {
- Jetpack_Sync_Options::update_option( 'jetpack_sync_full_config', $config );
+ Jetpack_Options::update_raw_option( 'jetpack_sync_full_config', $config );
}
private function get_config() {
- return Jetpack_Sync_Options::get_option( 'jetpack_sync_full_config' );
+ return Jetpack_Options::get_raw_option( 'jetpack_sync_full_config' );
}
private function write_option( $name, $value ) {
diff --git a/plugins/jetpack/sync/class.jetpack-sync-module-menus.php b/plugins/jetpack/sync/class.jetpack-sync-module-menus.php
new file mode 100644
index 00000000..34ce2b3f
--- /dev/null
+++ b/plugins/jetpack/sync/class.jetpack-sync-module-menus.php
@@ -0,0 +1,78 @@
+<?php
+
+class Jetpack_Sync_Module_Menus extends Jetpack_Sync_Module {
+ private $nav_items_just_added = array();
+
+ function name() {
+ return 'menus';
+ }
+
+ public function init_listeners( $callable ) {
+ add_action( 'wp_create_nav_menu', $callable, 10, 2 );
+ add_action( 'wp_update_nav_menu', array( $this, 'update_nav_menu' ), 10, 2 );
+ add_action( 'wp_add_nav_menu_item', array( $this, 'update_nav_menu_add_item' ), 10, 3 );
+ add_action( 'wp_update_nav_menu_item', array( $this, 'update_nav_menu_update_item' ), 10, 3 );
+ add_action( 'post_updated', array( $this, 'remove_just_added_menu_item' ), 10, 2 );
+
+ add_action( 'jetpack_sync_updated_nav_menu', $callable, 10, 2 );
+ add_action( 'jetpack_sync_updated_nav_menu_add_item', $callable, 10, 4 );
+ add_action( 'jetpack_sync_updated_nav_menu_update_item', $callable, 10, 4 );
+ add_action( 'delete_nav_menu', $callable, 10, 3 );
+ }
+
+ public function update_nav_menu( $menu_id, $menu_data = array() ) {
+ if ( empty( $menu_data ) ) {
+ return;
+ }
+ /**
+ * Helps sync log that a nav menu was updated.
+ *
+ * @since 5.0.0
+ *
+ * @param int $menu_id, the id of the menu
+ * @param object $menu_data
+ */
+ do_action( 'jetpack_sync_updated_nav_menu', $menu_id, $menu_data );
+ }
+
+ public function update_nav_menu_add_item( $menu_id, $nav_item_id, $nav_item_args ) {
+ $menu_data = wp_get_nav_menu_object( $menu_id );
+ $this->nav_items_just_added[] = $nav_item_id;
+ /**
+ * Helps sync log that a new menu item was added.
+ *
+ * @since 5.0.0
+ *
+ * @param int $menu_id, the id of the menu
+ * @param object $menu_data
+ * @param int $nav_item_id
+ * @param int $nav_item_args
+ */
+ do_action( 'jetpack_sync_updated_nav_menu_add_item', $menu_id, $menu_data, $nav_item_id, $nav_item_args );
+ }
+
+ public function update_nav_menu_update_item( $menu_id, $nav_item_id, $nav_item_args ) {
+ if ( in_array( $nav_item_id, $this->nav_items_just_added ) ) {
+ return;
+ }
+ $menu_data = wp_get_nav_menu_object( $menu_id );
+ /**
+ * Helps sync log that an update to the menu item happened.
+ *
+ * @since 5.0.0
+ *
+ * @param int $menu_id, the id of the menu
+ * @param object $menu_data
+ * @param int $nav_item_id
+ * @param int $nav_item_args
+ */
+ do_action( 'jetpack_sync_updated_nav_menu_update_item', $menu_id, $menu_data, $nav_item_id, $nav_item_args );
+ }
+
+ public function remove_just_added_menu_item( $nav_item_id, $post_after ) {
+ if ( 'nav_menu_item' !== $post_after->post_type ) {
+ return;
+ }
+ $this->nav_items_just_added = array_diff( $this->nav_items_just_added, array( $nav_item_id ) );
+ }
+}
diff --git a/plugins/jetpack/sync/class.jetpack-sync-module-options.php b/plugins/jetpack/sync/class.jetpack-sync-module-options.php
index 12fe91a3..523a1eef 100644
--- a/plugins/jetpack/sync/class.jetpack-sync-module-options.php
+++ b/plugins/jetpack/sync/class.jetpack-sync-module-options.php
@@ -71,16 +71,22 @@ class Jetpack_Sync_Module_Options extends Jetpack_Sync_Module {
// Is public so that we don't have to store so much data all the options twice.
function get_all_options() {
$options = array();
+ $random_string = wp_generate_password();
foreach ( $this->options_whitelist as $option ) {
- $options[ $option ] = get_option( $option );
+ $option_value = get_option( $option, $random_string );
+ if ( $option_value !== $random_string ) {
+ $options[ $option ] = $option_value;
+ }
}
// add theme mods
$theme_mods_option = 'theme_mods_'.get_option( 'stylesheet' );
- $theme_mods_value = get_option( $theme_mods_option );
+ $theme_mods_value = get_option( $theme_mods_option, $random_string );
+ if ( $theme_mods_value === $random_string ) {
+ return $options;
+ }
$this->filter_theme_mods( $theme_mods_value );
$options[ $theme_mods_option ] = $theme_mods_value;
-
return $options;
}
@@ -109,7 +115,6 @@ class Jetpack_Sync_Module_Options extends Jetpack_Sync_Module {
$this->filter_theme_mods( $args[2] );
}
}
-
return $args;
}
diff --git a/plugins/jetpack/sync/class.jetpack-sync-module-plugins.php b/plugins/jetpack/sync/class.jetpack-sync-module-plugins.php
index 8dbb3b36..a488950d 100644
--- a/plugins/jetpack/sync/class.jetpack-sync-module-plugins.php
+++ b/plugins/jetpack/sync/class.jetpack-sync-module-plugins.php
@@ -111,6 +111,9 @@ class Jetpack_Sync_Module_Plugins extends Jetpack_Sync_Module {
$plugin_path = $args[0];
$plugin_data = array();
+ if ( ! function_exists( 'get_plugins' ) ) {
+ require_once ABSPATH . 'wp-admin/includes/plugin.php';
+ }
$all_plugins = get_plugins();
if ( isset( $all_plugins[ $plugin_path ] ) ) {
$all_plugin_data = $all_plugins[ $plugin_path ];
diff --git a/plugins/jetpack/sync/class.jetpack-sync-module-posts.php b/plugins/jetpack/sync/class.jetpack-sync-module-posts.php
index 1088709e..80815acb 100644
--- a/plugins/jetpack/sync/class.jetpack-sync-module-posts.php
+++ b/plugins/jetpack/sync/class.jetpack-sync-module-posts.php
@@ -7,6 +7,7 @@ class Jetpack_Sync_Module_Posts extends Jetpack_Sync_Module {
private $just_published = array();
private $just_trashed = array();
private $action_handler;
+ private $import_end = false;
public function name() {
return 'posts';
@@ -21,6 +22,7 @@ class Jetpack_Sync_Module_Posts extends Jetpack_Sync_Module {
}
public function set_defaults() {
+ $this->import_end = false;
}
public function init_listeners( $callable ) {
@@ -42,8 +44,67 @@ class Jetpack_Sync_Module_Posts extends Jetpack_Sync_Module {
// listen for meta changes
$this->init_listeners_for_meta_type( 'post', $callable );
$this->init_meta_whitelist_handler( 'post', array( $this, 'filter_meta' ) );
+
+ add_action( 'export_wp', $callable );
+ add_action( 'jetpack_sync_import_end', $callable );
+
+ // Movable type, RSS, Livejournal
+ add_action( 'import_done', array( $this, 'sync_import_done' ) );
+
+ // WordPress, Blogger, Livejournal, woo tax rate
+ add_action( 'import_end', array( $this, 'sync_import_end' ) );
}
+ public function sync_import_done( $importer ) {
+ // We already ran an send the import
+ if ( $this->import_end ) {
+ return;
+ }
+ /**
+ * Sync Event that tells that the import is finished
+ *
+ * @since 5.0.0
+ *
+ * $param string $importer
+ */
+ do_action( 'jetpack_sync_import_end', $importer );
+ $this->import_end = true;
+ }
+
+ public function sync_import_end() {
+ // We already ran an send the import
+ if ( $this->import_end ) {
+ return;
+ }
+
+ $this->import_end = true;
+ $importer = 'unknown';
+ $backtrace = wp_debug_backtrace_summary(null, 0, false );
+ if ( $this->is_importer( $backtrace, 'Blogger_Importer' ) ) {
+ $importer = 'blogger';
+ }
+
+ if ( 'unknown' === $importer && $this->is_importer( $backtrace, 'WC_Tax_Rate_Importer' ) ) {
+ $importer = 'woo-tax-rate';
+ }
+
+ if ( 'unknown' === $importer && $this->is_importer( $backtrace, 'WP_Import' ) ) {
+ $importer = 'wordpress';
+ }
+
+ /** This filter is already documented in sync/class.jetpack-sync-module-posts.php */
+ do_action( 'jetpack_sync_import_end', $importer );
+ }
+
+ private function is_importer( $backtrace, $class_name ) {
+ foreach ( $backtrace as $trace ) {
+ if ( strpos( $trace, $class_name ) !== false ) {
+ return true;
+ }
+ }
+ return false;
+ }
+
public function init_full_sync_listeners( $callable ) {
add_action( 'jetpack_full_sync_posts', $callable ); // also sends post meta
}
@@ -93,7 +154,7 @@ class Jetpack_Sync_Module_Posts extends Jetpack_Sync_Module {
* @return array
*/
function expand_wp_insert_post( $args ) {
- return array( $args[0], $this->filter_post_content_and_add_links( $args[1] ), $args[2] );
+ return array( $args[0], $this->filter_post_content_and_add_links( $args[1] ), $args[2], $args[3] );
}
function filter_blacklisted_post_types( $args ) {
@@ -250,8 +311,18 @@ class Jetpack_Sync_Module_Posts extends Jetpack_Sync_Module {
}
}
- public function wp_insert_post( $post_ID, $post, $update ) {
- call_user_func( $this->action_handler, $post_ID, $post, $update );
+ public function wp_insert_post( $post_ID, $post = null , $update = null ) {
+ if ( ! is_numeric( $post_ID ) || is_null( $post ) ) {
+ return;
+ }
+
+ if ( Jetpack_Constants::get_constant( 'DOING_AUTOSAVE' ) ) {
+ $is_auto_save = true;
+ } else {
+ $is_auto_save = false;
+ }
+
+ call_user_func( $this->action_handler, $post_ID, $post, $update, $is_auto_save );
$this->send_published( $post_ID, $post );
$this->send_trashed( $post_ID, $post );
}
diff --git a/plugins/jetpack/sync/class.jetpack-sync-module-terms.php b/plugins/jetpack/sync/class.jetpack-sync-module-terms.php
index 13b185b4..c8068101 100644
--- a/plugins/jetpack/sync/class.jetpack-sync-module-terms.php
+++ b/plugins/jetpack/sync/class.jetpack-sync-module-terms.php
@@ -10,7 +10,8 @@ class Jetpack_Sync_Module_Terms extends Jetpack_Sync_Module {
function init_listeners( $callable ) {
add_action( 'created_term', array( $this, 'save_term_handler' ), 10, 3 );
add_action( 'edited_term', array( $this, 'save_term_handler' ), 10, 3 );
- add_action( 'jetpack_sync_save_term', $callable, 10, 4 );
+ add_action( 'jetpack_sync_save_term', $callable );
+ add_action( 'jetpack_sync_add_term', $callable );
add_action( 'delete_term', $callable, 10, 4 );
add_action( 'set_object_terms', $callable, 10, 6 );
add_action( 'deleted_term_relationships', $callable, 10, 2 );
@@ -73,8 +74,21 @@ class Jetpack_Sync_Module_Terms extends Jetpack_Sync_Module {
$term_object = get_term_by( 'id', $term_id, $taxonomy );
}
+ $current_filter = current_filter();
+
+ if ( 'created_term' === $current_filter ) {
+ /**
+ * Fires when the client needs to add a new term
+ *
+ * @since 5.0.0
+ *
+ * @param object the Term object
+ */
+ do_action( 'jetpack_sync_add_term', $term_object );
+ }
+
/**
- * Fires when the client needs to sync a new term
+ * Fires when the client needs to update a term
*
* @since 4.2.0
*
diff --git a/plugins/jetpack/sync/class.jetpack-sync-module-themes.php b/plugins/jetpack/sync/class.jetpack-sync-module-themes.php
index ca70acc2..e36743fd 100644
--- a/plugins/jetpack/sync/class.jetpack-sync-module-themes.php
+++ b/plugins/jetpack/sync/class.jetpack-sync-module-themes.php
@@ -11,14 +11,150 @@ class Jetpack_Sync_Module_Themes extends Jetpack_Sync_Module {
add_action( 'upgrader_process_complete', array( $this, 'check_upgrader'), 10, 2 );
add_action( 'jetpack_installed_theme', $callable, 10, 2 );
add_action( 'jetpack_updated_theme', $callable, 10, 2 );
+ add_action( 'delete_site_transient_update_themes', array( $this, 'detect_theme_deletion') );
+ add_action( 'jetpack_deleted_theme', $callable );
+ add_filter( 'wp_redirect', array( $this, 'detect_theme_edit' ) );
+ add_action( 'jetpack_edited_theme', $callable, 10, 2 );
+ add_action( 'update_site_option_allowedthemes', array( $this, 'sync_network_allowed_themes_change' ), 10, 4 );
+ add_action( 'jetpack_network_disabled_themes', $callable, 10, 2 );
+ add_action( 'jetpack_network_enabled_themes', $callable, 10, 2 );
// Sidebar updates.
add_action( 'update_option_sidebars_widgets', array( $this, 'sync_sidebar_widgets_actions' ), 10, 2 );
- add_action( 'jetpack_widget_added', $callable, 10, 2 );
- add_action( 'jetpack_widget_removed', $callable, 10, 2 );
- add_action( 'jetpack_widget_moved_to_inactive', $callable );
+
+ add_action( 'jetpack_widget_added', $callable, 10, 4 );
+ add_action( 'jetpack_widget_removed', $callable, 10, 4 );
+ add_action( 'jetpack_widget_moved_to_inactive', $callable, 10, 2 );
add_action( 'jetpack_cleared_inactive_widgets', $callable );
- add_action( 'jetpack_widget_reordered', $callable );
+ add_action( 'jetpack_widget_reordered', $callable, 10, 2 );
+ add_filter( 'widget_update_callback', array( $this, 'sync_widget_edit' ), 10, 4 );
+ add_action( 'jetpack_widget_edited', $callable );
+ }
+
+ public function sync_widget_edit( $instance, $new_instance, $old_instance, $widget_object ) {
+ $widget = array(
+ 'name' => $widget_object->name,
+ 'id' => $widget_object->id,
+ );
+ /**
+ * Trigger action to alert $callable sync listener that a widget was edited
+ *
+ * @since 5.0.0
+ *
+ * @param string $widget_name, Name of edited widget
+ */
+ do_action( 'jetpack_widget_edited', $widget );
+
+ return $instance;
+ }
+
+ public function sync_network_allowed_themes_change( $option, $value, $old_value, $network_id ) {
+ $all_enabled_theme_slugs = array_keys( $value );
+
+ if ( count( $old_value ) > count( $value ) ) {
+ $newly_disabled_theme_names = array_keys( array_diff_key( $old_value, $value ) );
+ $newly_disabled_themes = $this->get_theme_details_for_slugs( $newly_disabled_theme_names );
+ /**
+ * Trigger action to alert $callable sync listener that network themes were disabled
+ *
+ * @since 5.0.0
+ *
+ * @param mixed $newly_disabled_themes, Array of info about network disabled themes
+ * @param mixed $all_enabled_theme_slugs, Array of slugs of all enabled themes
+ */
+ do_action( 'jetpack_network_disabled_themes', $newly_disabled_themes, $all_enabled_theme_slugs );
+ return;
+ }
+
+ $newly_enabled_theme_names = array_keys( array_diff_key( $value, $old_value ) );
+ $newly_enabled_themes = $this->get_theme_details_for_slugs( $newly_enabled_theme_names );
+ /**
+ * Trigger action to alert $callable sync listener that network themes were enabled
+ *
+ * @since 5.0.0
+ *
+ * @param mixed $newly_enabled_themes , Array of info about network enabled themes
+ * @param mixed $all_enabled_theme_slugs, Array of slugs of all enabled themes
+ */
+ do_action( 'jetpack_network_enabled_themes', $newly_enabled_themes, $all_enabled_theme_slugs );
+ }
+
+ private function get_theme_details_for_slugs( $theme_slugs ) {
+ $theme_data = array();
+ foreach ( $theme_slugs as $slug ) {
+ $theme = wp_get_theme( $slug );
+ $theme_data[ $slug ] = array(
+ 'name' => $theme->get( 'Name' ),
+ 'version' => $theme->get( 'Version' ),
+ 'uri' => $theme->get( 'ThemeURI' ),
+ 'slug' => $slug,
+ );
+ }
+ return $theme_data;
+ }
+
+ public function detect_theme_edit( $redirect_url ) {
+ $url = wp_parse_url( admin_url( $redirect_url ) );
+ $theme_editor_url = wp_parse_url( admin_url( 'theme-editor.php' ) );
+
+ if ( $theme_editor_url['path'] !== $url['path'] ) {
+ return $redirect_url;
+ }
+
+ $query_params = array();
+ wp_parse_str( $url['query'], $query_params );
+ if (
+ ! isset( $_POST['newcontent'] ) ||
+ ! isset( $query_params['file'] ) ||
+ ! isset( $query_params['theme'] ) ||
+ ! isset( $query_params['updated'] )
+ ) {
+ return $redirect_url;
+ }
+ $theme = wp_get_theme( $query_params['theme'] );
+ $theme_data = array(
+ 'name' => $theme->get('Name'),
+ 'version' => $theme->get('Version'),
+ 'uri' => $theme->get( 'ThemeURI' ),
+ );
+
+ /**
+ * Trigger action to alert $callable sync listener that a theme was edited
+ *
+ * @since 5.0.0
+ *
+ * @param string $query_params['theme'], Slug of edited theme
+ * @param string $theme_data, Information about edited them
+ */
+ do_action( 'jetpack_edited_theme', $query_params['theme'], $theme_data );
+
+ return $redirect_url;
+ }
+
+ public function detect_theme_deletion() {
+ $backtrace = debug_backtrace();
+ $delete_theme_call = null;
+ foreach ( $backtrace as $call ) {
+ if ( isset( $call['function'] ) && 'delete_theme' === $call['function'] ) {
+ $delete_theme_call = $call;
+ break;
+ }
+ }
+ if ( empty( $delete_theme_call ) ) {
+ return;
+ }
+
+ $slug = $delete_theme_call['args'][0];
+
+ /**
+ * Signals to the sync listener that a theme was deleted and a sync action
+ * reflecting the deletion and theme slug should be sent
+ *
+ * @since 5.0.0
+ *
+ * @param string $slug Theme slug
+ */
+ do_action( 'jetpack_deleted_theme', $slug );
}
public function check_upgrader( $upgrader, $details) {
@@ -110,14 +246,27 @@ class Jetpack_Sync_Module_Themes extends Jetpack_Sync_Module {
return array( $this->get_theme_support_info() );
}
+ function get_widget_name( $widget_id ) {
+ global $wp_registered_widgets;
+ return ( isset( $wp_registered_widgets[ $widget_id ] ) ? $wp_registered_widgets[ $widget_id ]['name'] : null );
+ }
+
+ function get_sidebar_name( $sidebar_id ) {
+ global $wp_registered_sidebars;
+ return ( isset( $wp_registered_sidebars[ $sidebar_id ] ) ? $wp_registered_sidebars[ $sidebar_id ]['name'] : null );
+ }
+
function sync_add_widgets_to_sidebar( $new_widgets, $old_widgets, $sidebar ) {
$added_widgets = array_diff( $new_widgets, $old_widgets );
if ( empty( $added_widgets ) ) {
return array();
}
$moved_to_sidebar = array();
+ $sidebar_name = $this->get_sidebar_name( $sidebar );
+
foreach ( $added_widgets as $added_widget ) {
$moved_to_sidebar[] = $added_widget;
+ $added_widget_name = $this->get_widget_name( $added_widget );
/**
* Helps Sync log that a widget got added
*
@@ -125,8 +274,11 @@ class Jetpack_Sync_Module_Themes extends Jetpack_Sync_Module {
*
* @param string $sidebar, Sidebar id got changed
* @param string $added_widget, Widget id got added
+ * @param string $sidebar_name, Sidebar id got changed Since 5.0.0
+ * @param string $added_widget_name, Widget id got added Since 5.0.0
+ *
*/
- do_action( 'jetpack_widget_added', $sidebar, $added_widget );
+ do_action( 'jetpack_widget_added', $sidebar, $added_widget, $sidebar_name, $added_widget_name );
}
return $moved_to_sidebar;
}
@@ -139,10 +291,12 @@ class Jetpack_Sync_Module_Themes extends Jetpack_Sync_Module {
}
$moved_to_inactive = array();
+ $sidebar_name = $this->get_sidebar_name( $sidebar );
foreach( $removed_widgets as $removed_widget ) {
// Lets check if we didn't move the widget to in_active_widgets
if ( isset( $inactive_widgets ) && ! in_array( $removed_widget, $inactive_widgets ) ) {
+ $removed_widget_name = $this->get_widget_name( $removed_widget );
/**
* Helps Sync log that a widgte got removed
*
@@ -150,8 +304,10 @@ class Jetpack_Sync_Module_Themes extends Jetpack_Sync_Module {
*
* @param string $sidebar, Sidebar id got changed
* @param string $removed_widget, Widget id got removed
+ * @param string $sidebar_name, Name of the sidebar that changed Since 5.0.0
+ * @param string $removed_widget_name, Name of the widget that got removed Since 5.0.0
*/
- do_action( 'jetpack_widget_removed', $sidebar, $removed_widget );
+ do_action( 'jetpack_widget_removed', $sidebar, $removed_widget, $sidebar_name, $removed_widget_name );
} else {
$moved_to_inactive[] = $removed_widget;
}
@@ -171,14 +327,16 @@ class Jetpack_Sync_Module_Themes extends Jetpack_Sync_Module {
}
if ( serialize( $old_widgets ) !== serialize( $new_widgets ) ) {
+ $sidebar_name = $this->get_sidebar_name( $sidebar );
/**
* Helps Sync log that a sidebar id got reordered
*
* @since 4.9.0
*
* @param string $sidebar, Sidebar id got changed
+ * @param string $sidebar_name, Name of the sidebar that changed Since 5.0.0
*/
- do_action( 'jetpack_widget_reordered', $sidebar );
+ do_action( 'jetpack_widget_reordered', $sidebar, $sidebar_name );
}
}
@@ -202,8 +360,7 @@ class Jetpack_Sync_Module_Themes extends Jetpack_Sync_Module {
: array();
$moved_to_inactive_recently = $this->sync_remove_widgets_from_sidebar( $new_widgets, $old_widgets, $sidebar, $new_value['wp_inactive_widgets'] );
- $moved_to_inactive = array_merge( $moved_to_inactive, $moved_to_inactive_recently );
-
+ $moved_to_inactive_ids = array_merge( $moved_to_inactive, $moved_to_inactive_recently );
$moved_to_sidebar_recently = $this->sync_add_widgets_to_sidebar( $new_widgets, $old_widgets, $sidebar );
$moved_to_sidebar = array_merge( $moved_to_sidebar, $moved_to_sidebar_recently );
@@ -213,15 +370,17 @@ class Jetpack_Sync_Module_Themes extends Jetpack_Sync_Module {
}
// Treat inactive sidebar a bit differently
- if ( ! empty( $moved_to_inactive ) ) {
+ if ( ! empty( $moved_to_inactive_ids ) ) {
+ $moved_to_inactive_name = array_map( array( $this, 'get_widget_name' ), $moved_to_inactive_ids );
/**
* Helps Sync log that a widgets IDs got moved to in active
*
* @since 4.9.0
*
- * @param array $sidebar, Sidebar id got changed
+ * @param array $moved_to_inactive_ids, Array of widgets id that moved to inactive id got changed
+ * @param array $moved_to_inactive_names, Array of widgets names that moved to inactive id got changed Since 5.0.0
*/
- do_action( 'jetpack_widget_moved_to_inactive', $moved_to_inactive );
+ do_action( 'jetpack_widget_moved_to_inactive', $moved_to_inactive_ids, $moved_to_inactive_name );
} elseif ( empty( $moved_to_sidebar ) &&
empty( $new_value['wp_inactive_widgets']) &&
! empty( $old_value['wp_inactive_widgets'] ) ) {
diff --git a/plugins/jetpack/sync/class.jetpack-sync-module-updates.php b/plugins/jetpack/sync/class.jetpack-sync-module-updates.php
index 793bb52e..91969a1c 100644
--- a/plugins/jetpack/sync/class.jetpack-sync-module-updates.php
+++ b/plugins/jetpack/sync/class.jetpack-sync-module-updates.php
@@ -4,12 +4,15 @@ class Jetpack_Sync_Module_Updates extends Jetpack_Sync_Module {
const UPDATES_CHECKSUM_OPTION_NAME = 'jetpack_updates_sync_checksum';
+ private $old_wp_version = null;
+
function name() {
return 'updates';
}
public function init_listeners( $callable ) {
-
+ global $wp_version;
+ $this->old_wp_version = $wp_version;
add_action( 'set_site_transient_update_plugins', array( $this, 'validate_update_change' ), 10, 3 );
add_action( 'set_site_transient_update_themes', array( $this, 'validate_update_change' ), 10, 3 );
add_action( 'set_site_transient_update_core', array( $this, 'validate_update_change' ), 10, 3 );
@@ -28,6 +31,19 @@ class Jetpack_Sync_Module_Updates extends Jetpack_Sync_Module {
), 10, 2 );
add_action( 'automatic_updates_complete', $callable );
+
+
+ if ( is_multisite() ) {
+ add_action( 'update_site_option_wpmu_upgrade_site', array ( $this, 'update_core_network_event' ), 10, 3 );
+ add_action( 'jetpack_sync_core_update_network', $callable, 10, 3 );
+ }
+
+ // Send data when update completes
+ add_action( '_core_updated_successfully', array( $this, 'update_core' ) );
+ add_action( 'jetpack_sync_core_reinstalled_successfully', $callable );
+ add_action( 'jetpack_sync_core_autoupdated_successfully', $callable, 10, 2 );
+ add_action( 'jetpack_sync_core_updated_successfully', $callable, 10, 2 );
+
}
public function init_full_sync_listeners( $callable ) {
@@ -39,6 +55,62 @@ class Jetpack_Sync_Module_Updates extends Jetpack_Sync_Module {
add_filter( 'jetpack_sync_before_send_jetpack_update_themes_change', array( $this, 'expand_themes' ) );
}
+ public function update_core_network_event( $option, $wp_db_version, $old_wp_db_version ) {
+ global $wp_version;
+ /**
+ * Sync event for when core wp network updates to a new db version
+ *
+ * @since 5.0.0
+ *
+ * @param int $wp_db_version the latest wp_db_version
+ * @param int $old_wp_db_version previous wp_db_version
+ * @param string $wp_version the latest wp_version
+ *
+ */
+ do_action( 'jetpack_sync_core_update_network', $wp_db_version, $old_wp_db_version, $wp_version );
+ }
+
+ public function update_core( $new_wp_version ) {
+ global $pagenow;
+
+ if ( isset( $_GET[ 'action' ] ) && 'do-core-reinstall' === $_GET[ 'action' ] ) {
+ /**
+ * Sync event that fires when core reinstall was successful
+ *
+ * @since 5.0.0
+ *
+ * @param string $new_wp_version the updated WordPress version
+ */
+ do_action( 'jetpack_sync_core_reinstalled_successfully', $new_wp_version );
+ return;
+ }
+
+ // Core was autoudpated
+ if ( 'update-core.php' !== $pagenow ) {
+ /**
+ * Sync event that fires when core autoupdate was successful
+ *
+ * @since 5.0.0
+ *
+ * @param string $new_wp_version the updated WordPress version
+ * @param string $old_wp_version the previous WordPress version
+ */
+ do_action( 'jetpack_sync_core_autoupdated_successfully', $new_wp_version, $this->old_wp_version );
+ return;
+ }
+ /**
+ * Sync event that fires when core update was successful
+ *
+ * @since 5.0.0
+ *
+ * @param string $new_wp_version the updated WordPress version
+ * @param string $old_wp_version the previous WordPress version
+ */
+ do_action( 'jetpack_sync_core_updated_successfully', $new_wp_version, $this->old_wp_version );
+ return;
+
+ }
+
public function get_update_checksum( $value ) {
// Create an new array so we don't modify the object passed in.
$a_value = (array) $value;
diff --git a/plugins/jetpack/sync/class.jetpack-sync-module-woocommerce.php b/plugins/jetpack/sync/class.jetpack-sync-module-woocommerce.php
index a60fe3a5..0eac6e1b 100644
--- a/plugins/jetpack/sync/class.jetpack-sync-module-woocommerce.php
+++ b/plugins/jetpack/sync/class.jetpack-sync-module-woocommerce.php
@@ -4,17 +4,34 @@ require_once JETPACK__PLUGIN_DIR . '/sync/class.jetpack-sync-module.php';
class Jetpack_Sync_Module_WooCommerce extends Jetpack_Sync_Module {
- private $meta_whitelist = array(
+ private $order_item_meta_whitelist = array(
+ // https://github.com/woocommerce/woocommerce/blob/master/includes/data-stores/class-wc-order-item-product-store.php#L20
'_product_id',
'_variation_id',
'_qty',
+ // Tax ones also included in below class
+ // https://github.com/woocommerce/woocommerce/blob/master/includes/data-stores/class-wc-order-item-fee-data-store.php#L20
'_tax_class',
+ '_tax_status',
'_line_subtotal',
'_line_subtotal_tax',
'_line_total',
'_line_tax',
'_line_tax_data',
- '_visibility',
+ // https://github.com/woocommerce/woocommerce/blob/master/includes/data-stores/class-wc-order-item-shipping-data-store.php#L20
+ 'method_id',
+ 'cost',
+ 'total_tax',
+ 'taxes',
+ // https://github.com/woocommerce/woocommerce/blob/master/includes/data-stores/class-wc-order-item-tax-data-store.php#L20
+ 'rate_id',
+ 'label',
+ 'compound',
+ 'tax_amount',
+ 'shipping_tax_amount',
+ // https://github.com/woocommerce/woocommerce/blob/master/includes/data-stores/class-wc-order-item-coupon-data-store.php
+ 'discount_amount',
+ 'discount_amount_tax',
);
private $order_item_table_name;
@@ -81,7 +98,7 @@ class Jetpack_Sync_Module_WooCommerce extends Jetpack_Sync_Module {
return array(
$order_items,
- $this->get_metadata( $order_item_ids, 'order_item', $this->meta_whitelist )
+ $this->get_metadata( $order_item_ids, 'order_item', $this->order_item_meta_whitelist ),
);
}
diff --git a/plugins/jetpack/sync/class.jetpack-sync-modules.php b/plugins/jetpack/sync/class.jetpack-sync-modules.php
index 7c5fff4e..2e6a7aa3 100644
--- a/plugins/jetpack/sync/class.jetpack-sync-modules.php
+++ b/plugins/jetpack/sync/class.jetpack-sync-modules.php
@@ -15,6 +15,7 @@ require_once dirname( __FILE__ ) . '/class.jetpack-sync-module-network-options.p
require_once dirname( __FILE__ ) . '/class.jetpack-sync-module-updates.php';
require_once dirname( __FILE__ ) . '/class.jetpack-sync-module-users.php';
require_once dirname( __FILE__ ) . '/class.jetpack-sync-module-themes.php';
+require_once dirname( __FILE__ ) . '/class.jetpack-sync-module-menus.php';
require_once dirname( __FILE__ ) . '/class.jetpack-sync-module-attachments.php';
require_once dirname( __FILE__ ) . '/class.jetpack-sync-module-meta.php';
require_once dirname( __FILE__ ) . '/class.jetpack-sync-module-terms.php';
@@ -32,6 +33,7 @@ class Jetpack_Sync_Modules {
'Jetpack_Sync_Module_Network_Options',
'Jetpack_Sync_Module_Terms',
'Jetpack_Sync_Module_Themes',
+ 'Jetpack_Sync_Module_Menus',
'Jetpack_Sync_Module_Users',
'Jetpack_Sync_Module_Posts',
'Jetpack_Sync_Module_Comments',
diff --git a/plugins/jetpack/sync/class.jetpack-sync-options.php b/plugins/jetpack/sync/class.jetpack-sync-options.php
deleted file mode 100644
index fb935478..00000000
--- a/plugins/jetpack/sync/class.jetpack-sync-options.php
+++ /dev/null
@@ -1,62 +0,0 @@
-<?php
-
-/**
- * Simple class to read/write to the options table, bypassing
- * problematic caching with get_option/set_option
- **/
-
-class Jetpack_Sync_Options {
-
- static function delete_option( $name ) {
- global $wpdb;
- $wpdb->query( $wpdb->prepare( "DELETE FROM $wpdb->options WHERE option_name = %s", $name ) );
- }
-
- static function update_option( $name, $value, $autoload = false ) {
-
- $autoload_value = $autoload ? 'yes' : 'no';
-
- // we write our own option updating code to bypass filters/caching/etc on set_option/get_option
- global $wpdb;
- $serialized_value = maybe_serialize( $value );
- // try updating, if no update then insert
- // TODO: try to deal with the fact that unchanged values can return updated_num = 0
- // below we used "insert ignore" to at least suppress the resulting error
- $updated_num = $wpdb->query(
- $wpdb->prepare(
- "UPDATE $wpdb->options SET option_value = %s WHERE option_name = %s",
- $serialized_value,
- $name
- )
- );
-
- if ( ! $updated_num ) {
- $updated_num = $wpdb->query(
- $wpdb->prepare(
- "INSERT IGNORE INTO $wpdb->options ( option_name, option_value, autoload ) VALUES ( %s, %s, '$autoload_value' )",
- $name,
- $serialized_value
- )
- );
- }
- return $updated_num;
- }
-
- static function get_option( $name, $default = null ) {
- global $wpdb;
- $value = $wpdb->get_var(
- $wpdb->prepare(
- "SELECT option_value FROM $wpdb->options WHERE option_name = %s LIMIT 1",
- $name
- )
- );
- $value = maybe_unserialize( $value );
-
- if ( $value === null && $default !== null ) {
- return $default;
- }
-
- return $value;
- }
-
-} \ No newline at end of file
diff --git a/plugins/jetpack/sync/class.jetpack-sync-sender.php b/plugins/jetpack/sync/class.jetpack-sync-sender.php
index a3b0aa7b..86b6b5a9 100644
--- a/plugins/jetpack/sync/class.jetpack-sync-sender.php
+++ b/plugins/jetpack/sync/class.jetpack-sync-sender.php
@@ -83,12 +83,12 @@ class Jetpack_Sync_Sender {
public function do_sync_and_set_delays( $queue ) {
// don't sync if importing
if ( defined( 'WP_IMPORTING' ) && WP_IMPORTING ) {
- return false;
+ return new WP_Error( 'is_importing' );
}
// don't sync if we are throttled
if ( $this->get_next_sync_time( $queue->id ) > microtime( true ) ) {
- return false;
+ return new WP_Error( 'sync_throttled' );
}
$start_time = microtime( true );
@@ -104,10 +104,10 @@ class Jetpack_Sync_Sender {
if ( is_wp_error( $sync_result ) ) {
if ( 'unclosed_buffer' === $sync_result->get_error_code() ) {
$this->set_next_sync_time( time() + self::QUEUE_LOCKED_SYNC_DELAY, $queue->id );
- } else {
+ }
+ if ( 'wpcom_error' === $sync_result->get_error_code() ) {
$this->set_next_sync_time( time() + self::WPCOM_ERROR_SYNC_DELAY, $queue->id );
}
- $sync_result = false;
} elseif ( $exceeded_sync_wait_threshold ) {
// if we actually sent data and it took a while, wait before sending again
$this->set_next_sync_time( time() + $this->get_sync_wait_time(), $queue->id );
@@ -166,7 +166,7 @@ class Jetpack_Sync_Sender {
do_action( 'jetpack_sync_before_send_queue_' . $queue->id );
if ( $queue->size() === 0 ) {
- return false;
+ return new WP_Error( 'empty_queue_' . $queue->id );
}
// now that we're sure we are about to sync, try to
// ignore user abort so we can avoid getting into a
@@ -181,7 +181,7 @@ class Jetpack_Sync_Sender {
if ( ! $buffer ) {
// buffer has no items
- return false;
+ return new WP_Error( 'empty_buffer' );
}
if ( is_wp_error( $buffer ) ) {
@@ -215,11 +215,11 @@ class Jetpack_Sync_Sender {
$queue->force_checkin();
}
if ( is_wp_error( $processed_item_ids ) ) {
- return $processed_item_ids;
+ return new WP_Error( 'wpcom_error', $processed_item_ids->get_error_code() );
}
- // returning a WP_Error is a sign to the caller that we should wait a while
+ // returning a WP_Error('wpcom_error') is a sign to the caller that we should wait a while
// before syncing again
- return new WP_Error( 'server_error' );
+ return new WP_Error( 'wpcom_error', 'jetpack_sync_send_data_false' );
} else {
// detect if the last item ID was an error
$had_wp_error = is_wp_error( end( $processed_item_ids ) );
@@ -244,7 +244,7 @@ class Jetpack_Sync_Sender {
// returning a WP_Error is a sign to the caller that we should wait a while
// before syncing again
if ( $had_wp_error ) {
- return $wp_error;
+ return new WP_Error( 'wpcom_error', $wp_error->get_error_code() );
}
}
return true;