71

When a post is updated there are some hooks that are fired: 'pre_post_update' is an action fired just before the post is updated, the argument passed are 2: $post_ID and $data that is an array of all the other database colums of the post table 'transition_post_status' is an hook fired on update, and pass 3 arguments: $new_post_status, $old_post_status and $...


17

This simplest method would be to edit the data at the point it's inserted, rather than updating it afterwards, using wp_insert_post_data instead of save_post. This works on creating a new post or updating an existing post without change. It also avoids the danger of creating an infinite loop by triggering update_post within save_post. add_filter( '...


17

Since WordPress version 3.7. - IIRC - the save_post hook - more information about the hook and its usage at Code Reference: save_post and Codex: save_post - has a third parameter $update which can be used to determine just that. @param     int               $post_ID  ...


16

Maruti Mohanty’s suggestion is not bad, but it will fail. There are many core actions with a higher priority: wp-admin/menu.php: add_action('admin_menu', '_add_themes_utility_last', 101); wp-includes/admin-bar.php: add_action( 'wp_footer', 'wp_admin_bar_render', 1000 ); wp-includes/canonical.php add_action( 'template_redirect', '...


15

I haven't quite got the reputation to comment so I'm adding an answer even though Stephen's is excellent and correct. It just doesn't handle instances when you want to set the priority of the action. If you set the priority when adding the action but don't specify priority when you remove it you will still get an infinite loop. add_action('save_post', '...


14

The "save_post" action is only called when we actually changed something in the post page form. If we just press the update button, without changing anything, the "save_post" action is not called. This is important if we are editing a custom post type where we had custom meta boxes. If we rely on the "save_post" action and only change stuff on ...


11

I had the exact same need, so I wrote this function - which works. Modify it to your needs. Hope this helps. // set daily rating title function set_rating_title ($post_id) { if ( $post_id == null || empty($_POST) ) return; if ( !isset( $_POST['post_type'] ) || $_POST['post_type']!='rating' ) return; if ( wp_is_post_revision( ...


11

The way I perform this check (within a hooked function) is to compare the post date and modified date (in GMT for standardisation) function check_new_vs_update( $post_id ){ $myPost = get_post($post_id); $post_created = new DateTime( $myPost->post_date_gmt ); $post_modified = new DateTime( $myPost->post_modified_gmt ); $diff ...


10

The problem is that the function update_field from ACF works a little bit different from update_post_meta. Can you see it? update_post_meta( $post_id, $meta_key, $meta_value, $prev_value ); update_field( $field_key, $value, $post_id ); If you use update_post_meta you should in my opinion use get_post_meta to get the meta. If you use update_field you should ...


9

add_action has a priority parameter which is 10 by default, you can increase that to load your function late. Change add_action( 'save_post', 'do_custom_save' ); to add_action( 'save_post', 'do_custom_save', 100 ); Now the priority is to set to 100 and will load quite late and will allow other function associated to load before this function is executed....


8

Also, run the slug from sanitize_title_with_dashes() through wp_unique_post_slug() to ensure that it's unique. It will automatically append '-2', '-3' etc. if it's needed.


7

First of all you have to understand that when we update a post, wp_update_post function is called. But due to a bit not optimal design of WP core, the actual saving is processed by wp_insert_post function. See it in trac on line 3006. Ok, next lets see what is inside of wp_insert_post function. As you can see, on line 2950, save_post action is called each ...


7

A draft or "blank" is saved as soon as you start to create a new post. Those new posts have the post_status of auto-draft. Check for that to prevent your callback from firing on those "blank" post saves. function update_test( $post_id, $post ) { if (isset($post->post_status) && 'auto-draft' == $post->post_status) { return; } ...


7

You need to match the $priority you used to hook the action: remove_action( 'save_post', array( $this, 'save_box' ), 20 /* Same as add_action call */ ); http://codex.wordpress.org/Function_Reference/remove_action Make sure you take the $post_id argument in your save_box method too: function save_box( $post_id ) { ... }


7

Figured it out, hooking into content_save_pre: function remove_empty_lines( $content ){ // replace empty lines $content = preg_replace("/ /", "", $content); return $content; } add_action('content_save_pre', 'remove_empty_lines');


6

Instead of replacing spaces you should use the build in function sanitize_title() which will take care of the replacing for you. Like this: sanitize_title( $post_title, $post->ID ); Also, you should use a unique slug. Which you can get with the function wp_unique_post_slug() So putting it all together a solution might be: function ...


6

Based on pospi's suggestion to use transients, I came up with the following. The only problem is there is no hook to put the message below the h2 where other messages go, so I had to do a jQuery hack to get it there. First, save the error message duing your save_post (or similar) handler. I give it a short lifetime of 60 seconds, so it is there just long ...


6

TL;DR: No, you can use save_post. Unless you consider programmatic modification of only metadata "modifying a post". There (theoretically) is a way of modifying a post without triggering the save_post action hook: Direct modification of the database. But for one no plugin or theme author in his right mind would go that route and for another it would ...


6

For NEW post type 'post' use draft_to_publish action hook: function fpw_post_info( $post ) { if ( 'post' == $post->post_type ) { // echo '<pre>'; print_r( $post ); echo '<br />'; // $meta = get_post_meta( $post->ID ); print_r( $meta ); echo '</pre>'; die(); // your custom code goes here... } } ...


5

The post gets added and published but since you have the meta query and the meta key is not added when you submit the post from frontend, it does not show up. Use the following code which adds the meta data as needed. if ( isset( $_POST['submitted'] ) ) { $post_information = array( 'post_title' => wp_strip_all_tags( $...


5

Quite stupid solution, but works: function afterPostUpdated($meta_id, $post_id, $meta_key='', $meta_value=''){ if($meta_key=='_edit_lock') { if($_GET['message']==1) { // Your code here // } } } add_action('updated_post_meta', 'afterPostUpdated', 10, 4);


5

It's informative to check out the /wp-admin/post.php file, that contains the edit_post() function that calls wp_update_post(), which is a wp_insert_post() wrapper. Here's a skeleton for saving the assigned category terms: /** * Saving assigned category terms (skeleton) */ add_action( 'admin_action_editpost', function() { add_filter( '...


5

The save_post action also passes three parameters to your callback, one of which being $update which denotes whether the post being saved is an existing post or not. /** * Save post metadata when a post is saved. * * @param int $post_id The post ID. * @param post $post The post object. * @param bool $update Whether this is an existing post being ...


5

So appreciate this is a bit late but I was having the exact same issue, the $update parameter is almost completely useless if you want to check whether it is a new post or not. The way I got around this was to compare the $post->post_date with $post->post_modified. Full code snippet below. add_action( 'save_post', 'save_post_callback', 10, 3 ); ...


4

Example to ialocin answer with "update" paremeter: function save_func($ID, $post,$update) { if($update == false) { // do something if its first time publish } else { // Do something if its update } } add_action( 'save_post', 'save_func', 10, 3 );


4

Here's a solution that uses a static variable to prevent an infinite loop. This allows you to safely call wp_update_post() inside of a function that is hooked to save_post. function km_set_title_on_save( $post_id ) { // Set this variable to false initially. static $updated = false; // If title has already been set once, bail. if ( $updated ...


4

It's probably easiest to just check the post status within your function. Untested: add_action( 'save_post', 'rewrite_post', 10, 2 ); function rewrite_post( $post_id ) { if ( 'trash' != get_post_status( $post_id ) ) { remove_action( 'save_post', 'rewrite_post' ); $title = preg_replace( '/\_/', ' ', get_the_title( $post_id ) ); $...


4

Yes, this is possible. Something like this should affect all posts that are currently published. Literally run this once and then disable it by commenting out the add_action or you will have a bunch of unwanted queries to the database. Running once: With this code placed in your functions.php, the function will run when the front end of your site is loaded ...


4

Try this inside save_post but please note the code is not tested $old = get_post_meta($post_id, 'products'); $new = isset ( $_POST['products'] ) ? $_POST['products'] : array(); if ( empty ($new) ) { // no products selected: completely delete alla meta values for the post delete_post_meta($post_id, 'products'); } else { $already = array(); if ( ! ...


4

I know this has already been answered, but I felt as if it wasn't 100% real clear what the actual solution was. Here's my answer to add some clarification. He's right... You can't flush rewrite rules on save_post, because that action hook is fired AFTER the init action hook has been fired. As you know, Post Types and Taxonomies are registered on the init ...


Only top voted, non community-wiki answers of a minimum length are eligible