diff --git a/.gitignore b/.gitignore index 8f2936b3..f6220358 100644 --- a/.gitignore +++ b/.gitignore @@ -18,6 +18,7 @@ vendor/composer/installed.json vendor/composer/*/ !/tests /tests/*.suite.yml +codeception.yml build/ coverage/* schema.graphql diff --git a/access-functions.php b/access-functions.php new file mode 100644 index 00000000..0636e090 --- /dev/null +++ b/access-functions.php @@ -0,0 +1,26 @@ +getLoader( 'wc_crud' ); + $loader = $context->getLoader( 'wc_post_crud' ); $loader->buffer( [ $object_id ] ); return new Deferred( function () use ( $loader, $object_id ) { @@ -84,7 +86,7 @@ class Factory { * @return array * @access public */ - public static function resolve_coupon_connection( $source, array $args, $context, ResolveInfo $info ) { + public static function resolve_coupon_connection( $source, array $args, AppContext $context, ResolveInfo $info ) { $resolver = new Coupon_Connection_Resolver( $source, $args, $context, $info ); return $resolver->get_connection(); } @@ -100,7 +102,7 @@ class Factory { * @return array * @access public */ - public static function resolve_customer_connection( $source, array $args, $context, ResolveInfo $info ) { + public static function resolve_customer_connection( $source, array $args, AppContext $context, ResolveInfo $info ) { $resolver = new Customer_Connection_Resolver( $source, $args, $context, $info ); return $resolver->get_connection(); } @@ -116,7 +118,7 @@ class Factory { * @return array * @access public */ - public static function resolve_order_connection( $source, array $args, $context, ResolveInfo $info ) { + public static function resolve_order_connection( $source, array $args, AppContext $context, ResolveInfo $info ) { $resolver = new Order_Connection_Resolver( $source, $args, $context, $info ); return $resolver->get_connection(); } @@ -132,7 +134,7 @@ class Factory { * @return array * @access public */ - public static function resolve_product_connection( $source, array $args, $context, ResolveInfo $info ) { + public static function resolve_product_connection( $source, array $args, AppContext $context, ResolveInfo $info ) { $resolver = new Product_Connection_Resolver( $source, $args, $context, $info ); return $resolver->get_connection(); } @@ -148,7 +150,7 @@ class Factory { * @return array * @access public */ - public static function resolve_product_attribute_connection( $source, array $args, $context, ResolveInfo $info ) { + public static function resolve_product_attribute_connection( $source, array $args, AppContext $context, ResolveInfo $info ) { $resolver = new Product_Attribute_Connection_Resolver(); return $resolver->resolve( $source, $args, $context, $info ); } @@ -164,7 +166,7 @@ class Factory { * @return array * @access public */ - public static function resolve_product_download_connection( $source, array $args, $context, ResolveInfo $info ) { + public static function resolve_product_download_connection( $source, array $args, AppContext $context, ResolveInfo $info ) { $resolver = new Product_Download_Connection_Resolver(); return $resolver->resolve( $source, $args, $context, $info ); } @@ -180,7 +182,7 @@ class Factory { * @return array * @access public */ - public static function resolve_refund_connection( $source, array $args, $context, ResolveInfo $info ) { + public static function resolve_refund_connection( $source, array $args, AppContext $context, ResolveInfo $info ) { $resolver = new Refund_Connection_Resolver( $source, $args, $context, $info ); return $resolver->get_connection(); } diff --git a/src/data/connection/class-customer-connection-resolver.php b/src/data/connection/class-customer-connection-resolver.php index ad982746..5c015fec 100644 --- a/src/data/connection/class-customer-connection-resolver.php +++ b/src/data/connection/class-customer-connection-resolver.php @@ -13,7 +13,7 @@ namespace WPGraphQL\Extensions\WooCommerce\Data\Connection; use GraphQL\Type\Definition\ResolveInfo; use WPGraphQL\AppContext; use WPGraphQL\Data\Connection\AbstractConnectionResolver; -use WPGraphQL\Extensions\WooCommerce\Model\Refund; +use WPGraphQL\Extensions\WooCommerce\Model\Coupon; /** * Class Customer_Connection_Resolver diff --git a/src/data/loader/class-wc-post-crud-loader.php b/src/data/loader/class-wc-post-crud-loader.php new file mode 100644 index 00000000..8a8c3e48 --- /dev/null +++ b/src/data/loader/class-wc-post-crud-loader.php @@ -0,0 +1,159 @@ + $wc_post_types, + 'post_status' => 'any', + 'posts_per_page' => count( $keys ), + 'post__in' => $keys, + 'orderby' => 'post__in', + 'no_found_rows' => true, + 'split_the_query' => false, + 'ignore_sticky_posts' => true, + ); + + /** + * Ensure that WP_Query doesn't first ask for IDs since we already have them. + */ + add_filter( + 'split_the_query', + function ( $split, \WP_Query $query ) { + if ( false === $query->get( 'split_the_query' ) ) { + return false; + } + return $split; + }, + 10, + 2 + ); + new \WP_Query( $args ); + /** + * Loop over the posts and return an array of all_posts, + * where the key is the ID and the value is the Post passed through + * the model layer. + */ + foreach ( $keys as $key ) { + /** + * The query above has added our objects to the cache + * so now we can pluck them from the cache to return here + * and if they don't exist or aren't a valid post-type we can throw an error, otherwise + * we can proceed to resolve the object via the Model layer. + */ + $post_type = get_post_type( (int) $key ); + if ( ! $post_type ) { + /* translators: invalid id error message */ + throw new UserError( sprintf( __( 'No item was found with ID %s', 'wp-graphql-woocommerce' ), $key ) ); + } + + if ( ! in_array( $post_type, $wc_post_types, true ) ) { + /* translators: invalid post-type error message */ + throw new UserError( sprintf( __( '%s is not a valid WooCommerce post-type', 'wp-graphql-woocommerce' ), $post_type ) ); + } + + /** + * Return the instance through the Model to ensure we only + * return fields the consumer has access to. + */ + $this->loaded_objects[ $key ] = new Deferred( + function() use ( $post_type, $key ) { + // Resolve post author for future capability checks. + $author_id = get_post_field( 'post_author', $key ); + if ( ! empty( $author_id ) && absint( $author_id ) ) { + $author = DataSource::resolve_user( $author_id, $this->context ); + + return $author->then( + function () use ( $post_type, $key ) { + return $this->resolve_model( $post_type, $key ); + } + ); + } + return $this->resolve_model( $post_type, $key ); + } + ); + } + return ! empty( $this->loaded_objects ) ? $this->loaded_objects : array(); + } +} diff --git a/src/model/class-coupon.php b/src/model/class-coupon.php index 1de40b9b..fb5a67ee 100644 --- a/src/model/class-coupon.php +++ b/src/model/class-coupon.php @@ -100,10 +100,10 @@ class Coupon extends Crud_CPT { return ! empty( $this->data->get_date_expires() ) ? $this->data->get_date_expires() : null; }, 'usageCount' => function() { - return ! empty( $this->data->get_usage_count() ) ? $this->data->get_usage_count() : null; + return ! is_null( $this->data->get_usage_count() ) ? $this->data->get_usage_count() : null; }, 'individualUse' => function() { - return ! empty( $this->data->get_individual_use() ) ? $this->data->get_individual_use() : null; + return ! is_null( $this->data->get_individual_use() ) ? $this->data->get_individual_use() : null; }, 'usageLimit' => function() { return ! empty( $this->data->get_usage_limit() ) ? $this->data->get_usage_limit() : null; @@ -115,10 +115,10 @@ class Coupon extends Crud_CPT { return ! empty( $this->data->get_limit_usage_to_x_items() ) ? $this->data->get_limit_usage_to_x_items() : null; }, 'freeShipping' => function() { - return ! empty( $this->data->get_free_shipping() ) ? $this->data->get_free_shipping() : null; + return ! is_null( $this->data->get_free_shipping() ) ? $this->data->get_free_shipping() : null; }, 'excludeSaleItems' => function() { - return ! empty( $this->data->get_exclude_sale_items() ) ? $this->data->get_exclude_sale_items() : null; + return ! is_null( $this->data->get_exclude_sale_items() ) ? $this->data->get_exclude_sale_items() : null; }, 'minimumAmount' => function() { return ! empty( $this->data->get_minimum_amount() ) ? $this->data->get_minimum_amount() : null; diff --git a/src/model/class-customer.php b/src/model/class-customer.php index e98dacb7..78243332 100644 --- a/src/model/class-customer.php +++ b/src/model/class-customer.php @@ -34,7 +34,7 @@ class Customer extends Model { 'isPublic', 'id', 'customerId', - 'name', + 'displayName', ]; parent::__construct( 'list_users', $allowed_restricted_fields, $id ); @@ -55,58 +55,64 @@ class Customer extends Model { return ( ! empty( $this->data ) ) ? Relay::toGlobalId( 'customer', $this->data->get_id() ) : null; }, 'customerId' => function() { - return ( ! empty( $this->data ) ) ? $this->data->get_id() : null; + return ( ! empty( $this->data->get_id() ) ) ? $this->data->get_id() : null; }, 'isVatExempt' => function() { - return ( ! empty( $this->data ) ) ? $this->data->get_is_vat_exempt() : null; + return ( ! empty( $this->data->get_is_vat_exempt() ) ) ? $this->data->get_is_vat_exempt() : null; }, 'hasCalculatedShipping' => function() { - return ( ! empty( $this->data ) ) ? $this->data->has_calculated_shipping() : null; + return ( ! empty( $this->data->has_calculated_shipping() ) ) ? $this->data->has_calculated_shipping() : null; }, 'calculatedShipping' => function() { - return ( ! empty( $this->data ) ) ? $this->data->get_calculated_shipping() : null; - }, - 'lastOrder' => function() { - return ( ! empty( $this->data ) ) ? $this->data->get_last_order() : null; + return ( ! empty( $this->data->get_calculated_shipping() ) ) ? $this->data->get_calculated_shipping() : null; }, 'orderCount' => function() { - return ( ! empty( $this->data ) ) ? $this->data->get_order_count() : null; + return ( ! empty( $this->data->get_order_count() ) ) ? $this->data->get_order_count() : null; }, 'totalSpent' => function() { - return ( ! empty( $this->data ) ) ? $this->data->get_total_spent() : null; + return ( ! empty( $this->data->get_total_spent() ) ) ? $this->data->get_total_spent() : null; }, 'username' => function() { - return ( ! empty( $this->data ) ) ? $this->data->get_username() : null; + return ( ! empty( $this->data->get_username() ) ) ? $this->data->get_username() : null; }, 'email' => function() { - return ( ! empty( $this->data ) ) ? $this->data->get_email() : null; + return ( ! empty( $this->data->get_email() ) ) ? $this->data->get_email() : null; }, 'firstName' => function() { - return ( ! empty( $this->data ) ) ? $this->data->get_first_name() : null; + return ( ! empty( $this->data->get_first_name() ) ) ? $this->data->get_first_name() : null; }, 'lastName' => function() { - return ( ! empty( $this->data ) ) ? $this->data->get_last_name() : null; + return ( ! empty( $this->data->get_last_name() ) ) ? $this->data->get_last_name() : null; }, 'displayName' => function() { - return ( ! empty( $this->data ) ) ? $this->data->get_display_name() : null; + return ( ! empty( $this->data->get_display_name() ) ) ? $this->data->get_display_name() : null; }, 'role' => function() { - return ( ! empty( $this->data ) ) ? $this->data->get_role() : null; + return ( ! empty( $this->data->get_role() ) ) ? $this->data->get_role() : null; }, 'date' => function() { - return ( ! empty( $this->data ) ) ? $this->data->get_date_created() : null; + return ( ! empty( $this->data->get_date_created() ) ) ? $this->data->get_date_created() : null; }, 'modified' => function() { - return ( ! empty( $this->data ) ) ? $this->data->get_date_modified() : null; + return ( ! empty( $this->data->get_date_modified() ) ) ? $this->data->get_date_modified() : null; }, 'billing' => function() { - return ( ! empty( $this->data ) ) ? $this->data->get_billing() : null; + return ( ! empty( $this->data->get_billing() ) ) ? $this->data->get_billing() : null; }, 'shipping' => function() { - return ( ! empty( $this->data ) ) ? $this->data->get_shipping() : null; + return ( ! empty( $this->data->get_shipping() ) ) ? $this->data->get_shipping() : null; }, 'isPayingCustomer' => function() { - return ( ! empty( $this->data ) ) ? $this->data->get_is_paying_customer() : null; + return ( ! empty( $this->data->get_is_paying_customer() ) ) ? $this->data->get_is_paying_customer() : null; + }, + /** + * Connection resolvers fields + * + * These field resolvers are used in connection resolvers to define WP_Query argument + * Note: underscore naming style is used as a quick identifier + */ + 'last_order_id' => function() { + return ( ! empty( $this->data->get_last_order() ) ) ? $this->data->get_last_order()->get_id() : null; }, ); } diff --git a/src/model/class-product.php b/src/model/class-product.php index b1da1f6b..e2439383 100644 --- a/src/model/class-product.php +++ b/src/model/class-product.php @@ -120,11 +120,17 @@ class Product extends Crud_CPT { 'name' => function() { return ! empty( $this->data->get_name() ) ? $this->data->get_name() : null; }, + 'date' => function() { + return ! empty( $this->data ) ? $this->data->get_date_created() : null; + }, + 'modified' => function() { + return ! empty( $this->data ) ? $this->data->get_date_modified() : null; + }, 'status' => function() { return ! empty( $this->data->get_status() ) ? $this->data->get_status() : null; }, 'featured' => function() { - return ! empty( $this->data->get_featured() ) ? $this->data->get_featured() : null; + return ! is_null( $this->data->get_featured() ) ? $this->data->get_featured() : null; }, 'catalogVisibility' => function() { return ! empty( $this->data->get_catalog_visibility() ) ? $this->data->get_catalog_visibility() : null; @@ -223,7 +229,7 @@ class Product extends Crud_CPT { return ! empty( $this->data->get_date_on_sale_to() ) ? $this->data->get_date_on_sale_to() : null; }, 'totalSales' => function() { - return ! empty( $this->data->get_total_sales() ) ? $this->data->get_total_sales() : null; + return ! is_null( $this->data->get_total_sales() ) ? $this->data->get_total_sales() : null; }, 'taxStatus' => function() { return ! empty( $this->data->get_tax_status() ) ? $this->data->get_tax_status() : null; @@ -232,7 +238,7 @@ class Product extends Crud_CPT { return ! empty( $this->data->get_tax_class() ) ? $this->data->get_tax_class() : null; }, 'manageStock' => function() { - return ! empty( $this->data->get_manage_stock() ) ? $this->data->get_manage_stock() : null; + return ! is_null( $this->data->get_manage_stock() ) ? $this->data->get_manage_stock() : null; }, 'stockQuantity' => function() { return ! empty( $this->data->get_stock_quantity() ) ? $this->data->get_stock_quantity() : null; @@ -244,19 +250,19 @@ class Product extends Crud_CPT { return ! empty( $this->data->get_backorders() ) ? $this->data->get_backorders() : null; }, 'soldIndividually' => function() { - return ! empty( $this->data->get_sold_individually() ) ? $this->data->get_sold_individually() : null; + return ! is_null( $this->data->get_sold_individually() ) ? $this->data->get_sold_individually() : null; }, 'weight' => function() { - return ! empty( $this->data->get_weight() ) ? $this->data->get_weight() : null; + return ! is_null( $this->data->get_weight() ) ? $this->data->get_weight() : null; }, 'length' => function() { - return ! empty( $this->data->get_length() ) ? $this->data->get_length() : null; + return ! is_null( $this->data->get_length() ) ? $this->data->get_length() : null; }, 'width' => function() { - return ! empty( $this->data->get_width() ) ? $this->data->get_width() : null; + return ! is_null( $this->data->get_width() ) ? $this->data->get_width() : null; }, 'height' => function() { - return ! empty( $this->data->get_height() ) ? $this->data->get_height() : null; + return ! is_null( $this->data->get_height() ) ? $this->data->get_height() : null; }, 'reviewsAllowed' => function() { return ! empty( $this->data->get_reviews_allowed() ) ? $this->data->get_reviews_allowed() : null; @@ -265,28 +271,28 @@ class Product extends Crud_CPT { return ! empty( $this->data->get_purchase_note() ) ? $this->data->get_purchase_note() : null; }, 'menuOrder' => function() { - return ! empty( $this->data->get_menu_order() ) ? $this->data->get_menu_order() : null; + return ! is_null( $this->data->get_menu_order() ) ? $this->data->get_menu_order() : null; }, 'virtual' => function() { - return ! empty( $this->data->get_virtual() ) ? $this->data->get_virtual() : null; + return ! is_null( $this->data->get_virtual() ) ? $this->data->get_virtual() : null; }, 'downloadExpiry' => function() { - return ! empty( $this->data->get_download_expiry() ) ? $this->data->get_download_expiry() : null; + return ! is_null( $this->data->get_download_expiry() ) ? $this->data->get_download_expiry() : null; }, 'downloadable' => function() { - return ! empty( $this->data->get_downloadable() ) ? $this->data->get_downloadable() : null; + return ! is_null( $this->data->get_downloadable() ) ? $this->data->get_downloadable() : null; }, 'downloadLimit' => function() { - return ! empty( $this->data->get_download_limit() ) ? $this->data->get_download_limit() : null; + return ! is_null( $this->data->get_download_limit() ) ? $this->data->get_download_limit() : null; }, 'ratingCount' => function() { - return ! empty( $this->data->get_rating_counts() ) ? $this->data->get_rating_counts() : null; + return ! is_null( $this->data->get_rating_counts() ) ? $this->data->get_rating_counts() : null; }, 'averageRating' => function() { - return ! empty( $this->data->get_average_rating() ) ? $this->data->get_average_rating() : null; + return ! is_null( $this->data->get_average_rating() ) ? $this->data->get_average_rating() : null; }, 'reviewCount' => function() { - return ! empty( $this->data->get_review_count() ) ? $this->data->get_review_count() : null; + return ! is_null( $this->data->get_review_count() ) ? $this->data->get_review_count() : null; }, 'parentId' => function() { return ! empty( $this->data->get_parent_id() ) ? $this->data->get_parent_id() : null; diff --git a/src/model/class-refund.php b/src/model/class-refund.php index 11bb4f61..b70d1d42 100644 --- a/src/model/class-refund.php +++ b/src/model/class-refund.php @@ -33,12 +33,7 @@ class Refund extends Model { 'isPrivate', 'isPublic', 'id', - 'userId', - 'name', - 'firstName', - 'lastName', - 'description', - 'slug', + 'refundId', ]; parent::__construct( 'list_users', $allowed_restricted_fields, $id ); diff --git a/src/type/object/class-coupon-type.php b/src/type/object/class-coupon-type.php new file mode 100644 index 00000000..2f740eee --- /dev/null +++ b/src/type/object/class-coupon-type.php @@ -0,0 +1,201 @@ + __( 'A coupon object', 'wp-graphql-woocommerce' ), + 'interfaces' => [ WPObjectType::node_interface() ], + 'fields' => array( + 'id' => array( + 'type' => array( 'non_null' => 'ID' ), + 'description' => __( 'The globally unique identifier for the coupon', 'wp-graphql-woocommerce' ), + ), + 'couponId' => array( + 'type' => 'Int', + 'description' => __( 'The Id of the order. Equivalent to WP_Post->ID', 'wp-graphql-woocommerce' ), + ), + 'code' => array( + 'type' => 'String', + 'description' => __( 'Coupon code', 'wp-graphql-woocommerce' ), + ), + 'date' => array( + 'type' => 'String', + 'description' => __( 'Date coupon created', 'wp-graphql-woocommerce' ), + ), + 'modified' => array( + 'type' => 'String', + 'description' => __( 'Date coupon modified', 'wp-graphql-woocommerce' ), + ), + 'description' => array( + 'type' => 'String', + 'description' => __( 'Explanation of what the coupon does', 'wp-graphql-woocommerce' ), + ), + 'discountType' => array( + 'type' => 'DiscountTypeEnum', + 'description' => __( 'Type of discount', 'wp-graphql-woocommerce' ), + ), + 'amount' => array( + 'type' => 'Float', + 'description' => __( 'Amount off provided by the coupon', 'wp-graphql-woocommerce' ), + ), + 'dateExpiry' => array( + 'type' => 'String', + 'description' => __( 'Date coupon expires', 'wp-graphql-woocommerce' ), + ), + 'usageCount' => array( + 'type' => 'Int', + 'description' => __( 'How many times the coupon has been used', 'wp-graphql-woocommerce' ), + ), + 'individualUse' => array( + 'type' => 'Boolean', + 'description' => __( 'Individual use means this coupon cannot be used in conjunction with other coupons', 'wp-graphql-woocommerce' ), + ), + 'usageLimit' => array( + 'type' => 'Int', + 'description' => __( 'Amount of times this coupon can be used globally', 'wp-graphql-woocommerce' ), + ), + 'usageLimitPerUser' => array( + 'type' => 'Int', + 'description' => __( 'Amount of times this coupon can be used by a customer', 'wp-graphql-woocommerce' ), + ), + 'limitUsageToXItems' => array( + 'type' => 'Int', + 'description' => __( 'The number of products in your cart this coupon can apply to (for product discounts)', 'wp-graphql-woocommerce' ), + ), + 'freeShipping' => array( + 'type' => 'Boolean', + 'description' => __( 'Does this coupon grant free shipping?', 'wp-graphql-woocommerce' ), + ), + 'excludeSaleItems' => array( + 'type' => 'Boolean', + 'description' => __( 'Excluding sale items mean this coupon cannot be used on items that are on sale (or carts that contain on sale items)', 'wp-graphql-woocommerce' ), + ), + 'minimumAmount' => array( + 'type' => 'Float', + 'description' => __( 'Minimum spend amount that must be met before this coupon can be used', 'wp-graphql-woocommerce' ), + ), + 'maximumAmount' => array( + 'type' => 'Float', + 'description' => __( 'Maximum spend amount that must be met before this coupon can be used ', 'wp-graphql-woocommerce' ), + ), + 'emailRestrictions' => array( + 'type' => array( 'list_of' => 'String' ), + '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; + }, + ) + ); + + register_graphql_field( + 'RootQuery', + 'coupon', + array( + 'type' => 'Coupon', + 'description' => __( 'A coupon object', 'wp-graphql-woocommerce' ), + 'args' => array( + 'id' => array( + 'type' => array( + 'non_null' => 'ID', + ), + ), + ), + 'resolve' => function ( $source, array $args, AppContext $context, ResolveInfo $info ) { + $id_components = Relay::fromGlobalId( $args['id'] ); + if ( ! isset( $id_components['id'] ) || ! absint( $id_components['id'] ) ) { + throw new UserError( __( 'The ID input is invalid', 'wp-graphql-woocommerce' ) ); + } + $coupon_id = absint( $id_components['id'] ); + return Factory::resolve_crud_object( $coupon_id, $context ); + }, + ) + ); + + $post_by_args = array( + 'id' => array( + 'type' => 'ID', + 'description' => __( 'Get the coupon by its global ID', 'wp-graphql-woocommerce' ), + ), + 'couponId' => array( + 'type' => 'Int', + 'description' => __( 'Get the coupon by its database ID', 'wp-graphql-woocommerce' ), + ), + 'code' => array( + 'type' => 'String', + 'description' => __( 'Get the coupon by its code', 'wp-graphql-woocommerce' ), + ), + ); + + register_graphql_field( + 'RootQuery', + 'couponBy', + array( + 'type' => 'Coupon', + 'description' => __( 'A coupon object', 'wp-graphql-woocommerce' ), + 'args' => $post_by_args, + 'resolve' => function ( $source, array $args, AppContext $context, ResolveInfo $info ) { + $coupon_id = 0; + if ( ! empty( $args['id'] ) ) { + $id_components = Relay::fromGlobalId( $args['id'] ); + if ( empty( $id_components['id'] ) || empty( $id_components['type'] ) ) { + throw new UserError( __( 'The "id" is invalid', 'wp-graphql-woocommerce' ) ); + } + $coupon_id = absint( $id_components['id'] ); + } elseif ( ! empty( $args['couponId'] ) ) { + $coupon_id = absint( $args['couponId'] ); + } elseif ( ! empty( $args['code'] ) ) { + $post = get_page_by_title( $args['code'], $output = OBJECT, 'shop_coupon' ); + $coupon_id = $post->ID; + } + + $coupon = Factory::resolve_crud_object( $coupon_id, $context ); + if ( get_post( $coupon_id )->post_type !== 'shop_coupon' ) { + /* translators: not coupon found error message */ + throw new UserError( sprintf( __( 'No coupon exists with this id: %1$s', 'wp-graphql-woocommerce' ), $args['id'] ) ); + } + + return $coupon; + }, + ) + ); + } +} diff --git a/src/type/object/class-customer-address-type.php b/src/type/object/class-customer-address-type.php new file mode 100644 index 00000000..385da382 --- /dev/null +++ b/src/type/object/class-customer-address-type.php @@ -0,0 +1,107 @@ + __( 'A customer address object', 'wp-graphql-woocommerce' ), + 'fields' => array( + 'firstName' => array( + 'type' => 'String', + 'description' => __( 'First name', 'wp-graphql-woocommerce' ), + 'resolve' => function( $address ) { + return ! empty( $address['first_name'] ) ? $address['first_name'] : null; + }, + ), + 'lastName' => array( + 'type' => 'String', + 'description' => __( 'Last name', 'wp-graphql-woocommerce' ), + 'resolve' => function( $address ) { + return ! empty( $address['last_name'] ) ? $address['last_name'] : null; + }, + ), + 'company' => array( + 'type' => 'String', + 'description' => __( 'Company', 'wp-graphql-woocommerce' ), + 'resolve' => function( $address ) { + return ! empty( $address['company'] ) ? $address['company'] : null; + }, + ), + 'address1' => array( + 'type' => 'String', + 'description' => __( 'Address 1', 'wp-graphql-woocommerce' ), + 'resolve' => function( $address ) { + return ! empty( $address['address_1'] ) ? $address['address_1'] : null; + }, + ), + 'address2' => array( + 'type' => 'String', + 'description' => __( 'Address 2', 'wp-graphql-woocommerce' ), + 'resolve' => function( $address ) { + return ! empty( $address['address_2'] ) ? $address['address_2'] : null; + }, + ), + 'city' => array( + 'type' => 'String', + 'description' => __( 'City', 'wp-graphql-woocommerce' ), + 'resolve' => function( $address ) { + return ! empty( $address['city'] ) ? $address['city'] : null; + }, + ), + 'state' => array( + 'type' => 'String', + 'description' => __( 'State', 'wp-graphql-woocommerce' ), + 'resolve' => function( $address ) { + return ! empty( $address['state'] ) ? $address['state'] : null; + }, + ), + 'postcode' => array( + 'type' => 'String', + 'description' => __( 'Zip Postal Code', 'wp-graphql-woocommerce' ), + 'resolve' => function( $address ) { + return ! empty( $address['postcode'] ) ? $address['postcode'] : null; + }, + ), + 'country' => array( + 'type' => 'String', + 'description' => __( 'Country', 'wp-graphql-woocommerce' ), + 'resolve' => function( $address ) { + return ! empty( $address['country'] ) ? $address['country'] : null; + }, + ), + 'email' => array( + 'type' => 'String', + 'description' => __( 'E-mail', 'wp-graphql-woocommerce' ), + 'resolve' => function( $address ) { + return ! empty( $address['email'] ) ? $address['email'] : null; + }, + ), + 'phone' => array( + 'type' => 'String', + 'description' => __( 'Phone', 'wp-graphql-woocommerce' ), + 'resolve' => function( $address ) { + return ! empty( $address['phone'] ) ? $address['phone'] : null; + }, + ), + ), + ) + ); + } +} diff --git a/src/type/object/class-customer-type.php b/src/type/object/class-customer-type.php new file mode 100644 index 00000000..426a1863 --- /dev/null +++ b/src/type/object/class-customer-type.php @@ -0,0 +1,177 @@ + __( 'A customer object', 'wp-graphql-woocommerce' ), + 'interfaces' => [ WPObjectType::node_interface() ], + 'fields' => array( + 'id' => array( + 'type' => array( 'non_null' => 'ID' ), + 'description' => __( 'The globally unique identifier for the customer', 'wp-graphql-woocommerce' ), + ), + 'customerId' => array( + 'type' => 'Int', + 'description' => __( 'The Id of the user. Equivalent to WP_User->ID', 'wp-graphql-woocommerce' ), + ), + 'isVatExempt' => array( + 'type' => 'Boolean', + 'description' => __( 'Is customer VAT exempt?', 'wp-graphql-woocommerce' ), + ), + 'hasCalculatedShipping' => array( + 'type' => 'Boolean', + 'description' => __( 'Has calculated shipping?', 'wp-graphql-woocommerce' ), + ), + 'calculatedShipping' => array( + 'type' => 'Boolean', + 'description' => __( 'Has customer calculated shipping?', 'wp-graphql-woocommerce' ), + ), + 'lastOrder' => array( + 'type' => 'Order', + 'description' => __( 'Gets the customers last order.', 'wp-graphql-woocommerce' ), + 'resolve' => function( $source, array $args, AppContext $context ) { + return Factory::resolve_crud_object( $source->last_order_id, $context ); + }, + ), + 'orderCount' => array( + 'type' => 'Int', + 'description' => __( 'Return the number of orders this customer has.', 'wp-graphql-woocommerce' ), + ), + 'totalSpent' => array( + 'type' => 'Float', + 'description' => __( 'Return how much money this customer has spent.', 'wp-graphql-woocommerce' ), + ), + 'username' => array( + 'type' => 'String', + 'description' => __( 'Return the customer\'s username.', 'wp-graphql-woocommerce' ), + ), + 'email' => array( + 'type' => 'String', + 'description' => __( 'Return the customer\'s email.', 'wp-graphql-woocommerce' ), + ), + 'firstName' => array( + 'type' => 'String', + 'description' => __( 'Return the customer\'s first name.', 'wp-graphql-woocommerce' ), + ), + 'lastName' => array( + 'type' => 'String', + 'description' => __( 'Return the customer\'s last name.', 'wp-graphql-woocommerce' ), + ), + 'displayName' => array( + 'type' => 'String', + 'description' => __( 'Return the customer\'s display name.', 'wp-graphql-woocommerce' ), + ), + 'role' => array( + 'type' => 'String', + 'description' => __( 'Return the customer\'s user role.', 'wp-graphql-woocommerce' ), + ), + 'date' => array( + 'type' => 'String', + 'description' => __( 'Return the date customer was created', 'wp-graphql-woocommerce' ), + ), + 'modified' => array( + 'type' => 'String', + 'description' => __( 'Return the date customer was last updated', 'wp-graphql-woocommerce' ), + ), + 'billing' => array( + 'type' => 'CustomerAddress', + 'description' => __( 'Return the date customer billing address properties', 'wp-graphql-woocommerce' ), + ), + 'shipping' => array( + 'type' => 'CustomerAddress', + 'description' => __( 'Return the date customer shipping address properties', 'wp-graphql-woocommerce' ), + ), + 'isPayingCustomer' => array( + 'type' => 'Boolean', + '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; + }, + ) + ); + + register_graphql_field( + 'RootQuery', + 'customer', + array( + 'type' => 'Customer', + 'description' => __( 'A customer object', 'wp-graphql-woocommerce' ), + 'args' => array( + 'id' => array( + 'type' => array( 'non_null' => 'ID' ), + ), + ), + 'resolve' => function ( $source, array $args, AppContext $context, ResolveInfo $info ) { + $id_components = Relay::fromGlobalId( $args['id'] ); + if ( ! isset( $id_components['id'] ) || ! absint( $id_components['id'] ) ) { + throw new UserError( __( 'The ID input is invalid', 'wp-graphql-woocommerce' ) ); + } + + $customer_id = absint( $id_components['id'] ); + return Factory::resolve_customer( $customer_id, $context ); + }, + ) + ); + + register_graphql_field( + 'RootQuery', + 'customerBy', + array( + 'type' => 'Customer', + 'description' => __( 'A customer object', 'wp-graphql-woocommerce' ), + 'args' => array( + 'customerId' => array( + 'type' => array( 'non_null' => 'Int' ), + 'description' => __( 'Get the customer by their database ID', 'wp-graphql-woocommerce' ), + ), + ), + 'resolve' => function ( $source, array $args, AppContext $context, ResolveInfo $info ) { + if ( empty( $args['customerId'] ) ) { + throw new UserError( __( 'customerId must be provided and it must be an integer value', 'wp-graphql-woocommerce' ) ); + } + $customer_id = absint( $args['customerId'] ); + return Factory::resolve_customer( $customer_id, $context ); + }, + ) + ); + } +} diff --git a/src/type/object/class-order-type.php b/src/type/object/class-order-type.php new file mode 100644 index 00000000..4f434b38 --- /dev/null +++ b/src/type/object/class-order-type.php @@ -0,0 +1,290 @@ + __( 'A order object', 'wp-graphql-woocommerce' ), + 'interfaces' => [ WPObjectType::node_interface() ], + 'fields' => array( + 'id' => array( + 'type' => array( 'non_null' => 'ID' ), + 'description' => __( 'The globally unique identifier for the order', 'wp-graphql-woocommerce' ), + ), + 'orderId' => array( + 'type' => 'Int', + 'description' => __( 'The Id of the order. Equivalent to WP_Post->ID', 'wp-graphql-woocommerce' ), + ), + 'orderKey' => array( + 'type' => 'String', + 'description' => __( 'Order key', 'wp-graphql-woocommerce' ), + ), + 'date' => array( + 'type' => 'String', + 'description' => __( 'Date order was created', 'wp-graphql-woocommerce' ), + ), + 'modified' => array( + 'type' => 'String', + 'description' => __( 'Date order was last updated', 'wp-graphql-woocommerce' ), + ), + 'currency' => array( + 'type' => 'String', + 'description' => __( 'Order currency', 'wp-graphql-woocommerce' ), + ), + 'paymentMethod' => array( + 'type' => 'String', + 'description' => __( 'Payment method', 'wp-graphql-woocommerce' ), + ), + 'paymentMethodTitle' => array( + 'type' => 'String', + 'description' => __( 'Payment method title', 'wp-graphql-woocommerce' ), + ), + 'transactionId' => array( + 'type' => 'String', + 'description' => __( 'Transaction ID', 'wp-graphql-woocommerce' ), + ), + 'customerIpAddress' => array( + 'type' => 'String', + 'description' => __( 'Customer IP Address', 'wp-graphql-woocommerce' ), + ), + 'customerUserAgent' => array( + 'type' => 'String', + 'description' => __( 'Customer User Agent', 'wp-graphql-woocommerce' ), + ), + 'createdVia' => array( + 'type' => 'String', + 'description' => __( 'How order was created', 'wp-graphql-woocommerce' ), + ), + 'dateCompleted' => array( + 'type' => 'String', + 'description' => __( 'Date order was completed', 'wp-graphql-woocommerce' ), + ), + 'datePaid' => array( + 'type' => 'String', + 'description' => __( 'Date order was paid', 'wp-graphql-woocommerce' ), + ), + 'discountTotal' => array( + 'type' => 'Float', + 'description' => __( 'Discount total amount', 'wp-graphql-woocommerce' ), + ), + 'discountTax' => array( + 'type' => 'Float', + 'description' => __( 'Discount tax amount', 'wp-graphql-woocommerce' ), + ), + 'shippingTotal' => array( + 'type' => 'Float', + 'description' => __( 'Shipping total amount', 'wp-graphql-woocommerce' ), + ), + 'shippingTax' => array( + 'type' => 'Float', + 'description' => __( 'Shipping tax amount', 'wp-graphql-woocommerce' ), + ), + 'cartTax' => array( + 'type' => 'Float', + 'description' => __( 'Cart tax amount', 'wp-graphql-woocommerce' ), + ), + 'total' => array( + 'type' => 'Float', + 'description' => __( 'Order grand total', 'wp-graphql-woocommerce' ), + ), + 'totalTax' => array( + 'type' => 'Float', + 'description' => __( 'Order taxes', 'wp-graphql-woocommerce' ), + ), + 'subtotal' => array( + 'type' => 'Float', + 'description' => __( 'Order subtotal', 'wp-graphql-woocommerce' ), + ), + 'orderNumber' => array( + 'type' => 'String', + 'description' => __( 'Order number', 'wp-graphql-woocommerce' ), + ), + 'orderVersion' => array( + 'type' => 'String', + 'description' => __( 'Order version', 'wp-graphql-woocommerce' ), + ), + 'pricesIncludeTax' => array( + 'type' => 'Boolean', + 'description' => __( 'Prices include taxes?', 'wp-graphql-woocommerce' ), + ), + 'cartHash' => array( + 'type' => 'String', + 'description' => __( 'Cart hash', 'wp-graphql-woocommerce' ), + ), + 'customerNote' => array( + 'type' => 'String', + 'description' => __( 'Customer note', 'wp-graphql-woocommerce' ), + ), + 'isDownloadPermitted' => array( + 'type' => 'Boolean', + 'description' => __( 'Is product download is permitted', 'wp-graphql-woocommerce' ), + ), + 'billing' => array( + 'type' => 'CustomerAddress', + 'description' => __( 'Order billing properties', 'wp-graphql-woocommerce' ), + ), + 'shipping' => array( + 'type' => 'CustomerAddress', + 'description' => __( 'Order shipping properties', 'wp-graphql-woocommerce' ), + ), + 'status' => array( + 'type' => 'String', + 'description' => __( 'Order status', 'wp-graphql-woocommerce' ), + ), + 'parent' => array( + 'type' => 'Order', + 'description' => __( 'Parent order', 'wp-graphql-woocommerce' ), + 'resolve' => function( $order, array $args, AppContext $context ) { + return Factory::resolve_crud_object( $order->parent, $context ); + }, + ), + 'customer' => array( + 'type' => 'Customer', + 'description' => __( 'Order customer', 'wp-graphql-woocommerce' ), + 'resolve' => function( $order, array $args, AppContext $context ) { + return Factory::resolve_customer( $order->customer_id, $context ); + }, + ), + 'shippingAddressMapUrl' => array( + 'type' => 'String', + 'description' => __( 'Order customer', 'wp-graphql-woocommerce' ), + ), + 'hasBillingAddress' => array( + 'type' => 'Boolean', + 'description' => __( 'Order has a billing address?', 'wp-graphql-woocommerce' ), + ), + 'hasShippingAddress' => array( + 'type' => 'Boolean', + 'description' => __( 'Order has a shipping address?', 'wp-graphql-woocommerce' ), + ), + 'needsShippingAddress' => array( + 'type' => 'Boolean', + 'description' => __( 'If order needs shipping address', 'wp-graphql-woocommerce' ), + ), + 'hasDownloadableItem' => array( + 'type' => 'Boolean', + 'description' => __( 'If order contains a downloadable product', 'wp-graphql-woocommerce' ), + ), + 'needsPayment' => array( + 'type' => 'Boolean', + 'description' => __( 'If order needs payment', 'wp-graphql-woocommerce' ), + ), + 'needsProcessing' => array( + 'type' => 'Boolean', + 'description' => __( 'If order needs processing before it can be completed', '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; + }, + ) + ); + + register_graphql_field( + 'RootQuery', + 'order', + array( + 'type' => 'Order', + 'description' => __( 'A order object', 'wp-graphql-woocommerce' ), + 'args' => array( + 'id' => array( + 'type' => array( + 'non_null' => 'ID', + ), + ), + ), + 'resolve' => function ( $source, array $args, AppContext $context, ResolveInfo $info ) { + $id_components = Relay::fromGlobalId( $args['id'] ); + if ( ! isset( $id_components['id'] ) || ! absint( $id_components['id'] ) ) { + throw new UserError( __( 'The ID input is invalid', 'wp-graphql-woocommerce' ) ); + } + $order_id = absint( $id_components['id'] ); + return Factory::resolve_crud_object( $order_id, $context ); + }, + ) + ); + + $post_by_args = array( + 'id' => array( + 'type' => 'ID', + 'description' => __( 'Get the order by its global ID', 'wp-graphql-woocommerce' ), + ), + 'orderId' => array( + 'type' => 'Int', + 'description' => __( 'Get the order by its database ID', 'wp-graphql-woocommerce' ), + ), + 'orderNumber' => array( + 'type' => 'String', + 'description' => __( 'Get the order by its order number', 'wp-graphql-woocommerce' ), + ), + ); + + register_graphql_field( + 'RootQuery', + 'orderBy', + array( + 'type' => 'Order', + 'description' => __( 'A order object', 'wp-graphql-woocommerce' ), + 'args' => $post_by_args, + 'resolve' => function ( $source, array $args, AppContext $context, ResolveInfo $info ) { + $order_id = 0; + if ( ! empty( $args['id'] ) ) { + $id_components = Relay::fromGlobalId( $args['id'] ); + if ( empty( $id_components['id'] ) || empty( $id_components['type'] ) ) { + throw new UserError( __( 'The "id" is invalid', 'wp-graphql-woocommerce' ) ); + } + $order_id = absint( $id_components['id'] ); + } elseif ( ! empty( $args['orderId'] ) ) { + $order_id = absint( $args['orderId'] ); + } elseif ( ! empty( $args['orderNumber'] ) ) { + $order_id = 0; + } + + $order = Factory::resolve_crud_object( $order_id, $context ); + if ( get_post( $order_id )->post_type !== 'shop_order' ) { + /* translators: not order found error message */ + throw new UserError( sprintf( __( 'No order exists with this id: %1$s' ), $order_id ) ); + } + + return $order; + }, + ) + ); + } +} diff --git a/src/type/object/class-product-attribute-type.php b/src/type/object/class-product-attribute-type.php new file mode 100644 index 00000000..ab23c1fe --- /dev/null +++ b/src/type/object/class-product-attribute-type.php @@ -0,0 +1,84 @@ + __( 'A product attribute object', 'wp-graphql-woocommerce' ), + 'fields' => array( + 'attributeId' => array( + 'type' => array( 'non_null' => 'Int' ), + 'description' => __( 'Attribute ID', 'wp-graphql-woocommerce' ), + 'resolve' => function ( $attribute ) { + return ! empty( $attribute ) ? $attribute->get_id() : null; + }, + ), + 'name' => array( + 'type' => array( 'non_null' => 'String' ), + 'description' => __( 'Attribute name', 'wp-graphql-woocommerce' ), + 'resolve' => function ( $attribute ) { + return ! empty( $attribute ) ? $attribute->get_name() : null; + }, + ), + 'options' => array( + 'type' => array( 'list_of' => 'String' ), + 'description' => __( 'Attribute options', 'wp-graphql-woocommerce' ), + 'resolve' => function ( $attribute ) { + if ( empty( $attribute ) ) { + return null; + } + if ( ! $attribute->is_taxonomy() || ! taxonomy_exists( $attribute->get_name() ) ) { + return null; + } + $options = array(); + foreach ( $attribute->get_options() as $option ) { + $options[] = get_term_by( 'id', $option, $attribute->get_name() )->name; + } + return $options; + }, + ), + 'position' => array( + 'type' => array( 'non_null' => 'Int' ), + 'description' => __( 'Attribute position', 'wp-graphql-woocommerce' ), + 'resolve' => function ( $attribute ) { + return ! empty( $attribute ) ? $attribute->get_position() : null; + }, + ), + 'visible' => array( + 'type' => array( 'non_null' => 'Boolean' ), + 'description' => __( 'Is attribute visible', 'wp-graphql-woocommerce' ), + 'resolve' => function ( $attribute ) { + return ! empty( $attribute ) ? $attribute->get_visible() : null; + }, + ), + 'variation' => array( + 'type' => array( 'non_null' => 'Boolean' ), + 'description' => __( 'Is attribute on product variation', 'wp-graphql-woocommerce' ), + 'resolve' => function ( $attribute ) { + return ! empty( $attribute ) ? $attribute->get_variation() : null; + }, + ), + ), + ) + ); + } +} diff --git a/src/type/object/class-product-download-type.php b/src/type/object/class-product-download-type.php new file mode 100644 index 00000000..528560e6 --- /dev/null +++ b/src/type/object/class-product-download-type.php @@ -0,0 +1,90 @@ + __( 'A product object', 'wp-graphql-woocommerce' ), + 'fields' => array( + 'downloadId' => array( + 'type' => array( 'non_null' => 'Int' ), + 'description' => __( 'Product download ID', 'wp-graphql-woocommerce' ), + 'resolve' => function ( $download ) { + return ! empty( $download ) ? $download->get_id() : null; + }, + ), + 'name' => array( + 'type' => 'String', + 'description' => __( 'Product download name', 'wp-graphql-woocommerce' ), + 'resolve' => function ( $download ) { + return ! empty( $download ) ? $download->get_name() : null; + }, + ), + 'filePathType' => array( + 'type' => 'String', + 'description' => __( 'Type of file path set', 'wp-graphql-woocommerce' ), + 'resolve' => function ( $download ) { + return ! empty( $download ) ? $download->get_type_of_file_path() : null; + }, + ), + 'fileType' => array( + 'type' => 'String', + 'description' => __( 'File type', 'wp-graphql-woocommerce' ), + 'resolve' => function ( $download ) { + return ! empty( $download ) ? $download->get_file_type() : null; + }, + ), + 'fileExt' => array( + 'type' => 'String', + 'description' => __( 'File extension', 'wp-graphql-woocommerce' ), + 'resolve' => function ( $download ) { + return ! empty( $download ) ? $download->get_file_extension() : null; + }, + ), + 'allowedFileType' => array( + 'type' => 'Boolean', + 'description' => __( 'Is file allowed', 'wp-graphql-woocommerce' ), + 'resolve' => function ( $download ) { + return ! empty( $download ) ? $download->is_allowed_filetype() : null; + }, + ), + 'fileExists' => array( + 'type' => 'Boolean', + 'description' => __( 'Validate file exists', 'wp-graphql-woocommerce' ), + 'resolve' => function ( $download ) { + return ! empty( $download ) ? $download->file_exists() : null; + }, + ), + 'file' => array( + 'type' => 'String', + 'description' => __( 'Download file', 'wp-graphql-woocommerce' ), + 'resolve' => function ( $download ) { + return ! empty( $download ) ? $download->get_file() : null; + }, + ), + ), + ) + ); + } +} diff --git a/src/type/object/class-product-rating-counter-type.php b/src/type/object/class-product-rating-counter-type.php new file mode 100644 index 00000000..ac870160 --- /dev/null +++ b/src/type/object/class-product-rating-counter-type.php @@ -0,0 +1,82 @@ + __( 'A product rating counter', 'wp-graphql-woocommerce' ), + 'fields' => array( + 'fiveStars' => array( + 'type' => 'Int', + 'description' => __( 'Product\'s number of 5-star ratings', 'wp-graphql-woocommerce' ), + 'resolve' => function( $source ) { + return isset( $source[5] ) ? $source[5] : 0; + }, + ), + 'fourStars' => array( + 'type' => 'Int', + 'description' => __( 'Product\'s number of 4-star ratings', 'wp-graphql-woocommerce' ), + 'resolve' => function( $source ) { + return isset( $source[4] ) ? $source[4] : 0; + }, + ), + 'threeStars' => array( + 'type' => 'Int', + 'description' => __( 'Product\'s number of 3-star ratings', 'wp-graphql-woocommerce' ), + 'resolve' => function( $source ) { + return isset( $source[3] ) ? $source[3] : 0; + }, + ), + 'twoStars' => array( + 'type' => 'Int', + 'description' => __( 'Product\'s number of 2-star ratings', 'wp-graphql-woocommerce' ), + 'resolve' => function( $source ) { + return isset( $source[2] ) ? $source[2] : 0; + }, + ), + 'oneStars' => array( + 'type' => 'Int', + 'description' => __( 'Product\'s number of 1-star ratings', 'wp-graphql-woocommerce' ), + 'resolve' => function( $source ) { + return isset( $source[1] ) ? $source[1] : 0; + }, + ), + 'average' => array( + 'type' => 'Float', + 'description' => __( 'Product\'s rating average', 'wp-graphql-woocommerce' ), + 'resolve' => function( $source ) { + $count = 0; + $total = 0; + foreach ( $source as $grade => $num ) { + $count += $num; + $total += absint( $grade ) * $num; + } + return ! empty( $count ) ? min( 5, round( $total / $count, 2 ) ) : 0; + }, + ), + ), + ) + ); + } +} diff --git a/src/type/object/class-product-type.php b/src/type/object/class-product-type.php new file mode 100644 index 00000000..a714e852 --- /dev/null +++ b/src/type/object/class-product-type.php @@ -0,0 +1,334 @@ + __( 'A product object', 'wp-graphql-woocommerce' ), + 'interfaces' => [ WPObjectType::node_interface() ], + 'fields' => array( + 'id' => array( + 'type' => array( 'non_null' => 'ID' ), + 'description' => __( 'The globally unique identifier for the product', 'wp-graphql-woocommerce' ), + ), + 'productId' => array( + 'type' => 'Int', + 'description' => __( 'The Id of the order. Equivalent to WP_Post->ID', 'wp-graphql-woocommerce' ), + ), + 'slug' => array( + 'type' => 'String', + 'description' => __( 'Product slug', 'wp-graphql-woocommerce' ), + ), + 'date' => array( + 'type' => 'String', + 'description' => __( 'Date product created', 'wp-graphql-woocommerce' ), + ), + 'modified' => array( + 'type' => 'String', + 'description' => __( 'Date product last updated', 'wp-graphql-woocommerce' ), + ), + 'type' => array( + 'type' => 'String', + 'description' => __( 'Product type', 'wp-graphql-woocommerce' ), + ), + 'name' => array( + 'type' => 'String', + 'description' => __( 'Product name', 'wp-graphql-woocommerce' ), + ), + 'status' => array( + 'type' => 'String', + 'description' => __( 'Product status', 'wp-graphql-woocommerce' ), + ), + 'featured' => array( + 'type' => 'Boolean', + 'description' => __( 'If the product is featured', 'wp-graphql-woocommerce' ), + ), + 'catalogVisibility' => array( + 'type' => 'CatalogVisibilityEnum', + 'description' => __( 'Catalog visibility', 'wp-graphql-woocommerce' ), + ), + 'description' => array( + 'type' => 'String', + 'description' => __( 'Product description', 'wp-graphql-woocommerce' ), + ), + 'shortDescription' => array( + 'type' => 'String', + 'description' => __( 'Product short description', 'wp-graphql-woocommerce' ), + ), + 'sku' => array( + 'type' => 'String', + 'description' => __( 'Product SKU', 'wp-graphql-woocommerce' ), + ), + 'price' => array( + 'type' => 'String', + 'args' => array( + 'max' => array( + 'type' => 'Boolean', + 'description' => __( 'Show maximum price (Variable type product)', 'wp-graphql-woocommerce' ), + ), + ), + 'description' => __( 'Product\'s active price', 'wp-graphql-woocommerce' ), + 'resolve' => function( $product, array $args ) { + if ( ! empty( $args['max'] ) && $args['max'] ) { + // @codingStandardsIgnoreLine + return $product->priceMax; + } + // @codingStandardsIgnoreLine + return $product->price; + }, + ), + 'regularPrice' => array( + 'type' => 'String', + 'args' => array( + 'max' => array( + 'type' => 'Boolean', + 'description' => __( 'Show maximum price (Variable type product)', 'wp-graphql-woocommerce' ), + ), + ), + 'description' => __( 'Product\'s regular price', 'wp-graphql-woocommerce' ), + 'resolve' => function( $product, array $args ) { + if ( ! empty( $args['max'] ) && $args['max'] ) { + // @codingStandardsIgnoreLine + return $product->regularPriceMax; + } + // @codingStandardsIgnoreLine + return $product->regularPrice; + }, + ), + 'salePrice' => array( + 'type' => 'String', + 'args' => array( + 'max' => array( + 'type' => 'Boolean', + 'description' => __( 'Show maximum price (Variable type product)', 'wp-graphql-woocommerce' ), + ), + ), + 'description' => __( 'Product\'s sale price', 'wp-graphql-woocommerce' ), + 'resolve' => function( $product, array $args ) { + if ( ! empty( $args['max'] ) && $args['max'] ) { + // @codingStandardsIgnoreLine + return $product->salePriceMax; + } + // @codingStandardsIgnoreLine + return $product->salePrice; + }, + ), + 'dateOnSaleFrom' => array( + 'type' => 'String', + 'description' => __( 'Date on sale from', 'wp-graphql-woocommerce' ), + ), + 'dateOnSaleTo' => array( + 'type' => 'String', + 'description' => __( 'Date on sale to', 'wp-graphql-woocommerce' ), + ), + 'totalSales' => array( + 'type' => 'Int', + 'description' => __( 'Number total of sales', 'wp-graphql-woocommerce' ), + ), + 'taxStatus' => array( + 'type' => 'TaxStatusEnum', + 'description' => __( 'Tax status', 'wp-graphql-woocommerce' ), + ), + 'taxClass' => array( + 'type' => 'String', + 'description' => __( 'Tax class', 'wp-graphql-woocommerce' ), + ), + 'manageStock' => array( + 'type' => 'Boolean', + 'description' => __( 'If product manage stock', 'wp-graphql-woocommerce' ), + ), + 'stockQuantity' => array( + 'type' => 'Int', + 'description' => __( 'Number of items available for sale', 'wp-graphql-woocommerce' ), + ), + 'stockStatus' => array( + 'type' => 'StockStatusEnum', + 'description' => __( 'Product stock status', 'wp-graphql-woocommerce' ), + ), + 'backorders' => array( + 'type' => 'BackordersEnum', + 'description' => __( 'Product backorders status', 'wp-graphql-woocommerce' ), + ), + 'soldIndividually' => array( + 'type' => 'Boolean', + 'description' => __( 'If should be sold individually', 'wp-graphql-woocommerce' ), + ), + 'weight' => array( + 'type' => 'String', + 'description' => __( 'Product\'s weight', 'wp-graphql-woocommerce' ), + ), + 'length' => array( + 'type' => 'String', + 'description' => __( 'Product\'s length', 'wp-graphql-woocommerce' ), + ), + 'width' => array( + 'type' => 'String', + 'description' => __( 'Product\'s width', 'wp-graphql-woocommerce' ), + ), + 'height' => array( + 'type' => 'String', + 'description' => __( 'Product\'s height', 'wp-graphql-woocommerce' ), + ), + 'reviewsAllowed' => array( + 'type' => 'Boolean', + 'description' => __( 'If reviews are allowed', 'wp-graphql-woocommerce' ), + ), + 'purchaseNote' => array( + 'type' => 'String', + 'description' => __( 'Purchase note', 'wp-graphql-woocommerce' ), + ), + 'menuOrder' => array( + 'type' => 'Int', + 'description' => __( 'Menu order', 'wp-graphql-woocommerce' ), + ), + 'virtual' => array( + 'type' => 'Boolean', + 'description' => __( 'Is product virtual?', 'wp-graphql-woocommerce' ), + ), + 'downloadExpiry' => array( + 'type' => 'Int', + 'description' => __( 'Download expiry', 'wp-graphql-woocommerce' ), + ), + 'downloadable' => array( + 'type' => 'Boolean', + 'description' => __( 'Is downloadable?', 'wp-graphql-woocommerce' ), + ), + 'downloadLimit' => array( + 'type' => 'Int', + 'description' => __( 'Download limit', 'wp-graphql-woocommerce' ), + ), + 'ratingCount' => array( + 'type' => 'RatingCounter', + 'description' => __( 'Product rating counts', 'wp-graphql-woocommerce' ), + ), + 'averageRating' => array( + 'type' => 'Float', + 'description' => __( 'Product average count', 'wp-graphql-woocommerce' ), + ), + 'reviewCount' => array( + 'type' => 'Int', + 'description' => __( 'Product review count', 'wp-graphql-woocommerce' ), + ), + 'parentId' => array( + 'type' => 'Int', + 'description' => __( 'Parent product ID', 'wp-graphql-woocommerce' ), + ), + 'parent' => array( + 'type' => 'Product', + 'description' => __( 'Parent product', 'wp-graphql-woocommerce' ), + ), + 'image' => array( + 'type' => 'MediaItem', + 'description' => __( 'Main image', 'wp-graphql-woocommerce' ), + ), + 'shippingClassId' => array( + 'type' => 'Int', + 'description' => __( 'shipping class ID', '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; + }, + ) + ); + + register_graphql_field( + 'RootQuery', + 'product', + array( + 'type' => 'Product', + 'description' => __( 'A product object', 'wp-graphql-woocommerce' ), + 'args' => array( + 'id' => array( + 'type' => array( 'non_null' => 'ID' ), + ), + ), + 'resolve' => function ( $source, array $args, AppContext $context, ResolveInfo $info ) { + $id_components = Relay::fromGlobalId( $args['id'] ); + if ( ! isset( $id_components['id'] ) || ! absint( $id_components['id'] ) ) { + throw new UserError( __( 'The ID input is invalid', 'wp-graphql-woocommerce' ) ); + } + $product_id = absint( $id_components['id'] ); + return Factory::resolve_crud_object( $product_id, $context ); + }, + ) + ); + + $post_by_args = array( + 'id' => array( + 'type' => 'ID', + 'description' => __( 'Get the product by its global ID', 'wp-graphql-woocommerce' ), + ), + 'productId' => array( + 'type' => 'Int', + 'description' => __( 'Get the product by its database ID', 'wp-graphql-woocommerce' ), + ), + ); + + register_graphql_field( + 'RootQuery', + 'productBy', + array( + 'type' => 'Product', + 'description' => __( 'A product object', 'wp-graphql-woocommerce' ), + 'args' => $post_by_args, + 'resolve' => function ( $source, array $args, AppContext $context, ResolveInfo $info ) { + $product_id = 0; + if ( ! empty( $args['id'] ) ) { + $id_components = Relay::fromGlobalId( $args['id'] ); + if ( empty( $id_components['id'] ) || empty( $id_components['type'] ) ) { + throw new UserError( __( 'The "id" is invalid', 'wp-graphql-woocommerce' ) ); + } + $product_id = absint( $id_components['id'] ); + } elseif ( ! empty( $args['productId'] ) ) { + $product_id = absint( $args['productId'] ); + } + + $product = Factory::resolve_crud_object( $product_id, $context ); + if ( get_post( $product_id )->post_type !== 'product' ) { + /* translators: not coupon found error message */ + throw new UserError( sprintf( __( 'No product exists with this id: %1$s' ), $args['id'] ) ); + } + + return $product; + }, + ) + ); + } +} diff --git a/src/type/object/class-product-variation-type.php b/src/type/object/class-product-variation-type.php new file mode 100644 index 00000000..96e5b80c --- /dev/null +++ b/src/type/object/class-product-variation-type.php @@ -0,0 +1,175 @@ + __( 'A product variation object', 'wp-graphql-woocommerce' ), + 'interfaces' => [ WPObjectType::node_interface() ], + 'fields' => array( + 'id' => array( + 'type' => array( 'non_null' => 'ID' ), + 'description' => __( 'The globally unique identifier for the product variation', 'wp-graphql-woocommerce' ), + ), + 'variationId' => array( + 'type' => 'Int', + 'description' => __( 'The Id of the order. Equivalent to WP_Post->ID', 'wp-graphql-woocommerce' ), + ), + 'sku' => array( + 'type' => 'String', + 'description' => __( 'Product variation SKU (Stock-keeping unit)', 'wp-graphql-woocommerce' ), + ), + 'weight' => array( + 'type' => 'String', + 'description' => __( 'Product variation weight', 'wp-graphql-woocommerce' ), + ), + 'length' => array( + 'type' => 'String', + 'description' => __( 'Product variation length', 'wp-graphql-woocommerce' ), + ), + 'width' => array( + 'type' => 'String', + 'description' => __( 'Product variation width', 'wp-graphql-woocommerce' ), + ), + 'height' => array( + 'type' => 'String', + 'description' => __( 'Product variation height', 'wp-graphql-woocommerce' ), + ), + 'taxClass' => array( + 'type' => 'String', + 'description' => __( 'Product variation tax class', 'wp-graphql-woocommerce' ), + ), + 'manageStock' => array( + 'type' => 'ManageStockEnum', + 'description' => __( 'if/how product variation stock is managed', 'wp-graphql-woocommerce' ), + ), + 'stockQuantity' => array( + 'type' => 'Int', + 'description' => __( 'Product variation stock quantity', 'wp-graphql-woocommerce' ), + ), + 'backorders' => array( + 'type' => 'String', + 'description' => __( 'Product variation backorders', 'wp-graphql-woocommerce' ), + ), + 'image' => array( + 'type' => 'MediaItem', + 'description' => __( 'Product variation main image', 'wp-graphql-woocommerce' ), + ), + 'purchaseNote' => array( + 'type' => 'String', + 'description' => __( 'Product variation purchase_note', 'wp-graphql-woocommerce' ), + ), + 'shippingClass' => array( + 'type' => 'String', + 'description' => __( 'Product variation shipping class', 'wp-graphql-woocommerce' ), + ), + 'catalogVisibility' => array( + 'type' => 'String', + 'description' => __( 'Product variation catalog visibility', 'wp-graphql-woocommerce' ), + ), + 'hasAttributes' => array( + 'type' => 'Boolean', + 'description' => __( 'Does product variation have any visible attributes', 'wp-graphql-woocommerce' ), + ), + 'isPurchasable' => array( + 'type' => 'Boolean', + 'description' => __( 'If product variation can be bought', 'wp-graphql-woocommerce' ), + ), + 'price' => array( + 'type' => 'String', + 'description' => __( 'Product variation\'s active price', 'wp-graphql-woocommerce' ), + ), + 'regularPrice' => array( + 'type' => 'String', + 'description' => __( 'Product variation\'s regular price', 'wp-graphql-woocommerce' ), + ), + 'salePrice' => array( + 'type' => 'String', + 'description' => __( 'Product variation\'s sale price', 'wp-graphql-woocommerce' ), + ), + ), + '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; + }, + ) + ); + + register_graphql_field( + 'RootQuery', + 'productVariation', + array( + 'type' => 'ProductVariation', + 'description' => __( 'A product variation object', 'wp-graphql-woocommerce' ), + 'args' => array( + 'id' => array( + 'type' => array( 'non_null' => 'ID' ), + 'description' => __( 'Get the product variation by its global ID', 'wp-graphql-woocommerce' ), + ), + 'variationId' => array( + 'type' => 'Int', + 'description' => __( 'Get the product variation by its database ID', 'wp-graphql-woocommerce' ), + ), + ), + 'resolve' => function ( $source, array $args, AppContext $context, ResolveInfo $info ) { + $variation_id = 0; + if ( ! empty( $args['id'] ) ) { + $id_components = Relay::fromGlobalId( $args['id'] ); + if ( empty( $id_components['id'] ) || empty( $id_components['type'] ) ) { + throw new UserError( __( 'The "id" is invalid', 'wp-graphql-woocommerce' ) ); + } + + $arg = 'ID'; + $variation_id = absint( $id_components['id'] ); + } elseif ( ! empty( $args['variationId'] ) ) { + $arg = 'database ID'; + $variation_id = absint( $args['variationId'] ); + } + + $variation = Factory::resolve_crud_object( $variation_id, $context ); + if ( get_post( $variation_id )->post_type !== 'variation' ) { + /* translators: not coupon found error message */ + throw new UserError( sprintf( __( 'No product exists with this %1$s: %2$s' ), $arg, $args['id'] ) ); + } + + return $product; + }, + ) + ); + } +} diff --git a/src/type/object/class-refund-type.php b/src/type/object/class-refund-type.php new file mode 100644 index 00000000..6405ea80 --- /dev/null +++ b/src/type/object/class-refund-type.php @@ -0,0 +1,152 @@ + __( 'A refund object', 'wp-graphql-woocommerce' ), + 'interfaces' => [ WPObjectType::node_interface() ], + 'fields' => array( + 'id' => array( + 'type' => array( 'non_null' => 'ID' ), + 'description' => __( 'The globally unique identifier for the refund', 'wp-graphql-woocommerce' ), + ), + 'refundId' => array( + 'type' => 'Int', + 'description' => __( 'The Id of the order. Equivalent to WP_Post->ID', 'wp-graphql-woocommerce' ), + ), + 'title' => array( + 'type' => 'String', + 'description' => __( 'A title for the new post type', 'wp-graphql-woocommerce' ), + ), + 'amount' => array( + 'type' => 'Float', + 'description' => __( 'Refunded amount', 'wp-graphql-woocommerce' ), + ), + 'reason' => array( + 'type' => 'String', + 'description' => __( 'Reason for refund', 'wp-graphql-woocommerce' ), + ), + 'refundedBy' => array( + 'type' => 'User', + 'description' => __( 'User who completed the refund', 'wp-graphql-woocommerce' ), + 'resolve' => function( $source, array $args, AppContext $context ) { + return DataSource::resolve_user( $source->refunded_by_id, $context ); + }, + ), + ), + '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; + }, + ) + ); + + register_graphql_field( + 'RootQuery', + 'refund', + array( + 'type' => 'Refund', + 'description' => __( 'A refund object', 'wp-graphql-woocommerce' ), + 'args' => array( + 'id' => array( + 'type' => array( + 'non_null' => 'ID', + ), + ), + ), + 'resolve' => function ( $source, array $args, AppContext $context, ResolveInfo $info ) { + $id_components = Relay::fromGlobalId( $args['id'] ); + if ( ! isset( $id_components['id'] ) || ! absint( $id_components['id'] ) ) { + throw new UserError( __( 'The ID input is invalid', 'wp-graphql-woocommerce' ) ); + } + $refund_id = absint( $id_components['id'] ); + return Factory::resolve_crud_object( $refund_id, $context ); + }, + ) + ); + + $post_by_args = array( + 'id' => array( + 'type' => 'ID', + 'description' => __( 'Get the refund by its global ID', 'wp-graphql-woocommerce' ), + ), + 'refundId' => array( + 'type' => 'Int', + 'description' => __( 'Get the refund by its database ID', 'wp-graphql-woocommerce' ), + ), + 'orderNumber' => array( + 'type' => 'String', + 'description' => __( 'Get the refund by its order number', 'wp-graphql-woocommerce' ), + ), + ); + + register_graphql_field( + 'RootQuery', + 'refundBy', + array( + 'type' => 'Refund', + 'description' => __( 'A refund object', 'wp-graphql-woocommerce' ), + 'args' => $post_by_args, + 'resolve' => function ( $source, array $args, AppContext $context, ResolveInfo $info ) { + $refund_id = 0; + if ( ! empty( $args['id'] ) ) { + $id_components = Relay::fromGlobalId( $args['id'] ); + if ( empty( $id_components['id'] ) || empty( $id_components['type'] ) ) { + throw new UserError( __( 'The "id" is invalid', 'wp-graphql-woocommerce' ) ); + } + $refund_id = absint( $id_components['id'] ); + } elseif ( ! empty( $args['refundId'] ) ) { + $refund_id = absint( $args['refundId'] ); + } elseif ( ! empty( $args['orderNumber'] ) ) { + $refund_id = 0; + } + + $refund = Factory::resolve_crud_object( $refund_id, $context ); + if ( get_post( $refund_id )->post_type !== 'shop_order_refund' ) { + /* translators: not refund found error message */ + throw new UserError( sprintf( __( 'No refund exists with this id: %1$s' ), $refund_id ) ); + } + + return $refund; + }, + ) + ); + } +} diff --git a/vendor/composer/autoload_classmap.php b/vendor/composer/autoload_classmap.php index a4475930..1fcf2238 100644 --- a/vendor/composer/autoload_classmap.php +++ b/vendor/composer/autoload_classmap.php @@ -28,6 +28,7 @@ return array( 'WPGraphQL\\Extensions\\WooCommerce\\Data\\Factory' => $baseDir . '/src/data/class-factory.php', 'WPGraphQL\\Extensions\\WooCommerce\\Data\\Loader\\WC_Crud_Loader' => $baseDir . '/src/data/loader/class-wc-crud-loader.php', 'WPGraphQL\\Extensions\\WooCommerce\\Data\\Loader\\WC_Customer_Loader' => $baseDir . '/src/data/loader/class-wc-customer-loader.php', + 'WPGraphQL\\Extensions\\WooCommerce\\Data\\Loader\\WC_Post_Crud_Loader' => $baseDir . '/src/data/loader/class-wc-post-crud-loader.php', 'WPGraphQL\\Extensions\\WooCommerce\\Filters' => $baseDir . '/src/class-filters.php', 'WPGraphQL\\Extensions\\WooCommerce\\Model\\Coupon' => $baseDir . '/src/model/class-coupon.php', 'WPGraphQL\\Extensions\\WooCommerce\\Model\\Crud_CPT' => $baseDir . '/src/model/class-crud-cpt.php', @@ -43,13 +44,23 @@ return array( 'WPGraphQL\\Extensions\\WooCommerce\\Type\\WPEnum\\Stock_Status' => $baseDir . '/src/type/enum/class-stock-status.php', 'WPGraphQL\\Extensions\\WooCommerce\\Type\\WPEnum\\Tax_Status' => $baseDir . '/src/type/enum/class-tax-status.php', 'WPGraphQL\\Extensions\\WooCommerce\\Type\\WPObject\\Coupon' => $baseDir . '/src/type/object/class-coupon.php', + 'WPGraphQL\\Extensions\\WooCommerce\\Type\\WPObject\\Coupon_Type' => $baseDir . '/src/type/object/class-coupon-type.php', 'WPGraphQL\\Extensions\\WooCommerce\\Type\\WPObject\\Customer' => $baseDir . '/src/type/object/class-customer.php', 'WPGraphQL\\Extensions\\WooCommerce\\Type\\WPObject\\Customer_Address' => $baseDir . '/src/type/object/class-customer-address.php', + 'WPGraphQL\\Extensions\\WooCommerce\\Type\\WPObject\\Customer_Address_Type' => $baseDir . '/src/type/object/class-customer-address-type.php', + 'WPGraphQL\\Extensions\\WooCommerce\\Type\\WPObject\\Customer_Type' => $baseDir . '/src/type/object/class-customer-type.php', 'WPGraphQL\\Extensions\\WooCommerce\\Type\\WPObject\\Order' => $baseDir . '/src/type/object/class-order.php', + 'WPGraphQL\\Extensions\\WooCommerce\\Type\\WPObject\\Order_Type' => $baseDir . '/src/type/object/class-order-type.php', 'WPGraphQL\\Extensions\\WooCommerce\\Type\\WPObject\\Product' => $baseDir . '/src/type/object/class-product.php', 'WPGraphQL\\Extensions\\WooCommerce\\Type\\WPObject\\Product_Attribute' => $baseDir . '/src/type/object/class-product-attribute.php', + 'WPGraphQL\\Extensions\\WooCommerce\\Type\\WPObject\\Product_Attribute_Type' => $baseDir . '/src/type/object/class-product-attribute-type.php', 'WPGraphQL\\Extensions\\WooCommerce\\Type\\WPObject\\Product_Download' => $baseDir . '/src/type/object/class-product-download.php', + 'WPGraphQL\\Extensions\\WooCommerce\\Type\\WPObject\\Product_Download_Type' => $baseDir . '/src/type/object/class-product-download-type.php', + 'WPGraphQL\\Extensions\\WooCommerce\\Type\\WPObject\\Product_Rating_Counter_Type' => $baseDir . '/src/type/object/class-product-rating-counter-type.php', + 'WPGraphQL\\Extensions\\WooCommerce\\Type\\WPObject\\Product_Type' => $baseDir . '/src/type/object/class-product-type.php', 'WPGraphQL\\Extensions\\WooCommerce\\Type\\WPObject\\Product_Variation' => $baseDir . '/src/type/object/class-product-variation.php', + 'WPGraphQL\\Extensions\\WooCommerce\\Type\\WPObject\\Product_Variation_Type' => $baseDir . '/src/type/object/class-product-variation-type.php', 'WPGraphQL\\Extensions\\WooCommerce\\Type\\WPObject\\Refund' => $baseDir . '/src/type/object/class-refund.php', + 'WPGraphQL\\Extensions\\WooCommerce\\Type\\WPObject\\Refund_Type' => $baseDir . '/src/type/object/class-refund-type.php', 'WP_GraphQL_WooCommerce' => $baseDir . '/src/class-wp-graphql-woocommerce.php', ); diff --git a/vendor/composer/autoload_static.php b/vendor/composer/autoload_static.php index 99d9e59f..5512a8e7 100644 --- a/vendor/composer/autoload_static.php +++ b/vendor/composer/autoload_static.php @@ -43,6 +43,7 @@ class ComposerStaticInitda6f462572baf38f85a5791b44ce68dc 'WPGraphQL\\Extensions\\WooCommerce\\Data\\Factory' => __DIR__ . '/../..' . '/src/data/class-factory.php', 'WPGraphQL\\Extensions\\WooCommerce\\Data\\Loader\\WC_Crud_Loader' => __DIR__ . '/../..' . '/src/data/loader/class-wc-crud-loader.php', 'WPGraphQL\\Extensions\\WooCommerce\\Data\\Loader\\WC_Customer_Loader' => __DIR__ . '/../..' . '/src/data/loader/class-wc-customer-loader.php', + 'WPGraphQL\\Extensions\\WooCommerce\\Data\\Loader\\WC_Post_Crud_Loader' => __DIR__ . '/../..' . '/src/data/loader/class-wc-post-crud-loader.php', 'WPGraphQL\\Extensions\\WooCommerce\\Filters' => __DIR__ . '/../..' . '/src/class-filters.php', 'WPGraphQL\\Extensions\\WooCommerce\\Model\\Coupon' => __DIR__ . '/../..' . '/src/model/class-coupon.php', 'WPGraphQL\\Extensions\\WooCommerce\\Model\\Crud_CPT' => __DIR__ . '/../..' . '/src/model/class-crud-cpt.php', @@ -58,14 +59,24 @@ class ComposerStaticInitda6f462572baf38f85a5791b44ce68dc 'WPGraphQL\\Extensions\\WooCommerce\\Type\\WPEnum\\Stock_Status' => __DIR__ . '/../..' . '/src/type/enum/class-stock-status.php', 'WPGraphQL\\Extensions\\WooCommerce\\Type\\WPEnum\\Tax_Status' => __DIR__ . '/../..' . '/src/type/enum/class-tax-status.php', 'WPGraphQL\\Extensions\\WooCommerce\\Type\\WPObject\\Coupon' => __DIR__ . '/../..' . '/src/type/object/class-coupon.php', + 'WPGraphQL\\Extensions\\WooCommerce\\Type\\WPObject\\Coupon_Type' => __DIR__ . '/../..' . '/src/type/object/class-coupon-type.php', 'WPGraphQL\\Extensions\\WooCommerce\\Type\\WPObject\\Customer' => __DIR__ . '/../..' . '/src/type/object/class-customer.php', 'WPGraphQL\\Extensions\\WooCommerce\\Type\\WPObject\\Customer_Address' => __DIR__ . '/../..' . '/src/type/object/class-customer-address.php', + 'WPGraphQL\\Extensions\\WooCommerce\\Type\\WPObject\\Customer_Address_Type' => __DIR__ . '/../..' . '/src/type/object/class-customer-address-type.php', + 'WPGraphQL\\Extensions\\WooCommerce\\Type\\WPObject\\Customer_Type' => __DIR__ . '/../..' . '/src/type/object/class-customer-type.php', 'WPGraphQL\\Extensions\\WooCommerce\\Type\\WPObject\\Order' => __DIR__ . '/../..' . '/src/type/object/class-order.php', + 'WPGraphQL\\Extensions\\WooCommerce\\Type\\WPObject\\Order_Type' => __DIR__ . '/../..' . '/src/type/object/class-order-type.php', 'WPGraphQL\\Extensions\\WooCommerce\\Type\\WPObject\\Product' => __DIR__ . '/../..' . '/src/type/object/class-product.php', 'WPGraphQL\\Extensions\\WooCommerce\\Type\\WPObject\\Product_Attribute' => __DIR__ . '/../..' . '/src/type/object/class-product-attribute.php', + 'WPGraphQL\\Extensions\\WooCommerce\\Type\\WPObject\\Product_Attribute_Type' => __DIR__ . '/../..' . '/src/type/object/class-product-attribute-type.php', 'WPGraphQL\\Extensions\\WooCommerce\\Type\\WPObject\\Product_Download' => __DIR__ . '/../..' . '/src/type/object/class-product-download.php', + 'WPGraphQL\\Extensions\\WooCommerce\\Type\\WPObject\\Product_Download_Type' => __DIR__ . '/../..' . '/src/type/object/class-product-download-type.php', + 'WPGraphQL\\Extensions\\WooCommerce\\Type\\WPObject\\Product_Rating_Counter_Type' => __DIR__ . '/../..' . '/src/type/object/class-product-rating-counter-type.php', + 'WPGraphQL\\Extensions\\WooCommerce\\Type\\WPObject\\Product_Type' => __DIR__ . '/../..' . '/src/type/object/class-product-type.php', 'WPGraphQL\\Extensions\\WooCommerce\\Type\\WPObject\\Product_Variation' => __DIR__ . '/../..' . '/src/type/object/class-product-variation.php', + 'WPGraphQL\\Extensions\\WooCommerce\\Type\\WPObject\\Product_Variation_Type' => __DIR__ . '/../..' . '/src/type/object/class-product-variation-type.php', 'WPGraphQL\\Extensions\\WooCommerce\\Type\\WPObject\\Refund' => __DIR__ . '/../..' . '/src/type/object/class-refund.php', + 'WPGraphQL\\Extensions\\WooCommerce\\Type\\WPObject\\Refund_Type' => __DIR__ . '/../..' . '/src/type/object/class-refund-type.php', 'WP_GraphQL_WooCommerce' => __DIR__ . '/../..' . '/src/class-wp-graphql-woocommerce.php', );