I'm trying to hook on save_post to automatically assign a category (from a custom field) on post update and creation. Basically if the date event is 10/10/2020 - I want to assign the event to category '2020'.
So far, it's partially working because I actually have to hit the 'update' button twice to make it works. I'm stucked here for now. Being not much proefficient with PHP or WP wizardy, I've tried to document as best as I could.
If can help I also have debug logs here :
<?php
/**
* Create or update category for each event creation or udate
*
* @param int $post_id The post ID.
* @param post $post The post object.
* @param bool $update Whether this is an existing post being updated or not.
*/
function save_event( $post_id, $post, $update ) {
$id = $post_id;
// If this isn't a 'book' post, don't do anything.
$post_type = get_post_type($post_id);
if ( "event" != $post_type ) return;
// Check if year has been defined
$date = get_field('event_date', $post_id, false);
if (empty($date)) {
write_log( "Event date is not defined yet" );
return;
}
// Extract event's year
$date = new DateTime($date);
$year = $date->format('Y');
// Get existing category
$current_cats = get_the_category($post_id);
if ( ! empty( $current_cats ) ) {
$current_cat_name = esc_html( $current_cats[0]->name );
write_log( "Current category in use : {$current_cat_name}");
if ( ! empty($current_cat_name) && $year === $current_cat_name) {
write_log( "Matching existing category with event date");
return;
}
}
// Does the category exist? Should we create it?
$category_id = get_cat_ID($year);
if ( $category_id === 0) {
$category_id = wp_create_category( $year );
write_log( "Creating category : ({$year}) with ID of {$category_id}");
} else {
write_log( "Found category ({$year}) with ID of {$category_id}");
}
// Assign the category
$event_categories = array($category_id);
$post_categories = wp_set_post_categories( $id, $event_categories);
write_log( "A new category ({$year} - {$category_id} ) has been assigned to post {$id}");
write_log( json_encode($post_categories) );
}
add_action( 'save_post', 'save_event', 10, 3 );
I'm trying to hook on save_post to automatically assign a category (from a custom field) on post update and creation. Basically if the date event is 10/10/2020 - I want to assign the event to category '2020'.
So far, it's partially working because I actually have to hit the 'update' button twice to make it works. I'm stucked here for now. Being not much proefficient with PHP or WP wizardy, I've tried to document as best as I could.
If can help I also have debug logs here : https://pastebin.com/HQ9B6JqZ?fbclid=IwAR1Ag9_yekNMByN4Dim3BZPJ6ALdIPwQ77hP36W5Ht13QekpkuaofuoLlzY
<?php
/**
* Create or update category for each event creation or udate
*
* @param int $post_id The post ID.
* @param post $post The post object.
* @param bool $update Whether this is an existing post being updated or not.
*/
function save_event( $post_id, $post, $update ) {
$id = $post_id;
// If this isn't a 'book' post, don't do anything.
$post_type = get_post_type($post_id);
if ( "event" != $post_type ) return;
// Check if year has been defined
$date = get_field('event_date', $post_id, false);
if (empty($date)) {
write_log( "Event date is not defined yet" );
return;
}
// Extract event's year
$date = new DateTime($date);
$year = $date->format('Y');
// Get existing category
$current_cats = get_the_category($post_id);
if ( ! empty( $current_cats ) ) {
$current_cat_name = esc_html( $current_cats[0]->name );
write_log( "Current category in use : {$current_cat_name}");
if ( ! empty($current_cat_name) && $year === $current_cat_name) {
write_log( "Matching existing category with event date");
return;
}
}
// Does the category exist? Should we create it?
$category_id = get_cat_ID($year);
if ( $category_id === 0) {
$category_id = wp_create_category( $year );
write_log( "Creating category : ({$year}) with ID of {$category_id}");
} else {
write_log( "Found category ({$year}) with ID of {$category_id}");
}
// Assign the category
$event_categories = array($category_id);
$post_categories = wp_set_post_categories( $id, $event_categories);
write_log( "A new category ({$year} - {$category_id} ) has been assigned to post {$id}");
write_log( json_encode($post_categories) );
}
add_action( 'save_post', 'save_event', 10, 3 );
After getting year, you may check if category exists using
category_exists($cat_name);
if not found then create category using
wp_create_category( $cat_name, $parent );
after that you may create post using
$my_post = array(
'post_title' => wp_strip_all_tags( $_POST['post_title'] ),
'post_content' => $_POST['post_content'],
'post_status' => 'publish',
'post_author' => 1,
'post_category' => array( 8,39 )
);
// Insert the post into the database
wp_insert_post( $my_post );
You may also add category to a existing post using
wp_set_post_categories($post_id,$post_categories)
more information:
https://developer.wordpress.org/reference/functions/wp_insert_post/
https://codex.wordpress.org/Function_Reference/wp_create_category
https://developer.wordpress.org/reference/functions/category_exists/
So I've tried with set_object_terms() instead of wp_set_post_categories() but it's pretty much the same.
I've tried to dump almost everything I could : - $post_id and $post object are always available - post data are not sometimes available trough $_POST (see below)
I realized I couldn't always get my value by using get_field('event_date') or $_POST['acf']['field_5c766105f364e'] but I've found that get_field('event_date', $post_id) consistently returns the right value.
Now what's really odd is that the save_post() is triggered three times at each 'update' click.. and the logs tell me that the second one is sucessfull. There others tell me the category is already assigned to the right category.
So it actually works except I have no clues why : - hook get triggered three times - backend edit page does not reflect updated category (at the first click)
logs https://pastebin.com/dF2Q15Y0