WordPress at a glance

wp_insert_post() WP 1.0.0

Safely insert/update post in the database.

The function clears the passed data; makes some checks; fills in the missing variables (for example, if you do not pass the date of the post, the date will be set automatically).

For update existing post data, you need to set $postarr['ID'] parameter, which must contain the ID of the post you need to update. Or use special function wp_update_post() which works based on this function.

This function requires slashed data. This means that if you pass NOT $_POST data, then you need to process the passing data array with wp_slash().

Keep in mind that the function has hooks, for example, save_post, wp_insert_post. In the functions of such hooks, you can use $_POST or $_GET data. These data may be missing in the front end. Therefore, when the function is used in the front, it can cause errors. In such cases, look for errors in the functions of such hooks.

Categories

Categories need to be passed as an array of integers that match the category IDs in the database. This is the case even where only one category is assigned to the post.

See also: wp_set_post_terms()

Security

This function processes the passing data with sanitize_post(), which checks and clears the values of all fields (kses, etc.). Therefore, there is no need to worry about clearing the data being transferred.

However, you may need to remove HTML, JavaScript, or PHP tags from the title of the post or other fields. WordPress does not do this automatically. This can be easily done by using wp_strip_all_tags(), especially when users of yor site can publish posts from the front end:

// insert post to DB
$post_id = wp_insert_post( array(
	'post_title'    => wp_strip_all_tags( $_POST['post_title'] ), // clear all tags
	'post_content'  => $_POST['post_content'],
	'post_status'   => 'publish',
	'post_author'   => 1,
	'post_category' => array( 20,59 )
) );
Emoji note

From version 4.2, with the introduction of Emoji. This function automatically converts smiley symbols in the fields 'post_title', 'post_content', 'post_excerpt', if the encoding of DB tables utf8, not utf8mb4. This is doing with help of wp_encode_emoji() function.

Notes:

  • See: sanitize_post()
  • Global. wpdb. $wpdb WordPress database abstraction object.
  • Since 4.2.0 Support was added for encoding emoji in the post title, content, and excerpt.
  • Since 4.4.0 A 'meta_input' array can now be passed to $postarr to add post meta data.
Hooks from function:
Return

Int/0/WP_Error.

  • Post ID - when the post has been inserted.
  • 0 - when $wp_error parameter is disabled and there is an inserting error.
  • WP_Error object - when the $wp_error parameter is enabled and there is an inserting error.

Usage

$post_id = wp_insert_post( $postarr, $wp_error );

Usage template

// insert post into the database
$post_id = wp_insert_post( wp_slash( array(
	'post_status'   => 'draft',
	'post_type'     => 'post',
	'post_author'   => $user_ID,
	'post_parent'   => 0,
	'menu_order'    => 0,
	'guid'          => '',
	'post_excerpt'  => '',
	'tax_input'     => array( 'category' => ['term', 'term2', 'term3'] ),
	'meta_input'    => array( 'meta_key'=>'meta_value' ),
) ) );
$postarr(array) (required)

An array of data to be inserted into the Database. The array keys are exactly equal to the fields of the wp_posts table, the passed keys values will be inserted into the value of the table fields.

If you pass the ID parameter, the existing post with the same ID will be edited, i.e. when you specify the ID parameter, you update the post, not create a new one.

Parameters of the transmitted array:

