diff options
Diffstat (limited to 'plugins/jetpack/sync')
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; |