wp-graphql-woocommerce icon indicating copy to clipboard operation
wp-graphql-woocommerce copied to clipboard

Get all global attributes belonging to one category

Open alexkey89 opened this issue 3 years ago • 7 comments
trafficstars

Is your feature request related to a problem? Please describe. For example I want to filter products based on a particular attribute. The reason why is to have the "filter" fields available according the the category page.

Describe the solution you'd like I'd like to get all attribute fields belonging to that category. e.g

query GET_ATTRS {
  productCategory(id: "dresses", idType: SLUG) {
     allPaSize {
      name
      slug
    }
    allPaBrands {
      name
      slug
    }
  }
}

Describe alternatives you've considered This works but.. it gets the attributes of all categories regardless. I want to be able to get the available attributes according to selected category

 `query GET_ATTRS {
  allPaSize {
    edges {
      node {
        name
        slug
      }
    }
  }
}`

Ideally I'd like something like this: https://stackoverflow.com/questions/59005207/query-to-get-attributes-based-on-product-category-selected-in-woocommerce

Additional context Is there any chance of having this feature the soonest? Thanks.

alexkey89 avatar Jul 06 '22 07:07 alexkey89

Maybe as a workaround, you can do something like this. Then, make a fancy mapper that checks if there is a length on productCategory nodes.

  allPaIngredients {
    nodes {
      name
      products {
        nodes {
          productCategories (where: {slug:"YOUR_SLUG"}) {
            edges {
              node {
                id
                name
                slug
              }
            }
          }
        }
      }
    }
  }
}

JustinLek avatar Aug 12 '22 09:08 JustinLek

@alexkey89 @JustinLek Have you tried this?

{
  paColor(id: "red", idType: SLUG) {
    products(where: {attribute: "pa_color" attributeTerm: "red"}) {
      nodes {
        id
        name
      }
    }
  }
}

kidunot89 avatar Sep 11 '22 22:09 kidunot89

@kidunot89 No, that's not what we want. What @alexkey89 and I need is all available attributes based on a product category. So only return the color attributes that have products in that category. I also tried the following to see if there is length on the products array, but this will return all the products with that ingredient and doesn't filter on the category.

  allPaIngredients {
    nodes {
      id
      name
      taxonomyName
      slug
      products(
        where: {category: "dogs"}
      ) {
        nodes {
          id
        }
      }
    }
  }

JustinLek avatar Oct 18 '22 13:10 JustinLek

Agree with @JustinLek , We want to be able to filter products pretty much so we need the "filter-items" based on that category as well as the number of products according to that attribute (counter). For now I created a custom rest api endpoint to do this (without the counter). I can share it if that helps. Also this task should not have been closed.

alexkey89 avatar Oct 19 '22 19:10 alexkey89

@kidunot89 filtering on products inside custom attributes doesn't work either. For example, filtering products based on a category returns all products.

{
  allPaIngredients {
    products(where: {category: "dog"}) {
      nodes {
        id
        name
      }
    }
  }
}

JustinLek avatar Nov 01 '22 14:11 JustinLek

@kidunot89, did you find anything?

JustinLek avatar Nov 24 '22 11:11 JustinLek

@alexkey89 Thank You for this idea.

For everyone who still looking for working but not ideal solution.

add_action('rest_api_init', function () {
  register_rest_route('globalattr/v1', '/category-filters/(?P<category>[^/]+)', array(
    'methods' => 'GET',
    'callback' => 'globalattr_get_category_filters',
  ));
});

function globalattr_get_category_filters($request) {
  $filter_raw = array();
  $attrs_raw  = wc_get_attribute_taxonomy_names();
  $cat_name = get_term_by('slug', $request['category'], 'product_cat', ARRAY_A );
  $args = array(
    'category'  => array($cat_name['slug'] )
  );
  foreach( wc_get_products($args) as $product ){
    foreach( $product->get_attributes() as $attr_name => $attr ){
      $filter_raw[] = $attr_name;
      if(is_array($attr->get_terms())){    
        foreach( $attr->get_terms() as $term ){
          $terms_raw[] = $term->slug; // Modified to add the term slug instead of name
        }
      }
    }
  }
  $filters = array_unique(array_intersect((array)$filter_raw,(array)$attrs_raw));
  $return = array();
  if(is_array($filters)){    
    foreach ( $filters as $filter ){
      $terms = get_terms( $filter );
      if ( ! empty( $terms ) ) {
        $values = array(); // Create an array to hold the term slugs
        foreach ( $terms as $term ) {
          if(in_array($term->slug,$terms_raw)){ // Modified to check for the term slug instead of name
            $values[] = $term->slug; // Add the term slug to the values array
          }
        }
        if (!empty($values)) { // Only add the filter if there are values
          $return['items'][ $filter ] = array(
            'id'    => $filter,
            'type'  => 'checkbox',
            'label' => wc_attribute_label( $filter ),
            'values' => $values, // Add the values array to the response
          );
        }
      }
    }
  }
  return new WP_REST_Response($return, 200);
}

Example access: https://your-great-website/wp-json/globalattr/v1/category-filters/slug-of-category

Kapitan-Nemo avatar Oct 11 '23 14:10 Kapitan-Nemo