diff --git a/access-functions.php b/access-functions.php index ffbd6c7e..b409d0d6 100644 --- a/access-functions.php +++ b/access-functions.php @@ -6,25 +6,6 @@ * @since 0.0.1 */ -/** - * Adds an ObjectType to the TypeRegistry and node resolvers to Relay node definitions. - * - * @param string $type_name The name of the Type to register. - * @param array $config The Type config. - */ -function wc_register_graphql_object_type( $type_name, $config ) { - $config['kind'] = 'object'; - if ( ! empty( $config['resolve_node'] ) ) { - add_filter( 'graphql_resolve_node', $config['resolve_node'], 10, 4 ); - unset( $config['resolve_node'] ); - } - if ( ! empty( $config['resolve_node_type'] ) ) { - add_filter( 'graphql_resolve_node_type', $config['resolve_node_type'], 10, 2 ); - unset( $config['resolve_node_type'] ); - } - register_graphql_type( $type_name, $config ); -} - /** * Checks if source string starts with the target string * diff --git a/includes/class-core-schema-filters.php b/includes/class-core-schema-filters.php index 38f544c0..f1115364 100644 --- a/includes/class-core-schema-filters.php +++ b/includes/class-core-schema-filters.php @@ -63,6 +63,20 @@ class Core_Schema_Filters { 10, 5 ); + + // Add node resolvers. + add_filter( + 'graphql_resolve_node', + array( '\WPGraphQL\Extensions\WooCommerce\Data\Factory', 'resolve_node' ), + 10, + 4 + ); + add_filter( + 'graphql_resolve_node_type', + array( '\WPGraphQL\Extensions\WooCommerce\Data\Factory', 'resolve_node_type' ), + 10, + 2 + ); } /** @@ -155,39 +169,6 @@ class Core_Schema_Filters { ); } - /** - * Filters "WPUnionType" resolver to include "Products". - * - * @param mixed|null $type Object type definition. - * @param mixed|null $object Source resolver. - * @param \WPGraphQL\Type\WPUnionType $union WPUnionType instance. - * - * @return mixed|null - */ - public static function graphql_union_resolve_type( $type, $object, $union ) { - if ( $object instanceof \WPGraphQL\Extensions\WooCommerce\Model\Coupon ) { - return \WPGraphQL\TypeRegistry::get_type( 'Coupon' ); - } - - if ( $object instanceof \WPGraphQL\Extensions\WooCommerce\Model\Order ) { - return \WPGraphQL\TypeRegistry::get_type( 'Order' ); - } - - if ( $object instanceof \WPGraphQL\Extensions\WooCommerce\Model\Product ) { - return \WPGraphQL\TypeRegistry::get_type( 'Product' ); - } - - if ( $object instanceof \WPGraphQL\Extensions\WooCommerce\Model\ProductVariation ) { - return \WPGraphQL\TypeRegistry::get_type( 'ProductVariation' ); - } - - if ( $object instanceof \WPGraphQL\Extensions\WooCommerce\Model\Refund ) { - return \WPGraphQL\TypeRegistry::get_type( 'Refund' ); - } - - return $type; - } - /** * Registers WooCommerce taxonomies to be used in GraphQL schema * diff --git a/includes/class-type-registry.php b/includes/class-type-registry.php index 010ef7d7..09a5e55d 100644 --- a/includes/class-type-registry.php +++ b/includes/class-type-registry.php @@ -13,17 +13,11 @@ namespace WPGraphQL\Extensions\WooCommerce; */ class Type_Registry { /** - * Registers actions related to type registry. + * Registers WooGraphQL types, connections, unions, and mutations to GraphQL schema + * + * @param \WPGraphQL\Registry\TypeRegistry $type_registry Instance of the WPGraphQL TypeRegistry. */ - public static function add_actions() { - // Register types. - add_action( 'graphql_register_types', array( __CLASS__, 'graphql_register_types' ), 10 ); - } - - /** - * Registers WooGraphQL types, connection, and mutations to GraphQL schema - */ - public static function graphql_register_types() { + public function init( \WPGraphQL\Registry\TypeRegistry $type_registry ) { // Enumerations. \WPGraphQL\Extensions\WooCommerce\Type\WPEnum\Backorders::register(); \WPGraphQL\Extensions\WooCommerce\Type\WPEnum\Catalog_Visibility::register(); diff --git a/includes/class-wp-graphql-woocommerce.php b/includes/class-wp-graphql-woocommerce.php index 388ccdc6..a0bae8f0 100644 --- a/includes/class-wp-graphql-woocommerce.php +++ b/includes/class-wp-graphql-woocommerce.php @@ -32,8 +32,7 @@ if ( ! class_exists( 'WP_GraphQL_WooCommerce' ) ) : if ( ! isset( self::$instance ) && ! ( is_a( self::$instance, __CLASS__ ) ) ) { self::$instance = new self(); self::$instance->includes(); - self::$instance->actions(); - self::$instance->filters(); + self::$instance->setup(); } /** @@ -141,26 +140,23 @@ if ( ! class_exists( 'WP_GraphQL_WooCommerce' ) ) : } /** - * Sets up actions to run at certain spots throughout WordPress and the WPGraphQL execution cycle + * Sets up WooGraphQL schema. */ - private function actions() { - /** - * Setup actions - */ - \WPGraphQL\Extensions\WooCommerce\Type_Registry::add_actions(); - } - - /** - * Sets up filters to run at certain spots throughout WordPress and the WPGraphQL execution cycle - */ - private function filters() { - /** - * Setup filters - */ - \WPGraphQL\Extensions\WooCommerce\Core_Schema_Filters::add_filters(); - \WPGraphQL\Extensions\WooCommerce\ACF_Schema_Filters::add_filters(); + private function setup() { + // Register WooCommerce filters. \WPGraphQL\Extensions\WooCommerce\WooCommerce_Filters::add_filters(); + + // Register WPGraphQL core filters. + \WPGraphQL\Extensions\WooCommerce\Core_Schema_Filters::add_filters(); + + // Register WPGraphQL ACF filters. + \WPGraphQL\Extensions\WooCommerce\ACF_Schema_Filters::add_filters(); + + // Register WPGraphQL JWT Authentication filters. \WPGraphQL\Extensions\WooCommerce\JWT_Auth_Schema_Filters::add_filters(); + + $registry = new \WPGraphQL\Extensions\WooCommerce\Type_Registry(); + add_action( 'graphql_register_types', array( $registry, 'init' ) ); } } endif; diff --git a/includes/data/class-factory.php b/includes/data/class-factory.php index ba6a89d5..b65f56d4 100644 --- a/includes/data/class-factory.php +++ b/includes/data/class-factory.php @@ -195,6 +195,78 @@ class Factory { return null; } + /** + * Resolves Relay node for some WooGraphQL types. + * + * @param mixed $node Node object. + * @param string $id Object unique ID. + * @param string $type Node type. + * @param AppContext $context AppContext instance. + * + * @return mixed + */ + public static function resolve_node( $node, $id, $type, $context ) { + switch ( $type ) { + case 'customer': + $node = self::resolve_customer( $id, $context ); + break; + case 'shop_coupon': + case 'shop_order': + case 'shop_order_refund': + case 'product': + case 'product_variation': + $node = self::resolve_crud_object( $id, $context ); + break; + case 'shipping_method': + $node = self::resolve_shipping_method( $id ); + break; + case 'tax_rate': + $node = self::resolve_tax_rate( $id ); + break; + } + + return $node; + } + + /** + * Resolves Relay node type for some WooGraphQL types. + * + * @param string|null $type Node type. + * @param mixed $node Node object. + * + * @return string|null + */ + public static function resolve_node_type( $type, $node ) { + switch ( true ) { + case is_a( $node, Coupon::class ): + $type = 'Coupon'; + break; + case is_a( $node, Customer::class ): + $type = 'Customer'; + break; + case is_a( $node, Order::class ): + $type = 'Order'; + break; + case is_a( $node, Product::class ): + $type = 'Product'; + break; + case is_a( $node, Product_Variation::class ): + $type = 'ProductVariation'; + break; + case is_a( $node, Refund::class ): + $type = 'Refund'; + break; + case is_a( $node, Shipping_Method::class ): + $type = 'ShippingMethod'; + break; + case is_a( $node, Tax_Rate::class ): + $type = 'TaxRate'; + break; + } + + return $type; + } + /** * Resolves Coupon connections * diff --git a/includes/type/object/class-coupon-type.php b/includes/type/object/class-coupon-type.php index e4a02278..0c46611f 100644 --- a/includes/type/object/class-coupon-type.php +++ b/includes/type/object/class-coupon-type.php @@ -26,12 +26,12 @@ class Coupon_Type { * Register Coupon type and queries to the WPGraphQL schema */ public static function register() { - wc_register_graphql_object_type( + register_graphql_object_type( 'Coupon', array( - 'description' => __( 'A coupon object', 'wp-graphql-woocommerce' ), - 'interfaces' => [ WPObjectType::node_interface() ], - 'fields' => array( + 'description' => __( 'A coupon object', 'wp-graphql-woocommerce' ), + 'interfaces' => array( 'Node' ), + 'fields' => array( 'id' => array( 'type' => array( 'non_null' => 'ID' ), 'description' => __( 'The globally unique identifier for the coupon', 'wp-graphql-woocommerce' ), @@ -109,20 +109,6 @@ class Coupon_Type { 'description' => __( 'Only customers with a matching email address can use the coupon', 'wp-graphql-woocommerce' ), ), ), - 'resolve_node' => function( $node, $id, $type, $context ) { - if ( 'shop_coupon' === $type ) { - $node = Factory::resolve_crud_object( $id, $context ); - } - - return $node; - }, - 'resolve_node_type' => function( $type, $node ) { - if ( is_a( $node, Coupon::class ) ) { - $type = 'Coupon'; - } - - return $type; - }, ) ); diff --git a/includes/type/object/class-customer-type.php b/includes/type/object/class-customer-type.php index 36c227ef..b34aa640 100644 --- a/includes/type/object/class-customer-type.php +++ b/includes/type/object/class-customer-type.php @@ -27,12 +27,12 @@ class Customer_Type { * Registers Customer WPObject type */ public static function register() { - wc_register_graphql_object_type( + register_graphql_object_type( 'Customer', array( - 'description' => __( 'A customer object', 'wp-graphql-woocommerce' ), - 'interfaces' => [ WPObjectType::node_interface() ], - 'fields' => array( + 'description' => __( 'A customer object', 'wp-graphql-woocommerce' ), + 'interfaces' => array( 'Node' ), + 'fields' => array( 'id' => array( 'type' => array( 'non_null' => 'ID' ), 'description' => __( 'The globally unique identifier for the customer', 'wp-graphql-woocommerce' ), @@ -113,20 +113,6 @@ class Customer_Type { 'description' => __( 'Return the date customer was last updated', 'wp-graphql-woocommerce' ), ), ), - 'resolve_node' => function( $node, $id, $type, $context ) { - if ( 'customer' === $type ) { - $node = Factory::resolve_customer( $id, $context ); - } - - return $node; - }, - 'resolve_node_type' => function( $type, $node ) { - if ( is_a( $node, Customer::class ) ) { - $type = 'Customer'; - } - - return $type; - }, ) ); diff --git a/includes/type/object/class-order-type.php b/includes/type/object/class-order-type.php index 002cfd59..1001ac9d 100644 --- a/includes/type/object/class-order-type.php +++ b/includes/type/object/class-order-type.php @@ -26,12 +26,12 @@ class Order_Type { * Register Order type and queries to the WPGraphQL schema */ public static function register() { - wc_register_graphql_object_type( + register_graphql_object_type( 'Order', array( - 'description' => __( 'A order object', 'wp-graphql-woocommerce' ), - 'interfaces' => [ WPObjectType::node_interface() ], - 'fields' => array( + 'description' => __( 'A order object', 'wp-graphql-woocommerce' ), + 'interfaces' => array( 'Node' ), + 'fields' => array( 'id' => array( 'type' => array( 'non_null' => 'ID' ), 'description' => __( 'The globally unique identifier for the order', 'wp-graphql-woocommerce' ), @@ -321,20 +321,6 @@ class Order_Type { 'description' => __( 'Product downloads', 'wp-graphql-woocommerce' ), ), ), - 'resolve_node' => function( $node, $id, $type, $context ) { - if ( 'shop_order' === $type ) { - $node = Factory::resolve_crud_object( $id, $context ); - } - - return $node; - }, - 'resolve_node_type' => function( $type, $node ) { - if ( is_a( $node, Order::class ) ) { - $type = 'Order'; - } - - return $type; - }, ) ); diff --git a/includes/type/object/class-product-type.php b/includes/type/object/class-product-type.php index ab4e8756..5a06faec 100644 --- a/includes/type/object/class-product-type.php +++ b/includes/type/object/class-product-type.php @@ -27,12 +27,12 @@ class Product_Type { * Register Product type and queries to the WPGraphQL schema */ public static function register() { - wc_register_graphql_object_type( + register_graphql_object_type( 'Product', array( - 'description' => __( 'A product object', 'wp-graphql-woocommerce' ), - 'interfaces' => [ WPObjectType::node_interface() ], - 'fields' => array( + 'description' => __( 'A product object', 'wp-graphql-woocommerce' ), + 'interfaces' => array( 'Node' ), + 'fields' => array( 'id' => array( 'type' => array( 'non_null' => 'ID' ), 'description' => __( 'The globally unique identifier for the product', 'wp-graphql-woocommerce' ), @@ -323,20 +323,6 @@ class Product_Type { 'description' => __( 'Product\'s add to cart button text description', 'wp-graphql-woocommerce' ), ), ), - 'resolve_node' => function( $node, $id, $type, $context ) { - if ( 'product' === $type ) { - $node = Factory::resolve_crud_object( $id, $context ); - } - - return $node; - }, - 'resolve_node_type' => function( $type, $node ) { - if ( is_a( $node, Product::class ) ) { - $type = 'Product'; - } - - return $type; - }, ) ); diff --git a/includes/type/object/class-product-variation-type.php b/includes/type/object/class-product-variation-type.php index a395b25f..a05a4344 100644 --- a/includes/type/object/class-product-variation-type.php +++ b/includes/type/object/class-product-variation-type.php @@ -27,12 +27,12 @@ class Product_Variation_Type { * Register ProductVariation type to the WPGraphQL schema */ public static function register() { - wc_register_graphql_object_type( + register_graphql_object_type( 'ProductVariation', array( - 'description' => __( 'A product variation object', 'wp-graphql-woocommerce' ), - 'interfaces' => [ WPObjectType::node_interface() ], - 'fields' => array( + 'description' => __( 'A product variation object', 'wp-graphql-woocommerce' ), + 'interfaces' => array( 'Node' ), + 'fields' => array( 'id' => array( 'type' => array( 'non_null' => 'ID' ), 'description' => __( 'The globally unique identifier for the product variation', 'wp-graphql-woocommerce' ), @@ -241,20 +241,6 @@ class Product_Variation_Type { }, ), ), - 'resolve_node' => function( $node, $id, $type, $context ) { - if ( 'product_variation' === $type ) { - $node = Factory::resolve_crud_object( $id, $context ); - } - - return $node; - }, - 'resolve_node_type' => function( $type, $node ) { - if ( is_a( $node, Product_Variation::class ) ) { - $type = 'ProductVariation'; - } - - return $type; - }, ) ); diff --git a/includes/type/object/class-refund-type.php b/includes/type/object/class-refund-type.php index 621cdb56..c9e3992a 100644 --- a/includes/type/object/class-refund-type.php +++ b/includes/type/object/class-refund-type.php @@ -26,12 +26,12 @@ class Refund_Type { * Register Refund type and queries to the WPGraphQL schema */ public static function register() { - wc_register_graphql_object_type( + register_graphql_object_type( 'Refund', array( - 'description' => __( 'A refund object', 'wp-graphql-woocommerce' ), - 'interfaces' => [ WPObjectType::node_interface() ], - 'fields' => array( + 'description' => __( 'A refund object', 'wp-graphql-woocommerce' ), + 'interfaces' => array( 'Node' ), + 'fields' => array( 'id' => array( 'type' => array( 'non_null' => 'ID' ), 'description' => __( 'The globally unique identifier for the refund', 'wp-graphql-woocommerce' ), @@ -60,20 +60,6 @@ class Refund_Type { }, ), ), - 'resolve_node' => function( $node, $id, $type, $context ) { - if ( 'shop_order_refund' === $type ) { - $node = Factory::resolve_crud_object( $id, $context ); - } - - return $node; - }, - 'resolve_node_type' => function( $type, $node ) { - if ( is_a( $node, Refund::class ) ) { - $type = 'Refund'; - } - - return $type; - }, ) ); diff --git a/includes/type/object/class-shipping-method-type.php b/includes/type/object/class-shipping-method-type.php index debdd0c1..f241ef19 100644 --- a/includes/type/object/class-shipping-method-type.php +++ b/includes/type/object/class-shipping-method-type.php @@ -26,12 +26,12 @@ class Shipping_Method_Type { * Registers shipping method type */ public static function register() { - wc_register_graphql_object_type( + register_graphql_object_type( 'ShippingMethod', array( - 'description' => __( 'A shipping method object', 'wp-graphql-woocommercer' ), - 'interfaces' => [ WPObjectType::node_interface() ], - 'fields' => array( + 'description' => __( 'A shipping method object', 'wp-graphql-woocommercer' ), + 'interfaces' => array( 'Node' ), + 'fields' => array( 'id' => array( 'type' => array( 'non_null' => 'ID' ), 'description' => __( 'The globally unique identifier for the tax rate.', 'wp-graphql-woocommerce' ), @@ -49,20 +49,6 @@ class Shipping_Method_Type { 'description' => __( 'Shipping method description.', 'wp-graphql-woocommerce' ), ), ), - 'resolve_node' => function( $node, $id, $type, AppContext $context ) { - if ( 'shipping_method' === $type ) { - $node = Factory::resolve_shipping_method( $id ); - } - - return $node; - }, - 'resolve_node_type' => function( $type, $node ) { - if ( is_a( $node, Shipping_Method::class ) ) { - $type = 'ShippingMethod'; - } - - return $type; - }, ) ); diff --git a/includes/type/object/class-tax-rate-type.php b/includes/type/object/class-tax-rate-type.php index c2fee4a6..fc6da509 100644 --- a/includes/type/object/class-tax-rate-type.php +++ b/includes/type/object/class-tax-rate-type.php @@ -26,12 +26,12 @@ class Tax_Rate_Type { * Registers tax rate type */ public static function register() { - wc_register_graphql_object_type( + register_graphql_object_type( 'TaxRate', array( - 'description' => __( 'A Tax rate object', 'wp-graphql-woocommercer' ), - 'interfaces' => [ WPObjectType::node_interface() ], - 'fields' => array( + 'description' => __( 'A Tax rate object', 'wp-graphql-woocommercer' ), + 'interfaces' => array('Node'), + 'fields' => array( 'id' => array( 'type' => array( 'non_null' => 'ID' ), 'description' => __( 'The globally unique identifier for the tax rate.', 'wp-graphql-woocommerce' ), @@ -85,20 +85,6 @@ class Tax_Rate_Type { 'description' => __( 'Tax class. Default is standard.', 'wp-graphql-woocommerce' ), ), ), - 'resolve_node' => function( $node, $id, $type, AppContext $context ) { - if ( 'tax_rate' === $type ) { - $node = Factory::resolve_tax_rate( $id ); - } - - return $node; - }, - 'resolve_node_type' => function( $type, $node ) { - if ( is_a( $node, Tax_Rate::class ) ) { - $type = 'TaxRate'; - } - - return $type; - }, ) ); diff --git a/wp-graphql-woocommerce.php b/wp-graphql-woocommerce.php index ee87abe0..a2254750 100644 --- a/wp-graphql-woocommerce.php +++ b/wp-graphql-woocommerce.php @@ -19,6 +19,8 @@ // Exit if accessed directly. defined( 'ABSPATH' ) || exit; +define( 'GRAPHQL_DEBUG', true ); + /** * If the codeception remote coverage file exists, require it. *