Question

I need to insert a post via wp_insert_post and then add relevant post_meta - however, the WP admin has been customized with the excellent ACF.

I know I can add_post_meta in this way:

add_post_meta( $post_id, 'q_key_type', $q_key_type );

However, to make ACF happy, it's required to also use the "update_field" function - like so:

update_field( "field_52c737a413e07", $q_key_type, $post_id );

This method works fine, but I can't get a Taxonomy object to register correctly - I can get the value to save using add_post_meta - when I view the new post it does not recognise the Taxonomy - the value is empty, but in the postmeta table the value is stored correctly - what is missing is the correct field recognition.

I can save fields of the type "Text" and "User" correctly using these two methods.

Here is an image of two rows in the post_meta table - the first two are created by acf - the last two manually - they appear to be formatted identically:

enter image description here

I can only find one other reference to the same field name in the post_meta table - it contains an array with the following data - which seems to be the field set-up for acf:

Array (
    [key] => field_52c737a413e07
    [label] => Type
    [name] => q_key_type
    [type] => taxonomy
    [instructions] => 
    [required] => 0
    [taxonomy] => q_key_type
    [field_type] => select
    [allow_null] => 0
    [load_save_terms] => 1
    [return_format] => object
    [conditional_logic] => Array (
        [status] => 0
        [rules] => Array (
            [0] => Array (
                [field] => null
                [operator] => ==
                [value] => 
            )
        )
        [allorany] => all
    )
[order_no] => 3
)

So, the question is - where else is ACF saving the taxonomy data - I can't find anything in the terms tables?

Was it helpful?

Solution

I do need to add both post_meta:

add_post_meta( $insert_q_key_id, 'q_key_type', (int)$q_key_type ); // Q Key Type

And for ACF:

update_field( "field_52c737a413e07", (int)$q_key_type, $insert_q_key_id ); // Q Key Type

And the rest of the answer "should" be covered by wp_set_object_terms:

wp_set_object_terms( $insert_q_key_id, (int)$q_key_type, 'q_key_type', true );

However, this function is not fully available at the point I need it - so the answer was to create a simple replacement for this function:

     /**
     * simple wp_set_object_terms replacement as not available during API call
     * 
     * @since       0.4
     * @global      Object      $wpdb
     * @param       integer     $object_id
     * @param       integer     $tt_id
     * @return      Mixed       Integer of inserted row on success | Boolean false
     */
    public function q_wp_set_object_terms( $object_id = null, $tt_id = null )
    {

        if ( ! $object_id || ! $tt_id ) { return false; }

        global $wpdb; 

        if ( $wpdb->insert( $wpdb->term_relationships, array( 'object_id' => (int)$object_id, 'term_taxonomy_id' => (int)$tt_id ) ) ) {

            return $wpdb->insert_id;

        }

        // if not ##
        return false;

    }

Which I can call using a static class instance ( as the method is part of a separate class in my case... ):

Q_Key::q_wp_set_object_terms ( $insert_q_key_id, (int)$q_key_type );

OTHER TIPS

I've found that the update_field() function actually does the job for me, I don't know if it's been updated since to make that happen. All you have to watch out for is if you have a single choice (select) field or one that allows multiple selections - you need to pass through an array of taxonomy ID's if it's multiples, basically.

In example:

$field_key = 'field_xxxxxxxxxxxxxx';   //the field key of your chosen taxonomy field
$idarray = array("$termid->term_id");  //use an array to pass it multiple term IDs. Note that the term_id is in quotes, as it needs to be a string
$postid = '';                          //your post ID

update_field($field_key, $idarray, $postid);

The update_field() function will handle the serialize for you automatically based on the field settings, so you don't have to worry about anything else.

I've used this method to update both single and multiple taxonomy fields on the same post record, and I've tested that I can then query those results using the ACF-recommended ways of doing so, so it's definitely putting the data in correctly.

EDIT: one thing to bear in mind, you'll notice I've turned the term_id into a string by wrapping it in quotes - ACF stores the IDs as strings in serialized arrays, so this is essential or their suggested ways to query this data won't work (and when you go to end the field through wp-admin in the future, it will change it back to a string anyway).

Make sure you prefix the term ID of your custom taxonomy when using the update_field() function.

Example:

$post_id = "event_4"; // event (custom taxonomy) term ID = 4
update_field( 'my_field', 'my_value', $post_id );

The great ACF docs talk about this in the section 'Update a value from different objects': https://www.advancedcustomfields.com/resources/update_field/

ACF handles all the stuff around creating and syncing custom fields. No need to recreate that yourself with add_post_meta() etc.

I lost hours down this rabbit hole, really could use a RTFM! notification every 10 minute. 🤦‍♂️

Licensed under: CC-BY-SA with attribution
Not affiliated with wordpress.stackexchange
scroll top