Skip to content

Commit

Permalink
feat: Several product interfaces added. (#801)
Browse files Browse the repository at this point in the history
  • Loading branch information
kidunot89 authored Sep 15, 2023
1 parent 9ca2f48 commit 481c12c
Show file tree
Hide file tree
Showing 12 changed files with 665 additions and 327 deletions.
31 changes: 31 additions & 0 deletions includes/class-core-schema-filters.php
Original file line number Diff line number Diff line change
Expand Up @@ -384,4 +384,35 @@ public static function inject_type_resolver( $type, $value ) {

return $type;
}

/**
* Resolves GraphQL type for provided product model.
*
* @param \WPGraphQL\WooCommerce\Model\Product $value Product model.
*
* @throws \GraphQL\Error\UserError Invalid product type requested.
*
* @return mixed
*/
public static function resolve_product_type( $value ) {
$type_registry = \WPGraphQL::get_type_registry();
$possible_types = WooGraphQL::get_enabled_product_types();
$product_type = $value->get_type();
if ( isset( $possible_types[ $product_type ] ) ) {
return $type_registry->get_type( $possible_types[ $product_type ] );
} elseif ( str_ends_with( $product_type, 'variation' ) ) {
return $type_registry->get_type( 'ProductVariation' );
} elseif ( 'on' === woographql_setting( 'enable_unsupported_product_type', 'off' ) ) {
$unsupported_type = WooGraphQL::get_supported_product_type();
return $type_registry->get_type( $unsupported_type );
}

throw new UserError(
sprintf(
/* translators: %s: Product type */
__( 'The "%s" product type is not supported by the core WPGraphQL WooCommerce (WooGraphQL) schema.', 'wp-graphql-woocommerce' ),
$value->type
)
);
}
}
5 changes: 5 additions & 0 deletions includes/class-type-registry.php
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,11 @@ public function init() {
Type\WPInterface\Payment_Token::register_interface();
Type\WPInterface\Product_Union::register_interface();
Type\WPInterface\Cart_Item::register_interface();
Type\WPInterface\Downloadable_Products::register_interface();
Type\WPInterface\Inventoried_Products::register_interface();
Type\WPInterface\Products_With_Dimensions::register_interface();
Type\WPInterface\Products_With_Pricing::register_interface();
Type\WPInterface\Products_With_Variations::register_interface();

/**
* Objects.
Expand Down
5 changes: 5 additions & 0 deletions includes/class-wp-graphql-woocommerce.php
Original file line number Diff line number Diff line change
Expand Up @@ -245,6 +245,11 @@ private function includes() {
require $include_directory_path . 'type/interface/class-payment-token.php';
require $include_directory_path . 'type/interface/class-product-union.php';
require $include_directory_path . 'type/interface/class-cart-item.php';
require $include_directory_path . 'type/interface/class-downloadable-products.php';
require $include_directory_path . 'type/interface/class-inventoried-products.php';
require $include_directory_path . 'type/interface/class-products-with-dimensions.php';
require $include_directory_path . 'type/interface/class-products-with-pricing.php';
require $include_directory_path . 'type/interface/class-products-with-variations.php';

// Include object type class files.
require $include_directory_path . 'type/object/class-cart-error-types.php';
Expand Down
20 changes: 0 additions & 20 deletions includes/connection/class-products.php
Original file line number Diff line number Diff line change
Expand Up @@ -146,26 +146,6 @@ static function () {
)
);

// From VariableProduct to ProductVariation.
register_graphql_connection(
self::get_connection_config(
[
'fromType' => 'VariableProduct',
'toType' => 'ProductVariation',
'fromFieldName' => 'variations',
'resolve' => static function ( $source, array $args, AppContext $context, ResolveInfo $info ) {
$resolver = new Product_Connection_Resolver( $source, $args, $context, $info );

$resolver->set_query_arg( 'post_parent', $source->ID );
$resolver->set_query_arg( 'post_type', 'product_variation' );
$resolver->set_query_arg( 'post__in', $source->variation_ids );

return $resolver->get_connection();
},
]
)
);

register_graphql_connection(
[
'fromType' => 'ProductVariation',
Expand Down
72 changes: 72 additions & 0 deletions includes/type/interface/class-downloadable-products.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
<?php
/**
* Defines the fields for downloadable products.
*
* @package WPGraphQL\WooCommerce\Type\WPInterface
* @since TBD
*/

namespace WPGraphQL\WooCommerce\Type\WPInterface;

use WPGraphQL\WooCommerce\Core_Schema_Filters as Core;

/**
* Class Downloadable_Products
*/
class Downloadable_Products {
/**
* Registers the "DownloadableProducts" type
*
* @return void
* @throws \Exception
*/
public static function register_interface(): void {
register_graphql_interface_type(
'DownloadableProducts',
[
'description' => __( 'Downloadable products.', 'wp-graphql-woocommerce' ),
'interfaces' => [ 'Node' ],
'fields' => self::get_fields(),
'resolveType' => [ Core::class, 'resolve_product_type' ],
]
);
}

/**
* Defines "DownloadableProducts" fields.
*
* @return array
*/
public static function get_fields() {
return [
'id' => [
'type' => [ 'non_null' => 'ID' ],
'description' => __( 'Product or variation global ID', 'wp-graphql-woocommerce' ),
],
'databaseId' => [
'type' => [ 'non_null' => 'Int' ],
'description' => __( 'Product or variation ID', 'wp-graphql-woocommerce' ),
],
'virtual' => [
'type' => 'Boolean',
'description' => __( 'Is product virtual?', 'wp-graphql-woocommerce' ),
],
'downloadExpiry' => [
'type' => 'Int',
'description' => __( 'Download expiry', 'wp-graphql-woocommerce' ),
],
'downloadable' => [
'type' => 'Boolean',
'description' => __( 'Is downloadable?', 'wp-graphql-woocommerce' ),
],
'downloadLimit' => [
'type' => 'Int',
'description' => __( 'Download limit', 'wp-graphql-woocommerce' ),
],
'downloads' => [
'type' => [ 'list_of' => 'ProductDownload' ],
'description' => __( 'Product downloads', 'wp-graphql-woocommerce' ),
],
];
}
}
76 changes: 76 additions & 0 deletions includes/type/interface/class-inventoried-products.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
<?php
/**
* Defines the fields for manage product inventories.
*
* @package WPGraphQL\WooCommerce\Type\WPInterface
* @since TBD
*/

namespace WPGraphQL\WooCommerce\Type\WPInterface;

use WPGraphQL\WooCommerce\Core_Schema_Filters as Core;

/**
* Class Inventoried_Products
*/
class Inventoried_Products {
/**
* Registers the "InventoriedProducts" type
*
* @return void
* @throws \Exception
*/
public static function register_interface(): void {
register_graphql_interface_type(
'InventoriedProducts',
[
'description' => __( 'Products with stock information.', 'wp-graphql-woocommerce' ),
'interfaces' => [ 'Node' ],
'fields' => self::get_fields(),
'resolveType' => [ Core::class, 'resolve_product_type' ],
]
);
}

/**
* Defines "InventoriedProducts" fields.
*
* @return array
*/
public static function get_fields() {
return [
'id' => [
'type' => [ 'non_null' => 'ID' ],
'description' => __( 'Product or variation global ID', 'wp-graphql-woocommerce' ),
],
'databaseId' => [
'type' => [ 'non_null' => 'Int' ],
'description' => __( 'Product or variation ID', 'wp-graphql-woocommerce' ),
],
'manageStock' => [
'type' => 'Boolean',
'description' => __( 'If product manage stock', 'wp-graphql-woocommerce' ),
],
'stockQuantity' => [
'type' => 'Int',
'description' => __( 'Number of items available for sale', 'wp-graphql-woocommerce' ),
],
'backorders' => [
'type' => 'BackordersEnum',
'description' => __( 'Product backorders status', 'wp-graphql-woocommerce' ),
],
'soldIndividually' => [
'type' => 'Boolean',
'description' => __( 'If should be sold individually', 'wp-graphql-woocommerce' ),
],
'backordersAllowed' => [
'type' => 'Boolean',
'description' => __( 'Can product be backordered?', 'wp-graphql-woocommerce' ),
],
'stockStatus' => [
'type' => 'StockStatusEnum',
'description' => __( 'Product stock status', 'wp-graphql-woocommerce' ),
],
];
}
}
26 changes: 2 additions & 24 deletions includes/type/interface/class-product-union.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,7 @@

namespace WPGraphQL\WooCommerce\Type\WPInterface;

use GraphQL\Error\UserError;
use WPGraphQL;
use WPGraphQL\WooCommerce\WP_GraphQL_WooCommerce as WooGraphQL;
use WPGraphQL\WooCommerce\Core_Schema_Filters as Core;

/**
* Class Product_Union
Expand All @@ -29,27 +27,7 @@ public static function register_interface(): void {
'description' => __( 'Union between the product and product variation types', 'wp-graphql-woocommerce' ),
'interfaces' => [ 'Node' ],
'fields' => self::get_fields(),
'resolveType' => static function ( $value ) {
$type_registry = WPGraphQL::get_type_registry();
$possible_types = WooGraphQL::get_enabled_product_types();
$product_type = $value->get_type();
if ( isset( $possible_types[ $product_type ] ) ) {
return $type_registry->get_type( $possible_types[ $product_type ] );
} elseif ( str_ends_with( $product_type, 'variation' ) ) {
return $type_registry->get_type( 'ProductVariation' );
} elseif ( 'on' === woographql_setting( 'enable_unsupported_product_type', 'off' ) ) {
$unsupported_type = WooGraphQL::get_supported_product_type();
return $type_registry->get_type( $unsupported_type );
}

throw new UserError(
sprintf(
/* translators: %s: Product type */
__( 'The "%s" product type is not supported by the core WPGraphQL WooCommerce (WooGraphQL) schema.', 'wp-graphql-woocommerce' ),
$value->type
)
);
},
'resolveType' => [ Core::class, 'resolve_product_type' ],
]
);
}
Expand Down
80 changes: 80 additions & 0 deletions includes/type/interface/class-products-with-dimensions.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
<?php
/**
* Defines the fields for physical products.
*
* @package WPGraphQL\WooCommerce\Type\WPInterface
* @since TBD
*/

