wp_insert_post_data
Filters post data immediately before it is inserted into or updated in the database by wp_insert_post(). All data is slashed!
At this stage, escape slashes (\) have not yet been removed from the data; see wp_unslash().
This filter is useful when post data must be changed before it is inserted or updated—for example, to replace strings in the content, validate a date, or change fields such as post_name and guid.
Usage
add_filter( 'wp_insert_post_data', 'wp_kama_insert_post_data_filter', 10, 4 );
/**
* Function for `wp_insert_post_data` filter-hook.
*
* @param array $data An array of slashed, sanitized, and processed post data.
* @param array $postarr An array of sanitized (and slashed) but otherwise unmodified post data.
* @param array $unsanitized_postarr An array of slashed yet *unsanitized* and unprocessed post data as originally passed to wp_insert_post().
* @param bool $update Whether this is an existing post being updated.
*
* @return array
*/
function wp_kama_insert_post_data_filter( $data, $postarr, $unsanitized_postarr, $update ){
// filter...
return $data;
}
- $data(array)
Post data. The data contains escape slashes (
\)!Array ( [post_author] => 1 [post_date] => 2019-05-27 17:11:32 [post_date_gmt] => 2019-05-27 13:11:32 [post_content] => [post_content_filtered] => [post_title] => w3hosK-d_yE [post_excerpt] => [post_status] => inherit [post_type] => attachment [comment_status] => open [ping_status] => closed [post_password] => [post_name] => w3hosk-d_ye [to_ping] => [pinged] => [post_modified] => 2019-05-27 17:11:32 [post_modified_gmt] => 2019-05-27 13:11:32 [post_parent] => 0 [menu_order] => 0 [post_mime_type] => image/jpeg [guid] => http://wp-test.ru/wp-content/uploads/2019/05/w3hosK-d_yE-2.jpg )
- $postarr(array)
Original post data passed to
wp_insert_post().Array ( [post_author] => 1 [post_content] => [post_content_filtered] => [post_title] => w3hosK-d_yE [post_excerpt] => [post_status] => draft [post_type] => attachment [comment_status] => [ping_status] => [post_password] => [to_ping] => [pinged] => [post_parent] => 0 [menu_order] => 0 [guid] => http://wp-test.ru/wp-content/uploads/2019/05/w3hosK-d_yE-2.jpg [import_id] => 0 [context] => [file] => F:\server\sites\wp-test.ru\wp-content\uploads\2019\05\w3hosK-d_yE-2.jpg [post_mime_type] => image/jpeg [ID] => 0 [filter] => db )
- $unsanitized_postarr(array) (WP 5.4.1)
- Unsanitized post data. The data array contains slashes.
- $update(true/false) (WP 6.0)
truewhen an existing post is updated;falsewhen a new post is added.
Examples
#1 Remove \r (carriage return) from post content
## Removes \r (carriage return) from post content
add_action( 'wp_insert_post_data', 'remove_r_carriage_return', 0 );
function remove_r_carriage_return( $data ){
$data['post_content'] = str_replace( "\r", '', $data['post_content'] );
return $data;
}
#2 Change post data before updating
Before filtering the data, make sure that the intended post type is being changed in the intended context.
This example shows how to always store the post permalink in the guid field:
add_action( 'wp_insert_post_data', 'who_book_save', 20, 2 );
function who_book_save( $data, $postarr ){
if(
// Make sure we are editing the required post type
( empty( $_POST['post_type'] ) || 'book' !== $_POST['post_type'] )
||
// Skip autosaves
( defined('DOING_AUTOSAVE') && DOING_AUTOSAVE )
||
// Make sure we are on the required admin page
( 'book' !== get_current_screen()->id )
||
// Make sure the user can edit the post
! current_user_can( 'edit_post', $postarr['ID'] )
)
return $data;
// Everything is OK
$data['guid'] = get_permalink( $postarr['ID'] );
return $data;
}
#3 What the variables passed to the function look like
The following fields are passed in $data by default:
Array ( [post_author] => 1 [post_date] => 2015-07-15 02:44:40 [post_date_gmt] => 2015-07-14 23:44:40 [post_content] = content [post_content_filtered] => [post_title] => supermy [post_excerpt] => [post_status] => publish [post_type] => book [comment_status] => closed [ping_status] => closed [post_password] => [post_name] => supermy__ [to_ping] => [pinged] => [post_modified] => 2015-07-16 01:10:27 [post_modified_gmt] => 2015-07-15 22:10:27 [post_parent] => 0 [menu_order] => 0 [post_mime_type] => [guid] => http://example.com/?post_type=book&p=19 )
Default fields for the $postarr parameter:
'post_status' - 'draft'. 'post_type' - 'post'. 'post_author' - ID of the current user or the user who created the post. 'ping_status' - the 'default_ping_status' setting value. 'post_parent' - 0 'menu_order' - 0 'to_ping' - 'pinged' - empty string 'post_password' - empty string 'guid' - unique ID 'post_content_filtered' - 'post_excerpt' - text.
This is what $postarr looks like:
Array ( [post_status] => publish [post_type] => book [post_author] => 1 [ping_status] => closed [post_parent] => 0 [menu_order] => 0 [to_ping] => [pinged] => [post_password] => [guid] => http://example.com/?post_type=book&p=19 [post_content_filtered] => [post_excerpt] => [import_id] => 0 [post_content] = text [post_title] => supermy [context] => [ID] => 19 [post_date] => 2015-07-15 02:44:40 [post_date_gmt] => 2015-07-14 23:44:40 [comment_status] => closed [post_name] => supermy__ [post_modified] => 2015-07-16 00:48:42 [post_modified_gmt] => 2015-07-15 21:48:42 [post_mime_type] => [comment_count] => 0 [ancestors] => Array ( ) [post_category] => Array ( ) [tags_input] => Array ( ) [_wpnonce] => e296535396 [_wp_http_referer] => /wp-admin/post.php?post=19&action=edit [user_ID] => 1 [action] => editpost [originalaction] => editpost [original_post_status] => publish [referredby] => http://example.com/wp-admin/edit.php?post_type=book [_wp_original_http_referer] => http://example.com/wp-admin/edit.php?post_type=book [post_ID] => 19 [meta-box-order-nonce] => ea65cc23d4 [closedpostboxesnonce] => ca65bc8597 [samplepermalinknonce] => f19941a639 [hidden_post_status] => publish [hidden_post_password] => [hidden_post_visibility] => public [visibility] => public [mm] => 07 [jj] => 15 [aa] => 2015 [hh] => 02 [mn] => 44 [ss] => 40 [hidden_mm] => 07 [cur_mm] => 07 [hidden_jj] => 15 [cur_jj] => 16 [hidden_aa] => 2015 [cur_aa] => 2015 [hidden_hh] => 02 [cur_hh] => 00 [hidden_mn] => 44 [cur_mn] => 19 [original_publish] => Update [save] => Update [filter] => db )
#4 Prevent saving a post with the publish status
Suppose you created a custom transaction post type and registered custom post statuses.
These posts must not have any status other than the custom statuses. This is easy to control programmatically, but when such a post is edited in the admin panel, WordPress automatically assigns it the publish status on save. The following code solves the problem:
add_filter( 'wp_insert_post_data', 'restoring_status_saved_admin_panel' );
/**
* Restores the original transaction status when saving from the admin panel,
* because WordPress attempts to assign the publish status.
*
* @param array $data
*
* @return array
*/
function restoring_status_saved_admin_panel( $data ) {
if ( 'transaction' === $data['post_type'] && 'publish' === $data['post_status'] ) {
$data['post_status'] = sanitize_key( filter_input( INPUT_POST, 'original_post_status' ) );
}
return $data;
}Changelog
| Since 2.7.0 | Introduced. |
| Since 5.4.1 | The $unsanitized_postarr parameter was added. |
| Since 6.0.0 | The $update parameter was added. |
Where the hook is called
$data = apply_filters( 'wp_insert_post_data', $data, $postarr, $unsanitized_postarr, $update );
Where the hook is used in WordPress
add_filter( 'wp_insert_post_data', 'avoid_blog_page_permalink_collision', 10, 2 );
add_filter( 'wp_insert_post_data', array( $this, 'preserve_insert_changeset_post_content' ), 5, 3 );
remove_filter( 'wp_insert_post_data', array( $this, 'preserve_insert_changeset_post_content' ), 5 );
add_filter( 'wp_insert_post_data', '_wp_customize_changeset_filter_insert_post_data', 10, 2 );