Skip to content

Commit 481c12c

Browse files
authored
feat: Several product interfaces added. (#801)
1 parent 9ca2f48 commit 481c12c

12 files changed

+665
-327
lines changed

includes/class-core-schema-filters.php

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -384,4 +384,35 @@ public static function inject_type_resolver( $type, $value ) {
384384

385385
return $type;
386386
}
387+
388+
/**
389+
* Resolves GraphQL type for provided product model.
390+
*
391+
* @param \WPGraphQL\WooCommerce\Model\Product $value Product model.
392+
*
393+
* @throws \GraphQL\Error\UserError Invalid product type requested.
394+
*
395+
* @return mixed
396+
*/
397+
public static function resolve_product_type( $value ) {
398+
$type_registry = \WPGraphQL::get_type_registry();
399+
$possible_types = WooGraphQL::get_enabled_product_types();
400+
$product_type = $value->get_type();
401+
if ( isset( $possible_types[ $product_type ] ) ) {
402+
return $type_registry->get_type( $possible_types[ $product_type ] );
403+
} elseif ( str_ends_with( $product_type, 'variation' ) ) {
404+
return $type_registry->get_type( 'ProductVariation' );
405+
} elseif ( 'on' === woographql_setting( 'enable_unsupported_product_type', 'off' ) ) {
406+
$unsupported_type = WooGraphQL::get_supported_product_type();
407+
return $type_registry->get_type( $unsupported_type );
408+
}
409+
410+
throw new UserError(
411+
sprintf(
412+
/* translators: %s: Product type */
413+
__( 'The "%s" product type is not supported by the core WPGraphQL WooCommerce (WooGraphQL) schema.', 'wp-graphql-woocommerce' ),
414+
$value->type
415+
)
416+
);
417+
}
387418
}

