0
votes

I have clothes products. One product is in multiples categories, like "gender" ("men" or "women") and "type" (such as "pants", "shirts", etc.).

I want to list all categories and subcategories of "type" from products that exist in "men" category.

ID of "type" category: 1696

$args = array(
  'taxonomy' => 'product_cat',
  'orderby'  => 'title',
  'order'    => 'ASC',
  'child_of'   => 1696,
);
$categories = get_terms( $args );
print_r($categories);

That code gives me all the categories under 1696, but I would like to get only the "type" categories from products that also are in "men" category.

Am I clear?

Thanks a lot for your help.

2

2 Answers

2
votes

Since wordpress only allows one id at a time for child_of argument, you could create a custom array and run get_terms for every parent category that you want.

From the documentation:

  • child_of - (int) Term ID to retrieve child terms of. If multiple taxonomies are passed, $child_of is ignored. Default 0.
    wp_term_query

$child_cats = array();

$parent_cats = array(1696, {the other category id});

$args = array(
  'taxonomy' => 'product_cat',
  'orderby'  => 'title',
  'order'    => 'ASC',
  'child_of'=> $parent_cat
);

foreach ($parent_cats as $parent_cat) 
{
    $child_cats = array_merge($child_cats, get_terms($args));
};

print_r($child_cats);

Let me know if that's what you were looking for!

0
votes

Thanks for your help, but it's not what I need.

I found a way to achieve what I want. There must be a better way but here's how I did:

I'm looping every products and put them in arrays if they are in the gender category ("femme" and "homme").

    $categories_femme = array(); // 1718
    $categories_homme = array(); // 1700
    
    $args = array(
        'post_type' => 'product',
        'posts_per_page' => -1
    );
    $loop = new WP_Query( $args );
    if ( $loop->have_posts() ): while ( $loop->have_posts() ): $loop->the_post();

      global $product;

      $p_id = $product->get_id();
      
      // FEMME
      if( has_term( 1718, 'product_cat' ) ) {
        $categories_femme[] = wp_get_post_terms($p_id, 'product_cat');
      }
      // HOMME
      if( has_term( 1700, 'product_cat' ) ) {
        $categories_homme[] = wp_get_post_terms($p_id, 'product_cat');
      }

    endwhile; endif; wp_reset_postdata();

After that, I'm formating the array to get this structure of categories (one array per gender): array('term_id' => 'name_id', 'term_id' => 'name_id', 'term_id' => 'name_id');

    $categories_femme_formated = array();
    foreach ($categories_femme as $categorie_femme) {
      foreach ($categorie_femme as $categoriefemme) {
        $categories_femme_formated[$categoriefemme->term_id] = $categoriefemme->name;
      }
    }
    
    $categories_homme_formated = array();
    foreach ($categories_homme as $categorie_homme) {
      foreach ($categorie_homme as $categoriehomme) {
        $categories_homme_formated[$categoriehomme->term_id] = $categoriehomme->name;
      }
    }

After that, I'm looping through all clothes categories and looking if this category ID exist in the array created just before. If yes, I'm adding this category to the menu.

    $args = array(
      'taxonomy' => 'product_cat',
      'hide_empty' => false,
      'parent'   => 1696
    );
    $product_cat = get_terms( $args );

    // FEMME
    $count_order = 100;
    foreach ($product_cat as $parent_product_cat)
    {
      $p_id = $parent_product_cat->term_id;
      if (array_key_exists($p_id, $categories_femme_formated)) {
        $count_order++;
        $menu_items[] = _custom_nav_menu_item( $categories_femme_formated[$p_id], get_term_link($p_id), $count_order, 11407 );
        
        $child_args = array(
                'taxonomy' => 'product_cat',
                'hide_empty' => false,
                'parent'   => $parent_product_cat->term_id
            );
        $child_product_cats = get_terms( $child_args );
        $parent_order = $count_order;
        foreach ($child_product_cats as $child_product_cat)
        {
          $c_id = $child_product_cat->term_id;
          if (array_key_exists($c_id, $categories_femme_formated)) {
            $count_order++;
            $child_menu_id = 1000000 + $parent_order + 11407;
            $menu_items[] = _custom_nav_menu_item( $categories_femme_formated[$c_id], get_term_link($c_id), $count_order, $child_menu_id );
            
          }
        }
      }
    }
    
    // HOMME
    $count_order = 100;
    foreach ($product_cat as $parent_product_cat)
    {
      $p_id = $parent_product_cat->term_id;
      if (array_key_exists($p_id, $categories_homme_formated)) {
        $count_order++;
        $menu_items[] = _custom_nav_menu_item( $categories_homme_formated[$p_id], get_term_link($p_id), $count_order, 11408 );
        
        $child_args = array(
                'taxonomy' => 'product_cat',
                'hide_empty' => false,
                'parent'   => $parent_product_cat->term_id
            );
        $child_product_cats = get_terms( $child_args );
        $parent_order = $count_order;
        foreach ($child_product_cats as $child_product_cat)
        {
          $c_id = $child_product_cat->term_id;
          if (array_key_exists($c_id, $categories_homme_formated)) {
            $count_order++;
            $child_menu_id = 1000000 + $parent_order + 11408;
            $menu_items[] = _custom_nav_menu_item( $categories_homme_formated[$c_id], get_term_link($c_id), $count_order, $child_menu_id );
            
          }
        }
      }
    }

Just for everyone to understand, I'm calling this code inside a function called by:

add_filter( 'wp_nav_menu_objects', 'my_dynamic_menu_items' );

And here is the _custom_nav_menu_item function:

function _custom_nav_menu_item( $title, $url, $order, $parent = 0 ){
  $item = new stdClass();
  $item->ID = 1000000 + $order + $parent;
  $item->db_id = $item->ID;
  $item->title = $title;
  $item->url = $url;
  $item->menu_order = $order;
  $item->menu_item_parent = $parent;
  $item->type = '';
  $item->object = '';
  $item->object_id = '';
  $item->classes = array();
  $item->target = '';
  $item->attr_title = '';
  $item->description = '';
  $item->xfn = '';
  $item->status = '';
  $item->icon = '';
  $item->nolink = '';
  $item->hide = '';
  $item->mobile_hide = ''; 
  $item->cols = ''; 
  $item->tip_label = '';
  $item->popup_type = 'wide';
  $item->popup_pos = '';
  $item->popup_cols = 'col-4';
  $item->popup_max_width = '';
  $item->popup_bg_image = '';
  $item->popup_bg_pos = ''; 
  $item->popup_bg_repeat = ''; 
  $item->popup_bg_size = ''; 
  $item->popup_style = '';
  $item->block = '';
  $item->preview = '';
  $item->preview_fixed = ''; 
  $item->current = '';
  $item->current_item_ancestor = '';
  $item->current_item_parent = '';
  return $item;
}

Thanks again for your help. :)