84

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 $...


23

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( '...


18

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  ...


17

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', '...


13

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 ...


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');


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

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 ); ...


6

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( $...


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... } } ...


6

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);


6

The approved answer didn't work for me. I ended up trying several conditionals and the email would still get sent twice: function xxx_send_mail($id, $post, $update){ if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE ) { return; } if (wp_is_post_revision($id)) { ...


5

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 ...


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

Yes. You can use the save_post action and do it here is some function that remove the default wordpress category if there is some other category selected. I added some comments so you will understand the process. function remove_uncategorized($post_id) { // get default category $default_category = (int)get_option('default_category'); // check ...


4

When save_post runs, it has already saved the post on the database. Looking into WordPress core code, more specifically at the wp-includes/post.php's update_post() function, there is no built-in way to intercept a request before it is saved on the database. However, we can hook pre_post_update and use header() and get_post_edit_link() to prevent the post ...


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 ...


4

If you are using the save_post action hook; then you can prevent the code from executing during an autosave with the following conditional: function do_not_autosave( $post ) { // Check to see if we are autosaving if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) return; // Rest of the code here } add_action( 'save_post', '...


4

Based on your comment you appear to be using the REST API. There's no hook between uploading the file and creating the attachment post that could be used for this purpose in the API endpoint. The best you can do appears to be to use the rest_insert_attachment action. It provides callback functions with the WP_Post object for the attachment post, and the ...


4

First, you can use this hook to target only one custom type: https://developer.wordpress.org/reference/hooks/save_post_post-post_type/ This hook (and save_post) is called the first time when you click on "new ..." and then the hook is called with $update = FALSE. Then to send e-mail only when the object is updated, you can test $update like this: const ...


3

Why not hook in post_updated_messages. That way you can show this message just like the default wordpress post updated. add_filter('post_updated_messages', 'your_message'); function your_message(){ } Look for an example here: http://codex.wordpress.org/Function_Reference/register_post_type under post_updated_messages


3

save_post is too late. Look at the source and you can see that the post has already been saved when that hook fires. You will have to interrupt the process well before that hook if you want to prevent saving. I think I would lean toward something like this: add_filter( 'post_updated_messages', function($messages) { $messages['post'][11] = 'This is ...


3

Actions should not return anything, and action hooks are not built to do anything with a returned value. (That is what filters are for.) If you look at the source for that particular hook, you can see that even if you return something nothing happens. Whatever you return isn't captured. It vanishes from the code. The sample code you found is in my opinion ...


3

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 );


3

Message Storage The 'message' part of the $_GET array is what is responsible for holding the actual message value as integer. This means that everything that gets passed in there, will be set as actual message. The messages itself are stored inside a global array in the Admin UI templates. It's named $messages and has three keys per default: page post ...


3

I know this question is old but I find the answers here to not solve the issue. Extending off the answer from Ana Ban, using Otto's method, I found this to be the best method to handle errors. This doesn't require storing the errors in the db. I included a stripped down version of a Metabox object I use. This allows for me to easily add new error messages ...


3

Brian Fegter's response was the right idea, but it had a few bugs. Here's a more polished solution based on the same principle. Step 1: PHP Logic. Place in functions.php (or a plugin file) // Saving the post via AJAX add_action('save_post', 'save_post_ajax'); function save_post_ajax( $post_id ) { # Ignore autosaves if (defined('...


3

selected() was big help for setting a default value. The rest I found in this brilliant meta box tutorial: http://code.tutsplus.com/tutorials/how-to-create-custom-wordpress-writemeta-boxes--wp-20336 with examples for text input, checkboxes and dropdown. Also Custom post type's slug gets wrong when adding a custom meta box explained me how to correctly ...


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