3

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;
    }
}
  • If you output your $postarr['ID'] and $book_data[1], do you get the expected results? – vancoder Apr 30 '13 at 21:38
  • @vancoder: Yes, both are outputting fine (also tried to replace these with manual data for testing). Meanwhile the penny has dropped for me, I think: this a pre-saving scenario, and wp_set_object_terms is for when the post in question already exists. Though in that case it supposed to work at least when editing an already existing post, but it doesn't work at all, so the situation remains unclear to me. – MrValueType Apr 30 '13 at 21:45
  • The array that is returned does indeed suggest the code is working. On what basis do you think it is not? – vancoder Apr 30 '13 at 21:51
  • @vancoder: The term that supposed to be added is not visible in the admin editing screen after saving the post. Also, it is not listed in the terms page (edit-tags.php). Or in the case of an already existing 'author', the author's listing page doesn't contain the book in question either. – MrValueType Apr 30 '13 at 22:03
  • Have you checked if the term has made it as far as the wp_terms table? I'm just wondering if it is saving correctly, but just isn't coming out the other side. – vancoder Apr 30 '13 at 22:08
3

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 when wp_insert_post_data is executed the post in question is not yet in the database. And albeit I didn't manage to find it in taxonomy.php, it is logical to assume that the wp_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 into save_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:

...

// Fill in Author tag with Amazon data if missing
if ( ! has_term( $book_data[1], 'author', $postarr['ID'] ) ) {
    global $add_this_tax_term_to_book;
    $add_this_tax_term_to_book[] = $book_data[1];
    $add_this_tax_term_to_book[] = 'author';
}

...

And the code for save_post:

add_action('save_post', 'add_my_tax_term');
function add_my_tax_term( $post_id ) {
    global $add_this_tax_term_to_book;

    if ( !(empty( $add_this_tax_term_to_book )) ) {
        wp_set_object_terms( $post_id, $add_this_tax_term_to_book[0], $add_this_tax_term_to_book[1] );
}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.