diff --git a/packages/sync/src/modules/class-posts.php b/packages/sync/src/modules/class-posts.php index 3875611a7bde..b50c3909fdda 100644 --- a/packages/sync/src/modules/class-posts.php +++ b/packages/sync/src/modules/class-posts.php @@ -116,6 +116,7 @@ public function init_listeners( $callable ) { $this->action_handler = $callable; add_action( 'wp_insert_post', array( $this, 'wp_insert_post' ), 11, 3 ); + add_action( 'wp_after_insert_post', array( $this, 'wp_after_insert_post' ), 11, 2 ); add_action( 'jetpack_sync_save_post', $callable, 10, 4 ); add_action( 'deleted_post', $callable, 10 ); @@ -570,6 +571,34 @@ public function wp_insert_post( $post_ID, $post = null, $update = null ) { do_action( 'jetpack_sync_save_post', $post_ID, $post, $update, $state ); unset( $this->previous_status[ $post_ID ] ); + /* + * WP 5.6 introduced the wp_after_insert_post hook that triggers when + * the post, meta and terms has been updated. We are migrating send_published + * function to this hook to ensure we have all data for WP.com functionality. + * @todo: remove full if statement when WordPress 5.6 is the minimum required version. + */ + if ( ! function_exists( 'wp_after_insert_post' ) ) { + $this->send_published( $post_ID, $post ); + } + } + + /** + * Handler for the wp_after_insert_post hook. + * Called after creation/update of a new post. + * + * @param int $post_ID Post ID. + * @param \WP_Post $post Post object. + **/ + public function wp_after_insert_post( $post_ID, $post ) { + if ( ! is_numeric( $post_ID ) || is_null( $post ) ) { + return; + } + + // Workaround for https://github.com/woocommerce/woocommerce/issues/18007. + if ( $post && 'shop_order' === $post->post_type ) { + $post = get_post( $post_ID ); + } + $this->send_published( $post_ID, $post ); } diff --git a/tests/php/sync/test_class.jetpack-sync-posts.php b/tests/php/sync/test_class.jetpack-sync-posts.php index cb40f72a741a..b27f24f88c67 100644 --- a/tests/php/sync/test_class.jetpack-sync-posts.php +++ b/tests/php/sync/test_class.jetpack-sync-posts.php @@ -1225,6 +1225,37 @@ public function test_sync_jetpack_publish_post_works_with_interjecting_plugins() $this->assertEquals( $events[3]->action, 'jetpack_published_post' ); } + /** + * Data Provider for test_sync_jetpack_published_post_no_action test. + * + * @return array[] Test parameters. + */ + public function provider_jetpack_published_post_no_action() { + return array( + array( null, $this->post ), + array( 'alpha', $this->post ), + array( $this->post_id, null ), + array( -1111, $this->post ), + ); + } + + /** + * Verify no `jetpack_published_post` action is triggerd with invalid $post_ID or $post provided. + * + * @dataProvider provider_jetpack_published_post_no_action + * @param int $post_ID Post ID. + * @param \WP_Post $post Post object. + */ + public function test_sync_jetpack_published_post_no_action( $post_ID, $post ) { + $this->server_event_storage->reset(); + do_action( 'wp_after_insert_post', $post_ID, $post, false ); + + $this->sender->do_sync(); + + $events = $this->server_event_storage->get_all_events( 'jetpack_published_post' ); + $this->assertSame( 0, count( $events ) ); + } + /** * Test if `Modules\Posts\daily_akismet_meta_cleanup_before` will properly chunk it's parameters in chunks of 100 *