Scenario: there is a ‘Recommended Books’ section on the website which uses the ‘book’ custom post type and the ‘author’ custom taxonomy. I’m using Amazon Product Advertising API for retrieving book data and covers. When adding a new ‘book’ into WordPress, the user copies the book ID (ASIN) into the post edit field, and clicks ‘Publish’. Then, when saving the post, the post title (book title) and the author taxonomy term should be programmatically filled in through Amazon. (These are used to offer ‘Order by’ functionality on the front end.)
Currently I’m using wp_insert_post_data
to hook into the ‘book’ saving process, and the wp_set_object_terms
function to try to add the custom taxonomy term to the ‘book’.
The problem is: the wp_set_object_terms
function doesn’t seem to work. It won’t add anything, albeit returns an array which, according to Codex, should mean success. Though the returning array is odd (as far as I see). When using post ID 107 and term ID 3 (instead of an author string, for testing purposes) the returning array displays the following with print_r
:
Array
(
[0] => 3
)
(Also tried with wp_set_post_terms
, and it makes no difference.)
My complete function:
// Function to automatically retrieve and store Amazon Book data (title and author) when adding 'book' type posts
if( function_exists('asa_item') ) {
add_filter( 'wp_insert_post_data', 'filter_handler', '99', 2 );
function filter_handler( $data , $postarr ) {
// Proceed only if book is added/edited
if ( $postarr['post_type'] !== 'book')
return $data;
// Try to Extract ASIN from post body; ignore everything else
if ( preg_match( '/([0-9A-Z]{10})/', $data['post_content'], $matches) ) {
// Successful, store ASIN
$book_asin = $matches[0];
// Wrap ASIN in AmazonSimpleAdmin shortcode (with 'cover' template) automatically for user convenience
$data['post_content'] = '[asa cover]' . $matches[0] . '[/asa]';
} else {
// Unsuccessful: set to draft, return and show error message
$data['post_status'] = 'draft';
add_filter('redirect_post_location', 'my_redirect_post_location_filter_1', 99);
return $data;
}
// Retrieve and store book data from Amazon with AmazonSimpleAdmin plugin
$book_data = explode( "<sep>", asa_get_item( $book_asin, 'book_data' ) );
/******************
* index 0 = title
* index 1 = author
******************/
// Check data; if no data, set to draft, return and show error message
if ( $book_data[0] == '' ) {
$data['post_status'] = 'draft';
add_filter('redirect_post_location', 'my_redirect_post_location_filter_2', 99);
return $data;
}
// Fill in Post Title with Amazon data if empty
if ( $data['post_title'] == '' )
$data['post_title'] = $book_data[0];
// Fill in Author tag with Amazon data if missing
if ( ! has_term( $book_data[1], 'author', $postarr['ID'] ) ) {
wp_set_object_terms( $postarr['ID'], $book_data[1], 'author' );
}
return $data;
}
}
So, to answer my own question:
I haven’t found any solution inside
wp_insert_post_data
. I suspect that the problem is connected to the fact that whenwp_insert_post_data
is executed the post in question is not yet in the database. And albeit I didn’t manage to find it intaxonomy.php
, it is logical to assume that thewp_set_post_terms
function have some checking mechanism to avoid inserting term relationships with arbitrary/non-existent post ID’s.Anyhow, in
wp_insert_post_data
I defined a global variable to store the tax term which needs to be added (instead of trying to add it locally). Then I hooked intosave_post
, which is executed after the post have been saved, and retrieved/inserted the term from there.Seem to work just fine.
The relevant code part in
wp_insert_post_data
:And the code for
save_post
: