2

All my website's posts are assigned to subcategories, but not to their parent categories too:

enter image description here

Is there someway that I could massively assign posts to their parent categories too?

enter image description here

My website has more than 3k posts, so I need to find a quick way to do this. I didn't find any plugin that could help me. Any suggestions please?

2 Answers 2

0

be careful and only run it once

$_query = new WP_Query( array(
    'post_type' => 'post',
    'posts_per_page' => -1,
 ) );
function complete_parent_category( $term_id, $dep=array() ) {
    $category = get_term( $term_id, 'category' );
    $dep[ $category->term_id ] = $category->slug;
    if( $category->parent ) {
      $dep = complete_parent_category( $category->parent, $dep );
    }
    return $dep;
}
echo '<pre>';
while( $_query->have_posts() ) {
  $_query->next_post();
  echo '<br /><strong>'.$_query->post->post_title .'</strong> |>> ';
  $cat_post = array();
  $cats = get_the_category( $_query->post->ID );
  if( count( $cats ) ) {
    foreach ($cats as $cat) {
      $cat_post[ $cat->term_id ] = $cat->slug;
      if( $cat->parent == 0 ) continue; 
      $category_object = get_term( $cat, 'category' );
      $cat_post = complete_parent_category( $cat->parent, $cat_post );
    }
  }
  if( count( $cats ) == count( $cat_post ) ) return;
  $data = array(
      'ID'           => $_query->post->ID,
      'post_category' => array_keys($cat_post),
  );
  wp_update_post( $data );
}

wp_reset_postdata();

exit();
2
  • where should I place this code? In a seperate file? In index.php?
    – ktsixit
    Feb 17, 2014 at 14:01
  • It would be useful to describe a technique for a “one-shot” plug-in and also for automatically ticking parent categories for new posts or when category assignments are edited. Mar 15, 2019 at 21:23
0

Paste this into your functions.php file. The function will be triggered when you access the WordPress admin dashboard. The function runs only once because after its first run, an option assign_parent_terms_completed is set in the database. On subsequent runs, the function checks for this option and doesn't execute if it's set.

function assign_parent_terms_to_posts() {
    // Get all the posts
    $args = array(
        'post_type' => 'post',
        'posts_per_page' => -1
    );
    $query = new WP_Query($args);

    // If there are posts, loop through each one
    if($query->have_posts()) {
        while($query->have_posts()) {
            $query->the_post();

            // Get the child terms assigned to the post
            $child_terms = get_the_terms(get_the_ID(), 'category');

            // Loop through each child term
            foreach($child_terms as $child_term) {
                // If the term has a parent
                if(isset($child_term -> parent) && $child_term -> parent != 0) {
                    // Assign the parent term to the post
                    wp_set_post_terms(get_the_ID(), array($child_term -> parent), 'category', true);
                }
            }
        }
    }
    wp_reset_postdata(); // Reset the post data
}

// Hook the function to the 'admin_init' action
add_action('admin_init', 'run_assign_parent_terms_once');

function run_assign_parent_terms_once() {
    // Check if the function has already been run
    if(!get_option('assign_parent_terms_completed')) {
        assign_parent_terms_to_posts();
        // Mark the function as run
        update_option('assign_parent_terms_completed', true);
    }
}

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.