1

I'm working on a website that shows a lot of products, and this is my structure:

  • Product (custom post type)
  • -->Brand (custom taxonomy)
  • ------>Brand A (custom term)
  • ------>Brand B (custom term)
  • -->Department (custom taxonomy).
  • ------>Department A (custom term)
  • ------>Department B (custom term)

I need to show which brands are in each department, and the only way to link them is using my products (because each custom taxonomy is independent from each other). I'm able to do it by quering all the products of a specific department, and retriving the brand of each product (instead of its name). This is the code I use to perfom this task:

<?php
    $args = array(
     'tax_query' => array(
         array(
             'taxonomy' => 'department',
             'field' => 'slug',
             'terms' => array( 'department-a' )
         ),
     ),
     'orderby' => 'title',
     'order' => 'ASC',
     'post_type' => 'prod'
    );
    $query = new WP_Query( $args );

    if ( $query->have_posts() ) {

     $term = $query->queried_object;

     while ( $query->have_posts() ) : $query->the_post(); ?>

         <li>
                  <?php
         // Get brand for post
         $terms = get_the_terms( $post->ID , 'brand' );    

         foreach( $terms as $term ) {
            print $term->name . ' <br />';
            unset($term);
         }
         ?>

       </li>
    <?php
    endwhile;

    wp_reset_query();
    } ?>

However, as some of my products has the same Brand, I need to group them if this happen. So my output sould be something like: DEPARTMENT A: Brand A has 3 products, Brand B has 1 product, Brand C has 2 products, etc.

Do you have any idea of how can I acheive this? Thanks.

EDIT

Capiadge answer let me know how many products are in a brand, but I can't access to those products. I've made a dropdown that matches all my needs with Brands (it checks if my brand has one or more product, if it's one, it sets a href attribute that I get via ajax and jquery so the user can go the the product page; if it's more, it sets a value that I get so if the user clics it may see which products are in that brand). The only thing that I need and I can't achive is to do the same thing, but not get all the Brands, but the Brands that have products in only one specific department. (i.e: a dropdown like this, but only for Department a).

<input type="hidden" id="filtro_tipo" value="productos">
            <select name="filtro_marca" onchange="update_productos();" id="filtro_marca">
                <option value="0"><?php echo pll_current_language()=='es'?'Seleccione una marca':'Select a brand'; ?></option>
                <?php
                    $args = array(
                            'order'             => 'ASC',
                            'hide_empty'        => true,
                            'cache_domain'      => 'core'
                    );
                    $terms = get_terms('brand', $args);
                    foreach ($terms as $item) {
                        if ($item->count == 1) {
                            $tax_query = '';
                            $tax_query[] = array('taxonomy' => 'brand','field' => 'term_id','terms' => $item->term_id);
                            $term_post = get_posts(array('post_type' => 'prod','tax_query' => $tax_query));
                            if (!empty($term_post)) {
                                $term_post_link = get_permalink($term_post[0]->ID);
                                $id_prod = url_to_postid($term_post_link);
                                $nombre_prod = get_the_title($term_post[0]->ID);
                                echo '<option value="'.$nombre_prod.'" href="'.$id_prod.'">'.$item->name.'</option>';
                            }
                        } else {
                            echo '<option value="'.$item->term_id.'" label="'.$item->name.'">'.$item->name.'</option>';
                        }
                    }
                ?>
            </select>
3
  • I guess that every product could have more than one brand, isn't? And the final result should be a list of brands (with the number of associated products), not a list of products, am I right?
    – Capiedge
    May 30, 2016 at 19:55
  • 3
    Have you posted this question twice? wordpress.stackexchange.com/q/228182/46066
    – Tim Malone
    May 30, 2016 at 20:00
  • 1
    Hi Capiedge: I do need what you said (a list of brands with the number of associated products), but every product has only one brand. Hi Tim, Nope, as I commented to CK reply, the other post is about a different problem that I've solved but that, at the end, doesn't works for what I need. (But yes, it's the same project) May 30, 2016 at 20:06

1 Answer 1

1

This is my best approach: Store the values in an array during the while loop, and then using array_count_values php function, you obtain the desired output.

It is untested, but I think it should work:

if ( $query->have_posts() ) {

    //in this variable, declared as an array, we will store the values
    $products_array = array();

    while ( $query->have_posts() ) : $query->the_post();

        $terms = get_the_terms( $post->ID , 'brand' );
        if ( $terms && ! is_wp_error( $terms ) ) {
            $brand_name = $terms[0]->name;
        }
        $products_array[] = $brand_name;

    endwhile;

    wp_reset_query();

}

//At this point, the $products_array, should be more or less:
//array(brandA, brandB, brandC, brandB, brandB, brandB, brandA);

//array_count_values does the magic
$result = array_count_values($products_array);

foreach ($result as $key => $value) {

    echo $key . ' has ' . $value . ' products.<br/>';

}

Hope it helps!

3
  • Nice, but I think he also wants them divided into departments. Most straightforward - probably not most economical especially if there are many departments or departments are continually being added - is to use a conditional: If (get_the_terms($post->ID,'department') == 'Department A') for a $dept_a_array, and so on, then do a variation on your foreach for each department array. A more flexible version would require building an array of arrays to the same end, but programmatically.
    – CK MacLeod
    May 31, 2016 at 14:37
  • Hi Capiadge, I'm very sory for my late response, but I was out of my city. I have reviewed your answer, and it perfectly does whay you said (I can get how many products are in each brand of a specific department. However, I need to get into the products of that brand and I don' see any way to achieve this. I have edited my post to explain a littler more my problem, and to show a dropdown I made that fits all my needs but that can't filter by department also as I need. Do you think that may be possible? Thank you very much. Jun 2, 2016 at 15:05
  • I think that the comment that @CKMacLeod has written to you about use a conditional that checks the department is probably what you are looking for.
    – Capiedge
    Jun 2, 2016 at 20:16

Your Answer

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

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