Commit 32d193f96f for wordpress.org

commit 32d193f96fea928a487e51698fd1861bf6c66978
Author: Peter Wilson <wilson@peterwilson.cc>
Date:   Fri Oct 16 03:34:08 2020 +0000

    REST API, Posts: Add a hook to fire once a post, its terms and meta update.

    Introduces the action `wp_after_insert_post` inside a wrapper function of the same name. This hook allows plugin developers to access a posts full data (including its terms and meta data) regardless of the workflow used to save it.

    A new parameter is introduced to `wp_insert_post()` to indicate whether the hook should be fired within the function call or will be fired afterward.

    Props aristath, Collizo4sky, danielbachhuber, joyously, kadamwhite, kraftbj, markparnell, mikeschroder, noisysocks, peterwilsoncc, SergeyBiryukov, talldanwp, thewebprincess, TimothyBlynJacobs.
    Fixes #45114.

    Built from https://develop.svn.wordpress.org/trunk@49172


    git-svn-id: http://core.svn.wordpress.org/trunk@48934 1a063a9b-81f0-0310-95a4-ce76da25c4cd

diff --git a/wp-admin/includes/post.php b/wp-admin/includes/post.php
index 0faf51d412..78029fd456 100644
--- a/wp-admin/includes/post.php
+++ b/wp-admin/includes/post.php
@@ -685,12 +685,15 @@ function get_default_post_to_edit( $post_type = 'post', $create_in_db = false )
 				'post_title'  => __( 'Auto Draft' ),
 				'post_type'   => $post_type,
 				'post_status' => 'auto-draft',
-			)
+			),
+			false,
+			true
 		);
 		$post    = get_post( $post_id );
 		if ( current_theme_supports( 'post-formats' ) && post_type_supports( $post->post_type, 'post-formats' ) && get_option( 'default_post_format' ) ) {
 			set_post_format( $post, get_option( 'default_post_format' ) );
 		}