namespace WPGraphQL\WooCommerce\Type\WPInterface;

use WPGraphQL\WooCommerce\Core_Schema_Filters as Core;

/**
* Class Products_With_Dimensions
*/
class Products_With_Dimensions {
/**
* Registers the "ProductsWithDimensions" type
*
* @return void
* @throws \Exception
*/
public static function register_interface(): void {
register_graphql_interface_type(
'ProductsWithDimensions',
[
'description' => __( 'Physical products.', 'wp-graphql-woocommerce' ),
'interfaces' => [ 'Node' ],
'fields' => self::get_fields(),
'resolveType' => [ Core::class, 'resolve_product_type' ],
]
);
}

/**
* Defines "ProductsWithDimensions" fields.
*
* @return array
*/
public static function get_fields() {
return [
'id' => [
'type' => [ 'non_null' => 'ID' ],
'description' => __( 'Product or variation global ID', 'wp-graphql-woocommerce' ),
],
'databaseId' => [
'type' => [ 'non_null' => 'Int' ],
'description' => __( 'Product or variation ID', 'wp-graphql-woocommerce' ),
],
'weight' => [
'type' => 'String',
'description' => __( 'Product\'s weight', 'wp-graphql-woocommerce' ),
],
'length' => [
'type' => 'String',
'description' => __( 'Product\'s length', 'wp-graphql-woocommerce' ),
],
'width' => [
'type' => 'String',
'description' => __( 'Product\'s width', 'wp-graphql-woocommerce' ),
],
'height' => [
'type' => 'String',
'description' => __( 'Product\'s height', 'wp-graphql-woocommerce' ),
],
'shippingClassId' => [
'type' => 'Int',
'description' => __( 'shipping class ID', 'wp-graphql-woocommerce' ),
],
'shippingRequired' => [
'type' => 'Boolean',
'description' => __( 'Does product need to be shipped?', 'wp-graphql-woocommerce' ),
],
'shippingTaxable' => [
'type' => 'Boolean',
'description' => __( 'Is product shipping taxable?', 'wp-graphql-woocommerce' ),
],
];
}
}
Loading

0 comments on commit 481c12c

Please sign in to comment.