-1

I have a text string called $location_string which is an address in this format: 1 Victoria Street, Wellington, New Zealand as well as a custom hierarchical taxonomy called location.

I am trying to achieve the following:

1) Create location terms for each of the objects in the array. Country would be the top-level term, city a child of country, and street address a child of city.

2) Assign all the terms in the array to the post set by $post_id

I realise the code below is pretty flawed- any ideas on how I could fix it? Currently it only creates street and country, as well as creating street twice:

$location_array_reversed = array_reverse( $location_array );

$i = 0;
$len = count($location_array_reversed);

$location_array_ids = array();

foreach( $location_array_reversed as $term ){

    if ($i == 0) {

        // Top level term
        wp_insert_term( $term, 'location' );
        $tag = get_term_by( 'slug', $term, 'location' );
        $term_id =  $tag->term_id;

        // Save term ID to array
        $location_array_ids[] = $term_id;

    } else if ($i == $len - 1) {

        wp_insert_term( $term, 'location', array( 'parent'=> $term_id ) );

        // Child terms
        wp_insert_term( $term, 'location' );
        $tag = get_term_by( 'slug', $term, 'location' );
        $term_id =  $tag->term_id;

        // Save term ID to array
        $location_array_ids[] = $term_id;

    }

    $i++;

}

// Now assign terms to post
wp_set_object_terms( $post_id, $location_array_ids, 'location' );
1

Only the first and last term is added, all others are omitted in your code. A street is created twice, because you double-insert the last element of the array.

else if ($i == $len - 1) {
    wp_insert_term( $term, 'location', array( 'parent'=> $term_id ) );
    // Child terms
    wp_insert_term( $term, 'location' );
}

Try to change foreach loop:

$location_array_reversed = array_reverse( $location_array );

$parent_id = 0; 
$location_array_ids = [];
$taxonomy_slug = 'location';
foreach( $location_array_reversed as $term ) { 

    $res = term_exists( $term, $taxonomy_slug, $parent_id );
    if ( $res === NULL || $res == 0 )
        $res = wp_insert_term( $term, $taxonomy_slug, ['parent' => $parent_id] );

    $term_id =  (int) $res['term_id'];  // ID of existing or inserted term

    // Save term ID to array 
    $location_array_ids[] = $term_id; 
    $parent_id = $term_id; 
}
wp_set_object_terms($post_id, $location_array_ids, $taxonomy_slug);

wp_insert_term() returns ID of the inserted term, so you don't need to use get_term_by() to get ID of the inserted element.

  • Hmm, that works if the location doesn't exist, but errors out if it already does. I tried checking if the post exists but this results in no terms being assigned: $parent_id = 0; foreach( $location_array_reversed as $term ) { if( $term !== 0 && $term !== null ) { $res = get_term_by('name', $term, 'location'); } else { $res = wp_insert_term( $term, 'location', ['parent' => $parent_id] ); } $term_id = $res['term_id']; // last inserted term // Save term ID to array $location_array_ids[] = $term_id; $parent_id = $term_id; } – warm__tape May 22 at 22:56
  • @warm__tape I updated the code – nmr May 23 at 8:51

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.