$data = array(
	'ID'             => <post id>,                                             // Do you update an existing post?
	'menu_order'     => <order>,                                               // If the post is a "static page", set its order in the menu.
	'comment_status' => 'closed' | 'open',                                     // 'closed' means that comments are closed.
	'ping_status'    => 'closed' | 'open',                                     // 'closed' means the pings and notifications are off.
	'pinged'         => '',                                                    // separated list of URLs that have been pinged
	'to_ping'        => '',                                                    // Separated list of URLs that have been pinged
	'post_author'    => <user ID>,                                             // ID of post author
	'post_content'   => <the text of the post>,                                // post content
	'post_date'      => Y-m-d H:i:s,                                           // The time the post was created.
	'post_date_gmt'  => Y-m-d H:i:s,                                           // The time the post was created in GMT time zone.
	'post_excerpt'   => <an excerpt>,                                          // excerpt text
	'post_name'      => <the name>,                                            // The alternate name of the entry (slug) will be used in the Url.
	'post_parent'    => <post ID>,                                             // ID of the parent record, if necessary.
	'post_password'  => ?,                                                     // The password to view the post.
	'post_status'    => 'draft' | 'publish' | 'pending'| 'future' | 'private', // The status of the post being created.
	'post_title'     => <the title>,                                                   
	'post_type'      => 'post' | 'page' | 'nav_menu_item' | custom type, 
	'post_category'  => array(<category id>, <...>),                           // Category to which the post belongs to.
	'tags_input'     => '<tag>, <tag>, <...>',                                 // Post tags (indicated by names, slugs or ID).
	'tax_input'      => array( 'taxonomy_name' => array('term', 'term2') ),    // Which taxonomies to attach the post to. Like 'post_category', but for new taxonomies.
	'meta_input'     => array( 'meta_key'=>'meta_value' ),                     // Add the specified meta fields. Default is ''. Since WP 4.4.
);
  • $ID (int)
    The post ID. If equal to something other than 0, the post with that ID will be updated.

  • $post_author (int)
    The ID of the user who added the post. Default is the current user ID.

  • $post_date (string)
    The date of the post. Default is the current time.

  • $post_date_gmt (string)
    The date of the post in the GMT timezone. Default is the value of $post_date.

  • $post_content (mixed)
    The post content. Default empty.

  • $post_content_filtered (string)
    The filtered post content. Default empty.

  • $post_title (string)
    The post title. Default empty.

  • $post_excerpt (string)
    The post excerpt. Default empty.

  • $post_status (string)
    The post status. Default 'draft'.

  • $post_type (string)
    The post type. Default 'post'.

  • $comment_status (string)
    Whether the post can accept comments. Accepts 'open' or 'closed'. Default is the value of 'default_comment_status' option.

  • $ping_status (string)
    Whether the post can accept pings. Accepts 'open' or 'closed'. Default is the value of 'default_ping_status' option.

  • $post_password (string)
    The password to access the post. Default empty.

  • $post_name (string)
    The post name. Default is the sanitized post title when creating a new post.

  • $to_ping (string)
    Space or new line - separated list of URLs to ping. Default empty.

  • $pinged (string)
    Space or new line - separated list of URLs that have been pinged. Default empty.

  • $post_modified (string)
    The date when the post was last modified. Default is the current time.

  • $post_modified_gmt (string)
    The date when the post was last modified in the GMT timezone. Default is the current time.

  • $post_parent (int)
    Set this for the post it belongs to, if any.

  • $menu_order (int)
    The order the post should be displayed in.

  • $post_mime_type (string)
    The mime type of the post. Default empty.

  • $guid (string)
    Global Unique ID for referencing the post. Default empty.

  • $post_category (array)
    Array of category names, slugs, or IDs. Defaults to value of the 'default_category' option.

  • $tags_input (array)
    Array of tag names, slugs, or IDs. Default empty.

  • $tax_input (array)
    Array of taxonomy terms keyed by their taxonomy name. Default empty.

  • $meta_input (array)
    Array of post meta values keyed by their post meta key. Default empty.

Notes

  • post_title and post_content are required
  • post_status: If post_status=future, you must specify the post_date in order for WordPress to know when to publish post.
  • post_category: Equivalent to calling wp_set_post_categories().
  • tags_input: Equivalent to calling wp_set_post_tags().
  • tax_input: Equivalent to calling wp_set_post_terms() for each custom taxonomy in the array. if the current user does not have the capability to work with taxonomies then the definition of the tax_input parameter to attach the post to term will not work. To do this anyway, use wp_set_object_terms().
  • page_template: the page_template table field has been removed, now the template for the static page is set in wp_postmeta table. For doing this wp_insert_post() uses update_post_meta( $post_ID, '_wp_page_template', $page_template );