includes/class-type-registry.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,11 @@ public function init() {
7171
Type\WPInterface\Payment_Token::register_interface();
7272
Type\WPInterface\Product_Union::register_interface();
7373
Type\WPInterface\Cart_Item::register_interface();
74+
Type\WPInterface\Downloadable_Products::register_interface();
75+
Type\WPInterface\Inventoried_Products::register_interface();
76+
Type\WPInterface\Products_With_Dimensions::register_interface();
77+
Type\WPInterface\Products_With_Pricing::register_interface();
78+
Type\WPInterface\Products_With_Variations::register_interface();
7479

7580
/**
7681
* Objects.

includes/class-wp-graphql-woocommerce.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -245,6 +245,11 @@ private function includes() {
245245
require $include_directory_path . 'type/interface/class-payment-token.php';
246246
require $include_directory_path . 'type/interface/class-product-union.php';
247247
require $include_directory_path . 'type/interface/class-cart-item.php';
248+
require $include_directory_path . 'type/interface/class-downloadable-products.php';
249+
require $include_directory_path . 'type/interface/class-inventoried-products.php';
250+
require $include_directory_path . 'type/interface/class-products-with-dimensions.php';
251+
require $include_directory_path . 'type/interface/class-products-with-pricing.php';
252+
require $include_directory_path . 'type/interface/class-products-with-variations.php';
248253

249254
// Include object type class files.
250255
require $include_directory_path . 'type/object/class-cart-error-types.php';

includes/connection/class-products.php

Lines changed: 0 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -146,26 +146,6 @@ static function () {
146146
)
147147
);
148148

149-
// From VariableProduct to ProductVariation.
150-
register_graphql_connection(
151-
self::get_connection_config(
152-
[
153-
'fromType' => 'VariableProduct',
154-
'toType' => 'ProductVariation',
155-
'fromFieldName' => 'variations',
156-
'resolve' => static function ( $source, array $args, AppContext $context, ResolveInfo $info ) {
157-
$resolver = new Product_Connection_Resolver( $source, $args, $context, $info );
158-
159-
$resolver->set_query_arg( 'post_parent', $source->ID );
160-
$resolver->set_query_arg( 'post_type', 'product_variation' );
161-
$resolver->set_query_arg( 'post__in', $source->variation_ids );
162-
163-
return $resolver->get_connection();
164-
},
165-
]
166-
)
167-
);
168-
169149
register_graphql_connection(
170150
[
171151
'fromType' => 'ProductVariation',
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
<?php
2+
/**
3+
* Defines the fields for downloadable products.
4+
*
5+
* @package WPGraphQL\WooCommerce\Type\WPInterface
6+
* @since TBD
7+
*/
8+
9+
namespace WPGraphQL\WooCommerce\Type\WPInterface;
10+
11+
use WPGraphQL\WooCommerce\Core_Schema_Filters as Core;
12+
13+
/**
14+
* Class Downloadable_Products
15+
*/
16+
class Downloadable_Products {
17+
/**
18+
* Registers the "DownloadableProducts" type
19+
*
20+
* @return void
21+
* @throws \Exception
22+
*/
23+
public static function register_interface(): void {
24+
register_graphql_interface_type(
25+
'DownloadableProducts',
26+
[
27+
'description' => __( 'Downloadable products.', 'wp-graphql-woocommerce' ),
28+
'interfaces' => [ 'Node' ],
29+
'fields' => self::get_fields(),
30+
'resolveType' => [ Core::class, 'resolve_product_type' ],
31+
]
32+
);
33+
}
34+
35+
/**
36+
* Defines "DownloadableProducts" fields.
37+
*
38+
* @return array
39+
*/
40+
public static function get_fields() {
41+
return [
42+
'id' => [
43+
'type' => [ 'non_null' => 'ID' ],
44+
'description' => __( 'Product or variation global ID', 'wp-graphql-woocommerce' ),
45+
],
46+
'databaseId' => [
47+
'type' => [ 'non_null' => 'Int' ],
48+
'description' => __( 'Product or variation ID', 'wp-graphql-woocommerce' ),
49+
],
50+
'virtual' => [
51+
'type' => 'Boolean',
52+
'description' => __( 'Is product virtual?', 'wp-graphql-woocommerce' ),
53+
],
54+
'downloadExpiry' => [
55+
'type' => 'Int',
56+
'description' => __( 'Download expiry', 'wp-graphql-woocommerce' ),
57+
],
58+
'downloadable' => [
59+
'type' => 'Boolean',
60+
'description' => __( 'Is downloadable?', 'wp-graphql-woocommerce' ),
61+
],
62+
'downloadLimit' => [
63+
'type' => 'Int',
64+
'description' => __( 'Download limit', 'wp-graphql-woocommerce' ),
65+
],
66+
'downloads' => [
67+
'type' => [ 'list_of' => 'ProductDownload' ],
68+
'description' => __( 'Product downloads', 'wp-graphql-woocommerce' ),
69+
],
70+
];
71+
}
72+
}
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
<?php
2+
/**
3+
* Defines the fields for manage product inventories.
4+
*
5+
* @package WPGraphQL\WooCommerce\Type\WPInterface
6+
* @since TBD
7+
*/
8+
9+
namespace WPGraphQL\WooCommerce\Type\WPInterface;
10+
11+
use WPGraphQL\WooCommerce\Core_Schema_Filters as Core;
12+
13+
/**
14+
* Class Inventoried_Products
15+
*/
16+
class Inventoried_Products {
17+
/**
18+
* Registers the "InventoriedProducts" type
19+
*
20+
* @return void
21+
* @throws \Exception
22+
*/
23+
public static function register_interface(): void {
24+
register_graphql_interface_type(
25+
'InventoriedProducts',
26+
[
27+
'description' => __( 'Products with stock information.', 'wp-graphql-woocommerce' ),
28+
'interfaces' => [ 'Node' ],
29+
'fields' => self::get_fields(),
30+
'resolveType' => [ Core::class, 'resolve_product_type' ],
31+
]
32+
);
33+
}
34+
35+
/**
36+
* Defines "InventoriedProducts" fields.
37+
*
38+
* @return array
39+
*/
40+
public static function get_fields() {
41+
return [
42+
'id' => [
43+
'type' => [ 'non_null' => 'ID' ],
44+
'description' => __( 'Product or variation global ID', 'wp-graphql-woocommerce' ),
45+
],
46+
'databaseId' => [
47+
'type' => [ 'non_null' => 'Int' ],
48+
'description' => __( 'Product or variation ID', 'wp-graphql-woocommerce' ),
49+
],
50+
'manageStock' => [
51+
'type' => 'Boolean',
52+
'description' => __( 'If product manage stock', 'wp-graphql-woocommerce' ),
53+
],
54+
'stockQuantity' => [
55+
'type' => 'Int',
56+
'description' => __( 'Number of items available for sale', 'wp-graphql-woocommerce' ),
57+
],
58+
'backorders' => [
59+
'type' => 'BackordersEnum',
60+
'description' => __( 'Product backorders status', 'wp-graphql-woocommerce' ),
61+
],
62+
'soldIndividually' => [
63+
'type' => 'Boolean',
64+
'description' => __( 'If should be sold individually', 'wp-graphql-woocommerce' ),
65+
],
66+
'backordersAllowed' => [
67+
'type' => 'Boolean',
68+
'description' => __( 'Can product be backordered?', 'wp-graphql-woocommerce' ),
69+
],
70+
'stockStatus' => [
71+
'type' => 'StockStatusEnum',
72+
'description' => __( 'Product stock status', 'wp-graphql-woocommerce' ),
73+
],
74+
];
75+
}
76+
}

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

Lines changed: 2 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,7 @@
88

99
namespace WPGraphQL\WooCommerce\Type\WPInterface;
1010

11-
use GraphQL\Error\UserError;
12-
use WPGraphQL;
13-
use WPGraphQL\WooCommerce\WP_GraphQL_WooCommerce as WooGraphQL;
11+
use WPGraphQL\WooCommerce\Core_Schema_Filters as Core;
1412

1513
/**
1614
* Class Product_Union
@@ -29,27 +27,7 @@ public static function register_interface(): void {
2927
'description' => __( 'Union between the product and product variation types', 'wp-graphql-woocommerce' ),
3028
'interfaces' => [ 'Node' ],
3129
'fields' => self::get_fields(),
32-
'resolveType' => static function ( $value ) {
33-
$type_registry = WPGraphQL::get_type_registry();
34-
$possible_types = WooGraphQL::get_enabled_product_types();
35-
$product_type = $value->get_type();
36-
if ( isset( $possible_types[ $product_type ] ) ) {
37-
return $type_registry->get_type( $possible_types[ $product_type ] );
38-
} elseif ( str_ends_with( $product_type, 'variation' ) ) {
39-
return $type_registry->get_type( 'ProductVariation' );
40-
} elseif ( 'on' === woographql_setting( 'enable_unsupported_product_type', 'off' ) ) {
41-
$unsupported_type = WooGraphQL::get_supported_product_type();
42-
return $type_registry->get_type( $unsupported_type );
43-
}
44-
45-
throw new UserError(
46-
sprintf(
47-
/* translators: %s: Product type */
48-
__( 'The "%s" product type is not supported by the core WPGraphQL WooCommerce (WooGraphQL) schema.', 'wp-graphql-woocommerce' ),
49-
$value->type
50-
)
51-
);
52-
},
30+
'resolveType' => [ Core::class, 'resolve_product_type' ],
5331
]
5432
);
5533
}
Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
<?php
2+
/**
3+
* Defines the fields for physical products.
4+
*
5+
* @package WPGraphQL\WooCommerce\Type\WPInterface
6+
* @since TBD
7+
*/
8+
9+
namespace WPGraphQL\WooCommerce\Type\WPInterface;
10+
11+
use WPGraphQL\WooCommerce\Core_Schema_Filters as Core;
12+
13+
/**
14+
* Class Products_With_Dimensions
15+
*/
16+
class Products_With_Dimensions {
17+
/**
18+
* Registers the "ProductsWithDimensions" type
19+
*
20+
* @return void
21+
* @throws \Exception
22+
*/
23+
public static function register_interface(): void {
24+
register_graphql_interface_type(
25+
'ProductsWithDimensions',
26+
[
27+
'description' => __( 'Physical products.', 'wp-graphql-woocommerce' ),
28+
'interfaces' => [ 'Node' ],
29+
'fields' => self::get_fields(),
30+
'resolveType' => [ Core::class, 'resolve_product_type' ],
31+
]
32+
);
33+
}
34+
35+
/**
36+
* Defines "ProductsWithDimensions" fields.
37+
*
38+
* @return array
39+
*/
40+
public static function get_fields() {
41+
return [
42+
'id' => [
43+
'type' => [ 'non_null' => 'ID' ],
44+
'description' => __( 'Product or variation global ID', 'wp-graphql-woocommerce' ),
45+
],
46+
'databaseId' => [
47+
'type' => [ 'non_null' => 'Int' ],
48+
'description' => __( 'Product or variation ID', 'wp-graphql-woocommerce' ),
49+
],
50+
'weight' => [
51+
'type' => 'String',
52+
'description' => __( 'Product\'s weight', 'wp-graphql-woocommerce' ),
53+
],
54+
'length' => [
55+
'type' => 'String',
56+
'description' => __( 'Product\'s length', 'wp-graphql-woocommerce' ),
57+
],
58+
'width' => [
59+
'type' => 'String',
60+
'description' => __( 'Product\'s width', 'wp-graphql-woocommerce' ),
61+
],
62+
'height' => [
63+
'type' => 'String',
64+
'description' => __( 'Product\'s height', 'wp-graphql-woocommerce' ),
65+
],
66+
'shippingClassId' => [
67+
'type' => 'Int',
68+
'description' => __( 'shipping class ID', 'wp-graphql-woocommerce' ),
69+
],
70+
'shippingRequired' => [
71+
'type' => 'Boolean',
72+
'description' => __( 'Does product need to be shipped?', 'wp-graphql-woocommerce' ),
73+
],
74+
'shippingTaxable' => [
75+
'type' => 'Boolean',
76+
'description' => __( 'Is product shipping taxable?', 'wp-graphql-woocommerce' ),
77+
],
78+
];
79+
}
80+
}

0 commit comments

Comments
 (0)