Skip to content

Commit 134dc5e

Browse files
authored
feat: "found" field added to the Products Connection types (#804)
1 parent c526a5b commit 134dc5e

File tree

7 files changed

+84
-28
lines changed

7 files changed

+84
-28
lines changed

includes/connection/class-products.php

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -281,8 +281,11 @@ public static function get_connection_config( $args = [] ): array {
281281
public static function get_connection_fields(): array {
282282
return [
283283
'found' => [
284-
'type' => 'Number',
284+
'type' => 'Integer',
285285
'description' => __( 'Total products founds', 'wp-graphql-woocommerce' ),
286+
'resolve' => static function ( $source ) {
287+
return ! empty( $source['pageInfo']['found'] ) ? $source['pageInfo']['found'] : null;
288+
},
286289
],
287290
];
288291
}

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

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -86,11 +86,6 @@ public function get_query_args() {
8686
*/
8787
$query_args['ignore_sticky_posts'] = true;
8888

89-
/**
90-
* Don't calculate the total rows, it's not needed and can be expensive
91-
*/
92-
$query_args['no_found_rows'] = true;
93-
9489
/**
9590
* Set post_type
9691
*/
@@ -117,9 +112,11 @@ public function get_query_args() {
117112
/**
118113
* If the cursor offsets not empty,
119114
* ignore sticky posts on the query
115+
* and don't count the total number of posts
120116
*/
121-
if ( ! empty( $this->get_after_offset() ) || ! empty( $this->get_after_offset() ) ) {
117+
if ( ! empty( $this->get_after_offset() ) || ! empty( $this->get_before_offset() ) ) {
122118
$query_args['ignore_sticky_posts'] = true;
119+
$query_args['no_found_rows'] = true;
123120
}
124121

125122
/**
@@ -657,4 +654,14 @@ public function add_tax_query( $value ) {
657654

658655
return $this;
659656
}
657+
658+
/**
659+
* {@inheritDoc}
660+
*/
661+
public function get_page_info() {
662+
$page_info = parent::get_page_info();
663+
$page_info['found'] = $this->query->found_posts;
664+
665+
return $page_info;
666+
}
660667
}

includes/model/class-product.php

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -396,6 +396,9 @@ protected function init() {
396396
'soldIndividually' => function () {
397397
return $this->wc_data->is_sold_individually();
398398
},
399+
'lowStockAmount' => function () {
400+
return ! empty( $this->wc_data->get_low_stock_amount() ) ? $this->wc_data->get_low_stock_amount() : null;
401+
},
399402
'weight' => function () {
400403
return ! empty( $this->wc_data->get_weight() ) ? $this->wc_data->get_weight() : null;
401404
},

includes/type/interface/class-inventoried-product.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,10 @@ public static function get_fields() {
5151
'type' => 'ManageStockEnum',
5252
'description' => __( 'If product manage stock', 'wp-graphql-woocommerce' ),
5353
],
54+
'lowStockAmount' => [
55+
'type' => 'Int',
56+
'description' => __( 'Low stock amount', 'wp-graphql-woocommerce' ),
57+
],
5458
'stockQuantity' => [
5559
'type' => 'Int',
5660
'description' => __( 'Number of items available for sale', 'wp-graphql-woocommerce' ),

includes/type/object/class-root-query.php

Lines changed: 27 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ public static function register_fields() {
2929
register_graphql_fields(
3030
'RootQuery',
3131
[
32-
'cart' => [
32+
'cart' => [
3333
'type' => 'Cart',
3434
'args' => [
3535
'recalculateTotals' => [
@@ -52,7 +52,7 @@ public static function register_fields() {
5252
return $cart;
5353
},
5454
],
55-
'cartItem' => [
55+
'cartItem' => [
5656
'type' => 'CartItem',
5757
'args' => [
5858
'key' => [
@@ -69,7 +69,7 @@ public static function register_fields() {
6969
return $item;
7070
},
7171
],
72-
'cartFee' => [
72+
'cartFee' => [
7373
'type' => 'CartFee',
7474
'args' => [
7575
'id' => [
@@ -88,7 +88,7 @@ public static function register_fields() {
8888
return $fees[ $fee_id ];
8989
},
9090
],
91-
'coupon' => [
91+
'coupon' => [
9292
'type' => 'Coupon',
9393
'description' => __( 'A coupon object', 'wp-graphql-woocommerce' ),
9494
'args' => [
@@ -146,7 +146,7 @@ public static function register_fields() {
146146
return Factory::resolve_crud_object( $coupon_id, $context );
147147
},
148148
],
149-
'customer' => [
149+
'customer' => [
150150
'type' => 'Customer',
151151
'description' => __( 'A customer object', 'wp-graphql-woocommerce' ),
152152
'args' => [
@@ -194,7 +194,7 @@ public static function register_fields() {
194194
return Factory::resolve_session_customer();
195195
},
196196
],
197-
'order' => [
197+
'order' => [
198198
'type' => 'Order',
199199
'description' => __( 'A order object', 'wp-graphql-woocommerce' ),
200200
'args' => [
@@ -272,7 +272,7 @@ public static function register_fields() {
272272
return Factory::resolve_crud_object( $order_id, $context );
273273
},
274274
],
275-
'productVariation' => [
275+
'productVariation' => [
276276
'type' => 'ProductVariation',
277277
'description' => __( 'A product variation object', 'wp-graphql-woocommerce' ),
278278
'args' => [
@@ -318,7 +318,7 @@ public static function register_fields() {
318318
return Factory::resolve_crud_object( $variation_id, $context );
319319
},
320320
],
321-
'refund' => [
321+
'refund' => [
322322
'type' => 'Refund',
323323
'description' => __( 'A refund object', 'wp-graphql-woocommerce' ),
324324
'args' => [
@@ -399,7 +399,7 @@ public static function register_fields() {
399399
return Factory::resolve_crud_object( $refund_id, $context );
400400
},
401401
],
402-
'shippingMethod' => [
402+
'shippingMethod' => [
403403
'type' => 'ShippingMethod',
404404
'description' => __( 'A shipping method object', 'wp-graphql-woocommerce' ),
405405
'args' => [
@@ -434,7 +434,7 @@ public static function register_fields() {
434434
return Factory::resolve_shipping_method( $method_id );
435435
},
436436
],
437-
'taxRate' => [
437+
'taxRate' => [
438438
'type' => 'TaxRate',
439439
'description' => __( 'A tax rate object', 'wp-graphql-woocommerce' ),
440440
'args' => [
@@ -469,7 +469,17 @@ public static function register_fields() {
469469
return Factory::resolve_tax_rate( $rate_id, $context );
470470
},
471471
],
472-
'allowedCountries' => [
472+
'countries' => [
473+
'type' => [ 'list_of' => 'CountriesEnum' ],
474+
'description' => __( 'Countries', 'wp-graphql-woocommerce' ),
475+
'resolve' => static function () {
476+
$wc_countries = new \WC_Countries();
477+
$countries = $wc_countries->get_countries();
478+
479+
return array_keys( $countries );
480+
},
481+
],
482+
'allowedCountries' => [
473483
'type' => [ 'list_of' => 'CountriesEnum' ],
474484
'description' => __( 'Countries that the store sells to', 'wp-graphql-woocommerce' ),
475485
'resolve' => static function () {
@@ -479,7 +489,7 @@ public static function register_fields() {
479489
return array_keys( $countries );
480490
},
481491
],
482-
'allowedCountryStates' => [
492+
'countryStates' => [
483493
'type' => [ 'list_of' => 'CountryState' ],
484494
'args' => [
485495
'country' => [
@@ -535,10 +545,11 @@ public static function register_fields() {
535545
'RootQuery',
536546
$field_name,
537547
[
538-
'type' => $type_name,
548+
'type' => $type_name,
539549
/* translators: Product type slug */
540-
'description' => sprintf( __( 'A %s product object', 'wp-graphql-woocommerce' ), $type_key ),
541-
'args' => [
550+
'description' => sprintf( __( 'A %s product object', 'wp-graphql-woocommerce' ), $type_key ),
551+
'deprecationReason' => 'Use "product" instead.',
552+
'args' => [
542553
'id' => [
543554
'type' => 'ID',
544555
'description' => sprintf(
@@ -552,7 +563,7 @@ public static function register_fields() {
552563
'description' => __( 'Type of ID being used identify product', 'wp-graphql-woocommerce' ),
553564
],
554565
],
555-
'resolve' => static function ( $source, array $args, AppContext $context, ResolveInfo $info ) use ( $type_key, $unsupported_type_enabled ) {
566+
'resolve' => static function ( $source, array $args, AppContext $context, ResolveInfo $info ) use ( $type_key, $unsupported_type_enabled ) {
556567
$id = isset( $args['id'] ) ? $args['id'] : null;
557568
$id_type = isset( $args['idType'] ) ? $args['idType'] : 'global_id';
558569

tests/wpunit/ConnectionPaginationTest.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,7 @@ function( $key_a, $key_b ) {
149149
$query = '
150150
query ($first: Int, $last: Int, $after: String, $before: String) {
151151
products(first: $first, last: $last, after: $after, before: $before) {
152+
found
152153
nodes {
153154
databaseId
154155
}
@@ -170,6 +171,7 @@ function( $key_a, $key_b ) {
170171
$variables = [ 'first' => 2 ];
171172
$response = $this->graphql( compact( 'query', 'variables' ) );
172173
$expected = [
174+
$this->expectedField( 'products.found', 5 ),
173175
$this->expectedField( 'products.pageInfo.hasPreviousPage', false ),
174176
$this->expectedField( 'products.pageInfo.hasNextPage', true ),
175177
$this->expectedField( 'products.pageInfo.startCursor', $this->toCursor( $products[0] ) ),
@@ -191,6 +193,7 @@ function( $key_a, $key_b ) {
191193
];
192194
$response = $this->graphql( compact( 'query', 'variables' ) );
193195
$expected = [
196+
$this->expectedField( 'products.found', self::IS_NULL ),
194197
$this->expectedField( 'products.pageInfo.hasPreviousPage', true ),
195198
$this->expectedField( 'products.pageInfo.hasNextPage', false ),
196199
$this->expectedField( 'products.pageInfo.startCursor', $this->toCursor( $products[2] ) ),
@@ -210,6 +213,7 @@ function( $key_a, $key_b ) {
210213
$variables = [ 'last' => 2 ];
211214
$response = $this->graphql( compact( 'query', 'variables' ) );
212215
$expected = [
216+
$this->expectedField( 'products.found', 5 ),
213217
$this->expectedField( 'products.pageInfo.hasPreviousPage', true ),
214218
$this->expectedField( 'products.pageInfo.hasNextPage', false ),
215219
$this->expectedField( 'products.pageInfo.startCursor', $this->toCursor( $products[3] ) ),
@@ -231,6 +235,7 @@ function( $key_a, $key_b ) {
231235
];
232236
$response = $this->graphql( compact( 'query', 'variables' ) );
233237
$expected = [
238+
$this->expectedField( 'products.found', self::IS_NULL ),
234239
$this->expectedField( 'products.pageInfo.hasPreviousPage', true ),
235240
$this->expectedField( 'products.pageInfo.hasNextPage', true ),
236241
$this->expectedField( 'products.pageInfo.startCursor', $this->toCursor( $products[1] ) ),

tests/wpunit/RootQueriesTest.php

Lines changed: 28 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,29 @@
11
<?php
22

33
class RootQueriesTest extends \Tests\WPGraphQL\WooCommerce\TestCase\WooGraphQLTestCase {
4+
public function testBillingCountriesQuery() {
5+
// Create shipping zones and shipping rates.
6+
update_option( 'woocommerce_allowed_countries', 'specific' );
7+
update_option( 'woocommerce_specific_allowed_countries', [ 'US', 'CA' ] );
8+
9+
// Create query
10+
$query = '
11+
query {
12+
countries
13+
}
14+
';
15+
16+
$response = $this->graphql( compact( 'query' ) );
17+
$expected = [
18+
$this->expectedField( 'countries.#', 'US' ),
19+
$this->expectedField( 'countries.#', 'CA' ),
20+
$this->expectedField( 'countries.#', 'GB' ),
21+
$this->expectedField( 'countries.#', 'JP' ),
22+
];
23+
24+
$this->assertQuerySuccessful( $response, $expected );
25+
}
26+
427
public function testShippingCountriesQuery() {
528
// Create shipping zones and shipping rates.
629
update_option( 'woocommerce_allowed_countries', 'specific' );
@@ -31,7 +54,7 @@ public function testShippingCountryStatesQuery() {
3154
// Create query
3255
$query = '
3356
query ($country: CountriesEnum!) {
34-
allowedCountryStates(country: $country) {
57+
countryStates(country: $country) {
3558
name
3659
code
3760
}
@@ -42,14 +65,14 @@ public function testShippingCountryStatesQuery() {
4265
$response = $this->graphql( compact( 'query', 'variables' ) );
4366
$expected = [
4467
$this->expectedObject(
45-
'allowedCountryStates.#',
68+
'countryStates.#',
4669
[
4770
$this->expectedField( 'name', 'Alaska' ),
4871
$this->expectedField( 'code', 'AL' ),
4972
]
5073
),
5174
$this->expectedObject(
52-
'allowedCountryStates.#',
75+
'countryStates.#',
5376
[
5477
$this->not()->expectedField( 'name', 'Ontario' ),
5578
$this->not()->expectedField( 'code', 'ON' ),
@@ -63,14 +86,14 @@ public function testShippingCountryStatesQuery() {
6386
$response = $this->graphql( compact( 'query', 'variables' ) );
6487
$expected = [
6588
$this->expectedObject(
66-
'allowedCountryStates.#',
89+
'countryStates.#',
6790
[
6891
$this->expectedField( 'name', 'Ontario' ),
6992
$this->expectedField( 'code', 'ON' ),
7093
]
7194
),
7295
$this->expectedObject(
73-
'allowedCountryStates.#',
96+
'countryStates.#',
7497
[
7598
$this->not()->expectedField( 'name', 'Alaska' ),
7699
$this->not()->expectedField( 'code', 'AL' ),

0 commit comments

Comments
 (0)