Skip to content

Commit 6b0c798

Browse files
authored
feat: collectionStats query added (#785)
* feat: collectionStats query added * fix: `collectionStats` query completed and tested. * chore: Linter and PHPStan compliance met * chore: ProductTaxonomy values fixed. * chore: CollectionStatsQueryTest tweaked for CI
1 parent 356d705 commit 6b0c798

14 files changed

+922
-3
lines changed

includes/class-type-registry.php

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,8 @@ public function init() {
4343
Type\WPEnum\Orders_Orderby_Enum::register();
4444
Type\WPEnum\Id_Type_Enums::register();
4545
Type\WPEnum\Cart_Error_Type::register();
46+
Type\WPEnum\Product_Attribute_Enum::register();
47+
Type\WPEnum\Attribute_Operator_Enum::register();
4648

4749
/**
4850
* InputObjects.
@@ -60,6 +62,9 @@ public function init() {
6062
Type\WPInputObject\Product_Taxonomy_Filter_Input::register();
6163
Type\WPInputObject\Product_Taxonomy_Input::register();
6264
Type\WPInputObject\Orderby_Inputs::register();
65+
Type\WPInputObject\Collection_Stats_Query_Input::register();
66+
Type\WPInputObject\Collection_Stats_Where_Args::register();
67+
Type\WPInputObject\Product_Attribute_Filter_Input::register();
6368

6469
/**
6570
* Interfaces.
@@ -104,6 +109,7 @@ public function init() {
104109
Type\WPObject\Cart_Error_Types::register();
105110
Type\WPObject\Payment_Token_Types::register();
106111
Type\WPObject\Country_State_Type::register();
112+
Type\WPObject\Collection_Stats_Type::register();
107113

108114
/**
109115
* Object fields.

includes/class-wp-graphql-woocommerce.php

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -236,6 +236,8 @@ private function includes() {
236236
require $include_directory_path . 'type/enum/class-tax-rate-connection-orderby-enum.php';
237237
require $include_directory_path . 'type/enum/class-tax-status.php';
238238
require $include_directory_path . 'type/enum/class-taxonomy-operator.php';
239+
require $include_directory_path . 'type/enum/class-attribute-operator-enum.php';
240+
require $include_directory_path . 'type/enum/class-product-attribute-enum.php';
239241

240242
// Include interface type class files.
241243
require $include_directory_path . 'type/interface/class-attribute.php';
@@ -278,6 +280,7 @@ private function includes() {
278280
require $include_directory_path . 'type/object/class-variation-attribute-type.php';
279281
require $include_directory_path . 'type/object/class-payment-token-types.php';
280282
require $include_directory_path . 'type/object/class-country-state-type.php';
283+
require $include_directory_path . 'type/object/class-collection-stats-type.php';
281284

282285
// Include input type class files.
283286
require $include_directory_path . 'type/input/class-cart-item-input.php';
@@ -293,6 +296,9 @@ private function includes() {
293296
require $include_directory_path . 'type/input/class-product-taxonomy-input.php';
294297
require $include_directory_path . 'type/input/class-shipping-line-input.php';
295298
require $include_directory_path . 'type/input/class-tax-rate-connection-orderby-input.php';
299+
require $include_directory_path . 'type/input/class-collection-stats-query-input.php';
300+
require $include_directory_path . 'type/input/class-collection-stats-where-args.php';
301+
require $include_directory_path . 'type/input/class-product-attribute-filter-input.php';
296302

297303
// Include mutation type class files.
298304
require $include_directory_path . 'mutation/class-cart-add-fee.php';

includes/connection/class-products.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -427,6 +427,10 @@ public static function get_connection_args( $extra_args = [] ): array {
427427
'type' => 'Boolean',
428428
'description' => __( 'Include variations in the result set.', 'wp-graphql-woocommerce' ),
429429
],
430+
'rating' => [
431+
'type' => [ 'list_of' => 'Integer' ],
432+
'description' => __( 'Limit result set to products with a specific average rating. Must be between 1 and 5', 'wp-graphql-woocommerce' ),
433+
],
430434
];
431435

432436
if ( wc_tax_enabled() ) {

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

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -466,6 +466,19 @@ public function sanitize_input_fields( array $where_args ) {
466466
}//end switch
467467
}//end if
468468

469+
if ( ! empty( $where_args['rating'] ) ) {
470+
$rating = $where_args['rating'];
471+
$rating_terms = [];
472+
foreach ( $rating as $value ) {
473+
$rating_terms[] = 'rated-' . $value;
474+
}
475+
$tax_query[] = [
476+
'taxonomy' => 'product_visibility',
477+
'field' => 'name',
478+
'terms' => $rating_terms,
479+
];
480+
}
481+
469482
// Process "taxonomyFilter".
470483
$tax_filter_query = [];
471484
if ( ! empty( $where_args['taxonomyFilter'] ) ) {
@@ -563,6 +576,8 @@ public function sanitize_input_fields( array $where_args ) {
563576
$query_args[ $on_sale_key ] = $on_sale_ids;
564577
}
565578

579+
580+
566581
/**
567582
* {@inheritDoc}
568583
*/
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
<?php
2+
/**
3+
* WPEnum Type - AttributeOperatorEnum
4+
*
5+
* @package WPGraphQL\WooCommerce\Type\WPEnum
6+
* @since TBD
7+
*/
8+
9+
namespace WPGraphQL\WooCommerce\Type\WPEnum;
10+
11+
/**
12+
* Class Attribute_Operator_Enum
13+
*/
14+
class Attribute_Operator_Enum {
15+
/**
16+
* Registers type
17+
*
18+
* @return void
19+
*/
20+
public static function register() {
21+
register_graphql_enum_type(
22+
'AttributeOperatorEnum',
23+
[
24+
'description' => __( 'Collection statistic attributes operators', 'wp-graphql-woocommerce' ),
25+
'values' => [
26+
'IN' => [ 'value' => 'IN' ],
27+
'NOT_IN' => [ 'value' => 'NOT IN' ],
28+
'AND' => [ 'value' => 'AND' ],
29+
],
30+
]
31+
);
32+
}
33+
}
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
<?php
2+
/**
3+
* WPEnum Type - ProductAttributeEnum
4+
*
5+
* @package WPGraphQL\WooCommerce\Type\WPEnum
6+
* @since TBD
7+
*/
8+
9+
namespace WPGraphQL\WooCommerce\Type\WPEnum;
10+
11+
use WPGraphQL\Type\WPEnumType;
12+
13+
/**
14+
* Class Product_Attribute_Enum
15+
*/
16+
class Product_Attribute_Enum {
17+
/**
18+
* Registers type
19+
*
20+
* @return void
21+
*/
22+
public static function register() {
23+
// Get values from product attributes.
24+
$taxonomy_values = [];
25+
$taxonomies = wc_get_attribute_taxonomy_names();
26+
27+
foreach ( $taxonomies as $taxonomy ) {
28+
$tax_object = get_taxonomy( $taxonomy );
29+
30+
if ( false !== $tax_object && in_array( 'product', $tax_object->object_type, true ) ) {
31+
$taxonomy_values[ WPEnumType::get_safe_name( $taxonomy ) ] = [ 'value' => $taxonomy ];
32+
}
33+
}
34+
35+
register_graphql_enum_type(
36+
'ProductAttributeEnum',
37+
[
38+
'description' => __( 'Product attribute taxonomies', 'wp-graphql-woocommerce' ),
39+
'values' => $taxonomy_values,
40+
]
41+
);
42+
}
43+
}

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ public static function register() {
2828
$tax_object = get_taxonomy( $taxonomy );
2929

3030
if ( false !== $tax_object && in_array( 'product', $tax_object->object_type, true ) ) {
31-
$taxonomy_values[ WPEnumType::get_safe_name( $tax_object->graphql_single_name ) ] = [ 'value' => $taxonomy ];
31+
$taxonomy_values[ WPEnumType::get_safe_name( $taxonomy ) ] = [ 'value' => $taxonomy ];
3232
}
3333
}
3434

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
<?php
2+
/**
3+
* WPInputObjectType - CollectionStatsQueryInput
4+
*
5+
* @package WPGraphQL\WooCommerce\Type\WPInputObject
6+
* @since TBD
7+
*/
8+
9+
namespace WPGraphQL\WooCommerce\Type\WPInputObject;
10+
11+
/**
12+
* Class Collection_Stats_Query_Input
13+
*/
14+
class Collection_Stats_Query_Input {
15+
/**
16+
* Registers type
17+
*
18+
* @return void
19+
*/
20+
public static function register() {
21+
register_graphql_input_type(
22+
'CollectionStatsQueryInput',
23+
[
24+
'description' => __( 'Taxonomy query', 'wp-graphql-woocommerce' ),
25+
'fields' => [
26+
'taxonomy' => [
27+
'type' => [ 'non_null' => 'ProductAttributeEnum' ],
28+
'description' => __( 'Product Taxonomy', 'wp-graphql-woocommerce' ),
29+
],
30+
'relation' => [
31+
'type' => [ 'non_null' => 'RelationEnum' ],
32+
'description' => __( 'Taxonomy relation to query', 'wp-graphql-woocommerce' ),
33+
],
34+
],
35+
]
36+
);
37+
}
38+
}
Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
<?php
2+
/**
3+
* WPInputObjectType - CollectionStatsWhereArgs
4+
*
5+
* @package WPGraphQL\WooCommerce\Type\WPInputObject
6+
* @since TBD
7+
*/
8+
9+
namespace WPGraphQL\WooCommerce\Type\WPInputObject;
10+
11+
/**
12+
* Class Collection_Stats_Where_Args
13+
*/
14+
class Collection_Stats_Where_Args {
15+
/**
16+
* Registers type
17+
*
18+
* @return void
19+
*/
20+
public static function register() {
21+
register_graphql_input_type(
22+
'CollectionStatsWhereArgs',
23+
[
24+
'description' => __( 'Arguments used to filter the collection results', 'wp-graphql-woocommerce' ),
25+
'fields' => [
26+
'search' => [
27+
'type' => 'String',
28+
'description' => __( 'Limit result set to products based on a keyword search.', 'wp-graphql-woocommerce' ),
29+
],
30+
'slugIn' => [
31+
'type' => [ 'list_of' => 'String' ],
32+
'description' => __( 'Limit result set to products with specific slugs.', 'wp-graphql-woocommerce' ),
33+
],
34+
'typeIn' => [
35+
'type' => [ 'list_of' => 'ProductTypesEnum' ],
36+
'description' => __( 'Limit result set to products assigned to a group of specific types.', 'wp-graphql-woocommerce' ),
37+
],
38+
'exclude' => [
39+
'type' => [ 'list_of' => 'Int' ],
40+
'description' => __( 'Ensure result set excludes specific IDs.', 'wp-graphql-woocommerce' ),
41+
],
42+
'include' => [
43+
'type' => [ 'list_of' => 'Int' ],
44+
'description' => __( 'Limit result set to specific ids.', 'wp-graphql-woocommerce' ),
45+
],
46+
'sku' => [
47+
'type' => 'String',
48+
'description' => __( 'Limit result set to products with specific SKU(s). Use commas to separate.', 'wp-graphql-woocommerce' ),
49+
],
50+
'featured' => [
51+
'type' => 'Boolean',
52+
'description' => __( 'Limit result set to featured products.', 'wp-graphql-woocommerce' ),
53+
],
54+
'parentIn' => [
55+
'type' => [ 'list_of' => 'Int' ],
56+
'description' => __( 'Specify objects whose parent is in an array.', 'wp-graphql-woocommerce' ),
57+
],
58+
'parentNotIn' => [
59+
'type' => [ 'list_of' => 'Int' ],
60+
'description' => __( 'Specify objects whose parent is not in an array.', 'wp-graphql-woocommerce' ),
61+
],
62+
'categoryIn' => [
63+
'type' => [ 'list_of' => 'String' ],
64+
'description' => __( 'Limit result set to products assigned to a group of specific categories by name.', 'wp-graphql-woocommerce' ),
65+
],
66+
'categoryIdIn' => [
67+
'type' => [ 'list_of' => 'Int' ],
68+
'description' => __( 'Limit result set to products assigned to a specific group of category IDs.', 'wp-graphql-woocommerce' ),
69+
],
70+
'tagIn' => [
71+
'type' => [ 'list_of' => 'String' ],
72+
'description' => __( 'Limit result set to products assigned to a specific group of tags by name.', 'wp-graphql-woocommerce' ),
73+
],
74+
'tagIdIn' => [
75+
'type' => [ 'list_of' => 'Int' ],
76+
'description' => __( 'Limit result set to products assigned to a specific group of tag IDs.', 'wp-graphql-woocommerce' ),
77+
],
78+
'attributes' => [
79+
'type' => [ 'list_of' => 'ProductAttributeFilterInput' ],
80+
'description' => __( 'Limit result set to products with a specific attribute. Use the taxonomy name/attribute slug.', 'wp-graphql-woocommerce' ),
81+
],
82+
'stockStatus' => [
83+
'type' => [ 'list_of' => 'StockStatusEnum' ],
84+
'description' => __( 'Limit result set to products in stock or out of stock.', 'wp-graphql-woocommerce' ),
85+
],
86+
'onSale' => [
87+
'type' => 'Boolean',
88+
'description' => __( 'Limit result set to products on sale.', 'wp-graphql-woocommerce' ),
89+
],
90+
'minPrice' => [
91+
'type' => 'Float',
92+
'description' => __( 'Limit result set to products based on a minimum price.', 'wp-graphql-woocommerce' ),
93+
],
94+
'maxPrice' => [
95+
'type' => 'Float',
96+
'description' => __( 'Limit result set to products based on a maximum price.', 'wp-graphql-woocommerce' ),
97+
],
98+
'visibility' => [
99+
'type' => 'CatalogVisibilityEnum',
100+
'description' => __( 'Limit result set to products with a specific visibility level.', 'wp-graphql-woocommerce' ),
101+
],
102+
'rating' => [
103+
'type' => [ 'list_of' => 'Integer' ],
104+
'description' => __( 'Limit result set to products with a specific average rating. Must be between 1 and 5', 'wp-graphql-woocommerce' ),
105+
],
106+
],
107+
]
108+
);
109+
}
110+
}
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
<?php
2+
/**
3+
* WPInputObjectType - ProductAttributeFilterInput
4+
*
5+
* @package WPGraphQL\WooCommerce\Type\WPInputObject
6+
* @since TBD
7+
*/
8+
9+
namespace WPGraphQL\WooCommerce\Type\WPInputObject;
10+
11+
/**
12+
* Class Product_Attribute_Filter_Input
13+
*/
14+
class Product_Attribute_Filter_Input {
15+
/**
16+
* Registers type
17+
*
18+
* @return void
19+
*/
20+
public static function register() {
21+
register_graphql_input_type(
22+
'ProductAttributeFilterInput',
23+
[
24+
'description' => __( 'Product filter', 'wp-graphql-woocommerce' ),
25+
'fields' => [
26+
'taxonomy' => [
27+
'type' => [ 'non_null' => 'ProductAttributeEnum' ],
28+
'description' => __( 'Which field to select taxonomy term by.', 'wp-graphql-woocommerce' ),
29+
],
30+
'terms' => [
31+
'type' => [ 'list_of' => 'String' ],
32+
'description' => __( 'A list of term slugs', 'wp-graphql-woocommerce' ),
33+
],
34+
'ids' => [
35+
'type' => [ 'list_of' => 'Int' ],
36+
'description' => __( 'A list of term ids', 'wp-graphql-woocommerce' ),
37+
],
38+
'operator' => [
39+
'type' => 'AttributeOperatorEnum',
40+
'description' => __( 'Filter operation type', 'wp-graphql-woocommerce' ),
41+
],
42+
],
43+
]
44+
);
45+
}
46+
}

0 commit comments

Comments
 (0)