$wp_error(true/false)
Whether to return a WP_Error on failure.
Default: false

Examples

Before using wp_insert_post(), you need to create a data array, which is then passed to the functions. In the array, at least you need to specify post_title and post_content otherwise the post will not be created. Other fields for which no data is specified will be created automatically, with default values.

You can specify more data in the array than it is shown below. The array keys are names of the WordPress Database wp_posts table fields.

#1 Insert the post and check for errors

$post_id = wp_insert_post( $POST['post_data'], true );

if( is_wp_error($post_id) ){
	echo $post_id->get_error_message();
}
else {
	// you can now use $post_id to add, for example
	// meta field using add_post_meta() or update_post_meta()
}

#2 A simple example of inserting a new post into a WordPress Database

// Create an array
$post_data = array(
	'post_title'    => 'Заголовок записи',
	'post_content'  => 'Здесь должен быть контент (текст) записи.',
	'post_status'   => 'publish',
	'post_author'   => 1,
	'post_category' => array(8,39)
);

// Insert data into database
$post_id = wp_insert_post( wp_slash($post_data) );

Categories must be passed in the array, even if one category is specified. For example: 'post_category' => array(8)

See also: wp_set_post_terms() when you want to set custom taxonomies for a post.

#3 Insert post with custom taxonomy and post meta data

$post_arr = array(
	'post_title'   => 'Test post',
	'post_content' => 'Test post content',
	'post_status'  => 'publish',
	'post_author'  => get_current_user_id(),
	'tax_input'    => array(
		'hierarchical_tax'     => array( 13, 10 ),
		'non_hierarchical_tax' => 'tax name 1, tax name 2',
	),
	'meta_input'   => array(
		'test_meta_key' => 'value of test_meta_key',
	),
);

Code of wp_insert_post: wp-includes/post.php VER 4.9.8

