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?

5
  • 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, 2017 at 20:20
  • I dont get what you mean?
    – 730wavy
    Nov 21, 2017 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, 2017 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
    – 730wavy
    Nov 21, 2017 at 0:38
  • see the answer its will help you to understand the process and to fix your old code too.
    – Shibi
    Nov 21, 2017 at 1:14

1 Answer 1

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);
10
  • Both codes I put in functions as is and then what? The parent terms will set on the front end post forms?
    – 730wavy
    Nov 21, 2017 at 2:08
  • see the answer.. I edit it with some explanation.
    – Shibi
    Nov 21, 2017 at 2:18
  • Ok i got the first code working thanks, soon as i figure out the second one I'll accept the answer.
    – 730wavy
    Nov 21, 2017 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, 2017 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
    – 730wavy
    Dec 28, 2017 at 19:57

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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