Skip to content

Commit f5237b3

Browse files
authored
Merge pull request #126 from kidunot89/feature/new-product-connection-args
Adds "taxonomyFilter" to product connections
2 parents 0224c05 + 0501914 commit f5237b3

12 files changed

+252
-14
lines changed

includes/class-type-registry.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,8 @@ public static function graphql_register_types() {
3939
\WPGraphQL\Extensions\WooCommerce\Type\WPEnum\WC_Connection_Orderby_Enum::register();
4040
\WPGraphQL\Extensions\WooCommerce\Type\WPEnum\Tax_Rate_Connection_Orderby_Enum::register();
4141
\WPGraphQL\Extensions\WooCommerce\Type\WPEnum\Pricing_Field_Format::register();
42+
\WPGraphQL\Extensions\WooCommerce\Type\WPEnum\Product_Taxonomy::register();
43+
\WPGraphQL\Extensions\WooCommerce\Type\WPEnum\Taxonomy_Operator::register();
4244

4345
// InputObjects.
4446
\WPGraphQL\Extensions\WooCommerce\Type\WPInputObject\Customer_Address_Input::register();
@@ -51,6 +53,8 @@ public static function graphql_register_types() {
5153
\WPGraphQL\Extensions\WooCommerce\Type\WPInputObject\Shipping_Line_Input::register();
5254
\WPGraphQL\Extensions\WooCommerce\Type\WPInputObject\Create_Account_Input::register();
5355
\WPGraphQL\Extensions\WooCommerce\Type\WPInputObject\Cart_Item_Quantity_Input::register();
56+
\WPGraphQL\Extensions\WooCommerce\Type\WPInputObject\Product_Taxonomy_Filter_Input::register();
57+
\WPGraphQL\Extensions\WooCommerce\Type\WPInputObject\Product_Taxonomy_Filter_Relation_Input::register();
5458

5559
// Objects.
5660
\WPGraphQL\Extensions\WooCommerce\Type\WPObject\Coupon_Type::register();

includes/connection/class-products.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -270,6 +270,10 @@ public static function get_connection_args() {
270270
'type' => 'CatalogVisibilityEnum',
271271
'description' => __( 'Limit result set to products with a specific visibility level.', 'wp-graphql-woocommerce' ),
272272
),
273+
'taxonomyFilter' => array(
274+
'type' => array( 'list_of' => 'ProductTaxonomyFilterRelationInput' ),
275+
'description' => __( 'Limit result set with complex set of taxonomy filters.', 'wp-graphql-woocommerce' ),
276+
),
273277
);
274278

275279
if ( wc_tax_enabled() ) {

includes/data/connection/class-product-connection-resolver.php

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -478,6 +478,29 @@ public function sanitize_input_fields( array $where_args ) {
478478
}
479479
}
480480

481+
// Process "taxonomyFilter".
482+
if ( ! empty( $where_args['taxonomyFilter'] ) ) {
483+
foreach ( $where_args['taxonomyFilter'] as $filter ) {
484+
foreach ( $filter as $relation => $filter_args ) {
485+
foreach ( $filter_args as $filter_arg ) {
486+
$tax_query[] = array(
487+
'relation' => $relation,
488+
array(
489+
'taxonomy' => $filter_arg['taxonomy'],
490+
'field' => ! empty( $filter_arg['ids'] ) ? 'term_id' : 'slug',
491+
'terms' => ! empty( $filter_arg['ids'] )
492+
? $filter_arg['ids']
493+
: $filter_arg['terms'],
494+
'operator' => ! empty( $filter_arg['operator'] )
495+
? $filter_arg['operator']
496+
: 'IN',
497+
),
498+
);
499+
}
500+
}
501+
}
502+
}
503+
481504
if ( ! empty( $tax_query ) && 1 > count( $tax_query ) ) {
482505
$tax_query['relation'] = 'AND';
483506
}
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
<?php
2+
/**
3+
* WPEnum Type - ProductTaxonomyEnum
4+
*
5+
* @package \WPGraphQL\Extensions\WooCommerce\Type\WPEnum
6+
* @since 0.2.1
7+
*/
8+
9+
namespace WPGraphQL\Extensions\WooCommerce\Type\WPEnum;
10+
11+
use WPGraphQL\Type\WPEnumType;
12+
13+
/**
14+
* Class Product_Taxonomy
15+
*/
16+
class Product_Taxonomy {
17+
/**
18+
* Registers type
19+
*/
20+
public static function register() {
21+
// Get values from attributes taxonomies.
22+
$attribute_values = array();
23+
foreach ( wc_get_attribute_taxonomy_names() as $attribute ) {
24+
$attribute_values[ WPEnumType::get_safe_name( $attribute ) ] = array( 'value' => $attribute );
25+
}
26+
27+
register_graphql_enum_type(
28+
'ProductTaxonomyEnum',
29+
array(
30+
'description' => __( 'Product taxonomies', 'wp-graphql-woocommerce' ),
31+
'values' => array_merge(
32+
array(
33+
'TYPE' => array( 'value' => 'product_type' ),
34+
'CATEGORY' => array( 'value' => 'product_cat' ),
35+
'TAG' => array( 'value' => 'product_tag' ),
36+
'BRAND' => array( 'value' => 'product_brand' ),
37+
),
38+
$attribute_values
39+
),
40+
)
41+
);
42+
}
43+
}

includes/type/enum/class-product-types.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ public static function register() {
4545
register_graphql_enum_type(
4646
'ProductTypesEnum',
4747
array(
48-
'description' => __( 'Product type enumeration', 'wp-graphql' ),
48+
'description' => __( 'Product type enumeration', 'wp-graphql-woocommerce' ),
4949
'values' => $values,
5050
)
5151
);

includes/type/enum/class-tax-status.php

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -16,17 +16,15 @@ class Tax_Status {
1616
* Registers type
1717
*/
1818
public static function register() {
19-
$values = [
20-
'TAXABLE' => array( 'value' => 'taxable' ),
21-
'SHIPPING' => array( 'value' => 'shipping' ),
22-
'NONE' => array( 'value' => 'none' ),
23-
];
24-
2519
register_graphql_enum_type(
2620
'TaxStatusEnum',
2721
array(
2822
'description' => __( 'Product tax status enumeration', 'wp-graphql' ),
29-
'values' => $values,
23+
'values' => array(
24+
'TAXABLE' => array( 'value' => 'taxable' ),
25+
'SHIPPING' => array( 'value' => 'shipping' ),
26+
'NONE' => array( 'value' => 'none' ),
27+
),
3028
)
3129
);
3230
}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
<?php
2+
/**
3+
* WPEnum Type - TaxonomyOperatorEnum
4+
*
5+
* @package \WPGraphQL\Extensions\WooCommerce\Type\WPEnum
6+
* @since 0.2.1
7+
*/
8+
9+
namespace WPGraphQL\Extensions\WooCommerce\Type\WPEnum;
10+
11+
/**
12+
* Class Taxonomy_Operator
13+
*/
14+
class Taxonomy_Operator {
15+
/**
16+
* Registers type
17+
*/
18+
public static function register() {
19+
register_graphql_enum_type(
20+
'TaxonomyOperatorEnum',
21+
array(
22+
'description' => __( 'Taxonomy query operators', 'wp-graphql' ),
23+
'values' => array(
24+
'IN' => array( 'value' => 'IN' ),
25+
'NOT_IN' => array( 'value' => 'NOT IN' ),
26+
'AND' => array( 'value' => 'AND' ),
27+
'EXISTS' => array( 'value' => 'EXISTS' ),
28+
'NOT_EXISTS' => array( 'value' => 'NOT EXISTS' ),
29+
),
30+
)
31+
);
32+
}
33+
}
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
<?php
2+
/**
3+
* WPInputObjectType - ProductTaxonomyFilterInput
4+
*
5+
* @package \WPGraphQL\Extensions\WooCommerce\Type\WPInputObject
6+
* @since 0.2.1
7+
*/
8+
9+
namespace WPGraphQL\Extensions\WooCommerce\Type\WPInputObject;
10+
11+
/**
12+
* Class Product_Taxonomy_Filter_Input
13+
*/
14+
class Product_Taxonomy_Filter_Input {
15+
/**
16+
* Registers type
17+
*/
18+
public static function register() {
19+
register_graphql_input_type(
20+
'ProductTaxonomyFilterInput',
21+
array(
22+
'description' => __( 'Product filter', 'wp-graphql-woocommerce' ),
23+
'fields' => array(
24+
'taxonomy' => array(
25+
'type' => array( 'non_null' => 'ProductTaxonomyEnum' ),
26+
'description' => __( 'Which field to select taxonomy term by.', 'wp-graphql-woocommerce' ),
27+
),
28+
'terms' => array(
29+
'type' => array( 'list_of' => 'String' ),
30+
'description' => __( 'A list of term slugs', 'wp-graphql-woocommerce' ),
31+
),
32+
'ids' => array(
33+
'type' => array( 'list_of' => 'Int' ),
34+
'description' => __( 'A list of term ids', 'wp-graphql-woocommerce' ),
35+
),
36+
'operator' => array(
37+
'type' => 'TaxonomyOperatorEnum',
38+
'description' => __( 'Filter operation type', 'wp-graphql-woocommerce' ),
39+
),
40+
),
41+
)
42+
);
43+
}
44+
}
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
<?php
2+
/**
3+
* WPInputObjectType - ProductTaxonomyFilterRelationInput
4+
*
5+
* @package \WPGraphQL\Extensions\WooCommerce\Type\WPInputObject
6+
* @since 0.2.1
7+
*/
8+
9+
namespace WPGraphQL\Extensions\WooCommerce\Type\WPInputObject;
10+
11+
/**
12+
* Class Product_Taxonomy_Filter_Relation_Input
13+
*/
14+
class Product_Taxonomy_Filter_Relation_Input {
15+
/**
16+
* Registers type
17+
*/
18+
public static function register() {
19+
register_graphql_input_type(
20+
'ProductTaxonomyFilterRelationInput',
21+
array(
22+
'description' => __( 'Product taxonomy filter type', 'wp-graphql-woocommerce' ),
23+
'fields' => array(
24+
'or' => array(
25+
'type' => array( 'list_of' => 'ProductTaxonomyFilterInput' ),
26+
),
27+
'and' => array(
28+
'type' => array( 'list_of' => 'ProductTaxonomyFilterInput' ),
29+
),
30+
),
31+
)
32+
);
33+
}
34+
}

tests/wpunit/ProductQueriesTest.php

Lines changed: 53 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -222,6 +222,7 @@ public function testProductsQueryAndWhereArgs() {
222222
$featured: Boolean,
223223
$maxPrice: Float,
224224
$orderby: [WCConnectionOrderbyInput]
225+
$taxonomyFilter: [ProductTaxonomyFilterRelationInput]
225226
){
226227
products( where: {
227228
slug: $slug,
@@ -238,6 +239,7 @@ public function testProductsQueryAndWhereArgs() {
238239
featured: $featured,
239240
maxPrice: $maxPrice,
240241
orderby: $orderby
242+
taxonomyFilter: $taxonomyFilter
241243
} ) {
242244
nodes {
243245
id
@@ -483,7 +485,7 @@ public function testProductsQueryAndWhereArgs() {
483485
/**
484486
* Assertion Ten
485487
*
486-
* tests "categoryName" where argument
488+
* tests "category" where argument
487489
*/
488490
$variables = array( 'category' => 'category-three' );
489491
$actual = do_graphql_request( $query, 'ProductsQuery', $variables );
@@ -511,7 +513,7 @@ public function testProductsQueryAndWhereArgs() {
511513
/**
512514
* Assertion Eleven
513515
*
514-
* tests "categoryName" where argument
516+
* tests "categoryIn" where argument
515517
*/
516518
$variables = array( 'categoryIn' => array( 'category-three' ) );
517519
$actual = do_graphql_request( $query, 'ProductsQuery', $variables );
@@ -539,7 +541,7 @@ public function testProductsQueryAndWhereArgs() {
539541
/**
540542
* Assertion Twelve
541543
*
542-
* tests "categoryName" where argument
544+
* tests "categoryNotIn" where argument
543545
*/
544546
$variables = array( 'categoryNotIn' => array( 'category-four' ) );
545547
$actual = do_graphql_request( $query, 'ProductsQuery', $variables );
@@ -567,7 +569,7 @@ public function testProductsQueryAndWhereArgs() {
567569
/**
568570
* Assertion Thirteen
569571
*
570-
* tests "categoryName" where argument
572+
* tests "categoryId" where argument
571573
*/
572574
$variables = array( 'categoryId' => $category_3 );
573575
$actual = do_graphql_request( $query, 'ProductsQuery', $variables );
@@ -595,7 +597,7 @@ public function testProductsQueryAndWhereArgs() {
595597
/**
596598
* Assertion Fourteen
597599
*
598-
* tests "categoryName" where argument
600+
* tests "categoryIdIn" where argument
599601
*/
600602
$variables = array( 'categoryIdIn' => array( $category_3 ) );
601603
$actual = do_graphql_request( $query, 'ProductsQuery', $variables );
@@ -623,7 +625,7 @@ public function testProductsQueryAndWhereArgs() {
623625
/**
624626
* Assertion Fifteen
625627
*
626-
* tests "categoryName" where argument
628+
* tests "categoryIdNotIn" where argument
627629
*/
628630
$variables = array( 'categoryIdNotIn' => array( $category_4 ) );
629631
$actual = do_graphql_request( $query, 'ProductsQuery', $variables );
@@ -647,6 +649,51 @@ public function testProductsQueryAndWhereArgs() {
647649
codecept_debug( $actual );
648650

649651
$this->assertEquals( $expected, $actual );
652+
653+
/**
654+
* Assertion Sixteen
655+
*
656+
* tests "taxonomyFilter" where argument
657+
*/
658+
$variables = array(
659+
'taxonomyFilter' => array(
660+
array(
661+
'and' => array(
662+
array(
663+
'taxonomy' => 'CATEGORY',
664+
'terms' => array( 'category-three' ),
665+
),
666+
array(
667+
'taxonomy' => 'CATEGORY',
668+
'terms' => array( 'category-four' ),
669+
'operator' => 'NOT_IN'
670+
),
671+
)
672+
)
673+
),
674+
);
675+
$actual = do_graphql_request( $query, 'ProductsQuery', $variables );
676+
$expected = array(
677+
'data' => array(
678+
'products' => array(
679+
'nodes' => $this->helper->print_nodes(
680+
$products,
681+
array(
682+
'filter' => function( $id ) use ( $category_4, $category_3 ) {
683+
$product = \wc_get_product( $id );
684+
return ! in_array( $category_4, $product->get_category_ids() )
685+
&& in_array( $category_3, $product->get_category_ids() );
686+
},
687+
)
688+
),
689+
),
690+
),
691+
);
692+
693+
// use --debug flag to view.
694+
codecept_debug( $actual );
695+
696+
$this->assertEquals( $expected, $actual );
650697
}
651698

652699
public function testProductToTermConnection() {

0 commit comments

Comments
 (0)