<?php
function wp_insert_post( $postarr, $wp_error = false ) {
	global $wpdb;

	$user_id = get_current_user_id();

	$defaults = array(
		'post_author' => $user_id,
		'post_content' => '',
		'post_content_filtered' => '',
		'post_title' => '',
		'post_excerpt' => '',
		'post_status' => 'draft',
		'post_type' => 'post',
		'comment_status' => '',
		'ping_status' => '',
		'post_password' => '',
		'to_ping' =>  '',
		'pinged' => '',
		'post_parent' => 0,
		'menu_order' => 0,
		'guid' => '',
		'import_id' => 0,
		'context' => '',
	);

	$postarr = wp_parse_args($postarr, $defaults);

	unset( $postarr[ 'filter' ] );

	$postarr = sanitize_post($postarr, 'db');

	// Are we updating or creating?
	$post_ID = 0;
	$update = false;
	$guid = $postarr['guid'];

	if ( ! empty( $postarr['ID'] ) ) {
		$update = true;

		// Get the post ID and GUID.
		$post_ID = $postarr['ID'];
		$post_before = get_post( $post_ID );
		if ( is_null( $post_before ) ) {
			if ( $wp_error ) {
				return new WP_Error( 'invalid_post', __( 'Invalid post ID.' ) );
			}
			return 0;
		}

		$guid = get_post_field( 'guid', $post_ID );
		$previous_status = get_post_field('post_status', $post_ID );
	} else {
		$previous_status = 'new';
	}

	$post_type = empty( $postarr['post_type'] ) ? 'post' : $postarr['post_type'];

	$post_title = $postarr['post_title'];
	$post_content = $postarr['post_content'];
	$post_excerpt = $postarr['post_excerpt'];
	if ( isset( $postarr['post_name'] ) ) {
		$post_name = $postarr['post_name'];
	} elseif ( $update ) {
		// For an update, don't modify the post_name if it wasn't supplied as an argument.
		$post_name = $post_before->post_name;
	}

	$maybe_empty = 'attachment' !== $post_type
		&& ! $post_content && ! $post_title && ! $post_excerpt
		&& post_type_supports( $post_type, 'editor' )
		&& post_type_supports( $post_type, 'title' )
		&& post_type_supports( $post_type, 'excerpt' );

	/**
	 * Filters whether the post should be considered "empty".
	 *
	 * The post is considered "empty" if both:
	 * 1. The post type supports the title, editor, and excerpt fields
	 * 2. The title, editor, and excerpt fields are all empty
	 *
	 * Returning a truthy value to the filter will effectively short-circuit
	 * the new post being inserted, returning 0. If $wp_error is true, a WP_Error
	 * will be returned instead.
	 *
	 * @since 3.3.0
	 *
	 * @param bool  $maybe_empty Whether the post should be considered "empty".
	 * @param array $postarr     Array of post data.
	 */
	if ( apply_filters( 'wp_insert_post_empty_content', $maybe_empty, $postarr ) ) {
		if ( $wp_error ) {
			return new WP_Error( 'empty_content', __( 'Content, title, and excerpt are empty.' ) );
		} else {
			return 0;
		}
	}

	$post_status = empty( $postarr['post_status'] ) ? 'draft' : $postarr['post_status'];
	if ( 'attachment' === $post_type && ! in_array( $post_status, array( 'inherit', 'private', 'trash', 'auto-draft' ), true ) ) {
		$post_status = 'inherit';
	}

	if ( ! empty( $postarr['post_category'] ) ) {
		// Filter out empty terms.
		$post_category = array_filter( $postarr['post_category'] );
	}

	// Make sure we set a valid category.
	if ( empty( $post_category ) || 0 == count( $post_category ) || ! is_array( $post_category ) ) {
		// 'post' requires at least one category.
		if ( 'post' == $post_type && 'auto-draft' != $post_status ) {
			$post_category = array( get_option('default_category') );
		} else {
			$post_category = array();
		}
	}

	// Don't allow contributors to set the post slug for pending review posts.
	if ( 'pending' == $post_status && !current_user_can( 'publish_posts' ) ) {
		$post_name = '';
	}

	/*
	 * Create a valid post name. Drafts and pending posts are allowed to have
	 * an empty post name.
	 */
	if ( empty($post_name) ) {
		if ( !in_array( $post_status, array( 'draft', 'pending', 'auto-draft' ) ) ) {
			$post_name = sanitize_title($post_title);
		} else {
			$post_name = '';
		}
	} else {
		// On updates, we need to check to see if it's using the old, fixed sanitization context.
		$check_name = sanitize_title( $post_name, '', 'old-save' );
		if ( $update && strtolower( urlencode( $post_name ) ) == $check_name && get_post_field( 'post_name', $post_ID ) == $check_name ) {
			$post_name = $check_name;
		} else { // new post, or slug has changed.
			$post_name = sanitize_title($post_name);
		}
	}

	/*
	 * If the post date is empty (due to having been new or a draft) and status
	 * is not 'draft' or 'pending', set date to now.
	 */
	if ( empty( $postarr['post_date'] ) || '0000-00-00 00:00:00' == $postarr['post_date'] ) {
		if ( empty( $postarr['post_date_gmt'] ) || '0000-00-00 00:00:00' == $postarr['post_date_gmt'] ) {
			$post_date = current_time( 'mysql' );
		} else {
			$post_date = get_date_from_gmt( $postarr['post_date_gmt'] );
		}
	} else {
		$post_date = $postarr['post_date'];
	}

	// Validate the date.
	$mm = substr( $post_date, 5, 2 );
	$jj = substr( $post_date, 8, 2 );
	$aa = substr( $post_date, 0, 4 );
	$valid_date = wp_checkdate( $mm, $jj, $aa, $post_date );
	if ( ! $valid_date ) {
		if ( $wp_error ) {
			return new WP_Error( 'invalid_date', __( 'Invalid date.' ) );
		} else {
			return 0;
		}
	}

	if ( empty( $postarr['post_date_gmt'] ) || '0000-00-00 00:00:00' == $postarr['post_date_gmt'] ) {
		if ( ! in_array( $post_status, array( 'draft', 'pending', 'auto-draft' ) ) ) {
			$post_date_gmt = get_gmt_from_date( $post_date );
		} else {
			$post_date_gmt = '0000-00-00 00:00:00';
		}
	} else {
		$post_date_gmt = $postarr['post_date_gmt'];
	}

	if ( $update || '0000-00-00 00:00:00' == $post_date ) {
		$post_modified     = current_time( 'mysql' );
		$post_modified_gmt = current_time( 'mysql', 1 );
	} else {
		$post_modified     = $post_date;
		$post_modified_gmt = $post_date_gmt;
	}

	if ( 'attachment' !== $post_type ) {
		if ( 'publish' == $post_status ) {
			$now = gmdate('Y-m-d H:i:59');
			if ( mysql2date('U', $post_date_gmt, false) > mysql2date('U', $now, false) ) {
				$post_status = 'future';
			}
		} elseif ( 'future' == $post_status ) {
			$now = gmdate('Y-m-d H:i:59');
			if ( mysql2date('U', $post_date_gmt, false) <= mysql2date('U', $now, false) ) {
				$post_status = 'publish';
			}
		}
	}

	// Comment status.
	if ( empty( $postarr['comment_status'] ) ) {
		if ( $update ) {
			$comment_status = 'closed';
		} else {
			$comment_status = get_default_comment_status( $post_type );
		}
	} else {
		$comment_status = $postarr['comment_status'];
	}

	// These variables are needed by compact() later.
	$post_content_filtered = $postarr['post_content_filtered'];
	$post_author = isset( $postarr['post_author'] ) ? $postarr['post_author'] : $user_id;
	$ping_status = empty( $postarr['ping_status'] ) ? get_default_comment_status( $post_type, 'pingback' ) : $postarr['ping_status'];
	$to_ping = isset( $postarr['to_ping'] ) ? sanitize_trackback_urls( $postarr['to_ping'] ) : '';
	$pinged = isset( $postarr['pinged'] ) ? $postarr['pinged'] : '';
	$import_id = isset( $postarr['import_id'] ) ? $postarr['import_id'] : 0;

	/*
	 * The 'wp_insert_post_parent' filter expects all variables to be present.
	 * Previously, these variables would have already been extracted
	 */
	if ( isset( $postarr['menu_order'] ) ) {
		$menu_order = (int) $postarr['menu_order'];
	} else {
		$menu_order = 0;
	}

	$post_password = isset( $postarr['post_password'] ) ? $postarr['post_password'] : '';
	if ( 'private' == $post_status ) {
		$post_password = '';
	}

	if ( isset( $postarr['post_parent'] ) ) {
		$post_parent = (int) $postarr['post_parent'];
	} else {
		$post_parent = 0;
	}

	/**
	 * Filters the post parent -- used to check for and prevent hierarchy loops.
	 *
	 * @since 3.1.0
	 *
	 * @param int   $post_parent Post parent ID.
	 * @param int   $post_ID     Post ID.
	 * @param array $new_postarr Array of parsed post data.
	 * @param array $postarr     Array of sanitized, but otherwise unmodified post data.
	 */
	$post_parent = apply_filters( 'wp_insert_post_parent', $post_parent, $post_ID, compact( array_keys( $postarr ) ), $postarr );

	/*
	 * If the post is being untrashed and it has a desired slug stored in post meta,
	 * reassign it.
	 */
	if ( 'trash' === $previous_status && 'trash' !== $post_status ) {
		$desired_post_slug = get_post_meta( $post_ID, '_wp_desired_post_slug', true );
		if ( $desired_post_slug ) {
			delete_post_meta( $post_ID, '_wp_desired_post_slug' );
			$post_name = $desired_post_slug;
		}
	}

	// If a trashed post has the desired slug, change it and let this post have it.
	if ( 'trash' !== $post_status && $post_name ) {
		wp_add_trashed_suffix_to_post_name_for_trashed_posts( $post_name, $post_ID );
	}

	// When trashing an existing post, change its slug to allow non-trashed posts to use it.
	if ( 'trash' === $post_status && 'trash' !== $previous_status && 'new' !== $previous_status ) {
		$post_name = wp_add_trashed_suffix_to_post_name_for_post( $post_ID );
	}

	$post_name = wp_unique_post_slug( $post_name, $post_ID, $post_status, $post_type, $post_parent );

	// Don't unslash.
	$post_mime_type = isset( $postarr['post_mime_type'] ) ? $postarr['post_mime_type'] : '';

	// Expected_slashed (everything!).
	$data = compact( 'post_author', 'post_date', 'post_date_gmt', 'post_content', 'post_content_filtered', 'post_title', 'post_excerpt', 'post_status', 'post_type', 'comment_status', 'ping_status', 'post_password', 'post_name', 'to_ping', 'pinged', 'post_modified', 'post_modified_gmt', 'post_parent', 'menu_order', 'post_mime_type', 'guid' );

	$emoji_fields = array( 'post_title', 'post_content', 'post_excerpt' );

	foreach ( $emoji_fields as $emoji_field ) {
		if ( isset( $data[ $emoji_field ] ) ) {
			$charset = $wpdb->get_col_charset( $wpdb->posts, $emoji_field );
			if ( 'utf8' === $charset ) {
				$data[ $emoji_field ] = wp_encode_emoji( $data[ $emoji_field ] );
			}
		}
	}

	if ( 'attachment' === $post_type ) {
		/**
		 * Filters attachment post data before it is updated in or added to the database.
		 *
		 * @since 3.9.0
		 *
		 * @param array $data    An array of sanitized attachment post data.
		 * @param array $postarr An array of unsanitized attachment post data.
		 */
		$data = apply_filters( 'wp_insert_attachment_data', $data, $postarr );
	} else {
		/**
		 * Filters slashed post data just before it is inserted into the database.
		 *
		 * @since 2.7.0
		 *
		 * @param array $data    An array of slashed post data.
		 * @param array $postarr An array of sanitized, but otherwise unmodified post data.
		 */
		$data = apply_filters( 'wp_insert_post_data', $data, $postarr );
	}
	$data = wp_unslash( $data );
	$where = array( 'ID' => $post_ID );

	if ( $update ) {
		/**
		 * Fires immediately before an existing post is updated in the database.
		 *
		 * @since 2.5.0
		 *
		 * @param int   $post_ID Post ID.
		 * @param array $data    Array of unslashed post data.
		 */
		do_action( 'pre_post_update', $post_ID, $data );
		if ( false === $wpdb->update( $wpdb->posts, $data, $where ) ) {
			if ( $wp_error ) {
				return new WP_Error('db_update_error', __('Could not update post in the database'), $wpdb->last_error);
			} else {
				return 0;
			}
		}
	} else {
		// If there is a suggested ID, use it if not already present.
		if ( ! empty( $import_id ) ) {
			$import_id = (int) $import_id;
			if ( ! $wpdb->get_var( $wpdb->prepare("SELECT ID FROM $wpdb->posts WHERE ID = %d", $import_id) ) ) {
				$data['ID'] = $import_id;
			}
		}
		if ( false === $wpdb->insert( $wpdb->posts, $data ) ) {
			if ( $wp_error ) {
				return new WP_Error('db_insert_error', __('Could not insert post into the database'), $wpdb->last_error);
			} else {
				return 0;
			}
		}
		$post_ID = (int) $wpdb->insert_id;

		// Use the newly generated $post_ID.
		$where = array( 'ID' => $post_ID );
	}

	if ( empty( $data['post_name'] ) && ! in_array( $data['post_status'], array( 'draft', 'pending', 'auto-draft' ) ) ) {
		$data['post_name'] = wp_unique_post_slug( sanitize_title( $data['post_title'], $post_ID ), $post_ID, $data['post_status'], $post_type, $post_parent );
		$wpdb->update( $wpdb->posts, array( 'post_name' => $data['post_name'] ), $where );
		clean_post_cache( $post_ID );
	}

	if ( is_object_in_taxonomy( $post_type, 'category' ) ) {
		wp_set_post_categories( $post_ID, $post_category );
	}

	if ( isset( $postarr['tags_input'] ) && is_object_in_taxonomy( $post_type, 'post_tag' ) ) {
		wp_set_post_tags( $post_ID, $postarr['tags_input'] );
	}

	// New-style support for all custom taxonomies.
	if ( ! empty( $postarr['tax_input'] ) ) {
		foreach ( $postarr['tax_input'] as $taxonomy => $tags ) {
			$taxonomy_obj = get_taxonomy($taxonomy);
			if ( ! $taxonomy_obj ) {
				/* translators: %s: taxonomy name */
				_doing_it_wrong( __FUNCTION__, sprintf( __( 'Invalid taxonomy: %s.' ), $taxonomy ), '4.4.0' );
				continue;
			}

			// array = hierarchical, string = non-hierarchical.
			if ( is_array( $tags ) ) {
				$tags = array_filter($tags);
			}
			if ( current_user_can( $taxonomy_obj->cap->assign_terms ) ) {
				wp_set_post_terms( $post_ID, $tags, $taxonomy );
			}
		}
	}

	if ( ! empty( $postarr['meta_input'] ) ) {
		foreach ( $postarr['meta_input'] as $field => $value ) {
			update_post_meta( $post_ID, $field, $value );
		}
	}

	$current_guid = get_post_field( 'guid', $post_ID );

	// Set GUID.
	if ( ! $update && '' == $current_guid ) {
		$wpdb->update( $wpdb->posts, array( 'guid' => get_permalink( $post_ID ) ), $where );
	}

	if ( 'attachment' === $postarr['post_type'] ) {
		if ( ! empty( $postarr['file'] ) ) {
			update_attached_file( $post_ID, $postarr['file'] );
		}

		if ( ! empty( $postarr['context'] ) ) {
			add_post_meta( $post_ID, '_wp_attachment_context', $postarr['context'], true );
		}
	}

	// Set or remove featured image.
	if ( isset( $postarr['_thumbnail_id'] ) ) {
		$thumbnail_support = current_theme_supports( 'post-thumbnails', $post_type ) && post_type_supports( $post_type, 'thumbnail' ) || 'revision' === $post_type;
		if ( ! $thumbnail_support && 'attachment' === $post_type && $post_mime_type ) {
			if ( wp_attachment_is( 'audio', $post_ID ) ) {
				$thumbnail_support = post_type_supports( 'attachment:audio', 'thumbnail' ) || current_theme_supports( 'post-thumbnails', 'attachment:audio' );
			} elseif ( wp_attachment_is( 'video', $post_ID ) ) {
				$thumbnail_support = post_type_supports( 'attachment:video', 'thumbnail' ) || current_theme_supports( 'post-thumbnails', 'attachment:video' );
			}
		}

		if ( $thumbnail_support ) {
			$thumbnail_id = intval( $postarr['_thumbnail_id'] );
			if ( -1 === $thumbnail_id ) {
				delete_post_thumbnail( $post_ID );
			} else {
				set_post_thumbnail( $post_ID, $thumbnail_id );
			}
		}
	}

	clean_post_cache( $post_ID );

	$post = get_post( $post_ID );

	if ( ! empty( $postarr['page_template'] ) ) {
		$post->page_template = $postarr['page_template'];
		$page_templates = wp_get_theme()->get_page_templates( $post );
		if ( 'default' != $postarr['page_template'] && ! isset( $page_templates[ $postarr['page_template'] ] ) ) {
			if ( $wp_error ) {
				return new WP_Error( 'invalid_page_template', __( 'Invalid page template.' ) );
			}
			update_post_meta( $post_ID, '_wp_page_template', 'default' );
		} else {
			update_post_meta( $post_ID, '_wp_page_template', $postarr['page_template'] );
		}
	}

	if ( 'attachment' !== $postarr['post_type'] ) {
		wp_transition_post_status( $data['post_status'], $previous_status, $post );
	} else {
		if ( $update ) {
			/**
			 * Fires once an existing attachment has been updated.
			 *
			 * @since 2.0.0
			 *
			 * @param int $post_ID Attachment ID.
			 */
			do_action( 'edit_attachment', $post_ID );
			$post_after = get_post( $post_ID );

			/**
			 * Fires once an existing attachment has been updated.
			 *
			 * @since 4.4.0
			 *
			 * @param int     $post_ID      Post ID.
			 * @param WP_Post $post_after   Post object following the update.
			 * @param WP_Post $post_before  Post object before the update.
			 */
			do_action( 'attachment_updated', $post_ID, $post_after, $post_before );
		} else {

			/**
			 * Fires once an attachment has been added.
			 *
			 * @since 2.0.0
			 *
			 * @param int $post_ID Attachment ID.
			 */
			do_action( 'add_attachment', $post_ID );
		}

		return $post_ID;
	}

	if ( $update ) {
		/**
		 * Fires once an existing post has been updated.
		 *
		 * @since 1.2.0
		 *
		 * @param int     $post_ID Post ID.
		 * @param WP_Post $post    Post object.
		 */
		do_action( 'edit_post', $post_ID, $post );
		$post_after = get_post($post_ID);

		/**
		 * Fires once an existing post has been updated.
		 *
		 * @since 3.0.0
		 *
		 * @param int     $post_ID      Post ID.
		 * @param WP_Post $post_after   Post object following the update.
		 * @param WP_Post $post_before  Post object before the update.
		 */
		do_action( 'post_updated', $post_ID, $post_after, $post_before);
	}

	/**
	 * Fires once a post has been saved.
	 *
	 * The dynamic portion of the hook name, `$post->post_type`, refers to
	 * the post type slug.
	 *
	 * @since 3.7.0
	 *
	 * @param int     $post_ID Post ID.
	 * @param WP_Post $post    Post object.
	 * @param bool    $update  Whether this is an existing post being updated or not.
	 */
	do_action( "save_post_{$post->post_type}", $post_ID, $post, $update );

	/**
	 * Fires once a post has been saved.
	 *
	 * @since 1.5.0
	 *
	 * @param int     $post_ID Post ID.
	 * @param WP_Post $post    Post object.
	 * @param bool    $update  Whether this is an existing post being updated or not.
	 */
	do_action( 'save_post', $post_ID, $post, $update );

	/**
	 * Fires once a post has been saved.
	 *
	 * @since 2.0.0
	 *
	 * @param int     $post_ID Post ID.
	 * @param WP_Post $post    Post object.
	 * @param bool    $update  Whether this is an existing post being updated or not.
	 */
	do_action( 'wp_insert_post', $post_ID, $post, $update );

	return $post_ID;
}

Related Functions

From tag: wp_insert (insert in DB)

More from category: Insert, delete, update

No comments
    Hello, !     Log In . Register