0

I recently had a issue where I was trying to save the child terms on a front end post form. ORIGINAL POST AND CODE

I thought I had it good to go but now I just realize it's not setting the parent term as well, just the child term.

    $nhb_type_value = $_POST['nhb'];

    $nhb_type = wp_get_object_terms($Property_Id, 'city-type', array('fields' => 'ids'));
    $nhb_type = array_reverse($nhb_type);
                    if (!empty($nhb_type)) {
                        $terms = get_term($nhb_type[0], 'city-type');
                        $nhb_type_value = $terms->slug;
                    }

$city_type = wp_get_object_terms($Property_Id, 'city-type', array('fields' => 'ids'));
$city_type = array_reverse($city_type);
        if (!empty($city_type)) {
            $city_term = get_term($city_type[0], 'city-type');
            $city_type_value = $city_term->slug;
        }

Any ideas?

  • You need to set the parent as well. you can loop on all the posts and check if the post terms have a parent and then append him. wordpress don't auto set the parent term even in the admin. – Shibi Nov 20 '17 at 20:20
  • I dont get what you mean? – Rich Nov 21 '17 at 0:32
  • I meant if you want now to change all the posts that already posted you can loop on all over the posts and append the parent term. for new posts you need to add to the wp_set_object_terms the parent as well. – Shibi Nov 21 '17 at 0:37
  • How would I add it though to set object terms if In my question and my original post, I've tried doing so, thats what $city_type is – Rich Nov 21 '17 at 0:38
  • see the answer its will help you to understand the process and to fix your old code too. – Shibi Nov 21 '17 at 1:14
0

To fix all the older posts that you already posted with only the child term. You need run this function only 1 time and its will add you the parents terms. its for all the ancestors of the child term.

Make sure to backup the DB before you run this function.

function fix_terms_parents() {
    /**
     * Create a query that select all the posts in your post type
     */
    $query = new WP_Query(array('post_type' => 'property', 'posts_per_page' => -1));
    if ( $query->have_posts() ):
        while ( $query->have_posts() ) : $query->the_post();
            $post_id = get_the_ID();
            /**
             * Get all the terms that set to the post
             */
            $terms = get_the_terms($post_id, 'city-type');
            foreach($terms as $term) {
                /**
                 * Get the term ancestors and append them
                 */
                $ancestors = get_ancestors($term->term_id, 'city-type');
                if($ancestors) {
                    $new_terms = wp_set_object_terms($post_id, $ancestors, 'city-type', true);
                    // the $new_terms variable is array of all the new terms that you set
                }
            }
        endwhile;
        wp_reset_postdata();
    endif;
}

Here is a function to set all the term ancestors. you can use with the return that you get from wp_set_object_terms in your old code.

/**
 * @param int $post_id the post id
 * @param string $taxonomy
 * @param array terms ids
 *
 * @return array of the ancestors terms that was append
 */
function set_ancestors_terms($post_id, $taxonomy, $terms) {
    foreach($terms as $term_id) {
        $ancestors = get_ancestors($term_id, $taxonomy);
        if($ancestors) {
            // Append parent terms
            return wp_set_object_terms($post_id, $ancestors, $taxonomy, true);
        }
    }
}

The first function you need to run only 1 time put it in the function.php and add add_action( 'init', 'fix_terms_parents', 10); too before it to run it. After this you can delete this function its only to fix the old posts.

Before you run the first function create DB backup.

The Second function you add too to the functions.php and you run it in your old code when you set the terms you need to get the return like this and run the function.

$terms_array = wp_set_object_terms($pid, $nhb_type_value, 'city-type');
set_ancestors_terms($pid, 'city-type', $terms_array);
  • Both codes I put in functions as is and then what? The parent terms will set on the front end post forms? – Rich Nov 21 '17 at 2:08
  • see the answer.. I edit it with some explanation. – Shibi Nov 21 '17 at 2:18
  • Ok i got the first code working thanks, soon as i figure out the second one I'll accept the answer. – Rich Nov 21 '17 at 3:41
  • The second one is for your old code edit your question and add the code that you have with the function wp_set_object_terms() – Shibi Nov 21 '17 at 9:26
  • The parent terms are only set when the second dropdown (child terms) are selected/set. Any way to make it so that the parent terms can be set if the child terms arent? @shibi – Rich Dec 28 '17 at 19:57

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.