Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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