+		wp_after_insert_post( $post, false );

 		// Schedule auto-draft cleanup.
 		if ( ! wp_next_scheduled( 'wp_scheduled_auto_draft_delete' ) ) {
diff --git a/wp-includes/class-wp-customize-manager.php b/wp-includes/class-wp-customize-manager.php
index 832cf2f6fd..88a8128acd 100644
--- a/wp-includes/class-wp-customize-manager.php
+++ b/wp-includes/class-wp-customize-manager.php
@@ -3105,6 +3105,8 @@ final class WP_Customize_Manager {
 		/** This action is documented in wp-includes/post.php */
 		do_action( 'wp_insert_post', $post->ID, $post, true );

+		wp_after_insert_post( $post, true );
+
 		wp_trash_post_comments( $post_id );

 		/** This action is documented in wp-includes/post.php */
diff --git a/wp-includes/post.php b/wp-includes/post.php
index ee1c9caea9..2042342eea 100644
--- a/wp-includes/post.php
+++ b/wp-includes/post.php
@@ -3645,10 +3645,11 @@ function wp_get_recent_posts( $args = array(), $output = ARRAY_A ) {
  *     @type array  $tax_input             Array of taxonomy terms keyed by their taxonomy name. Default empty.
  *     @type array  $meta_input            Array of post meta values keyed by their post meta key. Default empty.
  * }
- * @param bool  $wp_error Optional. Whether to return a WP_Error on failure. Default false.
+ * @param bool  $wp_error         Optional. Whether to return a WP_Error on failure. Default false.
+ * @param bool  $fire_after_hooks Whether to fire the after insert hooks. Default true.
  * @return int|WP_Error The post ID on success. The value 0 or WP_Error on failure.
  */
-function wp_insert_post( $postarr, $wp_error = false ) {
+function wp_insert_post( $postarr, $wp_error = false, $fire_after_hooks = true ) {
 	global $wpdb;

 	// Capture original pre-sanitized array for passing into filters.
@@ -4310,6 +4311,10 @@ function wp_insert_post( $postarr, $wp_error = false ) {
 	 */
 	do_action( 'wp_insert_post', $post_ID, $post, $update );

+	if ( $fire_after_hooks ) {
+		wp_after_insert_post( $post, $update );
+	}
+
 	return $post_ID;
 }

@@ -4321,12 +4326,13 @@ function wp_insert_post( $postarr, $wp_error = false ) {
  *
  * @since 1.0.0
  *
- * @param array|object $postarr  Optional. Post data. Arrays are expected to be escaped,
- *                               objects are not. Default array.
- * @param bool         $wp_error Optional. Allow return of WP_Error on failure. Default false.
+ * @param array|object $postarr          Optional. Post data. Arrays are expected to be escaped,
+ *                                       objects are not. Default array.
+ * @param bool         $wp_error         Optional. Allow return of WP_Error on failure. Default false.
+ * @param bool         $fire_after_hooks Whether to fire the after insert hooks. Default true.
  * @return int|WP_Error The post ID on success. The value 0 or WP_Error on failure.
  */
-function wp_update_post( $postarr = array(), $wp_error = false ) {
+function wp_update_post( $postarr = array(), $wp_error = false, $fire_after_hooks = true ) {
 	if ( is_object( $postarr ) ) {
 		// Non-escaped post was passed.
 		$postarr = get_object_vars( $postarr );
@@ -4391,7 +4397,7 @@ function wp_update_post( $postarr = array(), $wp_error = false ) {
 		}
 	}

-	return wp_insert_post( $postarr, $wp_error );
+	return wp_insert_post( $postarr, $wp_error, $fire_after_hooks );
 }

 /**
@@ -4467,6 +4473,8 @@ function wp_publish_post( $post ) {

 	/** This action is documented in wp-includes/post.php */
 	do_action( 'wp_insert_post', $post->ID, $post, true );
+
+	wp_after_insert_post( $post, true );
 }

 /**
@@ -4916,6 +4924,34 @@ function wp_transition_post_status( $new_status, $old_status, $post ) {
 	do_action( "{$new_status}_{$post->post_type}", $post->ID, $post );
 }

+/**
+ * Fires actions after a post, its terms and meta data has been saved.
+ *
+ * @since 5.6.0
+ *
+ * @param int|WP_Post $post   The post ID or object that has been saved.
+ * @param bool        $update Whether this is an existing post being updated.
+ */
+function wp_after_insert_post( $post, $update ) {
+	$post = get_post( $post );
+	if ( ! $post ) {
+		return;
+	}
+
+	$post_id = $post->ID;
+
+	/**
+	 * Fires once a post, its terms and meta data has been saved.
+	 *
+	 * @since 5.6.0
+	 *
+	 * @param int     $post_id Post ID.
+	 * @param WP_Post $post    Post object.
+	 * @param bool    $update  Whether this is an existing post being updated.
+	 */
+	do_action( 'wp_after_insert_post', $post_id, $post, $update );
+}
+
 //
 // Comment, trackback, and pingback functions.
 //
@@ -5789,13 +5825,14 @@ function is_local_attachment( $url ) {
  *
  * @see wp_insert_post()
  *
- * @param string|array $args     Arguments for inserting an attachment.
- * @param string       $file     Optional. Filename.
- * @param int          $parent   Optional. Parent post ID.
- * @param bool         $wp_error Optional. Whether to return a WP_Error on failure. Default false.
+ * @param string|array $args             Arguments for inserting an attachment.
+ * @param string       $file             Optional. Filename.
+ * @param int          $parent           Optional. Parent post ID.
+ * @param bool         $wp_error         Optional. Whether to return a WP_Error on failure. Default false.
+ * @param bool         $fire_after_hooks Whether to fire the after insert hooks. Default true.
  * @return int|WP_Error The attachment ID on success. The value 0 or WP_Error on failure.
  */
-function wp_insert_attachment( $args, $file = false, $parent = 0, $wp_error = false ) {
+function wp_insert_attachment( $args, $file = false, $parent = 0, $wp_error = false, $fire_after_hooks = true ) {
 	$defaults = array(
 		'file'        => $file,
 		'post_parent' => 0,
@@ -5809,7 +5846,7 @@ function wp_insert_attachment( $args, $file = false, $parent = 0, $wp_error = fa

 	$data['post_type'] = 'attachment';

-	return wp_insert_post( $data, $wp_error );
+	return wp_insert_post( $data, $wp_error, $fire_after_hooks );
 }

 /**
diff --git a/wp-includes/rest-api/endpoints/class-wp-rest-attachments-controller.php b/wp-includes/rest-api/endpoints/class-wp-rest-attachments-controller.php
index 58aaa37a81..fcbf70f501 100644
--- a/wp-includes/rest-api/endpoints/class-wp-rest-attachments-controller.php
+++ b/wp-includes/rest-api/endpoints/class-wp-rest-attachments-controller.php
@@ -191,6 +191,8 @@ class WP_REST_Attachments_Controller extends WP_REST_Posts_Controller {
 		 */
 		do_action( 'rest_after_insert_attachment', $attachment, $request, true );

+		wp_after_insert_post( $attachment, false );
+
 		if ( defined( 'REST_REQUEST' ) && REST_REQUEST ) {
 			// Set a custom header with the attachment_id.
 			// Used by the browser/client to resume creating image sub-sizes after a PHP fatal error.
@@ -270,7 +272,7 @@ class WP_REST_Attachments_Controller extends WP_REST_Posts_Controller {
 		}

 		// $post_parent is inherited from $attachment['post_parent'].
-		$id = wp_insert_attachment( wp_slash( (array) $attachment ), $file, 0, true );
+		$id = wp_insert_attachment( wp_slash( (array) $attachment ), $file, 0, true, false );

 		if ( is_wp_error( $id ) ) {
 			if ( 'db_update_error' === $id->get_error_code() ) {
@@ -345,6 +347,8 @@ class WP_REST_Attachments_Controller extends WP_REST_Posts_Controller {
 		/** This action is documented in wp-includes/rest-api/endpoints/class-wp-rest-attachments-controller.php */
 		do_action( 'rest_after_insert_attachment', $attachment, $request, false );

+		wp_after_insert_post( $attachment, true );
+
 		$response = $this->prepare_item_for_response( $attachment, $request );
 		$response = rest_ensure_response( $response );

diff --git a/wp-includes/rest-api/endpoints/class-wp-rest-posts-controller.php b/wp-includes/rest-api/endpoints/class-wp-rest-posts-controller.php
index 76a924cf96..06db540af2 100644
--- a/wp-includes/rest-api/endpoints/class-wp-rest-posts-controller.php
+++ b/wp-includes/rest-api/endpoints/class-wp-rest-posts-controller.php
@@ -591,7 +591,7 @@ class WP_REST_Posts_Controller extends WP_REST_Controller {

 		$prepared_post->post_type = $this->post_type;

-		$post_id = wp_insert_post( wp_slash( (array) $prepared_post ), true );
+		$post_id = wp_insert_post( wp_slash( (array) $prepared_post ), true, false );

 		if ( is_wp_error( $post_id ) ) {

@@ -677,6 +677,8 @@ class WP_REST_Posts_Controller extends WP_REST_Controller {
 		 */
 		do_action( "rest_after_insert_{$this->post_type}", $post, $request, true );

+		wp_after_insert_post( $post, false );
+
 		$response = $this->prepare_item_for_response( $post, $request );
 		$response = rest_ensure_response( $response );

@@ -758,7 +760,7 @@ class WP_REST_Posts_Controller extends WP_REST_Controller {
 		}

 		// Convert the post object to an array, otherwise wp_update_post() will expect non-escaped input.
-		$post_id = wp_update_post( wp_slash( (array) $post ), true );
+		$post_id = wp_update_post( wp_slash( (array) $post ), true, false );

 		if ( is_wp_error( $post_id ) ) {
 			if ( 'db_update_error' === $post_id->get_error_code() ) {
@@ -828,6 +830,8 @@ class WP_REST_Posts_Controller extends WP_REST_Controller {
 		/** This action is documented in wp-includes/rest-api/endpoints/class-wp-rest-posts-controller.php */
 		do_action( "rest_after_insert_{$this->post_type}", $post, $request, false );

+		wp_after_insert_post( $post, true );
+
 		$response = $this->prepare_item_for_response( $post, $request );

 		return rest_ensure_response( $response );
diff --git a/wp-includes/version.php b/wp-includes/version.php
index 1bec5fdb76..89bfbfa259 100644
--- a/wp-includes/version.php
+++ b/wp-includes/version.php
@@ -13,7 +13,7 @@
  *
  * @global string $wp_version
  */
-$wp_version = '5.6-alpha-49171';
+$wp_version = '5.6-alpha-49172';

 /**
  * Holds the WordPress DB revision, increments when changes are made to the WordPress DB schema.