wp_insert_post
hook has a paramter which specifies whether it is be run only on post creation or post updation as well.
do_action( 'wp_insert_post', int $post_ID, WP_Post $post, bool $update )
So, you will need to run your code only if $update
is false
Thread Starter
TWD
(@twd)
Back to first principles.
I would expect this code to insert the value ‘1234’ on update.
But nothing happens.
Yes, I am a coding noob.
function set_external_client_id( $post_id, $post ){
if ( 'auction-client' == $post->post_type ) {
//only proceed if this is a Client post type
do_action( 'wp_insert_post', $post_id, $post, $update );
if($update){
$external_client_id = 1234;
update_post_meta( $post_id, 'wpcf-external-client-id', $external_client_id);
}
}
}
add_action( 'save_post', 'set_external_client_id', 30, 2 );
function set_external_client_id( $post_id, $post, $update ) {
if ( wp_is_post_revision( $post_id ) ) {
return;
}
if ( 'auction-client' == $post->post_type ) {
if( !$update ){
$external_client_id = 1234;
update_post_meta( $post_id, 'wpcf-external-client-id', $external_client_id);
}
}
}
add_action( 'wp_insert_post', 'set_external_client_id', 10, 3 );
Thread Starter
TWD
(@twd)
Thank you.
That works!
Now to expand on that to address the initial problem, how to find the highest External Client ID, increment it by “1” and save that value when the post is created (but not when updated).
Can you tell me what mistake I have made with this code?
The value is always saved as “1”.
function set_external_client_id( $post_id, $post, $update ) {
if ( wp_is_post_revision( $post_id ) ) {
return;
}
if ( 'auction-client' == $post->post_type ) {
if( !$update ){
$args = array(
'post_type' => 'auction-client',
'post_status' => 'publish',
);
$loop = new WP_Query( $args );
$find_highest_id = 0;
while ( $loop->have_posts() ) : $loop->the_post();
$external_client_id = get_post_meta( $post_id, 'wpcf-external-client-id', true );
if($external_client_id > $find_highest_id){
$find_highest_id = $external_client_id;
}
endwhile;
$external_client_id = $find_highest_id + 1;
update_post_meta( $post_id, 'wpcf-external-client-id', $external_client_id);
}
}
}
add_action( 'wp_insert_post', 'set_external_client_id', 10, 3 );
The problem is in your get_post_meta
.
Your code is:
get_post_meta( $post_id, 'wpcf-external-client-id', true );
In the first parameter, you have incorrectly passed $post_id
which is the ID of the newly created post.
You should pass the ID of the post in the loop. So, use get_the_ID()
instead.
Sidenote:
1. You should use wp_reset_postdata()
after the while loop
2. You could also have the WP_Query so that the results are displayed in descending order of the value of the meta field.
$args = array(
'post_type' => 'auction-client',
'post_status' => 'publish',
'meta_key' => 'wpcf-external-client-id',
'orderby' => 'meta_value_num',
'order' => 'DESC'
);
This way the first post in the loop will be the one with the highest value of ‘wpcf-external-client-id’. So you won’t need to loop through all the results; you’d be able to use just the first one.
-
This reply was modified 4 years, 2 months ago by
Shariq Khan.
Thread Starter
TWD
(@twd)
Terrific answer.
Thank you for taking the time to explain this.
That’s how others can learn!
You said:
“2. You could also have the WP_Query so that the results are displayed in descending order of the value of the meta field.”
I actually thought about this.
Is it MORE efficient to ask PHP to sort the results and then just pick the first result of the array? OR is it more efficient to loop through as I have done?
“This way the first post in the loop will be the one with the highest value of ‘wpcf-external-client-id’. So you won’t need to loop through all the results; you’d be able to use just the first one.”
BTW could you just remind me how to access the first post?
This would be an array of “post objects” correct?
Is it MORE efficient to ask PHP to sort the results and then just pick the first result of the array?
In this case, it will be MySQL that will be doing the sorting. So you are offloading the task of sorting to mySQL , instead of having PHP do it. And will be a bit faster, compared to let PHP do the sorting.
BTW could you just remind me how to access the first post?
Try this:
$loop = new WP_Query( $args );
$posts = $loop->posts;
$first_post = $posts[0];
Thread Starter
TWD
(@twd)
Thank you so much for all your help.
REALLY appreciate it.
I’m going to stick with my PHP approach for now, since its only a smallish number of records.
Here is the final code:
// only create a new external client ID if the post in new, NOT an update
function set_external_client_id( $post_id, $post, $update ) {
if ( wp_is_post_revision( $post_id ) ) {
return;
}
if ( 'auction-client' == $post->post_type ) {
if( !$update ){
$args = array(
'post_type' => 'auction-client',
);
$myloop = new WP_Query( $args );
//loop through all posts of this post type to find the highest client id
$find_highest_id = 0;
while ( $myloop->have_posts() ) : $myloop->the_post();
$this_post_id = get_the_ID();
$external_client_id = get_post_meta( $this_post_id, 'wpcf-external-client-id', true );
if($external_client_id > $find_highest_id){
$find_highest_id = $external_client_id;
}
endwhile;
wp_reset_postdata();
//take the highest value and increment it then save as client id for the new client
$external_client_id = $find_highest_id + 1;
update_post_meta( $post_id, 'wpcf-external-client-id', $external_client_id);
}
}
}
add_action( 'wp_insert_post', 'set_external_client_id', 10, 3 );