Is it possible within the save_post action to determine whether it’s a new post being created or an existing post being update?
Leave a Reply
You must be logged in to post a comment.
Is it possible within the save_post action to determine whether it’s a new post being created or an existing post being update?
You must be logged in to post a comment.
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.Note:
$update
is not alwaystrue
â you can see and test it yourself with below code. It is not well documented though, possibly far from optimally named, and hence creates misleading expectations. Below code can be used for some debugging, play around with when to intercept code execution, because otherwise you won’t see the information/messages. I think, the culprit in deceptive behavior is the handling of revisions and auto saves â which could be disabled, but I don’t recommend it, and haven’t tested it. Not sure if this warrants a Trac Ticket, so I didn’t open one, if you think so, please follow the link and do it yourself. Aside from that, as stated in the comments, if you have a specific problem, post a new question.The way I perform this check (within a hooked function) is to compare the post date and modified date (in GMT for standardisation)
This works because even at creation the post has a ‘modified’ date attached to it, which is exactly the same as the ‘created’ date, but we allow a variance of 1 second either way in case a second ticks over during the creation of the post.
I ended up just checking for the existence of a custom value prior to setting it. That way, if it’s a newly created post the custom value would not yet exist.
Example to ialocin answer with “update” paremeter:
I have just encountered the
save_post
about new and update. After reading the source code to understand the flow. I found that the following method might be useful. Since it is not yet mentioned before. See if it is useful to anyone. (The test is Core 5.3.3)The Post creation flow is approximately:
auto-draft
post is being created, even it is not saved, every time clickingAdd New
, anauto-draft
is createdBy comparing the $_POST object for new post and update post or republish post, the prominent difference is value
_wp_http_referer
, the new post is/wp-admin/post-new.php
Assumption: assumed the post is published/added from UI. If it is done by other mechanism, custom code, the checking is needed to adjust.
here is a functional code that worked and tested by me i used in my website also it solve the two following problem associated with save_post action :
problem to check between ubdate or insert
problem of twice insert by save_post action
You can use pre_post_update action hook for the update code and save_post for the new post code. It works before a post is updated.
As Darshan Thanki hinted (and Stephen Harris further elaborated), you can use
pre_post_update
to your advantage.The reason why I used globals is because
function is_new_post() use ( &$new_post )
is not valid in PHP (shocking…) so pulling in that variable into the function scope doesn’t work — hence the global.Note that this can really only reliably be used within/after the
save_post
event (which is usually sufficient, at least for what we’re doing with it).When save_post is triggered, all information about that post is already available, so in theory you could use
this is untested, though. =)
Another approach that uses a built-in function and no addition to the database would involve
get_post_status()
.Note however that it might not be appropriate if you plan to later set the status back to “draft” â your instructions would be repeated the next time you will update the post.
Depending on the context, you might want to consider the various strings that can be returned by
get_post_status()
to build a more appropriate scenario.See Codex for get_post_status() and Post Status
Since the
$update
param is useless, this is the fastest way I tested: